https://github.com/BeMg updated https://github.com/llvm/llvm-project/pull/156592
>From 092700505e150a5de6e623bf12f0dbd557017e24 Mon Sep 17 00:00:00 2001 From: Piyou Chen <[email protected]> Date: Fri, 13 Jun 2025 03:11:08 -0700 Subject: [PATCH 1/7] [clang][RISCV] support BITINT with mixed-type --- clang/lib/CodeGen/Targets/RISCV.cpp | 16 +- clang/test/CodeGen/RISCV/bitint.c | 233 ++++++++++++++++++++++++++++ clang/test/CodeGen/ext-int-cc.c | 8 +- 3 files changed, 246 insertions(+), 11 deletions(-) create mode 100644 clang/test/CodeGen/RISCV/bitint.c diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index 0ef39b68eb6e3..fb95880afe078 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -680,14 +680,11 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, if (const auto *ED = Ty->getAsEnumDecl()) Ty = ED->getIntegerType(); - // All integral types are promoted to XLen width - if (Size < XLen && Ty->isIntegralOrEnumerationType()) { - return extendType(Ty, CGT.ConvertType(Ty)); - } - if (const auto *EIT = Ty->getAs<BitIntType>()) { - if (EIT->getNumBits() < XLen) - return extendType(Ty, CGT.ConvertType(Ty)); + // FIXME: Maybe we should treat 32 as a special case and wait for + // the SPEC to decide. + if (EIT->getNumBits() <= 2*XLen) + return ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)); if (EIT->getNumBits() > 128 || (!getContext().getTargetInfo().hasInt128Type() && EIT->getNumBits() > 64)) @@ -696,6 +693,11 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, /*ByVal=*/false); } + // All integral types are promoted to XLen width + if (Size < XLen && Ty->isIntegralOrEnumerationType()) { + return extendType(Ty, CGT.ConvertType(Ty)); + } + return ABIArgInfo::getDirect(); } diff --git a/clang/test/CodeGen/RISCV/bitint.c b/clang/test/CodeGen/RISCV/bitint.c new file mode 100644 index 0000000000000..2c28c536dc1bc --- /dev/null +++ b/clang/test/CodeGen/RISCV/bitint.c @@ -0,0 +1,233 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature +// RUN: %clang_cc1 -triple riscv64 -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=RISCV64 +// RUN: %clang_cc1 -triple riscv32 -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=RISCV32 + +// RISCV64-LABEL: define {{[^@]+}}@test_bitint_17_add_unsigned +// RISCV64-SAME: (i17 noundef zeroext [[A:%.*]], i17 noundef zeroext [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// RISCV64-NEXT: entry: +// RISCV64-NEXT: [[ADD:%.*]] = add i17 [[B]], [[A]] +// RISCV64-NEXT: ret i17 [[ADD]] +// +// RISCV32-LABEL: define {{[^@]+}}@test_bitint_17_add_unsigned +// RISCV32-SAME: (i17 noundef zeroext [[A:%.*]], i17 noundef zeroext [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// RISCV32-NEXT: entry: +// RISCV32-NEXT: [[ADD:%.*]] = add i17 [[B]], [[A]] +// RISCV32-NEXT: ret i17 [[ADD]] +// +unsigned _BitInt(17) test_bitint_17_add_unsigned(unsigned _BitInt(17) a, unsigned _BitInt(17) b) { + return a + b; +} + +// RISCV64-LABEL: define {{[^@]+}}@test_bitint_17_add_signed +// RISCV64-SAME: (i17 noundef signext [[A:%.*]], i17 noundef signext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV64-NEXT: entry: +// RISCV64-NEXT: [[ADD:%.*]] = add nsw i17 [[B]], [[A]] +// RISCV64-NEXT: ret i17 [[ADD]] +// +// RISCV32-LABEL: define {{[^@]+}}@test_bitint_17_add_signed +// RISCV32-SAME: (i17 noundef signext [[A:%.*]], i17 noundef signext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV32-NEXT: entry: +// RISCV32-NEXT: [[ADD:%.*]] = add nsw i17 [[B]], [[A]] +// RISCV32-NEXT: ret i17 [[ADD]] +// +signed _BitInt(17) test_bitint_17_add_signed(signed _BitInt(17) a, signed _BitInt(17) b) { + return a + b; +} + +// RISCV64-LABEL: define {{[^@]+}}@test_bitint_17_add_default +// RISCV64-SAME: (i17 noundef signext [[A:%.*]], i17 noundef signext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV64-NEXT: entry: +// RISCV64-NEXT: [[ADD:%.*]] = add nsw i17 [[B]], [[A]] +// RISCV64-NEXT: ret i17 [[ADD]] +// +// RISCV32-LABEL: define {{[^@]+}}@test_bitint_17_add_default +// RISCV32-SAME: (i17 noundef signext [[A:%.*]], i17 noundef signext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV32-NEXT: entry: +// RISCV32-NEXT: [[ADD:%.*]] = add nsw i17 [[B]], [[A]] +// RISCV32-NEXT: ret i17 [[ADD]] +// +_BitInt(17) test_bitint_17_add_default(_BitInt(17) a, _BitInt(17) b) { + return a + b; +} + +// RISCV64-LABEL: define {{[^@]+}}@test_bitint_32_add_unsigned +// RISCV64-SAME: (i32 noundef zeroext [[A:%.*]], i32 noundef zeroext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV64-NEXT: entry: +// RISCV64-NEXT: [[ADD:%.*]] = add i32 [[B]], [[A]] +// RISCV64-NEXT: ret i32 [[ADD]] +// +// RISCV32-LABEL: define {{[^@]+}}@test_bitint_32_add_unsigned +// RISCV32-SAME: (i32 noundef zeroext [[A:%.*]], i32 noundef zeroext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV32-NEXT: entry: +// RISCV32-NEXT: [[ADD:%.*]] = add i32 [[B]], [[A]] +// RISCV32-NEXT: ret i32 [[ADD]] +// +unsigned _BitInt(32) test_bitint_32_add_unsigned(unsigned _BitInt(32) a, unsigned _BitInt(32) b) { + return a + b; +} + +// RISCV64-LABEL: define {{[^@]+}}@test_bitint_32_add_signed +// RISCV64-SAME: (i32 noundef signext [[A:%.*]], i32 noundef signext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV64-NEXT: entry: +// RISCV64-NEXT: [[ADD:%.*]] = add nsw i32 [[B]], [[A]] +// RISCV64-NEXT: ret i32 [[ADD]] +// +// RISCV32-LABEL: define {{[^@]+}}@test_bitint_32_add_signed +// RISCV32-SAME: (i32 noundef signext [[A:%.*]], i32 noundef signext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV32-NEXT: entry: +// RISCV32-NEXT: [[ADD:%.*]] = add nsw i32 [[B]], [[A]] +// RISCV32-NEXT: ret i32 [[ADD]] +// +signed _BitInt(32) test_bitint_32_add_signed(signed _BitInt(32) a, signed _BitInt(32) b) { + return a + b; +} + +// RISCV64-LABEL: define {{[^@]+}}@test_bitint_32_add_default +// RISCV64-SAME: (i32 noundef signext [[A:%.*]], i32 noundef signext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV64-NEXT: entry: +// RISCV64-NEXT: [[ADD:%.*]] = add nsw i32 [[B]], [[A]] +// RISCV64-NEXT: ret i32 [[ADD]] +// +// RISCV32-LABEL: define {{[^@]+}}@test_bitint_32_add_default +// RISCV32-SAME: (i32 noundef signext [[A:%.*]], i32 noundef signext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV32-NEXT: entry: +// RISCV32-NEXT: [[ADD:%.*]] = add nsw i32 [[B]], [[A]] +// RISCV32-NEXT: ret i32 [[ADD]] +// +_BitInt(32) test_bitint_32_add_default(_BitInt(32) a, _BitInt(32) b) { + return a + b; +} + + +// RISCV64-LABEL: define {{[^@]+}}@test_bitint_65_add_unsigned +// RISCV64-SAME: (i65 noundef zeroext [[A:%.*]], i65 noundef zeroext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV64-NEXT: entry: +// RISCV64-NEXT: [[ADD:%.*]] = add i65 [[B]], [[A]] +// RISCV64-NEXT: ret i65 [[ADD]] +// +// RISCV32-LABEL: define {{[^@]+}}@test_bitint_65_add_unsigned +// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +// RISCV32-NEXT: entry: +// RISCV32-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA6:![0-9]+]] +// RISCV32-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i65 +// RISCV32-NEXT: [[TMP3:%.*]] = load i128, ptr [[TMP1]], align 8, !tbaa [[TBAA6]] +// RISCV32-NEXT: [[B:%.*]] = trunc i128 [[TMP3]] to i65 +// RISCV32-NEXT: [[ADD:%.*]] = add i65 [[B]], [[A]] +// RISCV32-NEXT: [[STOREDV4:%.*]] = zext i65 [[ADD]] to i128 +// RISCV32-NEXT: store i128 [[STOREDV4]], ptr [[AGG_RESULT]], align 8, !tbaa [[TBAA6]] +// RISCV32-NEXT: ret void +// +unsigned _BitInt(65) test_bitint_65_add_unsigned(unsigned _BitInt(65) a, unsigned _BitInt(65) b) { + return a + b; +} + +// RISCV64-LABEL: define {{[^@]+}}@test_bitint_65_add_signed +// RISCV64-SAME: (i65 noundef signext [[A:%.*]], i65 noundef signext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV64-NEXT: entry: +// RISCV64-NEXT: [[ADD:%.*]] = add nsw i65 [[B]], [[A]] +// RISCV64-NEXT: ret i65 [[ADD]] +// +// RISCV32-LABEL: define {{[^@]+}}@test_bitint_65_add_signed +// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] { +// RISCV32-NEXT: entry: +// RISCV32-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA6]] +// RISCV32-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i65 +// RISCV32-NEXT: [[TMP3:%.*]] = load i128, ptr [[TMP1]], align 8, !tbaa [[TBAA6]] +// RISCV32-NEXT: [[B:%.*]] = trunc i128 [[TMP3]] to i65 +// RISCV32-NEXT: [[ADD:%.*]] = add nsw i65 [[B]], [[A]] +// RISCV32-NEXT: [[STOREDV4:%.*]] = sext i65 [[ADD]] to i128 +// RISCV32-NEXT: store i128 [[STOREDV4]], ptr [[AGG_RESULT]], align 8, !tbaa [[TBAA6]] +// RISCV32-NEXT: ret void +// +signed _BitInt(65) test_bitint_65_add_signed(signed _BitInt(65) a, signed _BitInt(65) b) { + return a + b; +} + +// RISCV64-LABEL: define {{[^@]+}}@test_bitint_65_add_default +// RISCV64-SAME: (i65 noundef signext [[A:%.*]], i65 noundef signext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV64-NEXT: entry: +// RISCV64-NEXT: [[ADD:%.*]] = add nsw i65 [[B]], [[A]] +// RISCV64-NEXT: ret i65 [[ADD]] +// +// RISCV32-LABEL: define {{[^@]+}}@test_bitint_65_add_default +// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] { +// RISCV32-NEXT: entry: +// RISCV32-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA6]] +// RISCV32-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i65 +// RISCV32-NEXT: [[TMP3:%.*]] = load i128, ptr [[TMP1]], align 8, !tbaa [[TBAA6]] +// RISCV32-NEXT: [[B:%.*]] = trunc i128 [[TMP3]] to i65 +// RISCV32-NEXT: [[ADD:%.*]] = add nsw i65 [[B]], [[A]] +// RISCV32-NEXT: [[STOREDV4:%.*]] = sext i65 [[ADD]] to i128 +// RISCV32-NEXT: store i128 [[STOREDV4]], ptr [[AGG_RESULT]], align 8, !tbaa [[TBAA6]] +// RISCV32-NEXT: ret void +// +_BitInt(65) test_bitint_65_add_default(_BitInt(65) a, _BitInt(65) b) { + return a + b; +} + + +// RISCV64-LABEL: define {{[^@]+}}@test_bitint_77_add_unsigned +// RISCV64-SAME: (i77 noundef zeroext [[A:%.*]], i77 noundef zeroext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV64-NEXT: entry: +// RISCV64-NEXT: [[ADD:%.*]] = add i77 [[B]], [[A]] +// RISCV64-NEXT: ret i77 [[ADD]] +// +// RISCV32-LABEL: define {{[^@]+}}@test_bitint_77_add_unsigned +// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] { +// RISCV32-NEXT: entry: +// RISCV32-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA10:![0-9]+]] +// RISCV32-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i77 +// RISCV32-NEXT: [[TMP3:%.*]] = load i128, ptr [[TMP1]], align 8, !tbaa [[TBAA10]] +// RISCV32-NEXT: [[B:%.*]] = trunc i128 [[TMP3]] to i77 +// RISCV32-NEXT: [[ADD:%.*]] = add i77 [[B]], [[A]] +// RISCV32-NEXT: [[STOREDV4:%.*]] = zext i77 [[ADD]] to i128 +// RISCV32-NEXT: store i128 [[STOREDV4]], ptr [[AGG_RESULT]], align 8, !tbaa [[TBAA10]] +// RISCV32-NEXT: ret void +// +unsigned _BitInt(77) test_bitint_77_add_unsigned(unsigned _BitInt(77) a, unsigned _BitInt(77) b) { + return a + b; +} + +// RISCV64-LABEL: define {{[^@]+}}@test_bitint_77_add_signed +// RISCV64-SAME: (i77 noundef signext [[A:%.*]], i77 noundef signext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV64-NEXT: entry: +// RISCV64-NEXT: [[ADD:%.*]] = add nsw i77 [[B]], [[A]] +// RISCV64-NEXT: ret i77 [[ADD]] +// +// RISCV32-LABEL: define {{[^@]+}}@test_bitint_77_add_signed +// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] { +// RISCV32-NEXT: entry: +// RISCV32-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA10]] +// RISCV32-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i77 +// RISCV32-NEXT: [[TMP3:%.*]] = load i128, ptr [[TMP1]], align 8, !tbaa [[TBAA10]] +// RISCV32-NEXT: [[B:%.*]] = trunc i128 [[TMP3]] to i77 +// RISCV32-NEXT: [[ADD:%.*]] = add nsw i77 [[B]], [[A]] +// RISCV32-NEXT: [[STOREDV4:%.*]] = sext i77 [[ADD]] to i128 +// RISCV32-NEXT: store i128 [[STOREDV4]], ptr [[AGG_RESULT]], align 8, !tbaa [[TBAA10]] +// RISCV32-NEXT: ret void +// +signed _BitInt(77) test_bitint_77_add_signed(signed _BitInt(77) a, signed _BitInt(77) b) { + return a + b; +} + +// RISCV64-LABEL: define {{[^@]+}}@test_bitint_77_add_default +// RISCV64-SAME: (i77 noundef signext [[A:%.*]], i77 noundef signext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV64-NEXT: entry: +// RISCV64-NEXT: [[ADD:%.*]] = add nsw i77 [[B]], [[A]] +// RISCV64-NEXT: ret i77 [[ADD]] +// +// RISCV32-LABEL: define {{[^@]+}}@test_bitint_77_add_default +// RISCV32-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] { +// RISCV32-NEXT: entry: +// RISCV32-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA10]] +// RISCV32-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i77 +// RISCV32-NEXT: [[TMP3:%.*]] = load i128, ptr [[TMP1]], align 8, !tbaa [[TBAA10]] +// RISCV32-NEXT: [[B:%.*]] = trunc i128 [[TMP3]] to i77 +// RISCV32-NEXT: [[ADD:%.*]] = add nsw i77 [[B]], [[A]] +// RISCV32-NEXT: [[STOREDV4:%.*]] = sext i77 [[ADD]] to i128 +// RISCV32-NEXT: store i128 [[STOREDV4]], ptr [[AGG_RESULT]], align 8, !tbaa [[TBAA10]] +// RISCV32-NEXT: ret void +// +_BitInt(77) test_bitint_77_add_default(_BitInt(77) a, _BitInt(77) b) { + return a + b; +} diff --git a/clang/test/CodeGen/ext-int-cc.c b/clang/test/CodeGen/ext-int-cc.c index 7cfd992fd48b4..f845afcf1e087 100644 --- a/clang/test/CodeGen/ext-int-cc.c +++ b/clang/test/CodeGen/ext-int-cc.c @@ -49,8 +49,8 @@ void ParamPassing(_BitInt(128) b, _BitInt(64) c) {} // R600: define{{.*}} void @ParamPassing(ptr addrspace(5) byval(i128) align 8 %{{.+}}, i64 %{{.+}}) // ARC: define{{.*}} void @ParamPassing(ptr byval(i128) align 4 %{{.+}}, i64 inreg %{{.+}}) // XCORE: define{{.*}} void @ParamPassing(ptr byval(i128) align 4 %{{.+}}, i64 %{{.+}}) -// RISCV64: define{{.*}} void @ParamPassing(i128 %{{.+}}, i64 %{{.+}}) -// RISCV32: define{{.*}} void @ParamPassing(ptr dead_on_return %{{.+}}, i64 %{{.+}}) +// RISCV64: define{{.*}} void @ParamPassing(i128 signext %{{.+}}, i64 signext %{{.+}}) +// RISCV32: define{{.*}} void @ParamPassing(ptr dead_on_return %{{.+}}, i64 signext %{{.+}}) // WASM: define{{.*}} void @ParamPassing(i128 %{{.+}}, i64 %{{.+}}) // SYSTEMZ: define{{.*}} void @ParamPassing(ptr dead_on_return %{{.+}}, i64 %{{.+}}) // PPC64: define{{.*}} void @ParamPassing(i128 %{{.+}}, i64 %{{.+}}) @@ -79,8 +79,8 @@ void ParamPassing2(_BitInt(127) b, _BitInt(63) c) {} // R600: define{{.*}} void @ParamPassing2(ptr addrspace(5) byval(i128) align 8 %{{.+}}, i63 %{{.+}}) // ARC: define{{.*}} void @ParamPassing2(ptr byval(i128) align 4 %{{.+}}, i63 inreg %{{.+}}) // XCORE: define{{.*}} void @ParamPassing2(ptr byval(i128) align 4 %{{.+}}, i63 %{{.+}}) -// RISCV64: define{{.*}} void @ParamPassing2(i127 %{{.+}}, i63 signext %{{.+}}) -// RISCV32: define{{.*}} void @ParamPassing2(ptr dead_on_return %{{.+}}, i63 %{{.+}}) +// RISCV64: define{{.*}} void @ParamPassing2(i127 signext %{{.+}}, i63 signext %{{.+}}) +// RISCV32: define{{.*}} void @ParamPassing2(ptr dead_on_return %{{.+}}, i63 signext %{{.+}}) // WASM: define{{.*}} void @ParamPassing2(i127 %{{.+}}, i63 %{{.+}}) // SYSTEMZ: define{{.*}} void @ParamPassing2(ptr dead_on_return %{{.+}}, i63 signext %{{.+}}) // PPC64: define{{.*}} void @ParamPassing2(i127 %{{.+}}, i63 signext %{{.+}}) >From 2629dac4c9598d3496ed1b3611168ac32301b40b Mon Sep 17 00:00:00 2001 From: Piyou Chen <[email protected]> Date: Tue, 2 Sep 2025 23:53:41 -0700 Subject: [PATCH 2/7] Update format --- clang/lib/CodeGen/Targets/RISCV.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index fb95880afe078..e2caff85c32f2 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -683,7 +683,7 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, if (const auto *EIT = Ty->getAs<BitIntType>()) { // FIXME: Maybe we should treat 32 as a special case and wait for // the SPEC to decide. - if (EIT->getNumBits() <= 2*XLen) + if (EIT->getNumBits() <= 2 * XLen) return ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)); if (EIT->getNumBits() > 128 || (!getContext().getTargetInfo().hasInt128Type() && >From db42ceab3850e37154832cd91256b372919c40f0 Mon Sep 17 00:00:00 2001 From: Piyou Chen <[email protected]> Date: Sun, 7 Sep 2025 22:01:17 -0700 Subject: [PATCH 3/7] Refine the comment --- clang/lib/CodeGen/Targets/RISCV.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index e2caff85c32f2..6af9c689354a1 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -682,7 +682,7 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, if (const auto *EIT = Ty->getAs<BitIntType>()) { // FIXME: Maybe we should treat 32 as a special case and wait for - // the SPEC to decide. + // the psABI to decide. if (EIT->getNumBits() <= 2 * XLen) return ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)); if (EIT->getNumBits() > 128 || >From a2c03fafb82bb8b18994efd5e0d75030c4196bb2 Mon Sep 17 00:00:00 2001 From: Piyou Chen <[email protected]> Date: Sun, 7 Sep 2025 22:01:40 -0700 Subject: [PATCH 4/7] Drop the curly braces --- clang/lib/CodeGen/Targets/RISCV.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index 6af9c689354a1..be2f5d5355f24 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -694,9 +694,8 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, } // All integral types are promoted to XLen width - if (Size < XLen && Ty->isIntegralOrEnumerationType()) { + if (Size < XLen && Ty->isIntegralOrEnumerationType()) return extendType(Ty, CGT.ConvertType(Ty)); - } return ABIArgInfo::getDirect(); } >From ded0caf54fb580ca1969c8956a73f9d5e24e444a Mon Sep 17 00:00:00 2001 From: Piyou Chen <[email protected]> Date: Fri, 12 Sep 2025 00:26:43 -0700 Subject: [PATCH 5/7] Use Indirect when Size > 2 * XLEN --- clang/lib/CodeGen/Targets/RISCV.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index be2f5d5355f24..7b2d104ab1cae 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -685,12 +685,9 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, // the psABI to decide. if (EIT->getNumBits() <= 2 * XLen) return ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)); - if (EIT->getNumBits() > 128 || - (!getContext().getTargetInfo().hasInt128Type() && - EIT->getNumBits() > 64)) - return getNaturalAlignIndirect( - Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(), - /*ByVal=*/false); + return getNaturalAlignIndirect( + Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(), + /*ByVal=*/false); } // All integral types are promoted to XLen width >From 04d20af5828521ad99b17703191e0973bf64fe24 Mon Sep 17 00:00:00 2001 From: Piyou Chen <[email protected]> Date: Fri, 12 Sep 2025 00:30:33 -0700 Subject: [PATCH 6/7] Add test for RV32 and fforce-enable-int128 --- clang/test/CodeGen/RISCV/bitint.c | 109 ++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/clang/test/CodeGen/RISCV/bitint.c b/clang/test/CodeGen/RISCV/bitint.c index 2c28c536dc1bc..0777a23420986 100644 --- a/clang/test/CodeGen/RISCV/bitint.c +++ b/clang/test/CodeGen/RISCV/bitint.c @@ -1,6 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature // RUN: %clang_cc1 -triple riscv64 -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=RISCV64 // RUN: %clang_cc1 -triple riscv32 -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=RISCV32 +// RUN: %clang_cc1 -triple riscv32 -fforce-enable-int128 -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=RISCV32_INT128 // RISCV64-LABEL: define {{[^@]+}}@test_bitint_17_add_unsigned // RISCV64-SAME: (i17 noundef zeroext [[A:%.*]], i17 noundef zeroext [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { @@ -14,6 +15,12 @@ // RISCV32-NEXT: [[ADD:%.*]] = add i17 [[B]], [[A]] // RISCV32-NEXT: ret i17 [[ADD]] // +// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_17_add_unsigned +// RISCV32_INT128-SAME: (i17 noundef zeroext [[A:%.*]], i17 noundef zeroext [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// RISCV32_INT128-NEXT: entry: +// RISCV32_INT128-NEXT: [[ADD:%.*]] = add i17 [[B]], [[A]] +// RISCV32_INT128-NEXT: ret i17 [[ADD]] +// unsigned _BitInt(17) test_bitint_17_add_unsigned(unsigned _BitInt(17) a, unsigned _BitInt(17) b) { return a + b; } @@ -30,6 +37,12 @@ unsigned _BitInt(17) test_bitint_17_add_unsigned(unsigned _BitInt(17) a, unsigne // RISCV32-NEXT: [[ADD:%.*]] = add nsw i17 [[B]], [[A]] // RISCV32-NEXT: ret i17 [[ADD]] // +// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_17_add_signed +// RISCV32_INT128-SAME: (i17 noundef signext [[A:%.*]], i17 noundef signext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV32_INT128-NEXT: entry: +// RISCV32_INT128-NEXT: [[ADD:%.*]] = add nsw i17 [[B]], [[A]] +// RISCV32_INT128-NEXT: ret i17 [[ADD]] +// signed _BitInt(17) test_bitint_17_add_signed(signed _BitInt(17) a, signed _BitInt(17) b) { return a + b; } @@ -46,6 +59,12 @@ signed _BitInt(17) test_bitint_17_add_signed(signed _BitInt(17) a, signed _BitIn // RISCV32-NEXT: [[ADD:%.*]] = add nsw i17 [[B]], [[A]] // RISCV32-NEXT: ret i17 [[ADD]] // +// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_17_add_default +// RISCV32_INT128-SAME: (i17 noundef signext [[A:%.*]], i17 noundef signext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV32_INT128-NEXT: entry: +// RISCV32_INT128-NEXT: [[ADD:%.*]] = add nsw i17 [[B]], [[A]] +// RISCV32_INT128-NEXT: ret i17 [[ADD]] +// _BitInt(17) test_bitint_17_add_default(_BitInt(17) a, _BitInt(17) b) { return a + b; } @@ -62,6 +81,12 @@ _BitInt(17) test_bitint_17_add_default(_BitInt(17) a, _BitInt(17) b) { // RISCV32-NEXT: [[ADD:%.*]] = add i32 [[B]], [[A]] // RISCV32-NEXT: ret i32 [[ADD]] // +// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_32_add_unsigned +// RISCV32_INT128-SAME: (i32 noundef zeroext [[A:%.*]], i32 noundef zeroext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV32_INT128-NEXT: entry: +// RISCV32_INT128-NEXT: [[ADD:%.*]] = add i32 [[B]], [[A]] +// RISCV32_INT128-NEXT: ret i32 [[ADD]] +// unsigned _BitInt(32) test_bitint_32_add_unsigned(unsigned _BitInt(32) a, unsigned _BitInt(32) b) { return a + b; } @@ -78,6 +103,12 @@ unsigned _BitInt(32) test_bitint_32_add_unsigned(unsigned _BitInt(32) a, unsigne // RISCV32-NEXT: [[ADD:%.*]] = add nsw i32 [[B]], [[A]] // RISCV32-NEXT: ret i32 [[ADD]] // +// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_32_add_signed +// RISCV32_INT128-SAME: (i32 noundef signext [[A:%.*]], i32 noundef signext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV32_INT128-NEXT: entry: +// RISCV32_INT128-NEXT: [[ADD:%.*]] = add nsw i32 [[B]], [[A]] +// RISCV32_INT128-NEXT: ret i32 [[ADD]] +// signed _BitInt(32) test_bitint_32_add_signed(signed _BitInt(32) a, signed _BitInt(32) b) { return a + b; } @@ -94,6 +125,12 @@ signed _BitInt(32) test_bitint_32_add_signed(signed _BitInt(32) a, signed _BitIn // RISCV32-NEXT: [[ADD:%.*]] = add nsw i32 [[B]], [[A]] // RISCV32-NEXT: ret i32 [[ADD]] // +// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_32_add_default +// RISCV32_INT128-SAME: (i32 noundef signext [[A:%.*]], i32 noundef signext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV32_INT128-NEXT: entry: +// RISCV32_INT128-NEXT: [[ADD:%.*]] = add nsw i32 [[B]], [[A]] +// RISCV32_INT128-NEXT: ret i32 [[ADD]] +// _BitInt(32) test_bitint_32_add_default(_BitInt(32) a, _BitInt(32) b) { return a + b; } @@ -117,6 +154,18 @@ _BitInt(32) test_bitint_32_add_default(_BitInt(32) a, _BitInt(32) b) { // RISCV32-NEXT: store i128 [[STOREDV4]], ptr [[AGG_RESULT]], align 8, !tbaa [[TBAA6]] // RISCV32-NEXT: ret void // +// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_65_add_unsigned +// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +// RISCV32_INT128-NEXT: entry: +// RISCV32_INT128-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA6:![0-9]+]] +// RISCV32_INT128-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i65 +// RISCV32_INT128-NEXT: [[TMP3:%.*]] = load i128, ptr [[TMP1]], align 8, !tbaa [[TBAA6]] +// RISCV32_INT128-NEXT: [[B:%.*]] = trunc i128 [[TMP3]] to i65 +// RISCV32_INT128-NEXT: [[ADD:%.*]] = add i65 [[B]], [[A]] +// RISCV32_INT128-NEXT: [[STOREDV4:%.*]] = zext i65 [[ADD]] to i128 +// RISCV32_INT128-NEXT: store i128 [[STOREDV4]], ptr [[AGG_RESULT]], align 8, !tbaa [[TBAA6]] +// RISCV32_INT128-NEXT: ret void +// unsigned _BitInt(65) test_bitint_65_add_unsigned(unsigned _BitInt(65) a, unsigned _BitInt(65) b) { return a + b; } @@ -139,6 +188,18 @@ unsigned _BitInt(65) test_bitint_65_add_unsigned(unsigned _BitInt(65) a, unsigne // RISCV32-NEXT: store i128 [[STOREDV4]], ptr [[AGG_RESULT]], align 8, !tbaa [[TBAA6]] // RISCV32-NEXT: ret void // +// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_65_add_signed +// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] { +// RISCV32_INT128-NEXT: entry: +// RISCV32_INT128-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA6]] +// RISCV32_INT128-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i65 +// RISCV32_INT128-NEXT: [[TMP3:%.*]] = load i128, ptr [[TMP1]], align 8, !tbaa [[TBAA6]] +// RISCV32_INT128-NEXT: [[B:%.*]] = trunc i128 [[TMP3]] to i65 +// RISCV32_INT128-NEXT: [[ADD:%.*]] = add nsw i65 [[B]], [[A]] +// RISCV32_INT128-NEXT: [[STOREDV4:%.*]] = sext i65 [[ADD]] to i128 +// RISCV32_INT128-NEXT: store i128 [[STOREDV4]], ptr [[AGG_RESULT]], align 8, !tbaa [[TBAA6]] +// RISCV32_INT128-NEXT: ret void +// signed _BitInt(65) test_bitint_65_add_signed(signed _BitInt(65) a, signed _BitInt(65) b) { return a + b; } @@ -161,6 +222,18 @@ signed _BitInt(65) test_bitint_65_add_signed(signed _BitInt(65) a, signed _BitIn // RISCV32-NEXT: store i128 [[STOREDV4]], ptr [[AGG_RESULT]], align 8, !tbaa [[TBAA6]] // RISCV32-NEXT: ret void // +// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_65_add_default +// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] { +// RISCV32_INT128-NEXT: entry: +// RISCV32_INT128-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA6]] +// RISCV32_INT128-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i65 +// RISCV32_INT128-NEXT: [[TMP3:%.*]] = load i128, ptr [[TMP1]], align 8, !tbaa [[TBAA6]] +// RISCV32_INT128-NEXT: [[B:%.*]] = trunc i128 [[TMP3]] to i65 +// RISCV32_INT128-NEXT: [[ADD:%.*]] = add nsw i65 [[B]], [[A]] +// RISCV32_INT128-NEXT: [[STOREDV4:%.*]] = sext i65 [[ADD]] to i128 +// RISCV32_INT128-NEXT: store i128 [[STOREDV4]], ptr [[AGG_RESULT]], align 8, !tbaa [[TBAA6]] +// RISCV32_INT128-NEXT: ret void +// _BitInt(65) test_bitint_65_add_default(_BitInt(65) a, _BitInt(65) b) { return a + b; } @@ -184,6 +257,18 @@ _BitInt(65) test_bitint_65_add_default(_BitInt(65) a, _BitInt(65) b) { // RISCV32-NEXT: store i128 [[STOREDV4]], ptr [[AGG_RESULT]], align 8, !tbaa [[TBAA10]] // RISCV32-NEXT: ret void // +// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_77_add_unsigned +// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] { +// RISCV32_INT128-NEXT: entry: +// RISCV32_INT128-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA10:![0-9]+]] +// RISCV32_INT128-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i77 +// RISCV32_INT128-NEXT: [[TMP3:%.*]] = load i128, ptr [[TMP1]], align 8, !tbaa [[TBAA10]] +// RISCV32_INT128-NEXT: [[B:%.*]] = trunc i128 [[TMP3]] to i77 +// RISCV32_INT128-NEXT: [[ADD:%.*]] = add i77 [[B]], [[A]] +// RISCV32_INT128-NEXT: [[STOREDV4:%.*]] = zext i77 [[ADD]] to i128 +// RISCV32_INT128-NEXT: store i128 [[STOREDV4]], ptr [[AGG_RESULT]], align 8, !tbaa [[TBAA10]] +// RISCV32_INT128-NEXT: ret void +// unsigned _BitInt(77) test_bitint_77_add_unsigned(unsigned _BitInt(77) a, unsigned _BitInt(77) b) { return a + b; } @@ -206,6 +291,18 @@ unsigned _BitInt(77) test_bitint_77_add_unsigned(unsigned _BitInt(77) a, unsigne // RISCV32-NEXT: store i128 [[STOREDV4]], ptr [[AGG_RESULT]], align 8, !tbaa [[TBAA10]] // RISCV32-NEXT: ret void // +// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_77_add_signed +// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] { +// RISCV32_INT128-NEXT: entry: +// RISCV32_INT128-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA10]] +// RISCV32_INT128-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i77 +// RISCV32_INT128-NEXT: [[TMP3:%.*]] = load i128, ptr [[TMP1]], align 8, !tbaa [[TBAA10]] +// RISCV32_INT128-NEXT: [[B:%.*]] = trunc i128 [[TMP3]] to i77 +// RISCV32_INT128-NEXT: [[ADD:%.*]] = add nsw i77 [[B]], [[A]] +// RISCV32_INT128-NEXT: [[STOREDV4:%.*]] = sext i77 [[ADD]] to i128 +// RISCV32_INT128-NEXT: store i128 [[STOREDV4]], ptr [[AGG_RESULT]], align 8, !tbaa [[TBAA10]] +// RISCV32_INT128-NEXT: ret void +// signed _BitInt(77) test_bitint_77_add_signed(signed _BitInt(77) a, signed _BitInt(77) b) { return a + b; } @@ -228,6 +325,18 @@ signed _BitInt(77) test_bitint_77_add_signed(signed _BitInt(77) a, signed _BitIn // RISCV32-NEXT: store i128 [[STOREDV4]], ptr [[AGG_RESULT]], align 8, !tbaa [[TBAA10]] // RISCV32-NEXT: ret void // +// RISCV32_INT128-LABEL: define {{[^@]+}}@test_bitint_77_add_default +// RISCV32_INT128-SAME: (ptr dead_on_unwind noalias writable writeonly sret(i128) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP0:%.*]], ptr dead_on_return noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] { +// RISCV32_INT128-NEXT: entry: +// RISCV32_INT128-NEXT: [[TMP2:%.*]] = load i128, ptr [[TMP0]], align 8, !tbaa [[TBAA10]] +// RISCV32_INT128-NEXT: [[A:%.*]] = trunc i128 [[TMP2]] to i77 +// RISCV32_INT128-NEXT: [[TMP3:%.*]] = load i128, ptr [[TMP1]], align 8, !tbaa [[TBAA10]] +// RISCV32_INT128-NEXT: [[B:%.*]] = trunc i128 [[TMP3]] to i77 +// RISCV32_INT128-NEXT: [[ADD:%.*]] = add nsw i77 [[B]], [[A]] +// RISCV32_INT128-NEXT: [[STOREDV4:%.*]] = sext i77 [[ADD]] to i128 +// RISCV32_INT128-NEXT: store i128 [[STOREDV4]], ptr [[AGG_RESULT]], align 8, !tbaa [[TBAA10]] +// RISCV32_INT128-NEXT: ret void +// _BitInt(77) test_bitint_77_add_default(_BitInt(77) a, _BitInt(77) b) { return a + b; } >From ca6cae9945f07501ad80dd814f2603a1d336a217 Mon Sep 17 00:00:00 2001 From: Piyou Chen <[email protected]> Date: Mon, 22 Sep 2025 06:04:00 -0700 Subject: [PATCH 7/7] Make RV64 _BitInt(32) always signext --- clang/lib/CodeGen/Targets/RISCV.cpp | 6 ++++-- clang/test/CodeGen/RISCV/bitint.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index 7b2d104ab1cae..00db658e5abac 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -681,8 +681,10 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, Ty = ED->getIntegerType(); if (const auto *EIT = Ty->getAs<BitIntType>()) { - // FIXME: Maybe we should treat 32 as a special case and wait for - // the psABI to decide. + + if (XLen == 64 && EIT->getNumBits() == 32) + return extendType(Ty, CGT.ConvertType(Ty)); + if (EIT->getNumBits() <= 2 * XLen) return ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)); return getNaturalAlignIndirect( diff --git a/clang/test/CodeGen/RISCV/bitint.c b/clang/test/CodeGen/RISCV/bitint.c index 0777a23420986..1ad43affac9e6 100644 --- a/clang/test/CodeGen/RISCV/bitint.c +++ b/clang/test/CodeGen/RISCV/bitint.c @@ -70,7 +70,7 @@ _BitInt(17) test_bitint_17_add_default(_BitInt(17) a, _BitInt(17) b) { } // RISCV64-LABEL: define {{[^@]+}}@test_bitint_32_add_unsigned -// RISCV64-SAME: (i32 noundef zeroext [[A:%.*]], i32 noundef zeroext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { +// RISCV64-SAME: (i32 noundef signext [[A:%.*]], i32 noundef signext [[B:%.*]]) local_unnamed_addr #[[ATTR0]] { // RISCV64-NEXT: entry: // RISCV64-NEXT: [[ADD:%.*]] = add i32 [[B]], [[A]] // RISCV64-NEXT: ret i32 [[ADD]] _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
