https://github.com/folkertdev created 
https://github.com/llvm/llvm-project/pull/213739

So that later arguments get the correct register alignment

https://godbolt.org/z/oaEf4Thvx

On current clang the aligned struct starts in `o1`, but with clang it is 
aligned and starts in `o2`. In practice I think only `float` could hit this 
(not an int, not an aggregate, smaller than 64 bits).

>From c7abf575e87e19aeb7a47332f751b43fdde380cb Mon Sep 17 00:00:00 2001
From: Folkert de Vries <[email protected]>
Date: Mon, 3 Aug 2026 16:20:40 +0200
Subject: [PATCH] [SPARC] use `divideCeil` to calculate register offset

So that over-aligned values get the correct register alignment
---
 clang/lib/CodeGen/Targets/Sparc.cpp    |  4 ++--
 clang/test/CodeGen/Sparc/sparcv9-abi.c | 10 ++++++++++
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/Targets/Sparc.cpp 
b/clang/lib/CodeGen/Targets/Sparc.cpp
index 3fa4e84823d51..f497637bc3e47 100644
--- a/clang/lib/CodeGen/Targets/Sparc.cpp
+++ b/clang/lib/CodeGen/Targets/Sparc.cpp
@@ -279,7 +279,7 @@ ABIArgInfo SparcV9ABIInfo::classifyType(QualType Ty, 
unsigned SizeLimit,
 
   // Other non-aggregates go in registers.
   if (!isAggregateTypeForABI(Ty)) {
-    RegOffset += Size / 64;
+    RegOffset += llvm::divideCeil(Size, 64);
     return ABIArgInfo::getDirect();
   }
 
@@ -295,7 +295,7 @@ ABIArgInfo SparcV9ABIInfo::classifyType(QualType Ty, 
unsigned SizeLimit,
   // Build a coercion type from the LLVM struct type.
   llvm::StructType *StrTy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty));
   if (!StrTy) {
-    RegOffset += Size / 64;
+    RegOffset += llvm::divideCeil(Size, 64);
     return ABIArgInfo::getDirect();
   }
 
diff --git a/clang/test/CodeGen/Sparc/sparcv9-abi.c 
b/clang/test/CodeGen/Sparc/sparcv9-abi.c
index 94c91e05a9d99..d33fd7ba3cde2 100644
--- a/clang/test/CodeGen/Sparc/sparcv9-abi.c
+++ b/clang/test/CodeGen/Sparc/sparcv9-abi.c
@@ -54,6 +54,16 @@ long double f_longdouble(long a, struct align16_longdouble 
b) {
        return b.x;
 }
 
+// CHECK-LABEL: define{{.*}} signext i32 @f_float_aligned(float noundef %a, 
i64 %0, i64 %b.coerce0, i64 %b.coerce1)
+int f_float_aligned(float a, struct align16_int b) {
+       return b.x;
+}
+
+// CHECK-LABEL: define{{.*}} signext i32 @f_float_pair_aligned(float noundef 
%a, float noundef %b, i64 %c.coerce0, i64 %c.coerce1)
+int f_float_pair_aligned(float a, float b, struct align16_int c) {
+       return c.x;
+}
+
 // CHECK-LABEL: define{{.*}} i64 @f_emptyvar(i32 noundef zeroext %count, ...)
 long f_emptyvar(unsigned count, ...) {
     long ret;

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

Reply via email to