diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -879,6 +879,8 @@ - Fix interaction of ``-mcpu`` and ``-march``, RISC-V backend will take the architecture extension union of ``-mcpu`` and ``-march`` before, and now will take architecture extensions from ``-march`` if both are given. +- An ABI mismatch between GCC and Clang that related to the + sign/zero-extension of integer scalars was fixed. X86 Support in Clang -------------------- diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -11008,11 +11008,6 @@ } } - // We must track the number of GPRs used in order to conform to the RISC-V - // ABI, as integer scalars passed in registers should have signext/zeroext - // when promoted, but are anyext if passed on the stack. As GPR usage is - // different for variadic arguments, we must also track whether we are - // examining a vararg or not. int ArgGPRsLeft = IsRetIndirect ? NumArgGPRs - 1 : NumArgGPRs; int ArgFPRsLeft = FLen ? NumArgFPRs : 0; int NumFixedArgs = FI.getNumRequiredArgs(); @@ -11290,7 +11285,6 @@ } uint64_t NeededAlign = getContext().getTypeAlign(Ty); - bool MustUseStack = false; // Determine the number of GPRs needed to pass the current argument // according to the ABI. 2*XLen-aligned varargs are passed in "aligned" // register pairs, so may consume 3 registers. @@ -11301,7 +11295,6 @@ NeededArgGPRs = 2; if (NeededArgGPRs > ArgGPRsLeft) { - MustUseStack = true; NeededArgGPRs = ArgGPRsLeft; } @@ -11312,14 +11305,13 @@ if (const EnumType *EnumTy = Ty->getAs()) Ty = EnumTy->getDecl()->getIntegerType(); - // All integral types are promoted to XLen width, unless passed on the - // stack. - if (Size < XLen && Ty->isIntegralOrEnumerationType() && !MustUseStack) { + // All integral types are promoted to XLen width + if (Size < XLen && Ty->isIntegralOrEnumerationType()) { return extendType(Ty); } if (const auto *EIT = Ty->getAs()) { - if (EIT->getNumBits() < XLen && !MustUseStack) + if (EIT->getNumBits() < XLen) return extendType(Ty); if (EIT->getNumBits() > 128 || (!getContext().getTargetInfo().hasInt128Type() && diff --git a/clang/test/CodeGen/RISCV/riscv32-ilp32-abi.c b/clang/test/CodeGen/RISCV/riscv32-ilp32-abi.c --- a/clang/test/CodeGen/RISCV/riscv32-ilp32-abi.c +++ b/clang/test/CodeGen/RISCV/riscv32-ilp32-abi.c @@ -22,20 +22,16 @@ int32_t a, b, c, d; }; -// Scalars passed on the stack should not have signext/zeroext attributes -// (they are anyext). +// Scalars passed on the stack should have signext/zeroext attributes, just as +// if they were passed in registers. -// CHECK-LABEL: define{{.*}} i32 @f_scalar_stack_1(i32 noundef %a, i64 noundef %b, float noundef %c, double noundef %d, fp128 noundef %e, i8 noundef zeroext %f, i8 noundef %g, i8 noundef %h) +// CHECK-LABEL: define{{.*}} i32 @f_scalar_stack_1(i32 noundef %a, i64 noundef %b, float noundef %c, double noundef %d, fp128 noundef %e, i8 noundef zeroext %f, i8 noundef signext %g, i8 noundef zeroext %h) int f_scalar_stack_1(int32_t a, int64_t b, float c, double d, long double e, uint8_t f, int8_t g, uint8_t h) { return g + h; } -// Ensure that scalars passed on the stack are still determined correctly in -// the presence of large return values that consume a register due to the need -// to pass a pointer. - -// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr noalias sret(%struct.large) align 4 %agg.result, float noundef %a, i64 noundef %b, double noundef %c, fp128 noundef %d, i8 noundef zeroext %e, i8 noundef %f, i8 noundef %g) +// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr noalias sret(%struct.large) align 4 %agg.result, float noundef %a, i64 noundef %b, double noundef %c, fp128 noundef %d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g) struct large f_scalar_stack_2(float a, int64_t b, double c, long double d, uint8_t e, int8_t f, uint8_t g) { return (struct large){a, e, f, g}; diff --git a/clang/test/CodeGen/RISCV/riscv32-ilp32-ilp32f-abi.c b/clang/test/CodeGen/RISCV/riscv32-ilp32-ilp32f-abi.c --- a/clang/test/CodeGen/RISCV/riscv32-ilp32-ilp32f-abi.c +++ b/clang/test/CodeGen/RISCV/riscv32-ilp32-ilp32f-abi.c @@ -24,20 +24,16 @@ int32_t a, b, c, d; }; -// Scalars passed on the stack should not have signext/zeroext attributes -// (they are anyext). +// Scalars passed on the stack should have signext/zeroext attributes, just as +// if they were passed in registers. -// CHECK-LABEL: define{{.*}} i32 @f_scalar_stack_1(i32 noundef %a, i64 noundef %b, i32 noundef %c, double noundef %d, fp128 noundef %e, i8 noundef zeroext %f, i8 noundef %g, i8 noundef %h) +// CHECK-LABEL: define{{.*}} i32 @f_scalar_stack_1(i32 noundef %a, i64 noundef %b, i32 noundef %c, double noundef %d, fp128 noundef %e, i8 noundef zeroext %f, i8 noundef signext %g, i8 noundef zeroext %h) int f_scalar_stack_1(int32_t a, int64_t b, int32_t c, double d, long double e, uint8_t f, int8_t g, uint8_t h) { return g + h; } -// Ensure that scalars passed on the stack are still determined correctly in -// the presence of large return values that consume a register due to the need -// to pass a pointer. - -// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr noalias sret(%struct.large) align 4 %agg.result, i32 noundef %a, i64 noundef %b, double noundef %c, fp128 noundef %d, i8 noundef zeroext %e, i8 noundef %f, i8 noundef %g) +// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr noalias sret(%struct.large) align 4 %agg.result, i32 noundef %a, i64 noundef %b, double noundef %c, fp128 noundef %d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g) struct large f_scalar_stack_2(int32_t a, int64_t b, double c, long double d, uint8_t e, int8_t f, uint8_t g) { return (struct large){a, e, f, g}; diff --git a/clang/test/CodeGen/RISCV/riscv32-ilp32-ilp32f-ilp32d-abi.c b/clang/test/CodeGen/RISCV/riscv32-ilp32-ilp32f-ilp32d-abi.c --- a/clang/test/CodeGen/RISCV/riscv32-ilp32-ilp32f-ilp32d-abi.c +++ b/clang/test/CodeGen/RISCV/riscv32-ilp32-ilp32f-ilp32d-abi.c @@ -194,10 +194,10 @@ return (v16i8){1, 2, 3, 4, 5, 6, 7, 8}; } -// Scalars passed on the stack should not have signext/zeroext attributes -// (they are anyext). +// Scalars passed on the stack should have signext/zeroext attributes, just as +// if they were passed in registers -// CHECK-LABEL: define{{.*}} i32 @f_scalar_stack_1(i32 %a.coerce, [2 x i32] %b.coerce, i64 %c.coerce, ptr noundef %d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef %g, i8 noundef %h) +// CHECK-LABEL: define{{.*}} i32 @f_scalar_stack_1(i32 %a.coerce, [2 x i32] %b.coerce, i64 %c.coerce, ptr noundef %d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g, i8 noundef signext %h) int f_scalar_stack_1(struct tiny a, struct small b, struct small_aligned c, struct large d, uint8_t e, int8_t f, uint8_t g, int8_t h) { return g + h; @@ -207,13 +207,13 @@ // the presence of large return values that consume a register due to the need // to pass a pointer. -// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr noalias sret(%struct.large) align 4 %agg.result, i32 noundef %a, i64 noundef %b, i64 noundef %c, fp128 noundef %d, i8 noundef zeroext %e, i8 noundef %f, i8 noundef %g) +// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr noalias sret(%struct.large) align 4 %agg.result, i32 noundef %a, i64 noundef %b, i64 noundef %c, fp128 noundef %d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g) struct large f_scalar_stack_2(int32_t a, int64_t b, int64_t c, long double d, uint8_t e, int8_t f, uint8_t g) { return (struct large){a, e, f, g}; } -// CHECK-LABEL: define{{.*}} fp128 @f_scalar_stack_4(i32 noundef %a, i64 noundef %b, i64 noundef %c, fp128 noundef %d, i8 noundef zeroext %e, i8 noundef %f, i8 noundef %g) +// CHECK-LABEL: define{{.*}} fp128 @f_scalar_stack_4(i32 noundef %a, i64 noundef %b, i64 noundef %c, fp128 noundef %d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g) long double f_scalar_stack_4(int32_t a, int64_t b, int64_t c, long double d, uint8_t e, int8_t f, uint8_t g) { return d; diff --git a/clang/test/CodeGen/RISCV/riscv32-ilp32f-abi.c b/clang/test/CodeGen/RISCV/riscv32-ilp32f-abi.c --- a/clang/test/CodeGen/RISCV/riscv32-ilp32f-abi.c +++ b/clang/test/CodeGen/RISCV/riscv32-ilp32f-abi.c @@ -3,10 +3,7 @@ #include -// Doubles are still passed in GPRs, so the 'e' argument will be anyext as -// GPRs are exhausted. - -// CHECK: define{{.*}} void @f_fpr_tracking(double noundef %a, double noundef %b, double noundef %c, double noundef %d, i8 noundef %e) +// CHECK: define{{.*}} void @f_fpr_tracking(double noundef %a, double noundef %b, double noundef %c, double noundef %d, i8 noundef signext %e) void f_fpr_tracking(double a, double b, double c, double d, int8_t e) {} // Lowering for doubles is unnmodified, as 64 > FLEN. diff --git a/clang/test/CodeGen/RISCV/riscv64-lp64-abi.c b/clang/test/CodeGen/RISCV/riscv64-lp64-abi.c --- a/clang/test/CodeGen/RISCV/riscv64-lp64-abi.c +++ b/clang/test/CodeGen/RISCV/riscv64-lp64-abi.c @@ -12,20 +12,16 @@ typedef unsigned char v32i8 __attribute__((vector_size(32))); -// Scalars passed on the stack should not have signext/zeroext attributes -// (they are anyext). +// Scalars passed on the stack should have signext/zeroext attributes, just as +// if they were passed in registers. -// CHECK-LABEL: define{{.*}} signext i32 @f_scalar_stack_1(i32 noundef signext %a, i128 noundef %b, float noundef %c, fp128 noundef %d, ptr noundef %0, i8 noundef zeroext %f, i8 noundef %g, i8 noundef %h) +// CHECK-LABEL: define{{.*}} signext i32 @f_scalar_stack_1(i32 noundef signext %a, i128 noundef %b, float noundef %c, fp128 noundef %d, ptr noundef %0, i8 noundef zeroext %f, i8 noundef signext %g, i8 noundef zeroext %h) int f_scalar_stack_1(int32_t a, __int128_t b, float c, long double d, v32i8 e, uint8_t f, int8_t g, uint8_t h) { return g + h; } -// Ensure that scalars passed on the stack are still determined correctly in -// the presence of large return values that consume a register due to the need -// to pass a pointer. - -// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr noalias sret(%struct.large) align 8 %agg.result, double noundef %a, i128 noundef %b, fp128 noundef %c, ptr noundef %0, i8 noundef zeroext %e, i8 noundef %f, i8 noundef %g) +// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr noalias sret(%struct.large) align 8 %agg.result, double noundef %a, i128 noundef %b, fp128 noundef %c, ptr noundef %0, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g) struct large f_scalar_stack_2(double a, __int128_t b, long double c, v32i8 d, uint8_t e, int8_t f, uint8_t g) { return (struct large){a, e, f, g}; diff --git a/clang/test/CodeGen/RISCV/riscv64-lp64-lp64f-abi.c b/clang/test/CodeGen/RISCV/riscv64-lp64-lp64f-abi.c --- a/clang/test/CodeGen/RISCV/riscv64-lp64-lp64f-abi.c +++ b/clang/test/CodeGen/RISCV/riscv64-lp64-lp64f-abi.c @@ -14,20 +14,16 @@ typedef unsigned char v32i8 __attribute__((vector_size(32))); -// Scalars passed on the stack should not have signext/zeroext attributes -// (they are anyext). +// Scalars passed on the stack should have signext/zeroext attributes, just as +// if they were passed in registers. -// CHECK-LABEL: define{{.*}} signext i32 @f_scalar_stack_1(i32 noundef signext %a, i128 noundef %b, double noundef %c, fp128 noundef %d, ptr noundef %0, i8 noundef zeroext %f, i8 noundef %g, i8 noundef %h) +// CHECK-LABEL: define{{.*}} signext i32 @f_scalar_stack_1(i32 noundef signext %a, i128 noundef %b, double noundef %c, fp128 noundef %d, ptr noundef %0, i8 noundef zeroext %f, i8 noundef signext %g, i8 noundef zeroext %h) int f_scalar_stack_1(int32_t a, __int128_t b, double c, long double d, v32i8 e, uint8_t f, int8_t g, uint8_t h) { return g + h; } -// Ensure that scalars passed on the stack are still determined correctly in -// the presence of large return values that consume a register due to the need -// to pass a pointer. - -// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr noalias sret(%struct.large) align 8 %agg.result, double noundef %a, i128 noundef %b, fp128 noundef %c, ptr noundef %0, i8 noundef zeroext %e, i8 noundef %f, i8 noundef %g) +// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr noalias sret(%struct.large) align 8 %agg.result, double noundef %a, i128 noundef %b, fp128 noundef %c, ptr noundef %0, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g) struct large f_scalar_stack_2(double a, __int128_t b, long double c, v32i8 d, uint8_t e, int8_t f, uint8_t g) { return (struct large){a, e, f, g}; diff --git a/clang/test/CodeGen/RISCV/riscv64-lp64-lp64f-lp64d-abi.c b/clang/test/CodeGen/RISCV/riscv64-lp64-lp64f-lp64d-abi.c --- a/clang/test/CodeGen/RISCV/riscv64-lp64-lp64f-lp64d-abi.c +++ b/clang/test/CodeGen/RISCV/riscv64-lp64-lp64f-lp64d-abi.c @@ -183,16 +183,16 @@ return (v32i8){1, 2, 3, 4, 5, 6, 7, 8}; } -// Scalars passed on the stack should not have signext/zeroext attributes -// (they are anyext). +// Scalars passed on the stack should have signext/zeroext attributes, just as +// if they were passed in registers. -// CHECK-LABEL: define{{.*}} signext i32 @f_scalar_stack_1(i64 %a.coerce, [2 x i64] %b.coerce, i128 %c.coerce, ptr noundef %d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef %g, i8 noundef %h) +// CHECK-LABEL: define{{.*}} signext i32 @f_scalar_stack_1(i64 %a.coerce, [2 x i64] %b.coerce, i128 %c.coerce, ptr noundef %d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g, i8 noundef signext %h) int f_scalar_stack_1(struct tiny a, struct small b, struct small_aligned c, struct large d, uint8_t e, int8_t f, uint8_t g, int8_t h) { return g + h; } -// CHECK-LABEL: define{{.*}} signext i32 @f_scalar_stack_2(i32 noundef signext %a, i128 noundef %b, i64 noundef %c, fp128 noundef %d, ptr noundef %0, i8 noundef zeroext %f, i8 noundef %g, i8 noundef %h) +// CHECK-LABEL: define{{.*}} signext i32 @f_scalar_stack_2(i32 noundef signext %a, i128 noundef %b, i64 noundef %c, fp128 noundef %d, ptr noundef %0, i8 noundef zeroext %f, i8 noundef signext %g, i8 noundef zeroext %h) int f_scalar_stack_2(int32_t a, __int128_t b, int64_t c, long double d, v32i8 e, uint8_t f, int8_t g, uint8_t h) { return g + h; @@ -202,16 +202,13 @@ // the presence of large return values that consume a register due to the need // to pass a pointer. -// CHECK-LABEL: define{{.*}} void @f_scalar_stack_3(ptr noalias sret(%struct.large) align 8 %agg.result, i32 noundef signext %a, i128 noundef %b, fp128 noundef %c, ptr noundef %0, i8 noundef zeroext %e, i8 noundef %f, i8 noundef %g) +// CHECK-LABEL: define{{.*}} void @f_scalar_stack_3(ptr noalias sret(%struct.large) align 8 %agg.result, i32 noundef signext %a, i128 noundef %b, fp128 noundef %c, ptr noundef %0, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g) struct large f_scalar_stack_3(uint32_t a, __int128_t b, long double c, v32i8 d, uint8_t e, int8_t f, uint8_t g) { return (struct large){a, e, f, g}; } // Ensure that ABI lowering happens as expected for vararg calls. -// Specifically, ensure that signext is emitted for varargs that will be -// passed in registers but not on the stack. Ensure this takes into account -// the use of "aligned" register pairs for varargs with 2*xlen alignment. int f_va_callee(int, ...); @@ -221,23 +218,23 @@ f_va_callee(1, 2, 3LL, 4.0f, 5.0, (struct tiny){6, 7, 8, 9}, (struct small){10, NULL}, (struct small_aligned){11}, (struct large){12, 13, 14, 15}); - // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, fp128 noundef 0xL00000000000000004001400000000000, i32 noundef signext 6, i32 noundef signext 7, i32 noundef 8, i32 noundef 9) + // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, fp128 noundef 0xL00000000000000004001400000000000, i32 noundef signext 6, i32 noundef signext 7, i32 noundef signext 8, i32 noundef signext 9) f_va_callee(1, 2, 3, 4, 5.0L, 6, 7, 8, 9); - // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, i128 {{%.*}}, i32 noundef signext 6, i32 noundef signext 7, i32 noundef 8, i32 noundef 9) + // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, i128 {{%.*}}, i32 noundef signext 6, i32 noundef signext 7, i32 noundef signext 8, i32 noundef signext 9) f_va_callee(1, 2, 3, 4, (struct small_aligned){5}, 6, 7, 8, 9); - // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, [2 x i64] {{%.*}}, i32 noundef signext 6, i32 noundef signext 7, i32 noundef 8, i32 noundef 9) + // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, [2 x i64] {{%.*}}, i32 noundef signext 6, i32 noundef signext 7, i32 noundef signext 8, i32 noundef signext 9) f_va_callee(1, 2, 3, 4, (struct small){5, NULL}, 6, 7, 8, 9); - // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, i32 noundef signext 5, fp128 noundef 0xL00000000000000004001800000000000, i32 noundef 7, i32 noundef 8, i32 noundef 9) + // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, i32 noundef signext 5, fp128 noundef 0xL00000000000000004001800000000000, i32 noundef signext 7, i32 noundef signext 8, i32 noundef signext 9) f_va_callee(1, 2, 3, 4, 5, 6.0L, 7, 8, 9); - // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, i32 noundef signext 5, i128 {{%.*}}, i32 noundef 7, i32 noundef 8, i32 noundef 9) + // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, i32 noundef signext 5, i128 {{%.*}}, i32 noundef signext 7, i32 noundef signext 8, i32 noundef signext 9) f_va_callee(1, 2, 3, 4, 5, (struct small_aligned){6}, 7, 8, 9); - // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, i32 noundef signext 5, [2 x i64] {{%.*}}, i32 noundef signext 7, i32 noundef 8, i32 noundef 9) + // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, i32 noundef signext 5, [2 x i64] {{%.*}}, i32 noundef signext 7, i32 noundef signext 8, i32 noundef signext 9) f_va_callee(1, 2, 3, 4, 5, (struct small){6, NULL}, 7, 8, 9); - // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, i32 noundef signext 5, i32 noundef signext 6, fp128 noundef 0xL00000000000000004001C00000000000, i32 noundef 8, i32 noundef 9) + // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, i32 noundef signext 5, i32 noundef signext 6, fp128 noundef 0xL00000000000000004001C00000000000, i32 noundef signext 8, i32 noundef signext 9) f_va_callee(1, 2, 3, 4, 5, 6, 7.0L, 8, 9); - // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, i32 noundef signext 5, i32 noundef signext 6, i128 {{%.*}}, i32 noundef 8, i32 noundef 9) + // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, i32 noundef signext 5, i32 noundef signext 6, i128 {{%.*}}, i32 noundef signext 8, i32 noundef signext 9) f_va_callee(1, 2, 3, 4, 5, 6, (struct small_aligned){7}, 8, 9); - // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, i32 noundef signext 5, i32 noundef signext 6, [2 x i64] {{.*}}, i32 noundef 8, i32 noundef 9) + // CHECK: call signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, i32 noundef signext 5, i32 noundef signext 6, [2 x i64] {{.*}}, i32 noundef signext 8, i32 noundef signext 9) f_va_callee(1, 2, 3, 4, 5, 6, (struct small){7, NULL}, 8, 9); }