[clang] [SPARC] use `divideCeil` to calculate register offset (PR #213739)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 3 12:03:44 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-sparc
Author: Folkert de Vries (folkertdev)
<details>
<summary>Changes</summary>
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).
---
Full diff: https://github.com/llvm/llvm-project/pull/213739.diff
2 Files Affected:
- (modified) clang/lib/CodeGen/Targets/Sparc.cpp (+2-2)
- (modified) clang/test/CodeGen/Sparc/sparcv9-abi.c (+10)
``````````diff
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;
``````````
</details>
https://github.com/llvm/llvm-project/pull/213739
More information about the cfe-commits
mailing list