Skip to content

Bitfield structs that could fit in a single register are still returned by reference #10

Description

@pizzarollsroyce

Bitfield structs that have fewer than 32 bits of data should be returned in r10 as they should, but seem to only do that in some cases.

Test code:

#include <stdint.h>
struct TwoBits {
  uint16_t a: 1;
  uint16_t b: 1;
};
struct ThreeBits {
  uint16_t a: 1;
  uint16_t b: 1;
  uint16_t c: 1;
};

extern struct TwoBits MakeTwoBits() {
  struct TwoBits ret = {};
  ret.a = 1;
  return ret;
}

extern struct ThreeBits MakeThreeBits() {
  struct ThreeBits ret = {};
  ret.a = 1;
  return ret;
}

Compiled with clang -O2 -c struct_return.c -o struct_return.clang.o

Result:

00000000 <MakeTwoBits>:
       0: 41 41        	mov 0x1, r10
       2: 1f 18        	jmp [r31]

00000004 <MakeThreeBits>:
       4: e1 40        	mov 0x1, r7
       6: e6 d4 00 00  	st.h r7, 0x0[r6]
       a: 1f 18        	jmp [r31]

Note that the 3-field struct is now returned via a write to the pointer provided in r6.

Conversely, with GCC v810 (v810-gcc -O2 -c struct_return.c -o struct_return.o)

00000000 <_MakeTwoBits>:
   0:	41 41       	mov	1, r10
   2:	1f 18       	jmp	lp

00000004 <_MakeThreeBits>:
   4:	41 41       	mov	1, r10
   6:	1f 18       	jmp	lp

Changing the uint16_ts to uint8_ts doesn't increase this from 2 (so, it's not like it's erroneously adding up the entire bit widths of the primitive type or something).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions