-
Notifications
You must be signed in to change notification settings - Fork 11.7k
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
[RISCV][GISel] Legalizer and register bank selection for G_JUMP_TABLE and G_BRJT #71970
Conversation
@llvm/pr-subscribers-llvm-globalisel Author: Craig Topper (topperc) ChangesTesting together since they should come paired. Instruction selection will be a separate PR. Patch is 23.54 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/71970.diff 6 Files Affected:
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 1aba6b78d8a9d9b..f7f3a4ba923fcce 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -131,12 +131,14 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {
getActionDefinitionsBuilder(G_BRCOND).legalFor({sXLen}).minScalar(0, sXLen);
+ getActionDefinitionsBuilder(G_BRJT).legalFor({{p0, sXLen}});
+
getActionDefinitionsBuilder(G_PHI)
.legalFor({p0, sXLen})
.widenScalarToNextPow2(0)
.clampScalar(0, sXLen, sXLen);
- getActionDefinitionsBuilder(G_GLOBAL_VALUE)
+ getActionDefinitionsBuilder({G_GLOBAL_VALUE, G_JUMP_TABLE})
.legalFor({p0});
if (ST.hasStdExtM() || ST.hasStdExtZmmul()) {
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
index 60b6de0a760dcbb..3cdee17be8d1d88 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
@@ -166,12 +166,17 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case TargetOpcode::G_CONSTANT:
case TargetOpcode::G_FRAME_INDEX:
case TargetOpcode::G_GLOBAL_VALUE:
+ case TargetOpcode::G_JUMP_TABLE:
case TargetOpcode::G_BRCOND:
OperandsMapping = getOperandsMapping({GPRValueMapping, nullptr});
break;
case TargetOpcode::G_BR:
OperandsMapping = getOperandsMapping({nullptr});
break;
+ case TargetOpcode::G_BRJT:
+ OperandsMapping =
+ getOperandsMapping({GPRValueMapping, nullptr, GPRValueMapping});
+ break;
case TargetOpcode::G_ICMP:
OperandsMapping = getOperandsMapping(
{GPRValueMapping, nullptr, GPRValueMapping, GPRValueMapping});
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-jump-table-brjt.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-jump-table-brjt.mir
new file mode 100644
index 000000000000000..c9c5411f1ffad18
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-jump-table-brjt.mir
@@ -0,0 +1,121 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+m -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s
+
+--- |
+ define i32 @jt_test(i32 %x) {
+ entry:
+ switch i32 %x, label %return [
+ i32 75, label %sw.bb
+ i32 34, label %sw.bb
+ i32 56, label %sw.bb
+ i32 35, label %sw.bb
+ i32 40, label %sw.bb
+ i32 4, label %sw.bb1
+ i32 5, label %sw.bb1
+ i32 6, label %sw.bb1
+ ]
+
+ sw.bb: ; preds = %entry, %entry, %entry, %entry, %entry
+ %add = add nsw i32 %x, 42
+ br label %return
+
+ sw.bb1: ; preds = %entry, %entry, %entry
+ %mul = mul nsw i32 %x, 3
+ br label %return
+
+ return: ; preds = %sw.bb1, %sw.bb, %entry
+ %retval.0 = phi i32 [ %mul, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
+ ret i32 %retval.0
+ }
+
+...
+---
+name: jt_test
+tracksRegLiveness: true
+jumpTable:
+ kind: block-address
+ entries:
+ - id: 0
+ blocks: [ '%bb.3', '%bb.3', '%bb.3', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.2', '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2' ]
+body: |
+ ; CHECK-LABEL: name: jt_test
+ ; CHECK: bb.0.entry:
+ ; CHECK-NEXT: successors: %bb.4(0x071c71c7), %bb.1(0x78e38e39)
+ ; CHECK-NEXT: liveins: $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 71
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[C4]]
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ugt), [[SUB]](s32), [[C]]
+ ; CHECK-NEXT: G_BRCOND [[ICMP]](s32), %bb.4
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1.entry:
+ ; CHECK-NEXT: successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4c)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[JUMP_TABLE:%[0-9]+]]:_(p0) = G_JUMP_TABLE %jump-table.0
+ ; CHECK-NEXT: G_BRJT [[JUMP_TABLE]](p0), %jump-table.0, [[SUB]](s32)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2.sw.bb:
+ ; CHECK-NEXT: successors: %bb.4(0x80000000)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = nsw G_ADD [[COPY]], [[C2]]
+ ; CHECK-NEXT: G_BR %bb.4
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.3.sw.bb1:
+ ; CHECK-NEXT: successors: %bb.4(0x80000000)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = nsw G_MUL [[COPY]], [[C1]]
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.4.return:
+ ; CHECK-NEXT: [[PHI:%[0-9]+]]:_(s32) = G_PHI [[MUL]](s32), %bb.3, [[ADD]](s32), %bb.2, [[C3]](s32), %bb.0, [[C3]](s32), %bb.1
+ ; CHECK-NEXT: $x10 = COPY [[PHI]](s32)
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ bb.1.entry:
+ successors: %bb.4(0x071c71c7), %bb.5(0x78e38e39)
+ liveins: $x10
+
+ %0:_(s32) = COPY $x10
+ %4:_(s32) = G_CONSTANT i32 71
+ %8:_(s32) = G_CONSTANT i32 3
+ %10:_(s32) = G_CONSTANT i32 42
+ %13:_(s32) = G_CONSTANT i32 0
+ %1:_(s32) = G_CONSTANT i32 4
+ %2:_(s32) = G_SUB %0, %1
+ %6:_(s1) = G_ICMP intpred(ugt), %2(s32), %4
+ G_BRCOND %6(s1), %bb.4
+
+ bb.5.entry:
+ successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4b)
+
+ %7:_(p0) = G_JUMP_TABLE %jump-table.0
+ G_BRJT %7(p0), %jump-table.0, %2(s32)
+
+ bb.2.sw.bb:
+ %11:_(s32) = nsw G_ADD %0, %10
+ G_BR %bb.4
+
+ bb.3.sw.bb1:
+ %9:_(s32) = nsw G_MUL %0, %8
+
+ bb.4.return:
+ %12:_(s32) = G_PHI %9(s32), %bb.3, %11(s32), %bb.2, %13(s32), %bb.1, %13(s32), %bb.5
+ $x10 = COPY %12(s32)
+ PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-jump-table-brjt.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-jump-table-brjt.mir
new file mode 100644
index 000000000000000..22bcc9161b3e206
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-jump-table-brjt.mir
@@ -0,0 +1,130 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -mattr=+m -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s
+
+--- |
+ define i32 @jt_test(i32 %x) {
+ entry:
+ %0 = sext i32 %x to i64
+ switch i64 %0, label %return [
+ i64 75, label %sw.bb
+ i64 34, label %sw.bb
+ i64 56, label %sw.bb
+ i64 35, label %sw.bb
+ i64 40, label %sw.bb
+ i64 4, label %sw.bb1
+ i64 5, label %sw.bb1
+ i64 6, label %sw.bb1
+ ]
+
+ sw.bb:
+ %add = add nsw i32 %x, 42
+ br label %return
+
+ sw.bb1:
+ %mul = mul nsw i32 %x, 3
+ br label %return
+
+ return:
+ %retval.0 = phi i32 [ %mul, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
+ ret i32 %retval.0
+ }
+
+...
+---
+name: jt_test
+tracksRegLiveness: true
+jumpTable:
+ kind: custom32
+ entries:
+ - id: 0
+ blocks: [ '%bb.3', '%bb.3', '%bb.3', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.2', '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2' ]
+body: |
+ ; CHECK-LABEL: name: jt_test
+ ; CHECK: bb.0.entry:
+ ; CHECK-NEXT: successors: %bb.4(0x071c71c7), %bb.1(0x78e38e39)
+ ; CHECK-NEXT: liveins: $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 71
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+ ; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 32
+ ; CHECK-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s64) = G_SUB [[SEXT_INREG]], [[C4]]
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(ugt), [[SUB]](s64), [[C]]
+ ; CHECK-NEXT: G_BRCOND [[ICMP]](s64), %bb.4
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1.entry:
+ ; CHECK-NEXT: successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4c)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[JUMP_TABLE:%[0-9]+]]:_(p0) = G_JUMP_TABLE %jump-table.0
+ ; CHECK-NEXT: G_BRJT [[JUMP_TABLE]](p0), %jump-table.0, [[SUB]](s64)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2.sw.bb:
+ ; CHECK-NEXT: successors: %bb.4(0x80000000)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = nsw G_ADD [[TRUNC]], [[C2]]
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ADD]](s32)
+ ; CHECK-NEXT: G_BR %bb.4
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.3.sw.bb1:
+ ; CHECK-NEXT: successors: %bb.4(0x80000000)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = nsw G_MUL [[TRUNC]], [[C1]]
+ ; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s64) = G_ANYEXT [[MUL]](s32)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.4.return:
+ ; CHECK-NEXT: [[PHI:%[0-9]+]]:_(s64) = G_PHI [[ANYEXT1]](s64), %bb.3, [[ANYEXT]](s64), %bb.2, [[C3]](s64), %bb.0, [[C3]](s64), %bb.1
+ ; CHECK-NEXT: $x10 = COPY [[PHI]](s64)
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ bb.1.entry:
+ successors: %bb.4(0x071c71c7), %bb.5(0x78e38e39)
+ liveins: $x10
+
+ %1:_(s64) = COPY $x10
+ %0:_(s32) = G_TRUNC %1(s64)
+ %6:_(s64) = G_CONSTANT i64 71
+ %10:_(s32) = G_CONSTANT i32 3
+ %12:_(s32) = G_CONSTANT i32 42
+ %19:_(s64) = G_CONSTANT i64 0
+ %2:_(s64) = G_SEXT %0(s32)
+ %3:_(s64) = G_CONSTANT i64 4
+ %4:_(s64) = G_SUB %2, %3
+ %8:_(s1) = G_ICMP intpred(ugt), %4(s64), %6
+ G_BRCOND %8(s1), %bb.4
+
+ bb.5.entry:
+ successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4b)
+
+ %9:_(p0) = G_JUMP_TABLE %jump-table.0
+ G_BRJT %9(p0), %jump-table.0, %4(s64)
+
+ bb.2.sw.bb:
+ %13:_(s32) = nsw G_ADD %0, %12
+ %18:_(s64) = G_ANYEXT %13(s32)
+ G_BR %bb.4
+
+ bb.3.sw.bb1:
+ %11:_(s32) = nsw G_MUL %0, %10
+ %17:_(s64) = G_ANYEXT %11(s32)
+
+ bb.4.return:
+ %15:_(s64) = G_PHI %17(s64), %bb.3, %18(s64), %bb.2, %19(s64), %bb.1, %19(s64), %bb.5
+ $x10 = COPY %15(s64)
+ PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv32.mir
new file mode 100644
index 000000000000000..24be1b754ae94c9
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv32.mir
@@ -0,0 +1,129 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+m -run-pass=regbankselect \
+# RUN: -disable-gisel-legality-check -simplify-mir -verify-machineinstrs %s \
+# RUN: -o - | FileCheck -check-prefix=RV32I %s
+
+--- |
+ define i32 @jt_test(i32 %x) {
+ entry:
+ switch i32 %x, label %return [
+ i32 75, label %sw.bb
+ i32 34, label %sw.bb
+ i32 56, label %sw.bb
+ i32 35, label %sw.bb
+ i32 40, label %sw.bb
+ i32 4, label %sw.bb1
+ i32 5, label %sw.bb1
+ i32 6, label %sw.bb1
+ ]
+
+ sw.bb: ; preds = %entry, %entry, %entry, %entry, %entry
+ %add = add nsw i32 %x, 42
+ br label %return
+
+ sw.bb1: ; preds = %entry, %entry, %entry
+ %mul = mul nsw i32 %x, 3
+ br label %return
+
+ return: ; preds = %sw.bb1, %sw.bb, %entry
+ %retval.0 = phi i32 [ %mul, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
+ ret i32 %retval.0
+ }
+
+...
+---
+name: jt_test
+legalized: true
+tracksRegLiveness: true
+jumpTable:
+ kind: block-address
+ entries:
+ - id: 0
+ blocks: [ '%bb.3', '%bb.3', '%bb.3', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.2', '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2' ]
+body: |
+ ; RV32I-LABEL: name: jt_test
+ ; RV32I: bb.0.entry:
+ ; RV32I-NEXT: successors: %bb.4(0x071c71c7), %bb.1(0x78e38e39)
+ ; RV32I-NEXT: liveins: $x10
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s32) = COPY $x10
+ ; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 71
+ ; RV32I-NEXT: [[C1:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 3
+ ; RV32I-NEXT: [[C2:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 42
+ ; RV32I-NEXT: [[C3:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 0
+ ; RV32I-NEXT: [[C4:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 4
+ ; RV32I-NEXT: [[SUB:%[0-9]+]]:gprb(s32) = G_SUB [[COPY]], [[C4]]
+ ; RV32I-NEXT: [[ICMP:%[0-9]+]]:gprb(s32) = G_ICMP intpred(ugt), [[SUB]](s32), [[C]]
+ ; RV32I-NEXT: G_BRCOND [[ICMP]](s32), %bb.4
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: bb.1.entry:
+ ; RV32I-NEXT: successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4c)
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[JUMP_TABLE:%[0-9]+]]:gprb(p0) = G_JUMP_TABLE %jump-table.0
+ ; RV32I-NEXT: G_BRJT [[JUMP_TABLE]](p0), %jump-table.0, [[SUB]](s32)
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: bb.2.sw.bb:
+ ; RV32I-NEXT: [[ADD:%[0-9]+]]:gprb(s32) = nsw G_ADD [[COPY]], [[C2]]
+ ; RV32I-NEXT: G_BR %bb.4
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: bb.3.sw.bb1:
+ ; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; RV32I-NEXT: $x10 = COPY [[COPY]](s32)
+ ; RV32I-NEXT: $x11 = COPY [[C1]](s32)
+ ; RV32I-NEXT: PseudoCALL target-flags(riscv-call) &__mulsi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gprb(s32) = COPY $x10
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: bb.4.return:
+ ; RV32I-NEXT: [[PHI:%[0-9]+]]:gprb(s32) = G_PHI [[COPY1]](s32), %bb.3, [[ADD]](s32), %bb.2, [[C3]](s32), %bb.0, [[C3]](s32), %bb.1
+ ; RV32I-NEXT: $x10 = COPY [[PHI]](s32)
+ ; RV32I-NEXT: PseudoRET implicit $x10
+ bb.1.entry:
+ successors: %bb.4(0x071c71c7), %bb.5(0x78e38e39)
+ liveins: $x10
+
+ %0:_(s32) = COPY $x10
+ %4:_(s32) = G_CONSTANT i32 71
+ %8:_(s32) = G_CONSTANT i32 3
+ %10:_(s32) = G_CONSTANT i32 42
+ %13:_(s32) = G_CONSTANT i32 0
+ %1:_(s32) = G_CONSTANT i32 4
+ %2:_(s32) = G_SUB %0, %1
+ %15:_(s32) = G_ICMP intpred(ugt), %2(s32), %4
+ G_BRCOND %15(s32), %bb.4
+
+ bb.5.entry:
+ successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4b)
+
+ %7:_(p0) = G_JUMP_TABLE %jump-table.0
+ G_BRJT %7(p0), %jump-table.0, %2(s32)
+
+ bb.2.sw.bb:
+ %11:_(s32) = nsw G_ADD %0, %10
+ G_BR %bb.4
+
+ bb.3.sw.bb1:
+ ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ $x10 = COPY %0(s32)
+ $x11 = COPY %8(s32)
+ PseudoCALL target-flags(riscv-call) &__mulsi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ %9:_(s32) = COPY $x10
+
+ bb.4.return:
+ %12:_(s32) = G_PHI %9(s32), %bb.3, %11(s32), %bb.2, %13(s32), %bb.1, %13(s32), %bb.5
+ $x10 = COPY %12(s32)
+ PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv64.mir
new file mode 100644
index 000000000000000..6dbabeec8f6fd13
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv64.mir
@@ -0,0 +1,136 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -run-pass=regbankselect \
+# RUN: -disable-gisel-legality-check -simplify-mir -verify-machineinstrs %s \
+# RUN: -o - | FileCheck -check-prefix=RV64I %s
+
+--- |
+ define i32 @jt_test(i32 %x) {
+ entry:
+ %0 = sext i32 %x to i64
+ switch i64 %0, label %return [
+ i64 75, label %sw.bb
+ i64 34, label %sw.bb
+ i64 56, label %sw.bb
+ i64 35, label %sw.bb
+ i64 40, label %sw.bb
+ i64 4, label %sw.bb1
+ i64 5, label %sw.bb1
+ i64 6, label %sw.bb1
+ ]
+
+ sw.bb: ; preds = %entry, %entry, %entry, %entry, %entry
+ %add = add nsw i32 %x, 42
+ br label %return
+
+ sw.bb1: ; preds = %entry, %entry, %entry
+ %mul = mul nsw i32 %x, 3
+ br label %return
+
+ return: ; preds = %sw.bb1, %sw.bb, %entry
+ %retval.0 = phi i32 [ %mul, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
+ ret i32 %retval.0
+ }
+
+...
+---
+name: jt_test
+legalized: true
+tracksRegLiveness: true
+jumpTable:
+ kind: custom32
+ entries:
+ - id: 0
+ blocks: [ '%bb.3', '%bb.3', '%bb.3', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.2', '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb...
[truncated]
|
@llvm/pr-subscribers-backend-risc-v Author: Craig Topper (topperc) ChangesTesting together since they should come paired. Instruction selection will be a separate PR. Patch is 23.54 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/71970.diff 6 Files Affected:
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 1aba6b78d8a9d9b..f7f3a4ba923fcce 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -131,12 +131,14 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {
getActionDefinitionsBuilder(G_BRCOND).legalFor({sXLen}).minScalar(0, sXLen);
+ getActionDefinitionsBuilder(G_BRJT).legalFor({{p0, sXLen}});
+
getActionDefinitionsBuilder(G_PHI)
.legalFor({p0, sXLen})
.widenScalarToNextPow2(0)
.clampScalar(0, sXLen, sXLen);
- getActionDefinitionsBuilder(G_GLOBAL_VALUE)
+ getActionDefinitionsBuilder({G_GLOBAL_VALUE, G_JUMP_TABLE})
.legalFor({p0});
if (ST.hasStdExtM() || ST.hasStdExtZmmul()) {
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
index 60b6de0a760dcbb..3cdee17be8d1d88 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
@@ -166,12 +166,17 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case TargetOpcode::G_CONSTANT:
case TargetOpcode::G_FRAME_INDEX:
case TargetOpcode::G_GLOBAL_VALUE:
+ case TargetOpcode::G_JUMP_TABLE:
case TargetOpcode::G_BRCOND:
OperandsMapping = getOperandsMapping({GPRValueMapping, nullptr});
break;
case TargetOpcode::G_BR:
OperandsMapping = getOperandsMapping({nullptr});
break;
+ case TargetOpcode::G_BRJT:
+ OperandsMapping =
+ getOperandsMapping({GPRValueMapping, nullptr, GPRValueMapping});
+ break;
case TargetOpcode::G_ICMP:
OperandsMapping = getOperandsMapping(
{GPRValueMapping, nullptr, GPRValueMapping, GPRValueMapping});
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-jump-table-brjt.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-jump-table-brjt.mir
new file mode 100644
index 000000000000000..c9c5411f1ffad18
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv32/legalize-jump-table-brjt.mir
@@ -0,0 +1,121 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+m -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s
+
+--- |
+ define i32 @jt_test(i32 %x) {
+ entry:
+ switch i32 %x, label %return [
+ i32 75, label %sw.bb
+ i32 34, label %sw.bb
+ i32 56, label %sw.bb
+ i32 35, label %sw.bb
+ i32 40, label %sw.bb
+ i32 4, label %sw.bb1
+ i32 5, label %sw.bb1
+ i32 6, label %sw.bb1
+ ]
+
+ sw.bb: ; preds = %entry, %entry, %entry, %entry, %entry
+ %add = add nsw i32 %x, 42
+ br label %return
+
+ sw.bb1: ; preds = %entry, %entry, %entry
+ %mul = mul nsw i32 %x, 3
+ br label %return
+
+ return: ; preds = %sw.bb1, %sw.bb, %entry
+ %retval.0 = phi i32 [ %mul, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
+ ret i32 %retval.0
+ }
+
+...
+---
+name: jt_test
+tracksRegLiveness: true
+jumpTable:
+ kind: block-address
+ entries:
+ - id: 0
+ blocks: [ '%bb.3', '%bb.3', '%bb.3', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.2', '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2' ]
+body: |
+ ; CHECK-LABEL: name: jt_test
+ ; CHECK: bb.0.entry:
+ ; CHECK-NEXT: successors: %bb.4(0x071c71c7), %bb.1(0x78e38e39)
+ ; CHECK-NEXT: liveins: $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 71
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[C4]]
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ugt), [[SUB]](s32), [[C]]
+ ; CHECK-NEXT: G_BRCOND [[ICMP]](s32), %bb.4
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1.entry:
+ ; CHECK-NEXT: successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4c)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[JUMP_TABLE:%[0-9]+]]:_(p0) = G_JUMP_TABLE %jump-table.0
+ ; CHECK-NEXT: G_BRJT [[JUMP_TABLE]](p0), %jump-table.0, [[SUB]](s32)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2.sw.bb:
+ ; CHECK-NEXT: successors: %bb.4(0x80000000)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = nsw G_ADD [[COPY]], [[C2]]
+ ; CHECK-NEXT: G_BR %bb.4
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.3.sw.bb1:
+ ; CHECK-NEXT: successors: %bb.4(0x80000000)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = nsw G_MUL [[COPY]], [[C1]]
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.4.return:
+ ; CHECK-NEXT: [[PHI:%[0-9]+]]:_(s32) = G_PHI [[MUL]](s32), %bb.3, [[ADD]](s32), %bb.2, [[C3]](s32), %bb.0, [[C3]](s32), %bb.1
+ ; CHECK-NEXT: $x10 = COPY [[PHI]](s32)
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ bb.1.entry:
+ successors: %bb.4(0x071c71c7), %bb.5(0x78e38e39)
+ liveins: $x10
+
+ %0:_(s32) = COPY $x10
+ %4:_(s32) = G_CONSTANT i32 71
+ %8:_(s32) = G_CONSTANT i32 3
+ %10:_(s32) = G_CONSTANT i32 42
+ %13:_(s32) = G_CONSTANT i32 0
+ %1:_(s32) = G_CONSTANT i32 4
+ %2:_(s32) = G_SUB %0, %1
+ %6:_(s1) = G_ICMP intpred(ugt), %2(s32), %4
+ G_BRCOND %6(s1), %bb.4
+
+ bb.5.entry:
+ successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4b)
+
+ %7:_(p0) = G_JUMP_TABLE %jump-table.0
+ G_BRJT %7(p0), %jump-table.0, %2(s32)
+
+ bb.2.sw.bb:
+ %11:_(s32) = nsw G_ADD %0, %10
+ G_BR %bb.4
+
+ bb.3.sw.bb1:
+ %9:_(s32) = nsw G_MUL %0, %8
+
+ bb.4.return:
+ %12:_(s32) = G_PHI %9(s32), %bb.3, %11(s32), %bb.2, %13(s32), %bb.1, %13(s32), %bb.5
+ $x10 = COPY %12(s32)
+ PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-jump-table-brjt.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-jump-table-brjt.mir
new file mode 100644
index 000000000000000..22bcc9161b3e206
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-jump-table-brjt.mir
@@ -0,0 +1,130 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -mattr=+m -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s
+
+--- |
+ define i32 @jt_test(i32 %x) {
+ entry:
+ %0 = sext i32 %x to i64
+ switch i64 %0, label %return [
+ i64 75, label %sw.bb
+ i64 34, label %sw.bb
+ i64 56, label %sw.bb
+ i64 35, label %sw.bb
+ i64 40, label %sw.bb
+ i64 4, label %sw.bb1
+ i64 5, label %sw.bb1
+ i64 6, label %sw.bb1
+ ]
+
+ sw.bb:
+ %add = add nsw i32 %x, 42
+ br label %return
+
+ sw.bb1:
+ %mul = mul nsw i32 %x, 3
+ br label %return
+
+ return:
+ %retval.0 = phi i32 [ %mul, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
+ ret i32 %retval.0
+ }
+
+...
+---
+name: jt_test
+tracksRegLiveness: true
+jumpTable:
+ kind: custom32
+ entries:
+ - id: 0
+ blocks: [ '%bb.3', '%bb.3', '%bb.3', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.2', '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2' ]
+body: |
+ ; CHECK-LABEL: name: jt_test
+ ; CHECK: bb.0.entry:
+ ; CHECK-NEXT: successors: %bb.4(0x071c71c7), %bb.1(0x78e38e39)
+ ; CHECK-NEXT: liveins: $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 71
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+ ; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s64) = G_SEXT_INREG [[COPY]], 32
+ ; CHECK-NEXT: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s64) = G_SUB [[SEXT_INREG]], [[C4]]
+ ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s64) = G_ICMP intpred(ugt), [[SUB]](s64), [[C]]
+ ; CHECK-NEXT: G_BRCOND [[ICMP]](s64), %bb.4
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1.entry:
+ ; CHECK-NEXT: successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4c)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[JUMP_TABLE:%[0-9]+]]:_(p0) = G_JUMP_TABLE %jump-table.0
+ ; CHECK-NEXT: G_BRJT [[JUMP_TABLE]](p0), %jump-table.0, [[SUB]](s64)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2.sw.bb:
+ ; CHECK-NEXT: successors: %bb.4(0x80000000)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = nsw G_ADD [[TRUNC]], [[C2]]
+ ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ADD]](s32)
+ ; CHECK-NEXT: G_BR %bb.4
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.3.sw.bb1:
+ ; CHECK-NEXT: successors: %bb.4(0x80000000)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s32) = nsw G_MUL [[TRUNC]], [[C1]]
+ ; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(s64) = G_ANYEXT [[MUL]](s32)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.4.return:
+ ; CHECK-NEXT: [[PHI:%[0-9]+]]:_(s64) = G_PHI [[ANYEXT1]](s64), %bb.3, [[ANYEXT]](s64), %bb.2, [[C3]](s64), %bb.0, [[C3]](s64), %bb.1
+ ; CHECK-NEXT: $x10 = COPY [[PHI]](s64)
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ bb.1.entry:
+ successors: %bb.4(0x071c71c7), %bb.5(0x78e38e39)
+ liveins: $x10
+
+ %1:_(s64) = COPY $x10
+ %0:_(s32) = G_TRUNC %1(s64)
+ %6:_(s64) = G_CONSTANT i64 71
+ %10:_(s32) = G_CONSTANT i32 3
+ %12:_(s32) = G_CONSTANT i32 42
+ %19:_(s64) = G_CONSTANT i64 0
+ %2:_(s64) = G_SEXT %0(s32)
+ %3:_(s64) = G_CONSTANT i64 4
+ %4:_(s64) = G_SUB %2, %3
+ %8:_(s1) = G_ICMP intpred(ugt), %4(s64), %6
+ G_BRCOND %8(s1), %bb.4
+
+ bb.5.entry:
+ successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4b)
+
+ %9:_(p0) = G_JUMP_TABLE %jump-table.0
+ G_BRJT %9(p0), %jump-table.0, %4(s64)
+
+ bb.2.sw.bb:
+ %13:_(s32) = nsw G_ADD %0, %12
+ %18:_(s64) = G_ANYEXT %13(s32)
+ G_BR %bb.4
+
+ bb.3.sw.bb1:
+ %11:_(s32) = nsw G_MUL %0, %10
+ %17:_(s64) = G_ANYEXT %11(s32)
+
+ bb.4.return:
+ %15:_(s64) = G_PHI %17(s64), %bb.3, %18(s64), %bb.2, %19(s64), %bb.1, %19(s64), %bb.5
+ $x10 = COPY %15(s64)
+ PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv32.mir
new file mode 100644
index 000000000000000..24be1b754ae94c9
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv32.mir
@@ -0,0 +1,129 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+m -run-pass=regbankselect \
+# RUN: -disable-gisel-legality-check -simplify-mir -verify-machineinstrs %s \
+# RUN: -o - | FileCheck -check-prefix=RV32I %s
+
+--- |
+ define i32 @jt_test(i32 %x) {
+ entry:
+ switch i32 %x, label %return [
+ i32 75, label %sw.bb
+ i32 34, label %sw.bb
+ i32 56, label %sw.bb
+ i32 35, label %sw.bb
+ i32 40, label %sw.bb
+ i32 4, label %sw.bb1
+ i32 5, label %sw.bb1
+ i32 6, label %sw.bb1
+ ]
+
+ sw.bb: ; preds = %entry, %entry, %entry, %entry, %entry
+ %add = add nsw i32 %x, 42
+ br label %return
+
+ sw.bb1: ; preds = %entry, %entry, %entry
+ %mul = mul nsw i32 %x, 3
+ br label %return
+
+ return: ; preds = %sw.bb1, %sw.bb, %entry
+ %retval.0 = phi i32 [ %mul, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
+ ret i32 %retval.0
+ }
+
+...
+---
+name: jt_test
+legalized: true
+tracksRegLiveness: true
+jumpTable:
+ kind: block-address
+ entries:
+ - id: 0
+ blocks: [ '%bb.3', '%bb.3', '%bb.3', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.2', '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2' ]
+body: |
+ ; RV32I-LABEL: name: jt_test
+ ; RV32I: bb.0.entry:
+ ; RV32I-NEXT: successors: %bb.4(0x071c71c7), %bb.1(0x78e38e39)
+ ; RV32I-NEXT: liveins: $x10
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s32) = COPY $x10
+ ; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 71
+ ; RV32I-NEXT: [[C1:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 3
+ ; RV32I-NEXT: [[C2:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 42
+ ; RV32I-NEXT: [[C3:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 0
+ ; RV32I-NEXT: [[C4:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 4
+ ; RV32I-NEXT: [[SUB:%[0-9]+]]:gprb(s32) = G_SUB [[COPY]], [[C4]]
+ ; RV32I-NEXT: [[ICMP:%[0-9]+]]:gprb(s32) = G_ICMP intpred(ugt), [[SUB]](s32), [[C]]
+ ; RV32I-NEXT: G_BRCOND [[ICMP]](s32), %bb.4
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: bb.1.entry:
+ ; RV32I-NEXT: successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4c)
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: [[JUMP_TABLE:%[0-9]+]]:gprb(p0) = G_JUMP_TABLE %jump-table.0
+ ; RV32I-NEXT: G_BRJT [[JUMP_TABLE]](p0), %jump-table.0, [[SUB]](s32)
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: bb.2.sw.bb:
+ ; RV32I-NEXT: [[ADD:%[0-9]+]]:gprb(s32) = nsw G_ADD [[COPY]], [[C2]]
+ ; RV32I-NEXT: G_BR %bb.4
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: bb.3.sw.bb1:
+ ; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ ; RV32I-NEXT: $x10 = COPY [[COPY]](s32)
+ ; RV32I-NEXT: $x11 = COPY [[C1]](s32)
+ ; RV32I-NEXT: PseudoCALL target-flags(riscv-call) &__mulsi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gprb(s32) = COPY $x10
+ ; RV32I-NEXT: {{ $}}
+ ; RV32I-NEXT: bb.4.return:
+ ; RV32I-NEXT: [[PHI:%[0-9]+]]:gprb(s32) = G_PHI [[COPY1]](s32), %bb.3, [[ADD]](s32), %bb.2, [[C3]](s32), %bb.0, [[C3]](s32), %bb.1
+ ; RV32I-NEXT: $x10 = COPY [[PHI]](s32)
+ ; RV32I-NEXT: PseudoRET implicit $x10
+ bb.1.entry:
+ successors: %bb.4(0x071c71c7), %bb.5(0x78e38e39)
+ liveins: $x10
+
+ %0:_(s32) = COPY $x10
+ %4:_(s32) = G_CONSTANT i32 71
+ %8:_(s32) = G_CONSTANT i32 3
+ %10:_(s32) = G_CONSTANT i32 42
+ %13:_(s32) = G_CONSTANT i32 0
+ %1:_(s32) = G_CONSTANT i32 4
+ %2:_(s32) = G_SUB %0, %1
+ %15:_(s32) = G_ICMP intpred(ugt), %2(s32), %4
+ G_BRCOND %15(s32), %bb.4
+
+ bb.5.entry:
+ successors: %bb.3(0x2d2d2d2d), %bb.4(0x07878787), %bb.2(0x4b4b4b4b)
+
+ %7:_(p0) = G_JUMP_TABLE %jump-table.0
+ G_BRJT %7(p0), %jump-table.0, %2(s32)
+
+ bb.2.sw.bb:
+ %11:_(s32) = nsw G_ADD %0, %10
+ G_BR %bb.4
+
+ bb.3.sw.bb1:
+ ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+ $x10 = COPY %0(s32)
+ $x11 = COPY %8(s32)
+ PseudoCALL target-flags(riscv-call) &__mulsi3, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
+ ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+ %9:_(s32) = COPY $x10
+
+ bb.4.return:
+ %12:_(s32) = G_PHI %9(s32), %bb.3, %11(s32), %bb.2, %13(s32), %bb.1, %13(s32), %bb.5
+ $x10 = COPY %12(s32)
+ PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv64.mir
new file mode 100644
index 000000000000000..6dbabeec8f6fd13
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/jump-table-brjt-rv64.mir
@@ -0,0 +1,136 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -run-pass=regbankselect \
+# RUN: -disable-gisel-legality-check -simplify-mir -verify-machineinstrs %s \
+# RUN: -o - | FileCheck -check-prefix=RV64I %s
+
+--- |
+ define i32 @jt_test(i32 %x) {
+ entry:
+ %0 = sext i32 %x to i64
+ switch i64 %0, label %return [
+ i64 75, label %sw.bb
+ i64 34, label %sw.bb
+ i64 56, label %sw.bb
+ i64 35, label %sw.bb
+ i64 40, label %sw.bb
+ i64 4, label %sw.bb1
+ i64 5, label %sw.bb1
+ i64 6, label %sw.bb1
+ ]
+
+ sw.bb: ; preds = %entry, %entry, %entry, %entry, %entry
+ %add = add nsw i32 %x, 42
+ br label %return
+
+ sw.bb1: ; preds = %entry, %entry, %entry
+ %mul = mul nsw i32 %x, 3
+ br label %return
+
+ return: ; preds = %sw.bb1, %sw.bb, %entry
+ %retval.0 = phi i32 [ %mul, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
+ ret i32 %retval.0
+ }
+
+...
+---
+name: jt_test
+legalized: true
+tracksRegLiveness: true
+jumpTable:
+ kind: custom32
+ entries:
+ - id: 0
+ blocks: [ '%bb.3', '%bb.3', '%bb.3', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.2', '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.2', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.2', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4',
+ '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb.4', '%bb...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
; CHECK-NEXT: $x10 = COPY [[PHI]](s32) | ||
; CHECK-NEXT: PseudoRET implicit $x10 | ||
bb.1.entry: | ||
successors: %bb.4(0x071c71c7), %bb.5(0x78e38e39) |
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.
Do we really need the branch probability data? It may make the test easier to read without it?
] | ||
|
||
sw.bb: ; preds = %entry, %entry, %entry, %entry, %entry | ||
%add = add nsw i32 %x, 42 |
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.
Do we need the add
and mul
here? Can we just return? Legalizer and regbank selection will never do any any optimizing of the jump table to the default label if jump targets only contain a branch to the default label.
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.
I just copied this test from AArch64's IR translator and selection test. I'll simplify it.
kind: block-address | ||
entries: | ||
- id: 0 | ||
blocks: [ '%bb.3', '%bb.3', '%bb.3', '%bb.4', '%bb.4', '%bb.4', |
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.
Does this need to be so big to convey the functionality in this test?
@@ -131,13 +131,14 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) { | |||
|
|||
getActionDefinitionsBuilder(G_BRCOND).legalFor({sXLen}).minScalar(0, sXLen); | |||
|
|||
getActionDefinitionsBuilder(G_BRJT).legalFor({{p0, sXLen}}); |
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.
I wanted to respond to your comment from #71951
Does the s32 case ever occur? IRTranslator::emitJumpTableHeader seems to use the integer size of the pointer to create the type for that operand.
It would be fine to only support sXLen, although it definitely would be legal if we used s32 since it'll always generate a valid offset. I am okay to omit s32 as a legal type here to simplify. I don't have a strong opinion so you can decide.
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.
If it generated s32, the instruction selection code would have to insert an extend to use the index wouldn't it?
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.
Yea, sounds like it is better to not legalize it to avoid doing the extra work in selection to extend, and the code would be worse.
f3a061d
to
b95806f
Compare
@@ -0,0 +1,159 @@ | |||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py | |||
# RUN: llc -mtriple=riscv64 -mattr=+m -run-pass=legalizer %s -o - \ |
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.
still need +m?
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.
LGTM.
… and G_BRJT (llvm#71970) Testing together since they should come paired. Instruction selection will be a separate PR.
Testing together since they should come paired.
Instruction selection will be a separate PR.