Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -766,6 +766,8 @@ - ``sifive-7-rv32`` and ``sifive-7-rv64`` are no longer supported for ``-mcpu``. Use ``sifive-e76``, ``sifive-s76``, or ``sifive-u74`` instead. - Native detections via ``-mcpu=native`` and ``-mtune=native`` are supported. +- An ABI mismatch between GCC and Clang that related to the + sign/zero-extension of integer scalars was fixed. X86 Support in Clang -------------------- Index: clang/lib/CodeGen/TargetInfo.cpp =================================================================== --- clang/lib/CodeGen/TargetInfo.cpp +++ clang/lib/CodeGen/TargetInfo.cpp @@ -11276,7 +11276,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. @@ -11287,7 +11286,6 @@ NeededArgGPRs = 2; if (NeededArgGPRs > ArgGPRsLeft) { - MustUseStack = true; NeededArgGPRs = ArgGPRsLeft; } @@ -11298,14 +11296,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() && Index: clang/test/CodeGen/RISCV/riscv32-abi.c =================================================================== --- clang/test/CodeGen/RISCV/riscv32-abi.c +++ clang/test/CodeGen/RISCV/riscv32-abi.c @@ -273,11 +273,11 @@ 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. // ILP32-ILP32F-ILP32D-LABEL: define dso_local i32 @f_scalar_stack_1 -// ILP32-ILP32F-ILP32D-SAME: (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:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (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:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // int f_scalar_stack_1(struct tiny a, struct small b, struct small_aligned c, @@ -285,12 +285,8 @@ 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. - // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_scalar_stack_2 -// ILP32-ILP32F-ILP32D-SAME: (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:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (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:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // struct large f_scalar_stack_2(int32_t a, int64_t b, int64_t c, long double d, @@ -299,7 +295,7 @@ } // ILP32-ILP32F-ILP32D-LABEL: define dso_local fp128 @f_scalar_stack_3 -// ILP32-ILP32F-ILP32D-SAME: (i32 noundef [[A:%.*]], i64 noundef [[B:%.*]], i64 noundef [[C:%.*]], fp128 noundef [[D:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef [[F:%.*]], i8 noundef [[G:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (i32 noundef [[A:%.*]], i64 noundef [[B:%.*]], i64 noundef [[C:%.*]], fp128 noundef [[D:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // long double f_scalar_stack_3(int32_t a, int64_t b, int64_t c, long double d, @@ -317,41 +313,18 @@ void f_scalar_stack_4(double a, int64_t b, double c, int64_t d, int e, int64_t f, float g, double h, long double i) {} -// Scalars passed on the stack should not have signext/zeroext attributes -// (they are anyext). - -// ILP32-LABEL: define dso_local i32 @f_scalar_stack_5 -// ILP32-SAME: (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:%.*]]) #[[ATTR0]] { -// ILP32: entry: -// -// ILP32F-LABEL: define dso_local i32 @f_scalar_stack_5 -// ILP32F-SAME: (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 [[H:%.*]]) #[[ATTR0]] { -// ILP32F: entry: -// -// ILP32D-LABEL: define dso_local i32 @f_scalar_stack_5 -// ILP32D-SAME: (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:%.*]]) #[[ATTR0]] { -// ILP32D: entry: +// ILP32-ILP32F-ILP32D-LABEL: define dso_local i32 @f_scalar_stack_5 +// ILP32-ILP32F-ILP32D-SAME: (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:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D: entry: // int f_scalar_stack_5(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. - -// ILP32-LABEL: define dso_local void @f_scalar_stack_6 -// ILP32-SAME: (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:%.*]]) #[[ATTR0]] { -// ILP32: entry: -// -// ILP32F-LABEL: define dso_local void @f_scalar_stack_6 -// ILP32F-SAME: (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 [[G:%.*]]) #[[ATTR0]] { -// ILP32F: entry: -// -// ILP32D-LABEL: define dso_local void @f_scalar_stack_6 -// ILP32D-SAME: (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:%.*]]) #[[ATTR0]] { -// ILP32D: entry: +// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_scalar_stack_6 +// ILP32-ILP32F-ILP32D-SAME: (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:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D: entry: // struct large f_scalar_stack_6(float a, int64_t b, double c, long double d, uint8_t e, int8_t f, uint8_t g) { @@ -368,16 +341,9 @@ void f_agg_stack(double a, int64_t b, double c, int64_t d, struct tiny e, struct small f, struct small_aligned g, struct large h) {} -// Doubles are still passed in GPRs, so the 'e' argument will be anyext as -// GPRs are exhausted. - -// ILP32-ILP32F-LABEL: define dso_local void @f_fpr_tracking -// ILP32-ILP32F-SAME: (double noundef [[A:%.*]], double noundef [[B:%.*]], double noundef [[C:%.*]], double noundef [[D:%.*]], i8 noundef [[E:%.*]]) #[[ATTR0]] { -// ILP32-ILP32F: entry: -// -// ILP32D-LABEL: define dso_local void @f_fpr_tracking -// ILP32D-SAME: (double noundef [[A:%.*]], double noundef [[B:%.*]], double noundef [[C:%.*]], double noundef [[D:%.*]], i8 noundef signext [[E:%.*]]) #[[ATTR0]] { -// ILP32D: entry: +// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_fpr_tracking +// ILP32-ILP32F-ILP32D-SAME: (double noundef [[A:%.*]], double noundef [[B:%.*]], double noundef [[C:%.*]], double noundef [[D:%.*]], i8 noundef signext [[E:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D: entry: // void f_fpr_tracking(double a, double b, double c, double d, int8_t e) {} @@ -413,19 +379,9 @@ return (struct int_double_s){1, 2.0}; } -// Verify that the tracking of used GPRs and FPRs works correctly by checking -// that small integers are sign/zero extended when passed in registers. - -// Doubles are passed in FPRs, so argument 'i' will be passed zero-extended -// because it will be passed in a GPR. - -// ILP32-ILP32F-LABEL: define dso_local void @f_fpr_tracking2 -// ILP32-ILP32F-SAME: (double noundef [[A:%.*]], double noundef [[B:%.*]], double noundef [[C:%.*]], double noundef [[D:%.*]], double noundef [[E:%.*]], double noundef [[F:%.*]], double noundef [[G:%.*]], double noundef [[H:%.*]], i8 noundef [[I:%.*]]) #[[ATTR0]] { -// ILP32-ILP32F: entry: -// -// ILP32D-LABEL: define dso_local void @f_fpr_tracking2 -// ILP32D-SAME: (double noundef [[A:%.*]], double noundef [[B:%.*]], double noundef [[C:%.*]], double noundef [[D:%.*]], double noundef [[E:%.*]], double noundef [[F:%.*]], double noundef [[G:%.*]], double noundef [[H:%.*]], i8 noundef zeroext [[I:%.*]]) #[[ATTR0]] { -// ILP32D: entry: +// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_fpr_tracking2 +// ILP32-ILP32F-ILP32D-SAME: (double noundef [[A:%.*]], double noundef [[B:%.*]], double noundef [[C:%.*]], double noundef [[D:%.*]], double noundef [[E:%.*]], double noundef [[F:%.*]], double noundef [[G:%.*]], double noundef [[H:%.*]], i8 noundef zeroext [[I:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D: entry: // void f_fpr_tracking2(double a, double b, double c, double d, double e, double f, double g, double h, uint8_t i) {} @@ -1022,19 +978,9 @@ return 1.0; } -// Verify that the tracking of used GPRs and FPRs works correctly by checking -// that small integers are sign/zero extended when passed in registers. - -// Floats are passed in FPRs, so argument 'i' will be passed zero-extended -// because it will be passed in a GPR. - -// ILP32-LABEL: define dso_local void @f_fpr_tracking_3 -// ILP32-SAME: (float noundef [[A:%.*]], float noundef [[B:%.*]], float noundef [[C:%.*]], float noundef [[D:%.*]], float noundef [[E:%.*]], float noundef [[F:%.*]], float noundef [[G:%.*]], float noundef [[H:%.*]], i8 noundef [[I:%.*]]) #[[ATTR0]] { -// ILP32: entry: -// -// ILP32F-ILP32D-LABEL: define dso_local void @f_fpr_tracking_3 -// ILP32F-ILP32D-SAME: (float noundef [[A:%.*]], float noundef [[B:%.*]], float noundef [[C:%.*]], float noundef [[D:%.*]], float noundef [[E:%.*]], float noundef [[F:%.*]], float noundef [[G:%.*]], float noundef [[H:%.*]], i8 noundef zeroext [[I:%.*]]) #[[ATTR0]] { -// ILP32F-ILP32D: entry: +// ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_fpr_tracking_3 +// ILP32-ILP32F-ILP32D-SAME: (float noundef [[A:%.*]], float noundef [[B:%.*]], float noundef [[C:%.*]], float noundef [[D:%.*]], float noundef [[E:%.*]], float noundef [[F:%.*]], float noundef [[G:%.*]], float noundef [[H:%.*]], i8 noundef zeroext [[I:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D: entry: // void f_fpr_tracking_3(float a, float b, float c, float d, float e, float f, float g, float h, uint8_t i) {} @@ -1574,3 +1520,5 @@ union float_u f_ret_float_u(void) { return (union float_u){1.0}; } +//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +// ILP32F: {{.*}} Index: clang/test/CodeGen/RISCV/riscv64-abi.c =================================================================== --- clang/test/CodeGen/RISCV/riscv64-abi.c +++ clang/test/CodeGen/RISCV/riscv64-abi.c @@ -269,11 +269,11 @@ 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. // LP64-LP64F-LP64D-LABEL: define dso_local signext i32 @f_scalar_stack_1 -// LP64-LP64F-LP64D-SAME: (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:%.*]]) #[[ATTR0]] { +// LP64-LP64F-LP64D-SAME: (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:%.*]]) #[[ATTR0]] { // LP64-LP64F-LP64D: entry: // int f_scalar_stack_1(struct tiny a, struct small b, struct small_aligned c, @@ -282,7 +282,7 @@ } // LP64-LP64F-LP64D-LABEL: define dso_local signext i32 @f_scalar_stack_2 -// LP64-LP64F-LP64D-SAME: (i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], i64 noundef [[C:%.*]], fp128 noundef [[D:%.*]], ptr noundef [[TMP0:%.*]], i8 noundef zeroext [[F:%.*]], i8 noundef [[G:%.*]], i8 noundef [[H:%.*]]) #[[ATTR0]] { +// LP64-LP64F-LP64D-SAME: (i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], i64 noundef [[C:%.*]], fp128 noundef [[D:%.*]], ptr noundef [[TMP0:%.*]], i8 noundef zeroext [[F:%.*]], i8 noundef signext [[G:%.*]], i8 noundef zeroext [[H:%.*]]) #[[ATTR0]] { // LP64-LP64F-LP64D: entry: // int f_scalar_stack_2(int32_t a, __int128_t b, int64_t c, long double d, v32i8 e, @@ -290,13 +290,9 @@ return g + h; } -// LP64-LP64F-LABEL: define dso_local signext i32 @f_scalar_stack_3 -// LP64-LP64F-SAME: (i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], double noundef [[C:%.*]], fp128 noundef [[D:%.*]], ptr noundef [[TMP0:%.*]], i8 noundef zeroext [[F:%.*]], i8 noundef [[G:%.*]], i8 noundef [[H:%.*]]) #[[ATTR0]] { -// LP64-LP64F: entry: -// -// LP64D-LABEL: define dso_local signext i32 @f_scalar_stack_3 -// LP64D-SAME: (i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], double noundef [[C:%.*]], fp128 noundef [[D:%.*]], ptr noundef [[TMP0:%.*]], i8 noundef zeroext [[F:%.*]], i8 noundef signext [[G:%.*]], i8 noundef [[H:%.*]]) #[[ATTR0]] { -// LP64D: entry: +// LP64-LP64F-LP64D-LABEL: define dso_local signext i32 @f_scalar_stack_3 +// LP64-LP64F-LP64D-SAME: (i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], double noundef [[C:%.*]], fp128 noundef [[D:%.*]], ptr noundef [[TMP0:%.*]], i8 noundef zeroext [[F:%.*]], i8 noundef signext [[G:%.*]], i8 noundef zeroext [[H:%.*]]) #[[ATTR0]] { +// LP64-LP64F-LP64D: entry: // int f_scalar_stack_3(int32_t a, __int128_t b, double c, long double d, v32i8 e, uint8_t f, int8_t g, uint8_t h) { @@ -308,7 +304,7 @@ // to pass a pointer. // LP64-LP64F-LP64D-LABEL: define dso_local void @f_scalar_stack_4 -// LP64-LP64F-LP64D-SAME: (ptr noalias sret([[STRUCT_LARGE:%.*]]) align 8 [[AGG_RESULT:%.*]], i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], fp128 noundef [[C:%.*]], ptr noundef [[TMP0:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef [[F:%.*]], i8 noundef [[G:%.*]]) #[[ATTR0]] { +// LP64-LP64F-LP64D-SAME: (ptr noalias sret([[STRUCT_LARGE:%.*]]) align 8 [[AGG_RESULT:%.*]], i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], fp128 noundef [[C:%.*]], ptr noundef [[TMP0:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]]) #[[ATTR0]] { // LP64-LP64F-LP64D: entry: // struct large f_scalar_stack_4(uint32_t a, __int128_t b, long double c, v32i8 d, @@ -316,45 +312,27 @@ return (struct large){a, e, f, g}; } -// LP64-LP64F-LABEL: define dso_local void @f_scalar_stack_5 -// LP64-LP64F-SAME: (ptr noalias sret([[STRUCT_LARGE:%.*]]) align 8 [[AGG_RESULT:%.*]], double noundef [[A:%.*]], i128 noundef [[B:%.*]], fp128 noundef [[C:%.*]], ptr noundef [[TMP0:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef [[F:%.*]], i8 noundef [[G:%.*]]) #[[ATTR0]] { -// LP64-LP64F: entry: -// -// LP64D-LABEL: define dso_local void @f_scalar_stack_5 -// LP64D-SAME: (ptr noalias sret([[STRUCT_LARGE:%.*]]) align 8 [[AGG_RESULT:%.*]], double noundef [[A:%.*]], i128 noundef [[B:%.*]], fp128 noundef [[C:%.*]], ptr noundef [[TMP0:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef [[G:%.*]]) #[[ATTR0]] { -// LP64D: entry: +// LP64-LP64F-LP64D-LABEL: define dso_local void @f_scalar_stack_5 +// LP64-LP64F-LP64D-SAME: (ptr noalias sret([[STRUCT_LARGE:%.*]]) align 8 [[AGG_RESULT:%.*]], double noundef [[A:%.*]], i128 noundef [[B:%.*]], fp128 noundef [[C:%.*]], ptr noundef [[TMP0:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]]) #[[ATTR0]] { +// LP64-LP64F-LP64D: entry: // struct large f_scalar_stack_5(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}; } -// LP64-LABEL: define dso_local signext i32 @f_scalar_stack_6 -// LP64-SAME: (i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], float noundef [[C:%.*]], fp128 noundef [[D:%.*]], ptr noundef [[TMP0:%.*]], i8 noundef zeroext [[F:%.*]], i8 noundef [[G:%.*]], i8 noundef [[H:%.*]]) #[[ATTR0]] { -// LP64: entry: -// -// LP64F-LP64D-LABEL: define dso_local signext i32 @f_scalar_stack_6 -// LP64F-LP64D-SAME: (i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], float noundef [[C:%.*]], fp128 noundef [[D:%.*]], ptr noundef [[TMP0:%.*]], i8 noundef zeroext [[F:%.*]], i8 noundef signext [[G:%.*]], i8 noundef [[H:%.*]]) #[[ATTR0]] { -// LP64F-LP64D: entry: +// LP64-LP64F-LP64D-LABEL: define dso_local signext i32 @f_scalar_stack_6 +// LP64-LP64F-LP64D-SAME: (i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], float noundef [[C:%.*]], fp128 noundef [[D:%.*]], ptr noundef [[TMP0:%.*]], i8 noundef zeroext [[F:%.*]], i8 noundef signext [[G:%.*]], i8 noundef zeroext [[H:%.*]]) #[[ATTR0]] { +// LP64-LP64F-LP64D: entry: // int f_scalar_stack_6(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; } -// Verify that the tracking of used GPRs and FPRs works correctly by checking -// that small integers are sign/zero extended when passed in registers. - -// Floats are passed in FPRs, so argument 'i' will be passed zero-extended -// because it will be passed in a GPR. - -// LP64-LABEL: define dso_local void @f_fpr_tracking -// LP64-SAME: (float noundef [[A:%.*]], float noundef [[B:%.*]], float noundef [[C:%.*]], float noundef [[D:%.*]], float noundef [[E:%.*]], float noundef [[F:%.*]], float noundef [[G:%.*]], float noundef [[H:%.*]], i8 noundef [[I:%.*]]) #[[ATTR0]] { -// LP64: entry: -// -// LP64F-LP64D-LABEL: define dso_local void @f_fpr_tracking -// LP64F-LP64D-SAME: (float noundef [[A:%.*]], float noundef [[B:%.*]], float noundef [[C:%.*]], float noundef [[D:%.*]], float noundef [[E:%.*]], float noundef [[F:%.*]], float noundef [[G:%.*]], float noundef [[H:%.*]], i8 noundef zeroext [[I:%.*]]) #[[ATTR0]] { -// LP64F-LP64D: entry: +// LP64-LP64F-LP64D-LABEL: define dso_local void @f_fpr_tracking +// LP64-LP64F-LP64D-SAME: (float noundef [[A:%.*]], float noundef [[B:%.*]], float noundef [[C:%.*]], float noundef [[D:%.*]], float noundef [[E:%.*]], float noundef [[F:%.*]], float noundef [[G:%.*]], float noundef [[H:%.*]], i8 noundef zeroext [[I:%.*]]) #[[ATTR0]] { +// LP64-LP64F-LP64D: entry: // void f_fpr_tracking(float a, float b, float c, float d, float e, float f, float g, float h, uint8_t i) {} @@ -944,19 +922,9 @@ return (union float_u){1.0}; } -// Verify that the tracking of used GPRs and FPRs works correctly by checking -// that small integers are sign/zero extended when passed in registers. - -// Doubles are passed in FPRs, so argument 'i' will be passed zero-extended -// because it will be passed in a GPR. - -// LP64-LP64F-LABEL: define dso_local void @f_fpr_tracking2 -// LP64-LP64F-SAME: (double noundef [[A:%.*]], double noundef [[B:%.*]], double noundef [[C:%.*]], double noundef [[D:%.*]], double noundef [[E:%.*]], double noundef [[F:%.*]], double noundef [[G:%.*]], double noundef [[H:%.*]], i8 noundef [[I:%.*]]) #[[ATTR0]] { -// LP64-LP64F: entry: -// -// LP64D-LABEL: define dso_local void @f_fpr_tracking2 -// LP64D-SAME: (double noundef [[A:%.*]], double noundef [[B:%.*]], double noundef [[C:%.*]], double noundef [[D:%.*]], double noundef [[E:%.*]], double noundef [[F:%.*]], double noundef [[G:%.*]], double noundef [[H:%.*]], i8 noundef zeroext [[I:%.*]]) #[[ATTR0]] { -// LP64D: entry: +// LP64-LP64F-LP64D-LABEL: define dso_local void @f_fpr_tracking2 +// LP64-LP64F-LP64D-SAME: (double noundef [[A:%.*]], double noundef [[B:%.*]], double noundef [[C:%.*]], double noundef [[D:%.*]], double noundef [[E:%.*]], double noundef [[F:%.*]], double noundef [[G:%.*]], double noundef [[H:%.*]], i8 noundef zeroext [[I:%.*]]) #[[ATTR0]] { +// LP64-LP64F-LP64D: entry: // void f_fpr_tracking2(double a, double b, double c, double d, double e, double f, double g, double h, uint8_t i) {}