llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Koakuma (koachan)

<details>
<summary>Changes</summary>

Unlike in registers (in which zero-size structs take up an argument slot), 
zero-sized structs take zero space when it's passed in the stack, so don't pad 
it.

Additionally, in that case we need to turn off flattening too, since the 
argument technically should still appear in the list instead of being flattened 
away. This is needed to make argument loading from stack slots still work in 
the presence of zero-sized struct arguments.

This should fix the ABI mismatch with GCC as reported in 
https://github.com/llvm/llvm-project/issues/213561.

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


2 Files Affected:

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


``````````diff
diff --git a/clang/lib/CodeGen/Targets/Sparc.cpp 
b/clang/lib/CodeGen/Targets/Sparc.cpp
index 25f0009fe7a09..b6a3e37dd6bbd 100644
--- a/clang/lib/CodeGen/Targets/Sparc.cpp
+++ b/clang/lib/CodeGen/Targets/Sparc.cpp
@@ -371,17 +371,25 @@ ABIArgInfo SparcV9ABIInfo::classifyType(QualType Ty, 
unsigned SizeLimit,
 
   CoerceBuilder CB(VMContext, getDataLayout());
   CB.addStruct(0, StrTy);
-  // 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(), uint64_t(1)),
-      64));
+
+  // All structs, even empty ones, should take up a register argument slot, so
+  // pin the minimum struct size to one bit. However, empty structs don't take
+  // up any stack slot, so only do it on register arguments (i.e. the first
+  // six).
+  bool IsStackArgument = RegOffset > 5;
+  uint64_t ActualSize = CB.DL.getTypeSizeInBits(StrTy).getKnownMinValue();
+  uint64_t ExpandedSize = std::max(ActualSize, uint64_t(1));
+  if (IsStackArgument)
+    ExpandedSize = ActualSize;
+
+  CB.pad(llvm::alignTo(ExpandedSize, 64));
   RegOffset += PaddingSlots + CB.Size / 64;
 
   // Try to use the original type for coercion.
   llvm::Type *CoerceTy = CB.isUsableType(StrTy) ? StrTy : CB.getType();
 
-  ABIArgInfo AAI = ABIArgInfo::getDirect(CoerceTy, 0, Padding);
+  ABIArgInfo AAI = ABIArgInfo::getDirect(CoerceTy, 0, Padding,
+                                         !IsStackArgument && ExpandedSize == 
0);
   AAI.setInReg(CB.InReg);
   return AAI;
 }
diff --git a/clang/test/CodeGen/Sparc/sparcv9-abi.c 
b/clang/test/CodeGen/Sparc/sparcv9-abi.c
index 61849fc00ed12..ce8fa1ef0bb1b 100644
--- a/clang/test/CodeGen/Sparc/sparcv9-abi.c
+++ b/clang/test/CodeGen/Sparc/sparcv9-abi.c
@@ -21,7 +21,8 @@ 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; }
 
-// Zero-sized structs reserves an argument register slot if passed directly.
+// Zero-sized structs reserves an argument register slot, but not argument
+// stack slots, if passed directly.
 struct empty {};
 struct emptyarr { struct empty a[10]; };
 
@@ -37,6 +38,11 @@ struct empty f_empty(struct empty x) { return x; }
 // CHECK-LABEL: define{{.*}} i64 @f_emptyarr(i64 %x.coerce)
 struct empty f_emptyarr(struct emptyarr x) { return x.a[0]; }
 
+// CHECK-LABEL: define{{.*}} i64 @f_emptystackarg(i64 %a0.coerce, i64 
%a1.coerce, i64 %a2.coerce, i64 %a3.coerce, i64 %a4.coerce, i64 %a5.coerce, 
%struct.empty %a6.coerce, %struct.empty %a7.coerce)
+struct empty f_emptystackarg(struct empty a0, struct empty a1, struct empty 
a2, struct empty a3, struct empty a4, struct empty a5, struct empty a6, struct 
empty a7) {
+    return a7;
+}
+
 // CHECK-LABEL: define{{.*}} void @f_aligncaller(i64 %a.coerce0, i64 
%a.coerce1)
 // CHECK-LABEL: declare{{.*}} void @f_aligncallee(i32 noundef signext, i64, 
i64, i64)
 void f_aligncallee(int pad, struct align16_int a);

``````````

</details>


https://github.com/llvm/llvm-project/pull/217065
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to