- 
                Notifications
    You must be signed in to change notification settings 
- Fork 15k
[clang][RISCV] support BITINT with mixed-type #156592
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
0927005
              2629dac
              db42cea
              a2c03fa
              ded0caf
              04d20af
              ca6cae9
              5333575
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
|  | @@ -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. | ||
|         
                  topperc marked this conversation as resolved.
              Outdated
          
            Show resolved
            Hide resolved | ||
| if (EIT->getNumBits() <= 2 * XLen) | ||
| return ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)); | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we call  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's something a bit strange happening here. will be treated as 32 in If we use the  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm guessing the call to  I guess we can leave it how you have it then. | ||
| 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)); | ||
| } | ||
|         
                  topperc marked this conversation as resolved.
              Outdated
          
            Show resolved
            Hide resolved | ||
|  | ||
| return ABIArgInfo::getDirect(); | ||
| } | ||
|  | ||
|  | ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -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; | ||
| } | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The FIXME comment indicates uncertainty about handling 32-bit BitInt types and references waiting for a specification decision. This suggests the implementation may be incomplete or temporary for this specific case.