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
