[clang] [clang][SPARC] Treat empty structs as if it's a one-bit type in the CC (PR #90338)

via cfe-commits cfe-commits at lists.llvm.org
Sat Apr 27 04:07:00 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-sparc

@llvm/pr-subscribers-clang-codegen

Author: Koakuma (koachan)

<details>
<summary>Changes</summary>

Make sure that empty structs are treated as if it has a size of one bit in function parameters and return types so that it occupies a full argument and/or return register slot.

This fixes crashes and miscompilations when passing and/or returning empty structs.

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


2 Files Affected:

- (modified) clang/lib/CodeGen/Targets/Sparc.cpp (+4-1) 
- (modified) clang/test/CodeGen/sparcv9-abi.c (+6) 


``````````diff
diff --git a/clang/lib/CodeGen/Targets/Sparc.cpp b/clang/lib/CodeGen/Targets/Sparc.cpp
index 9025a633f328e2..b82e9a69e19671 100644
--- a/clang/lib/CodeGen/Targets/Sparc.cpp
+++ b/clang/lib/CodeGen/Targets/Sparc.cpp
@@ -263,7 +263,10 @@ SparcV9ABIInfo::classifyType(QualType Ty, unsigned SizeLimit) const {
 
   CoerceBuilder CB(getVMContext(), getDataLayout());
   CB.addStruct(0, StrTy);
-  CB.pad(llvm::alignTo(CB.DL.getTypeSizeInBits(StrTy), 64));
+  // All structs, even empty ones, should take up a register argument slot,
+  // so pin the minimum struct size to one bit.
+  CB.pad(llvm::alignTo(
+      std::max(CB.DL.getTypeSizeInBits(StrTy).getKnownMinValue(), 1UL), 64));
 
   // Try to use the original type for coercion.
   llvm::Type *CoerceTy = CB.isUsableType(StrTy) ? StrTy : CB.getType();
diff --git a/clang/test/CodeGen/sparcv9-abi.c b/clang/test/CodeGen/sparcv9-abi.c
index 5e74a9a883cefa..360bd9d9019e56 100644
--- a/clang/test/CodeGen/sparcv9-abi.c
+++ b/clang/test/CodeGen/sparcv9-abi.c
@@ -21,6 +21,12 @@ char f_int_4(char x) { return x; }
 // CHECK-LABEL: define{{.*}} fp128 @f_ld(fp128 noundef %x)
 long double f_ld(long double x) { return x; }
 
+// Empty struct is lowered as a placeholder word parameter.
+struct empty {};
+
+// CHECK-LABEL: define{{.*}} i64 @f_empty(i64 %x.coerce)
+struct empty f_empty(struct empty x) { return x; }
+
 // Small structs are passed in registers.
 struct small {
   int *a, *b;

``````````

</details>


https://github.com/llvm/llvm-project/pull/90338


More information about the cfe-commits mailing list