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