llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-hexagon Author: Brian Cain (androm3da) <details> <summary>Changes</summary> 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). --- Full diff: https://github.com/llvm/llvm-project/pull/180385.diff 2 Files Affected: - (modified) clang/lib/CodeGen/Targets/Hexagon.cpp (+1-1) - (modified) clang/test/CodeGen/hexagon-linux-vararg.c (+33) ``````````diff 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; +} `````````` </details> https://github.com/llvm/llvm-project/pull/180385 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
