https://github.com/androm3da created 
https://github.com/llvm/llvm-project/pull/180385

Use ConstantInt::getSigned instead of ConstantInt::get when creating a negative 
alignment mask in EmitVAArgFromMemory. This is the same fix as commit 
8546294db95d (PR #176115) which addressed the issue in EmitVAArgForHexagonLinux.

Added a test case that exercises the EmitVAArgFromMemory alignment path using a 
struct that is both >8 bytes (to trigger EmitVAArgFromMemory) and has 8-byte 
alignment (to trigger the alignment masking code).

>From 6c80a57814c1d113501d009abd9378d7305900ce Mon Sep 17 00:00:00 2001
From: Brian Cain <[email protected]>
Date: Sat, 7 Feb 2026 19:38:25 -0800
Subject: [PATCH] [Hexagon] Fix signed constant creation in EmitVAArgFromMemory

Use ConstantInt::getSigned instead of ConstantInt::get when creating
a negative alignment mask in EmitVAArgFromMemory. This is the same fix
as commit 8546294db95d (PR #176115) which addressed the issue
in EmitVAArgForHexagonLinux.

Added a test case that exercises the EmitVAArgFromMemory alignment path
using a struct that is both >8 bytes (to trigger EmitVAArgFromMemory)
and has 8-byte alignment (to trigger the alignment masking code).
---
 clang/lib/CodeGen/Targets/Hexagon.cpp     |  2 +-
 clang/test/CodeGen/hexagon-linux-vararg.c | 33 +++++++++++++++++++++++
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/Targets/Hexagon.cpp 
b/clang/lib/CodeGen/Targets/Hexagon.cpp
index f334a7f7012d9..7e4eb0fff8e24 100644
--- a/clang/lib/CodeGen/Targets/Hexagon.cpp
+++ b/clang/lib/CodeGen/Targets/Hexagon.cpp
@@ -210,7 +210,7 @@ Address HexagonABIInfo::EmitVAArgFromMemory(CodeGenFunction 
&CGF,
 
     // Create a mask which should be "AND"ed
     // with (overflow_arg_area + align - 1)
-    llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int32Ty, -(int)Align);
+    llvm::Value *Mask = llvm::ConstantInt::getSigned(CGF.Int32Ty, -(int)Align);
     __overflow_area_pointer = CGF.Builder.CreateIntToPtr(
         CGF.Builder.CreateAnd(AsInt, Mask), __overflow_area_pointer->getType(),
         "__overflow_area_pointer.align");
diff --git a/clang/test/CodeGen/hexagon-linux-vararg.c 
b/clang/test/CodeGen/hexagon-linux-vararg.c
index 11722e27f751c..da3bdd1e40392 100644
--- a/clang/test/CodeGen/hexagon-linux-vararg.c
+++ b/clang/test/CodeGen/hexagon-linux-vararg.c
@@ -153,3 +153,36 @@ int foo(int xx, ...) {
 long long test_align(va_list args) {
   return va_arg(args, long long);
 }
+
+// Struct > 8 bytes with 8-byte alignment to test EmitVAArgFromMemory 
alignment.
+// This triggers the alignment masking code where -(int)Align must use 
getSigned.
+struct LargeAligned {
+  long long x;
+  int y;
+};
+
+// CHECK-LABEL: define dso_local i64 @test_large_aligned_vaarg(
+// CHECK-SAME: ptr noundef [[ARGS:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[ARGS_ADDR:%.*]] = alloca ptr, align 4
+// CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_LARGEALIGNED:%.*]], align 8
+// CHECK-NEXT:    store ptr [[ARGS]], ptr [[ARGS_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[ARGS_ADDR]], align 4
+// CHECK-NEXT:    [[__OVERFLOW_AREA_POINTER_P:%.*]] = getelementptr inbounds 
nuw [[STRUCT___VA_LIST_TAG:%.*]], ptr [[TMP0]], i32 0, i32 2
+// CHECK-NEXT:    [[__OVERFLOW_AREA_POINTER:%.*]] = load ptr, ptr 
[[__OVERFLOW_AREA_POINTER_P]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i8, ptr 
[[__OVERFLOW_AREA_POINTER]], i64 7
+// CHECK-NEXT:    [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i32
+// The mask must be -8 (0xFFFFFFF8), not a large positive number.
+// CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP2]], -8
+// CHECK-NEXT:    [[__OVERFLOW_AREA_POINTER_ALIGN:%.*]] = inttoptr i32 
[[TMP3]] to ptr
+// CHECK-NEXT:    [[__OVERFLOW_AREA_POINTER_NEXT:%.*]] = getelementptr i8, ptr 
[[__OVERFLOW_AREA_POINTER_ALIGN]], i32 16
+// CHECK-NEXT:    store ptr [[__OVERFLOW_AREA_POINTER_NEXT]], ptr 
[[__OVERFLOW_AREA_POINTER_P]], align 4
+// CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 8 [[S]], ptr 
align 8 [[__OVERFLOW_AREA_POINTER_ALIGN]], i32 16, i1 false)
+// CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds nuw 
[[STRUCT_LARGEALIGNED]], ptr [[S]], i32 0, i32 0
+// CHECK-NEXT:    [[TMP4:%.*]] = load i64, ptr [[X]], align 8
+// CHECK-NEXT:    ret i64 [[TMP4]]
+//
+long long test_large_aligned_vaarg(va_list args) {
+  struct LargeAligned s = va_arg(args, struct LargeAligned);
+  return s.x;
+}

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

Reply via email to