llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-clang

Author: Owen Anderson (resistor)

<details>
<summary>Changes</summary>

This fixes an issue reported in 
https://github.com/llvm/llvm-project/issues/148536 where
writes to flexible array members would sometimes be lost if the struct happened 
to hit
one of the cases where it would be passed in GPRs rather than on the stack.


---
Full diff: https://github.com/llvm/llvm-project/pull/148541.diff


2 Files Affected:

- (modified) clang/lib/CodeGen/Targets/RISCV.cpp (+4) 
- (added) clang/test/CodeGen/RISCV/abi-flexible-array-members.cpp (+46) 


``````````diff
diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp 
b/clang/lib/CodeGen/Targets/RISCV.cpp
index e3232b61a693c..5bf0f29903f56 100644
--- a/clang/lib/CodeGen/Targets/RISCV.cpp
+++ b/clang/lib/CodeGen/Targets/RISCV.cpp
@@ -609,6 +609,10 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, 
bool IsFixed,
   if (isEmptyRecord(getContext(), Ty, true) && Size == 0)
     return ABIArgInfo::getIgnore();
 
+  // Structures with flexible arrays are always indirect.
+  if (Ty->isStructureTypeWithFlexibleArrayMember())
+    return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
+
   // Pass floating point values via FPRs if possible.
   if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() &&
       FLen >= Size && ArgFPRsLeft) {
diff --git a/clang/test/CodeGen/RISCV/abi-flexible-array-members.cpp 
b/clang/test/CodeGen/RISCV/abi-flexible-array-members.cpp
new file mode 100644
index 0000000000000..b6f25982fd3f6
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/abi-flexible-array-members.cpp
@@ -0,0 +1,46 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --filter "^define |^entry:" --version 2
+// RUN: %clang_cc1 -x c++ -triple riscv32 -target-feature +f -target-abi 
ilp32f -emit-llvm %s -o - \
+// RUN:   | FileCheck -check-prefixes=CHECK32 %s
+// RUN: %clang_cc1 -x c++ -triple riscv32 -target-feature +f -target-feature 
+d -target-abi ilp32d -emit-llvm %s -o - \
+// RUN:   | FileCheck -check-prefixes=CHECK32 %s
+// RUN: %clang_cc1 -x c++ -triple riscv64 -target-feature +f -target-abi lp64f 
-emit-llvm %s -o - \
+// RUN:   | FileCheck -check-prefixes=CHECK64 %s
+// RUN: %clang_cc1 -x c++ -triple riscv64 -target-feature +f -target-feature 
+d -target-abi lp64d -emit-llvm %s -o - \
+// RUN:   | FileCheck -check-prefixes=CHECK64 %s
+
+#include <stdint.h>
+
+// Structs containing C99 flexible array members should always be passed and 
returned on the stack.
+
+struct s1 {
+    int a;
+    int b[];
+};
+
+// CHECK32-LABEL: define dso_local void @_Z7test_012s1
+// CHECK32-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S1:%.*]]) 
align 4 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_S1]]) align 4 [[A:%.*]]) 
#[[ATTR0:[0-9]+]] {
+// CHECK32:  entry:
+//
+// CHECK64-LABEL: define dso_local void @_Z7test_012s1
+// CHECK64-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S1:%.*]]) 
align 4 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_S1]]) align 4 [[A:%.*]]) 
#[[ATTR0:[0-9]+]] {
+// CHECK64:  entry:
+//
+struct s1 test_01(struct s1 a) {
+  return a;
+}
+
+
+// CHECK32-LABEL: define dso_local void @_Z7test_02v
+// CHECK32-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S1:%.*]]) 
align 4 [[AGG_RESULT:%.*]]) #[[ATTR0]] {
+// CHECK32:  entry:
+//
+// CHECK64-LABEL: define dso_local void @_Z7test_02v
+// CHECK64-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S1:%.*]]) 
align 4 [[AGG_RESULT:%.*]]) #[[ATTR0]] {
+// CHECK64:  entry:
+//
+struct s1 test_02() {
+    struct s1 r;
+    r.a = 0;
+    r.b[0] = 1;
+    return r;
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/148541
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to