Currently we expand `{}` and store zeros to the stack and then do a full mode load back. This is a waste, instead we should just use the zero cst in the mode that fits the bitsize.
Boostrapped and tested on x86_64-linux-gnu. Build and tested for aarch64-linux-gnu. PR middle-end/110459 gcc/ChangeLog: * expr.cc (store_field): For `{}` exp where bitsize is known to be less than BITS_PER_WORD, use zero cst. gcc/testsuite/ChangeLog: * g++.target/aarch64/array-return-1.C: New test. * g++.target/i386/array-return-1.C: New test. Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com> --- gcc/expr.cc | 10 ++++++++- .../g++.target/aarch64/array-return-1.C | 22 +++++++++++++++++++ .../g++.target/i386/array-return-1.C | 20 +++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.target/aarch64/array-return-1.C create mode 100644 gcc/testsuite/g++.target/i386/array-return-1.C diff --git a/gcc/expr.cc b/gcc/expr.cc index 1eeefa1cadc..af03809cad8 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -8243,7 +8243,15 @@ store_field (rtx target, poly_int64 bitsize, poly_int64 bitpos, } } - temp = expand_normal (exp); + if (TREE_CODE (exp) == CONSTRUCTOR + && CONSTRUCTOR_NELTS (exp) == 0 + && known_le (bitsize, BITS_PER_WORD)) + { + machine_mode temp_mode = smallest_int_mode_for_size (bitsize).require (); + temp = CONST0_RTX (temp_mode); + } + else + temp = expand_normal (exp); /* We don't support variable-sized BLKmode bitfields, since our handling of BLKmode is bound up with the ability to break diff --git a/gcc/testsuite/g++.target/aarch64/array-return-1.C b/gcc/testsuite/g++.target/aarch64/array-return-1.C new file mode 100644 index 00000000000..7c0aa480775 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/array-return-1.C @@ -0,0 +1,22 @@ +// { dg-do compile } +// { dg-options "-O2" } +// { dg-final { check-function-bodies "**" "" "" { target { le } } } } + +// PR middle-end/110459 + +/* +**_Z7sample2c: +** and w0, w0, 255 +** ret +*/ + +struct array { + char data[4]; +}; + +// There should be no adjustment to the stack +// { dg-final { scan-assembler-not "sp, sp," } } +auto sample2(char c) { + array buffer = {c, 0, 0, 0}; + return buffer; +} diff --git a/gcc/testsuite/g++.target/i386/array-return-1.C b/gcc/testsuite/g++.target/i386/array-return-1.C new file mode 100644 index 00000000000..f11905d01e5 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/array-return-1.C @@ -0,0 +1,20 @@ +// { dg-do compile } +// { dg-options "-O2" } +// { dg-final { check-function-bodies "**" "" "" { target { ! ia32 } } } } + +// PR middle-end/110459 + +/* +**_Z7sample2c: +** movzbl %dil, %eax +** ret +*/ + +struct array { + char data[4]; +}; + +array sample2(char c) { + array buffer = {c, 0, 0, 0}; + return buffer; +} -- 2.43.0