Issue |
148536
|
Summary |
[Clang][RISCV] Unexpectedly lost writes to C99 flexible array member when guaranteed return copy elision should apply
|
Labels |
clang
|
Assignees |
|
Reporter |
resistor
|
Consider a function on RV32 that returns this struct by value:
```
struct FooStruct {
int a;
int b;
int c[];
};
FooStruct foo() {
FooStruct ret;
ret.a = 0;
ret.b = 0;
ret.c[0] = 0x124512;
ret.c[1] = 0x535;
return ret;
}
```
Because of guaranteed return copy elision in C++17, the caller of `foo` should be allocating space for the return value, and providing a hidden "out" parameter for `foo` to write through.
This is complicated in this case because this struct hits the case in the RV ABI where two XLEN-size members are passed in registers rather than on the stack.
What I would expect to happen is that `a` and `b` are returned in registers, and an out-pointer is taken as an argument and used to write to `c`.
What actually seems to happen is that the writes to `c` are entirely elided: https://godbolt.org/z/P7b1TzjTq
```
foo():
li a0, 0
li a1, 0
ret
```
If the types of the `a` and `b` fields are changed to `long long` (thereby avoiding the two-XLEN-sized-fields ABI case), then the writes to `c` are suddenly preserved!
```
foo():
sw zero, 0(a0)
sw zero, 4(a0)
sw zero, 8(a0)
sw zero, 12(a0)
lui a1, 292
li a2, 1333
addi a1, a1, 1298
sw a1, 16(a0)
sw a2, 20(a0)
ret
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs