summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@sifive.com>2023-11-18 12:33:25 -0800
committerGitHub <noreply@github.com>2023-11-18 12:33:25 -0800
commit20f544d047e34283884d09e24db400de5077487f (patch)
tree2baed61d3404406bb4bc37f5464003bafe348390
parent8ad4df8327e617c7ef1a727df61e4600ef13ed85 (diff)
[RISCV][GISel] Instruction selection for G_JUMP_TABLE and G_BRJT. (#71987)
-rw-r--r--llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp148
-rw-r--r--llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-medium-rv64.mir160
-rw-r--r--llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-pic-rv32.mir157
-rw-r--r--llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-pic-rv64.mir161
-rw-r--r--llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-rv32.mir213
-rw-r--r--llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-small-rv64.mir161
-rw-r--r--llvm/test/CodeGen/RISCV/GlobalISel/jumptable.ll257
7 files changed, 1257 insertions, 0 deletions
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index 25f4a217c070..3c72269d1e00 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -20,6 +20,7 @@
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/IR/IntrinsicsRISCV.h"
#include "llvm/Support/Debug.h"
@@ -64,6 +65,8 @@ private:
bool materializeImm(Register Reg, int64_t Imm, MachineIRBuilder &MIB) const;
bool selectGlobalValue(MachineInstr &MI, MachineIRBuilder &MIB,
MachineRegisterInfo &MRI) const;
+ bool selectJumpTable(MachineInstr &MI, MachineIRBuilder &MIB,
+ MachineRegisterInfo &MRI) const;
bool selectSExtInreg(MachineInstr &MI, MachineIRBuilder &MIB) const;
bool selectSelect(MachineInstr &MI, MachineIRBuilder &MIB,
MachineRegisterInfo &MRI) const;
@@ -483,6 +486,8 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
}
case TargetOpcode::G_GLOBAL_VALUE:
return selectGlobalValue(MI, MIB, MRI);
+ case TargetOpcode::G_JUMP_TABLE:
+ return selectJumpTable(MI, MIB, MRI);
case TargetOpcode::G_BRCOND: {
Register LHS, RHS;
RISCVCC::CondCode CC;
@@ -493,6 +498,58 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
MI.eraseFromParent();
return constrainSelectedInstRegOperands(*Bcc, TII, TRI, RBI);
}
+ case TargetOpcode::G_BRJT: {
+ // FIXME: Move to legalization?
+ const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
+ unsigned EntrySize = MJTI->getEntrySize(MF.getDataLayout());
+ assert((EntrySize == 4 || (Subtarget->is64Bit() && EntrySize == 8)) &&
+ "Unsupported jump-table entry size");
+ assert(
+ (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 ||
+ MJTI->getEntryKind() == MachineJumpTableInfo::EK_Custom32 ||
+ MJTI->getEntryKind() == MachineJumpTableInfo::EK_BlockAddress) &&
+ "Unexpected jump-table entry kind");
+
+ auto SLL =
+ MIB.buildInstr(RISCV::SLLI, {&RISCV::GPRRegClass}, {MI.getOperand(2)})
+ .addImm(Log2_32(EntrySize));
+ if (!SLL.constrainAllUses(TII, TRI, RBI))
+ return false;
+
+ // TODO: Use SHXADD. Moving to legalization would fix this automatically.
+ auto ADD = MIB.buildInstr(RISCV::ADD, {&RISCV::GPRRegClass},
+ {MI.getOperand(0), SLL.getReg(0)});
+ if (!ADD.constrainAllUses(TII, TRI, RBI))
+ return false;
+
+ unsigned LdOpc = EntrySize == 8 ? RISCV::LD : RISCV::LW;
+ auto Dest =
+ MIB.buildInstr(LdOpc, {&RISCV::GPRRegClass}, {ADD.getReg(0)})
+ .addImm(0)
+ .addMemOperand(MF.getMachineMemOperand(
+ MachinePointerInfo::getJumpTable(MF), MachineMemOperand::MOLoad,
+ EntrySize, Align(MJTI->getEntryAlignment(MF.getDataLayout()))));
+ if (!Dest.constrainAllUses(TII, TRI, RBI))
+ return false;
+
+ // If the Kind is EK_LabelDifference32, the table stores an offset from
+ // the location of the table. Add the table address to get an absolute
+ // address.
+ if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32) {
+ Dest = MIB.buildInstr(RISCV::ADD, {&RISCV::GPRRegClass},
+ {Dest.getReg(0), MI.getOperand(0)});
+ if (!Dest.constrainAllUses(TII, TRI, RBI))
+ return false;
+ }
+
+ auto Branch =
+ MIB.buildInstr(RISCV::PseudoBRIND, {}, {Dest.getReg(0)}).addImm(0);
+ if (!Branch.constrainAllUses(TII, TRI, RBI))
+ return false;
+
+ MI.eraseFromParent();
+ return true;
+ }
case TargetOpcode::G_SEXT_INREG:
return selectSExtInreg(MI, MIB);
case TargetOpcode::G_FRAME_INDEX: {
@@ -784,6 +841,97 @@ bool RISCVInstructionSelector::selectGlobalValue(
return false;
}
+// FIXME: This is very similar to selectGlobalValue. Merge somehow?
+bool RISCVInstructionSelector::selectJumpTable(MachineInstr &MI,
+ MachineIRBuilder &MIB,
+ MachineRegisterInfo &MRI) const {
+ assert(MI.getOpcode() == TargetOpcode::G_JUMP_TABLE &&
+ "Expected G_JUMP_TABLE");
+
+ int Idx = MI.getOperand(1).getIndex();
+
+ Register DefReg = MI.getOperand(0).getReg();
+ const LLT DefTy = MRI.getType(DefReg);
+ MachineInstr *Result = nullptr;
+
+ // When HWASAN is used and tagging of global variables is enabled
+ // they should be accessed via the GOT, since the tagged address of a global
+ // is incompatible with existing code models. This also applies to non-pic
+ // mode.
+ if (TM.isPositionIndependent() || Subtarget->allowTaggedGlobals()) {
+ if (!Subtarget->allowTaggedGlobals()) {
+ // Use PC-relative addressing to access the symbol. This generates the
+ // pattern (PseudoLLA sym), which expands to (addi (auipc %pcrel_hi(sym))
+ // %pcrel_lo(auipc)).
+ Result =
+ MIB.buildInstr(RISCV::PseudoLLA, {DefReg}, {}).addJumpTableIndex(Idx);
+ } else {
+ // Use PC-relative addressing to access the GOT for this symbol, then
+ // load the address from the GOT. This generates the pattern (PseudoLGA
+ // sym), which expands to (ld (addi (auipc %got_pcrel_hi(sym))
+ // %pcrel_lo(auipc))).
+ MachineFunction &MF = *MI.getParent()->getParent();
+ MachineMemOperand *MemOp = MF.getMachineMemOperand(
+ MachinePointerInfo::getGOT(MF),
+ MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable |
+ MachineMemOperand::MOInvariant,
+ DefTy, Align(DefTy.getSizeInBits() / 8));
+
+ Result = MIB.buildInstr(RISCV::PseudoLGA, {DefReg}, {})
+ .addJumpTableIndex(Idx)
+ .addMemOperand(MemOp);
+ }
+
+ if (!constrainSelectedInstRegOperands(*Result, TII, TRI, RBI))
+ return false;
+
+ MI.eraseFromParent();
+ return true;
+ }
+
+ switch (TM.getCodeModel()) {
+ default: {
+ reportGISelFailure(const_cast<MachineFunction &>(*MF), *TPC, *MORE,
+ getName(), "Unsupported code model for lowering", MI);
+ return false;
+ }
+ case CodeModel::Small: {
+ // Must lie within a single 2 GiB address range and must lie between
+ // absolute addresses -2 GiB and +2 GiB. This generates the pattern (addi
+ // (lui %hi(sym)) %lo(sym)).
+ Register AddrHiDest = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+ MachineInstr *AddrHi = MIB.buildInstr(RISCV::LUI, {AddrHiDest}, {})
+ .addJumpTableIndex(Idx, RISCVII::MO_HI);
+
+ if (!constrainSelectedInstRegOperands(*AddrHi, TII, TRI, RBI))
+ return false;
+
+ Result = MIB.buildInstr(RISCV::ADDI, {DefReg}, {AddrHiDest})
+ .addJumpTableIndex(Idx, RISCVII::MO_LO);
+
+ if (!constrainSelectedInstRegOperands(*Result, TII, TRI, RBI))
+ return false;
+
+ MI.eraseFromParent();
+ return true;
+ }
+ case CodeModel::Medium: {
+ // Generate a sequence for accessing addresses within any 2GiB range
+ // within the address space. This generates the pattern (PseudoLLA sym),
+ // which expands to (addi (auipc %pcrel_hi(sym)) %pcrel_lo(auipc)).
+ Result =
+ MIB.buildInstr(RISCV::PseudoLLA, {DefReg}, {}).addJumpTableIndex(Idx);
+
+ if (!constrainSelectedInstRegOperands(*Result, TII, TRI, RBI))
+ return false;
+
+ MI.eraseFromParent();
+ return true;
+ }
+ }
+ return false;
+}
+
bool RISCVInstructionSelector::selectSExtInreg(MachineInstr &MI,
MachineIRBuilder &MIB) const {
if (!STI.isRV64())
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-medium-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-medium-rv64.mir
new file mode 100644
index 000000000000..5d980e772145
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-medium-rv64.mir
@@ -0,0 +1,160 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -run-pass=instruction-select %s -o - \
+# RUN: -code-model=medium | FileCheck %s
+
+--- |
+ define i32 @jt_test(i32 signext %in) {
+ entry:
+ %0 = sext i32 %in to i64
+ switch i64 %0, label %default [
+ i64 1, label %bb1
+ i64 2, label %bb2
+ i64 3, label %bb3
+ i64 4, label %bb4
+ i64 5, label %bb5
+ i64 6, label %bb6
+ ]
+
+ bb1: ; preds = %entry
+ ret i32 4
+
+ bb2: ; preds = %entry
+ ret i32 3
+
+ bb3: ; preds = %entry
+ ret i32 2
+
+ bb4: ; preds = %entry
+ ret i32 1
+
+ bb5: ; preds = %entry
+ ret i32 100
+
+ bb6: ; preds = %entry
+ ret i32 200
+
+ default: ; preds = %entry
+ ret i32 1000
+ }
+
+...
+---
+name: jt_test
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+jumpTable:
+ kind: block-address
+ entries:
+ - id: 0
+ blocks: [ '%bb.2', '%bb.3', '%bb.4', '%bb.5', '%bb.6', '%bb.7' ]
+body: |
+ ; CHECK-LABEL: name: jt_test
+ ; CHECK: bb.0.entry:
+ ; CHECK-NEXT: successors: %bb.8(0x40000000), %bb.1(0x40000000)
+ ; CHECK-NEXT: liveins: $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+ ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 5
+ ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[COPY]], 0
+ ; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI [[ADDIW]], -1
+ ; CHECK-NEXT: BLTU [[ADDI]], [[ADDI1]], %bb.8
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1.entry:
+ ; CHECK-NEXT: successors: %bb.2(0x15555555), %bb.3(0x15555555), %bb.4(0x15555555), %bb.5(0x15555555), %bb.6(0x15555555), %bb.7(0x15555555)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[PseudoLLA:%[0-9]+]]:gpr = PseudoLLA %jump-table.0
+ ; CHECK-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADDI1]], 3
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[PseudoLLA]], [[SLLI]]
+ ; CHECK-NEXT: [[LD:%[0-9]+]]:gprjalr = LD [[ADD]], 0 :: (load (s64) from jump-table)
+ ; CHECK-NEXT: PseudoBRIND [[LD]], 0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2.bb1:
+ ; CHECK-NEXT: [[ADDI2:%[0-9]+]]:gpr = ADDI $x0, 4
+ ; CHECK-NEXT: $x10 = COPY [[ADDI2]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.3.bb2:
+ ; CHECK-NEXT: [[ADDI3:%[0-9]+]]:gpr = ADDI $x0, 3
+ ; CHECK-NEXT: $x10 = COPY [[ADDI3]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.4.bb3:
+ ; CHECK-NEXT: [[ADDI4:%[0-9]+]]:gpr = ADDI $x0, 2
+ ; CHECK-NEXT: $x10 = COPY [[ADDI4]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.5.bb4:
+ ; CHECK-NEXT: [[ADDI5:%[0-9]+]]:gpr = ADDI $x0, 1
+ ; CHECK-NEXT: $x10 = COPY [[ADDI5]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.6.bb5:
+ ; CHECK-NEXT: [[ADDI6:%[0-9]+]]:gpr = ADDI $x0, 100
+ ; CHECK-NEXT: $x10 = COPY [[ADDI6]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.7.bb6:
+ ; CHECK-NEXT: [[ADDI7:%[0-9]+]]:gpr = ADDI $x0, 200
+ ; CHECK-NEXT: $x10 = COPY [[ADDI7]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.8.default:
+ ; CHECK-NEXT: [[ADDI8:%[0-9]+]]:gpr = ADDI $x0, 1000
+ ; CHECK-NEXT: $x10 = COPY [[ADDI8]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ bb.1.entry:
+ successors: %bb.8, %bb.9
+ liveins: $x10
+
+ %1:gprb(s64) = COPY $x10
+ %2:gprb(s64) = G_ASSERT_SEXT %1, 32
+ %7:gprb(s64) = G_CONSTANT i64 5
+ %3:gprb(s64) = G_SEXT_INREG %2, 32
+ %4:gprb(s64) = G_CONSTANT i64 1
+ %5:gprb(s64) = G_SUB %3, %4
+ %26:gprb(s64) = G_ICMP intpred(ugt), %5(s64), %7
+ G_BRCOND %26(s64), %bb.8
+
+ bb.9.entry:
+ successors: %bb.2, %bb.3, %bb.4, %bb.5, %bb.6, %bb.7
+
+ %10:gprb(p0) = G_JUMP_TABLE %jump-table.0
+ G_BRJT %10(p0), %jump-table.0, %5(s64)
+
+ bb.2.bb1:
+ %22:gprb(s64) = G_CONSTANT i64 4
+ $x10 = COPY %22(s64)
+ PseudoRET implicit $x10
+
+ bb.3.bb2:
+ %20:gprb(s64) = G_CONSTANT i64 3
+ $x10 = COPY %20(s64)
+ PseudoRET implicit $x10
+
+ bb.4.bb3:
+ %18:gprb(s64) = G_CONSTANT i64 2
+ $x10 = COPY %18(s64)
+ PseudoRET implicit $x10
+
+ bb.5.bb4:
+ %16:gprb(s64) = G_CONSTANT i64 1
+ $x10 = COPY %16(s64)
+ PseudoRET implicit $x10
+
+ bb.6.bb5:
+ %14:gprb(s64) = G_CONSTANT i64 100
+ $x10 = COPY %14(s64)
+ PseudoRET implicit $x10
+
+ bb.7.bb6:
+ %12:gprb(s64) = G_CONSTANT i64 200
+ $x10 = COPY %12(s64)
+ PseudoRET implicit $x10
+
+ bb.8.default:
+ %24:gprb(s64) = G_CONSTANT i64 1000
+ $x10 = COPY %24(s64)
+ PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-pic-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-pic-rv32.mir
new file mode 100644
index 000000000000..27fe465ccf69
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-pic-rv32.mir
@@ -0,0 +1,157 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -run-pass=instruction-select %s -o - \
+# RUN: -relocation-model=pic | FileCheck %s
+
+--- |
+ define i32 @jt_test(i32 signext %in) {
+ entry:
+ switch i32 %in, label %default [
+ i32 1, label %bb1
+ i32 2, label %bb2
+ i32 3, label %bb3
+ i32 4, label %bb4
+ i32 5, label %bb5
+ i32 6, label %bb6
+ ]
+
+ bb1: ; preds = %entry
+ ret i32 4
+
+ bb2: ; preds = %entry
+ ret i32 3
+
+ bb3: ; preds = %entry
+ ret i32 2
+
+ bb4: ; preds = %entry
+ ret i32 1
+
+ bb5: ; preds = %entry
+ ret i32 100
+
+ bb6: ; preds = %entry
+ ret i32 200
+
+ default: ; preds = %entry
+ ret i32 1000
+ }
+
+...
+---
+name: jt_test
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+jumpTable:
+ kind: label-difference32
+ entries:
+ - id: 0
+ blocks: [ '%bb.2', '%bb.3', '%bb.4', '%bb.5', '%bb.6', '%bb.7' ]
+body: |
+ ; CHECK-LABEL: name: jt_test
+ ; CHECK: bb.0.entry:
+ ; CHECK-NEXT: successors: %bb.8(0x40000000), %bb.1(0x40000000)
+ ; CHECK-NEXT: liveins: $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+ ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 5
+ ; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 200
+ ; CHECK-NEXT: [[ADDI2:%[0-9]+]]:gpr = ADDI $x0, 100
+ ; CHECK-NEXT: [[ADDI3:%[0-9]+]]:gpr = ADDI $x0, 1
+ ; CHECK-NEXT: [[ADDI4:%[0-9]+]]:gpr = ADDI $x0, 2
+ ; CHECK-NEXT: [[ADDI5:%[0-9]+]]:gpr = ADDI $x0, 3
+ ; CHECK-NEXT: [[ADDI6:%[0-9]+]]:gpr = ADDI $x0, 4
+ ; CHECK-NEXT: [[ADDI7:%[0-9]+]]:gpr = ADDI $x0, 1000
+ ; CHECK-NEXT: [[ADDI8:%[0-9]+]]:gpr = ADDI [[COPY]], -1
+ ; CHECK-NEXT: BLTU [[ADDI]], [[ADDI8]], %bb.8
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1.entry:
+ ; CHECK-NEXT: successors: %bb.2(0x15555555), %bb.3(0x15555555), %bb.4(0x15555555), %bb.5(0x15555555), %bb.6(0x15555555), %bb.7(0x15555555)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[PseudoLLA:%[0-9]+]]:gpr = PseudoLLA %jump-table.0
+ ; CHECK-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADDI8]], 2
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[PseudoLLA]], [[SLLI]]
+ ; CHECK-NEXT: [[LW:%[0-9]+]]:gpr = LW [[ADD]], 0 :: (load (s32) from jump-table)
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:gprjalr = ADD [[LW]], [[PseudoLLA]]
+ ; CHECK-NEXT: PseudoBRIND [[ADD1]], 0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2.bb1:
+ ; CHECK-NEXT: $x10 = COPY [[ADDI6]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.3.bb2:
+ ; CHECK-NEXT: $x10 = COPY [[ADDI5]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.4.bb3:
+ ; CHECK-NEXT: $x10 = COPY [[ADDI4]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.5.bb4:
+ ; CHECK-NEXT: $x10 = COPY [[ADDI3]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.6.bb5:
+ ; CHECK-NEXT: $x10 = COPY [[ADDI2]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.7.bb6:
+ ; CHECK-NEXT: $x10 = COPY [[ADDI1]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.8.default:
+ ; CHECK-NEXT: $x10 = COPY [[ADDI7]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ bb.1.entry:
+ successors: %bb.8, %bb.9
+ liveins: $x10
+
+ %0:gprb(s32) = COPY $x10
+ %4:gprb(s32) = G_CONSTANT i32 5
+ %8:gprb(s32) = G_CONSTANT i32 200
+ %9:gprb(s32) = G_CONSTANT i32 100
+ %10:gprb(s32) = G_CONSTANT i32 1
+ %11:gprb(s32) = G_CONSTANT i32 2
+ %12:gprb(s32) = G_CONSTANT i32 3
+ %13:gprb(s32) = G_CONSTANT i32 4
+ %14:gprb(s32) = G_CONSTANT i32 1000
+ %1:gprb(s32) = G_CONSTANT i32 1
+ %2:gprb(s32) = G_SUB %0, %1
+ %16:gprb(s32) = G_ICMP intpred(ugt), %2(s32), %4
+ G_BRCOND %16(s32), %bb.8
+
+ bb.9.entry:
+ successors: %bb.2, %bb.3, %bb.4, %bb.5, %bb.6, %bb.7
+
+ %7:gprb(p0) = G_JUMP_TABLE %jump-table.0
+ G_BRJT %7(p0), %jump-table.0, %2(s32)
+
+ bb.2.bb1:
+ $x10 = COPY %13(s32)
+ PseudoRET implicit $x10
+
+ bb.3.bb2:
+ $x10 = COPY %12(s32)
+ PseudoRET implicit $x10
+
+ bb.4.bb3:
+ $x10 = COPY %11(s32)
+ PseudoRET implicit $x10
+
+ bb.5.bb4:
+ $x10 = COPY %10(s32)
+ PseudoRET implicit $x10
+
+ bb.6.bb5:
+ $x10 = COPY %9(s32)
+ PseudoRET implicit $x10
+
+ bb.7.bb6:
+ $x10 = COPY %8(s32)
+ PseudoRET implicit $x10
+
+ bb.8.default:
+ $x10 = COPY %14(s32)
+ PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-pic-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-pic-rv64.mir
new file mode 100644
index 000000000000..77156b913c5e
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-pic-rv64.mir
@@ -0,0 +1,161 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -run-pass=instruction-select %s -o - \
+# RUN: -relocation-model=pic | FileCheck %s
+
+--- |
+ define i32 @jt_test(i32 signext %in) {
+ entry:
+ %0 = sext i32 %in to i64
+ switch i64 %0, label %default [
+ i64 1, label %bb1
+ i64 2, label %bb2
+ i64 3, label %bb3
+ i64 4, label %bb4
+ i64 5, label %bb5
+ i64 6, label %bb6
+ ]
+
+ bb1: ; preds = %entry
+ ret i32 4
+
+ bb2: ; preds = %entry
+ ret i32 3
+
+ bb3: ; preds = %entry
+ ret i32 2
+
+ bb4: ; preds = %entry
+ ret i32 1
+
+ bb5: ; preds = %entry
+ ret i32 100
+
+ bb6: ; preds = %entry
+ ret i32 200
+
+ default: ; preds = %entry
+ ret i32 1000
+ }
+
+...
+---
+name: jt_test
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+jumpTable:
+ kind: label-difference32
+ entries:
+ - id: 0
+ blocks: [ '%bb.2', '%bb.3', '%bb.4', '%bb.5', '%bb.6', '%bb.7' ]
+body: |
+ ; CHECK-LABEL: name: jt_test
+ ; CHECK: bb.0.entry:
+ ; CHECK-NEXT: successors: %bb.8(0x40000000), %bb.1(0x40000000)
+ ; CHECK-NEXT: liveins: $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+ ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 5
+ ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[COPY]], 0
+ ; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI [[ADDIW]], -1
+ ; CHECK-NEXT: BLTU [[ADDI]], [[ADDI1]], %bb.8
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1.entry:
+ ; CHECK-NEXT: successors: %bb.2(0x15555555), %bb.3(0x15555555), %bb.4(0x15555555), %bb.5(0x15555555), %bb.6(0x15555555), %bb.7(0x15555555)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[PseudoLLA:%[0-9]+]]:gpr = PseudoLLA %jump-table.0
+ ; CHECK-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADDI1]], 2
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[PseudoLLA]], [[SLLI]]
+ ; CHECK-NEXT: [[LW:%[0-9]+]]:gpr = LW [[ADD]], 0 :: (load (s32) from jump-table)
+ ; CHECK-NEXT: [[ADD1:%[0-9]+]]:gprjalr = ADD [[LW]], [[PseudoLLA]]
+ ; CHECK-NEXT: PseudoBRIND [[ADD1]], 0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2.bb1:
+ ; CHECK-NEXT: [[ADDI2:%[0-9]+]]:gpr = ADDI $x0, 4
+ ; CHECK-NEXT: $x10 = COPY [[ADDI2]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.3.bb2:
+ ; CHECK-NEXT: [[ADDI3:%[0-9]+]]:gpr = ADDI $x0, 3
+ ; CHECK-NEXT: $x10 = COPY [[ADDI3]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.4.bb3:
+ ; CHECK-NEXT: [[ADDI4:%[0-9]+]]:gpr = ADDI $x0, 2
+ ; CHECK-NEXT: $x10 = COPY [[ADDI4]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.5.bb4:
+ ; CHECK-NEXT: [[ADDI5:%[0-9]+]]:gpr = ADDI $x0, 1
+ ; CHECK-NEXT: $x10 = COPY [[ADDI5]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.6.bb5:
+ ; CHECK-NEXT: [[ADDI6:%[0-9]+]]:gpr = ADDI $x0, 100
+ ; CHECK-NEXT: $x10 = COPY [[ADDI6]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.7.bb6:
+ ; CHECK-NEXT: [[ADDI7:%[0-9]+]]:gpr = ADDI $x0, 200
+ ; CHECK-NEXT: $x10 = COPY [[ADDI7]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.8.default:
+ ; CHECK-NEXT: [[ADDI8:%[0-9]+]]:gpr = ADDI $x0, 1000
+ ; CHECK-NEXT: $x10 = COPY [[ADDI8]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ bb.1.entry:
+ successors: %bb.8, %bb.9
+ liveins: $x10
+
+ %1:gprb(s64) = COPY $x10
+ %2:gprb(s64) = G_ASSERT_SEXT %1, 32
+ %7:gprb(s64) = G_CONSTANT i64 5
+ %3:gprb(s64) = G_SEXT_INREG %2, 32
+ %4:gprb(s64) = G_CONSTANT i64 1
+ %5:gprb(s64) = G_SUB %3, %4
+ %26:gprb(s64) = G_ICMP intpred(ugt), %5(s64), %7
+ G_BRCOND %26(s64), %bb.8
+
+ bb.9.entry:
+ successors: %bb.2, %bb.3, %bb.4, %bb.5, %bb.6, %bb.7
+
+ %10:gprb(p0) = G_JUMP_TABLE %jump-table.0
+ G_BRJT %10(p0), %jump-table.0, %5(s64)
+
+ bb.2.bb1:
+ %22:gprb(s64) = G_CONSTANT i64 4
+ $x10 = COPY %22(s64)
+ PseudoRET implicit $x10
+
+ bb.3.bb2:
+ %20:gprb(s64) = G_CONSTANT i64 3
+ $x10 = COPY %20(s64)
+ PseudoRET implicit $x10
+
+ bb.4.bb3:
+ %18:gprb(s64) = G_CONSTANT i64 2
+ $x10 = COPY %18(s64)
+ PseudoRET implicit $x10
+
+ bb.5.bb4:
+ %16:gprb(s64) = G_CONSTANT i64 1
+ $x10 = COPY %16(s64)
+ PseudoRET implicit $x10
+
+ bb.6.bb5:
+ %14:gprb(s64) = G_CONSTANT i64 100
+ $x10 = COPY %14(s64)
+ PseudoRET implicit $x10
+
+ bb.7.bb6:
+ %12:gprb(s64) = G_CONSTANT i64 200
+ $x10 = COPY %12(s64)
+ PseudoRET implicit $x10
+
+ bb.8.default:
+ %24:gprb(s64) = G_CONSTANT i64 1000
+ $x10 = COPY %24(s64)
+ PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-rv32.mir
new file mode 100644
index 000000000000..388c238b86eb
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-rv32.mir
@@ -0,0 +1,213 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+m -run-pass=instruction-select %s -o - \
+# RUN: -code-model=small | FileCheck %s --check-prefix=RV32-SMALL
+# RUN: llc -mtriple=riscv32 -mattr=+m -run-pass=instruction-select %s -o - \
+# RUN: -code-model=medium | FileCheck %s --check-prefix=RV32-MEDIUM
+
+--- |
+ define i32 @jt_test(i32 signext %in) {
+ entry:
+ switch i32 %in, label %default [
+ i32 1, label %bb1
+ i32 2, label %bb2
+ i32 3, label %bb3
+ i32 4, label %bb4
+ i32 5, label %bb5
+ i32 6, label %bb6
+ ]
+
+ bb1: ; preds = %entry
+ ret i32 4
+
+ bb2: ; preds = %entry
+ ret i32 3
+
+ bb3: ; preds = %entry
+ ret i32 2
+
+ bb4: ; preds = %entry
+ ret i32 1
+
+ bb5: ; preds = %entry
+ ret i32 100
+
+ bb6: ; preds = %entry
+ ret i32 200
+
+ default: ; preds = %entry
+ ret i32 1000
+ }
+
+...
+---
+name: jt_test
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+jumpTable:
+ kind: block-address
+ entries:
+ - id: 0
+ blocks: [ '%bb.2', '%bb.3', '%bb.4', '%bb.5', '%bb.6', '%bb.7' ]
+body: |
+ ; RV32-SMALL-LABEL: name: jt_test
+ ; RV32-SMALL: bb.0.entry:
+ ; RV32-SMALL-NEXT: successors: %bb.8(0x40000000), %bb.1(0x40000000)
+ ; RV32-SMALL-NEXT: liveins: $x10
+ ; RV32-SMALL-NEXT: {{ $}}
+ ; RV32-SMALL-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+ ; RV32-SMALL-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 5
+ ; RV32-SMALL-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 200
+ ; RV32-SMALL-NEXT: [[ADDI2:%[0-9]+]]:gpr = ADDI $x0, 100
+ ; RV32-SMALL-NEXT: [[ADDI3:%[0-9]+]]:gpr = ADDI $x0, 1
+ ; RV32-SMALL-NEXT: [[ADDI4:%[0-9]+]]:gpr = ADDI $x0, 2
+ ; RV32-SMALL-NEXT: [[ADDI5:%[0-9]+]]:gpr = ADDI $x0, 3
+ ; RV32-SMALL-NEXT: [[ADDI6:%[0-9]+]]:gpr = ADDI $x0, 4
+ ; RV32-SMALL-NEXT: [[ADDI7:%[0-9]+]]:gpr = ADDI $x0, 1000
+ ; RV32-SMALL-NEXT: [[ADDI8:%[0-9]+]]:gpr = ADDI [[COPY]], -1
+ ; RV32-SMALL-NEXT: BLTU [[ADDI]], [[ADDI8]], %bb.8
+ ; RV32-SMALL-NEXT: {{ $}}
+ ; RV32-SMALL-NEXT: bb.1.entry:
+ ; RV32-SMALL-NEXT: successors: %bb.2(0x15555555), %bb.3(0x15555555), %bb.4(0x15555555), %bb.5(0x15555555), %bb.6(0x15555555), %bb.7(0x15555555)
+ ; RV32-SMALL-NEXT: {{ $}}
+ ; RV32-SMALL-NEXT: [[LUI:%[0-9]+]]:gpr = LUI target-flags(riscv-hi) %jump-table.0
+ ; RV32-SMALL-NEXT: [[ADDI9:%[0-9]+]]:gpr = ADDI [[LUI]], target-flags(riscv-lo) %jump-table.0
+ ; RV32-SMALL-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADDI8]], 2
+ ; RV32-SMALL-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[ADDI9]], [[SLLI]]
+ ; RV32-SMALL-NEXT: [[LW:%[0-9]+]]:gprjalr = LW [[ADD]], 0 :: (load (s32) from jump-table)
+ ; RV32-SMALL-NEXT: PseudoBRIND [[LW]], 0
+ ; RV32-SMALL-NEXT: {{ $}}
+ ; RV32-SMALL-NEXT: bb.2.bb1:
+ ; RV32-SMALL-NEXT: $x10 = COPY [[ADDI6]]
+ ; RV32-SMALL-NEXT: PseudoRET implicit $x10
+ ; RV32-SMALL-NEXT: {{ $}}
+ ; RV32-SMALL-NEXT: bb.3.bb2:
+ ; RV32-SMALL-NEXT: $x10 = COPY [[ADDI5]]
+ ; RV32-SMALL-NEXT: PseudoRET implicit $x10
+ ; RV32-SMALL-NEXT: {{ $}}
+ ; RV32-SMALL-NEXT: bb.4.bb3:
+ ; RV32-SMALL-NEXT: $x10 = COPY [[ADDI4]]
+ ; RV32-SMALL-NEXT: PseudoRET implicit $x10
+ ; RV32-SMALL-NEXT: {{ $}}
+ ; RV32-SMALL-NEXT: bb.5.bb4:
+ ; RV32-SMALL-NEXT: $x10 = COPY [[ADDI3]]
+ ; RV32-SMALL-NEXT: PseudoRET implicit $x10
+ ; RV32-SMALL-NEXT: {{ $}}
+ ; RV32-SMALL-NEXT: bb.6.bb5:
+ ; RV32-SMALL-NEXT: $x10 = COPY [[ADDI2]]
+ ; RV32-SMALL-NEXT: PseudoRET implicit $x10
+ ; RV32-SMALL-NEXT: {{ $}}
+ ; RV32-SMALL-NEXT: bb.7.bb6:
+ ; RV32-SMALL-NEXT: $x10 = COPY [[ADDI1]]
+ ; RV32-SMALL-NEXT: PseudoRET implicit $x10
+ ; RV32-SMALL-NEXT: {{ $}}
+ ; RV32-SMALL-NEXT: bb.8.default:
+ ; RV32-SMALL-NEXT: $x10 = COPY [[ADDI7]]
+ ; RV32-SMALL-NEXT: PseudoRET implicit $x10
+ ;
+ ; RV32-MEDIUM-LABEL: name: jt_test
+ ; RV32-MEDIUM: bb.0.entry:
+ ; RV32-MEDIUM-NEXT: successors: %bb.8(0x40000000), %bb.1(0x40000000)
+ ; RV32-MEDIUM-NEXT: liveins: $x10
+ ; RV32-MEDIUM-NEXT: {{ $}}
+ ; RV32-MEDIUM-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+ ; RV32-MEDIUM-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 5
+ ; RV32-MEDIUM-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 200
+ ; RV32-MEDIUM-NEXT: [[ADDI2:%[0-9]+]]:gpr = ADDI $x0, 100
+ ; RV32-MEDIUM-NEXT: [[ADDI3:%[0-9]+]]:gpr = ADDI $x0, 1
+ ; RV32-MEDIUM-NEXT: [[ADDI4:%[0-9]+]]:gpr = ADDI $x0, 2
+ ; RV32-MEDIUM-NEXT: [[ADDI5:%[0-9]+]]:gpr = ADDI $x0, 3
+ ; RV32-MEDIUM-NEXT: [[ADDI6:%[0-9]+]]:gpr = ADDI $x0, 4
+ ; RV32-MEDIUM-NEXT: [[ADDI7:%[0-9]+]]:gpr = ADDI $x0, 1000
+ ; RV32-MEDIUM-NEXT: [[ADDI8:%[0-9]+]]:gpr = ADDI [[COPY]], -1
+ ; RV32-MEDIUM-NEXT: BLTU [[ADDI]], [[ADDI8]], %bb.8
+ ; RV32-MEDIUM-NEXT: {{ $}}
+ ; RV32-MEDIUM-NEXT: bb.1.entry:
+ ; RV32-MEDIUM-NEXT: successors: %bb.2(0x15555555), %bb.3(0x15555555), %bb.4(0x15555555), %bb.5(0x15555555), %bb.6(0x15555555), %bb.7(0x15555555)
+ ; RV32-MEDIUM-NEXT: {{ $}}
+ ; RV32-MEDIUM-NEXT: [[PseudoLLA:%[0-9]+]]:gpr = PseudoLLA %jump-table.0
+ ; RV32-MEDIUM-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADDI8]], 2
+ ; RV32-MEDIUM-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[PseudoLLA]], [[SLLI]]
+ ; RV32-MEDIUM-NEXT: [[LW:%[0-9]+]]:gprjalr = LW [[ADD]], 0 :: (load (s32) from jump-table)
+ ; RV32-MEDIUM-NEXT: PseudoBRIND [[LW]], 0
+ ; RV32-MEDIUM-NEXT: {{ $}}
+ ; RV32-MEDIUM-NEXT: bb.2.bb1:
+ ; RV32-MEDIUM-NEXT: $x10 = COPY [[ADDI6]]
+ ; RV32-MEDIUM-NEXT: PseudoRET implicit $x10
+ ; RV32-MEDIUM-NEXT: {{ $}}
+ ; RV32-MEDIUM-NEXT: bb.3.bb2:
+ ; RV32-MEDIUM-NEXT: $x10 = COPY [[ADDI5]]
+ ; RV32-MEDIUM-NEXT: PseudoRET implicit $x10
+ ; RV32-MEDIUM-NEXT: {{ $}}
+ ; RV32-MEDIUM-NEXT: bb.4.bb3:
+ ; RV32-MEDIUM-NEXT: $x10 = COPY [[ADDI4]]
+ ; RV32-MEDIUM-NEXT: PseudoRET implicit $x10
+ ; RV32-MEDIUM-NEXT: {{ $}}
+ ; RV32-MEDIUM-NEXT: bb.5.bb4:
+ ; RV32-MEDIUM-NEXT: $x10 = COPY [[ADDI3]]
+ ; RV32-MEDIUM-NEXT: PseudoRET implicit $x10
+ ; RV32-MEDIUM-NEXT: {{ $}}
+ ; RV32-MEDIUM-NEXT: bb.6.bb5:
+ ; RV32-MEDIUM-NEXT: $x10 = COPY [[ADDI2]]
+ ; RV32-MEDIUM-NEXT: PseudoRET implicit $x10
+ ; RV32-MEDIUM-NEXT: {{ $}}
+ ; RV32-MEDIUM-NEXT: bb.7.bb6:
+ ; RV32-MEDIUM-NEXT: $x10 = COPY [[ADDI1]]
+ ; RV32-MEDIUM-NEXT: PseudoRET implicit $x10
+ ; RV32-MEDIUM-NEXT: {{ $}}
+ ; RV32-MEDIUM-NEXT: bb.8.default:
+ ; RV32-MEDIUM-NEXT: $x10 = COPY [[ADDI7]]
+ ; RV32-MEDIUM-NEXT: PseudoRET implicit $x10
+ bb.1.entry:
+ successors: %bb.8, %bb.9
+ liveins: $x10
+
+ %0:gprb(s32) = COPY $x10
+ %4:gprb(s32) = G_CONSTANT i32 5
+ %8:gprb(s32) = G_CONSTANT i32 200
+ %9:gprb(s32) = G_CONSTANT i32 100
+ %10:gprb(s32) = G_CONSTANT i32 1
+ %11:gprb(s32) = G_CONSTANT i32 2
+ %12:gprb(s32) = G_CONSTANT i32 3
+ %13:gprb(s32) = G_CONSTANT i32 4
+ %14:gprb(s32) = G_CONSTANT i32 1000
+ %1:gprb(s32) = G_CONSTANT i32 1
+ %2:gprb(s32) = G_SUB %0, %1
+ %16:gprb(s32) = G_ICMP intpred(ugt), %2(s32), %4
+ G_BRCOND %16(s32), %bb.8
+
+ bb.9.entry:
+ successors: %bb.2, %bb.3, %bb.4, %bb.5, %bb.6, %bb.7
+
+ %7:gprb(p0) = G_JUMP_TABLE %jump-table.0
+ G_BRJT %7(p0), %jump-table.0, %2(s32)
+
+ bb.2.bb1:
+ $x10 = COPY %13(s32)
+ PseudoRET implicit $x10
+
+ bb.3.bb2:
+ $x10 = COPY %12(s32)
+ PseudoRET implicit $x10
+
+ bb.4.bb3:
+ $x10 = COPY %11(s32)
+ PseudoRET implicit $x10
+
+ bb.5.bb4:
+ $x10 = COPY %10(s32)
+ PseudoRET implicit $x10
+
+ bb.6.bb5:
+ $x10 = COPY %9(s32)
+ PseudoRET implicit $x10
+
+ bb.7.bb6:
+ $x10 = COPY %8(s32)
+ PseudoRET implicit $x10
+
+ bb.8.default:
+ $x10 = COPY %14(s32)
+ PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-small-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-small-rv64.mir
new file mode 100644
index 000000000000..09a855105c26
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-small-rv64.mir
@@ -0,0 +1,161 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -run-pass=instruction-select %s -o - \
+# RUN: -code-model=small | FileCheck %s
+
+--- |
+ define i32 @jt_test(i32 signext %in) {
+ entry:
+ %0 = sext i32 %in to i64
+ switch i64 %0, label %default [
+ i64 1, label %bb1
+ i64 2, label %bb2
+ i64 3, label %bb3
+ i64 4, label %bb4
+ i64 5, label %bb5
+ i64 6, label %bb6
+ ]
+
+ bb1: ; preds = %entry
+ ret i32 4
+
+ bb2: ; preds = %entry
+ ret i32 3
+
+ bb3: ; preds = %entry
+ ret i32 2
+
+ bb4: ; preds = %entry
+ ret i32 1
+
+ bb5: ; preds = %entry
+ ret i32 100
+
+ bb6: ; preds = %entry
+ ret i32 200
+
+ default: ; preds = %entry
+ ret i32 1000
+ }
+
+...
+---
+name: jt_test
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+jumpTable:
+ kind: custom32
+ entries:
+ - id: 0
+ blocks: [ '%bb.2', '%bb.3', '%bb.4', '%bb.5', '%bb.6', '%bb.7' ]
+body: |
+ ; CHECK-LABEL: name: jt_test
+ ; CHECK: bb.0.entry:
+ ; CHECK-NEXT: successors: %bb.8(0x40000000), %bb.1(0x40000000)
+ ; CHECK-NEXT: liveins: $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+ ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 5
+ ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[COPY]], 0
+ ; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI [[ADDIW]], -1
+ ; CHECK-NEXT: BLTU [[ADDI]], [[ADDI1]], %bb.8
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1.entry:
+ ; CHECK-NEXT: successors: %bb.2(0x15555555), %bb.3(0x15555555), %bb.4(0x15555555), %bb.5(0x15555555), %bb.6(0x15555555), %bb.7(0x15555555)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[LUI:%[0-9]+]]:gpr = LUI target-flags(riscv-hi) %jump-table.0
+ ; CHECK-NEXT: [[ADDI2:%[0-9]+]]:gpr = ADDI [[LUI]], target-flags(riscv-lo) %jump-table.0
+ ; CHECK-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[ADDI1]], 2
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:gpr = ADD [[ADDI2]], [[SLLI]]
+ ; CHECK-NEXT: [[LW:%[0-9]+]]:gprjalr = LW [[ADD]], 0 :: (load (s32) from jump-table)
+ ; CHECK-NEXT: PseudoBRIND [[LW]], 0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2.bb1:
+ ; CHECK-NEXT: [[ADDI3:%[0-9]+]]:gpr = ADDI $x0, 4
+ ; CHECK-NEXT: $x10 = COPY [[ADDI3]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.3.bb2:
+ ; CHECK-NEXT: [[ADDI4:%[0-9]+]]:gpr = ADDI $x0, 3
+ ; CHECK-NEXT: $x10 = COPY [[ADDI4]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.4.bb3:
+ ; CHECK-NEXT: [[ADDI5:%[0-9]+]]:gpr = ADDI $x0, 2
+ ; CHECK-NEXT: $x10 = COPY [[ADDI5]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.5.bb4:
+ ; CHECK-NEXT: [[ADDI6:%[0-9]+]]:gpr = ADDI $x0, 1
+ ; CHECK-NEXT: $x10 = COPY [[ADDI6]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.6.bb5:
+ ; CHECK-NEXT: [[ADDI7:%[0-9]+]]:gpr = ADDI $x0, 100
+ ; CHECK-NEXT: $x10 = COPY [[ADDI7]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.7.bb6:
+ ; CHECK-NEXT: [[ADDI8:%[0-9]+]]:gpr = ADDI $x0, 200
+ ; CHECK-NEXT: $x10 = COPY [[ADDI8]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.8.default:
+ ; CHECK-NEXT: [[ADDI9:%[0-9]+]]:gpr = ADDI $x0, 1000
+ ; CHECK-NEXT: $x10 = COPY [[ADDI9]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ bb.1.entry:
+ successors: %bb.8, %bb.9
+ liveins: $x10
+
+ %1:gprb(s64) = COPY $x10
+ %2:gprb(s64) = G_ASSERT_SEXT %1, 32
+ %7:gprb(s64) = G_CONSTANT i64 5
+ %3:gprb(s64) = G_SEXT_INREG %2, 32
+ %4:gprb(s64) = G_CONSTANT i64 1
+ %5:gprb(s64) = G_SUB %3, %4
+ %26:gprb(s64) = G_ICMP intpred(ugt), %5(s64), %7
+ G_BRCOND %26(s64), %bb.8
+
+ bb.9.entry:
+ successors: %bb.2, %bb.3, %bb.4, %bb.5, %bb.6, %bb.7
+
+ %10:gprb(p0) = G_JUMP_TABLE %jump-table.0
+ G_BRJT %10(p0), %jump-table.0, %5(s64)
+
+ bb.2.bb1:
+ %22:gprb(s64) = G_CONSTANT i64 4
+ $x10 = COPY %22(s64)
+ PseudoRET implicit $x10
+
+ bb.3.bb2:
+ %20:gprb(s64) = G_CONSTANT i64 3
+ $x10 = COPY %20(s64)
+ PseudoRET implicit $x10
+
+ bb.4.bb3:
+ %18:gprb(s64) = G_CONSTANT i64 2
+ $x10 = COPY %18(s64)
+ PseudoRET implicit $x10
+
+ bb.5.bb4:
+ %16:gprb(s64) = G_CONSTANT i64 1
+ $x10 = COPY %16(s64)
+ PseudoRET implicit $x10
+
+ bb.6.bb5:
+ %14:gprb(s64) = G_CONSTANT i64 100
+ $x10 = COPY %14(s64)
+ PseudoRET implicit $x10
+
+ bb.7.bb6:
+ %12:gprb(s64) = G_CONSTANT i64 200
+ $x10 = COPY %12(s64)
+ PseudoRET implicit $x10
+
+ bb.8.default:
+ %24:gprb(s64) = G_CONSTANT i64 1000
+ $x10 = COPY %24(s64)
+ PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/jumptable.ll b/llvm/test/CodeGen/RISCV/GlobalISel/jumptable.ll
new file mode 100644
index 000000000000..601290812bb2
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/jumptable.ll
@@ -0,0 +1,257 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv32 -code-model=small -verify-machineinstrs < %s \
+; RUN: -global-isel | FileCheck %s -check-prefixes=RV32I-SMALL
+; RUN: llc -mtriple=riscv32 -code-model=medium -verify-machineinstrs < %s \
+; RUN: -global-isel | FileCheck %s -check-prefixes=RV32I-MEDIUM
+; RUN: llc -mtriple=riscv32 -relocation-model=pic -verify-machineinstrs < %s \
+; RUN: -global-isel | FileCheck %s -check-prefixes=RV32I-PIC
+; RUN: llc -mtriple=riscv64 -code-model=small -verify-machineinstrs < %s \
+; RUN: -global-isel | FileCheck %s -check-prefixes=RV64I-SMALL
+; RUN: llc -mtriple=riscv64 -code-model=medium -verify-machineinstrs < %s \
+; RUN: -global-isel | FileCheck %s -check-prefixes=RV64I-MEDIUM
+; RUN: llc -mtriple=riscv64 -relocation-model=pic -verify-machineinstrs < %s \
+; RUN: -global-isel | FileCheck %s -check-prefixes=RV64I-PIC
+
+define void @above_threshold(i32 signext %in, ptr %out) nounwind {
+; RV32I-SMALL-LABEL: above_threshold:
+; RV32I-SMALL: # %bb.0: # %entry
+; RV32I-SMALL-NEXT: li a2, 5
+; RV32I-SMALL-NEXT: addi a0, a0, -1
+; RV32I-SMALL-NEXT: bltu a2, a0, .LBB0_9
+; RV32I-SMALL-NEXT: # %bb.1: # %entry
+; RV32I-SMALL-NEXT: lui a2, %hi(.LJTI0_0)
+; RV32I-SMALL-NEXT: addi a2, a2, %lo(.LJTI0_0)
+; RV32I-SMALL-NEXT: slli a0, a0, 2
+; RV32I-SMALL-NEXT: add a0, a2, a0
+; RV32I-SMALL-NEXT: lw a0, 0(a0)
+; RV32I-SMALL-NEXT: jr a0
+; RV32I-SMALL-NEXT: .LBB0_2: # %bb1
+; RV32I-SMALL-NEXT: li a0, 4
+; RV32I-SMALL-NEXT: j .LBB0_8
+; RV32I-SMALL-NEXT: .LBB0_3: # %bb5
+; RV32I-SMALL-NEXT: li a0, 100
+; RV32I-SMALL-NEXT: j .LBB0_8
+; RV32I-SMALL-NEXT: .LBB0_4: # %bb3
+; RV32I-SMALL-NEXT: li a0, 2
+; RV32I-SMALL-NEXT: j .LBB0_8
+; RV32I-SMALL-NEXT: .LBB0_5: # %bb4
+; RV32I-SMALL-NEXT: li a0, 1
+; RV32I-SMALL-NEXT: j .LBB0_8
+; RV32I-SMALL-NEXT: .LBB0_6: # %bb2
+; RV32I-SMALL-NEXT: li a0, 3
+; RV32I-SMALL-NEXT: j .LBB0_8
+; RV32I-SMALL-NEXT: .LBB0_7: # %bb6
+; RV32I-SMALL-NEXT: li a0, 200
+; RV32I-SMALL-NEXT: .LBB0_8: # %exit
+; RV32I-SMALL-NEXT: sw a0, 0(a1)
+; RV32I-SMALL-NEXT: .LBB0_9: # %exit
+; RV32I-SMALL-NEXT: ret
+;
+; RV32I-MEDIUM-LABEL: above_threshold:
+; RV32I-MEDIUM: # %bb.0: # %entry
+; RV32I-MEDIUM-NEXT: li a2, 5
+; RV32I-MEDIUM-NEXT: addi a0, a0, -1
+; RV32I-MEDIUM-NEXT: bltu a2, a0, .LBB0_9
+; RV32I-MEDIUM-NEXT: # %bb.1: # %entry
+; RV32I-MEDIUM-NEXT: .Lpcrel_hi0:
+; RV32I-MEDIUM-NEXT: auipc a2, %pcrel_hi(.LJTI0_0)
+; RV32I-MEDIUM-NEXT: addi a2, a2, %pcrel_lo(.Lpcrel_hi0)
+; RV32I-MEDIUM-NEXT: slli a0, a0, 2
+; RV32I-MEDIUM-NEXT: add a0, a2, a0
+; RV32I-MEDIUM-NEXT: lw a0, 0(a0)
+; RV32I-MEDIUM-NEXT: jr a0
+; RV32I-MEDIUM-NEXT: .LBB0_2: # %bb1
+; RV32I-MEDIUM-NEXT: li a0, 4
+; RV32I-MEDIUM-NEXT: j .LBB0_8
+; RV32I-MEDIUM-NEXT: .LBB0_3: # %bb5
+; RV32I-MEDIUM-NEXT: li a0, 100
+; RV32I-MEDIUM-NEXT: j .LBB0_8
+; RV32I-MEDIUM-NEXT: .LBB0_4: # %bb3
+; RV32I-MEDIUM-NEXT: li a0, 2
+; RV32I-MEDIUM-NEXT: j .LBB0_8
+; RV32I-MEDIUM-NEXT: .LBB0_5: # %bb4
+; RV32I-MEDIUM-NEXT: li a0, 1
+; RV32I-MEDIUM-NEXT: j .LBB0_8
+; RV32I-MEDIUM-NEXT: .LBB0_6: # %bb2
+; RV32I-MEDIUM-NEXT: li a0, 3
+; RV32I-MEDIUM-NEXT: j .LBB0_8
+; RV32I-MEDIUM-NEXT: .LBB0_7: # %bb6
+; RV32I-MEDIUM-NEXT: li a0, 200
+; RV32I-MEDIUM-NEXT: .LBB0_8: # %exit
+; RV32I-MEDIUM-NEXT: sw a0, 0(a1)
+; RV32I-MEDIUM-NEXT: .LBB0_9: # %exit
+; RV32I-MEDIUM-NEXT: ret
+;
+; RV32I-PIC-LABEL: above_threshold:
+; RV32I-PIC: # %bb.0: # %entry
+; RV32I-PIC-NEXT: li a2, 5
+; RV32I-PIC-NEXT: addi a0, a0, -1
+; RV32I-PIC-NEXT: bltu a2, a0, .LBB0_9
+; RV32I-PIC-NEXT: # %bb.1: # %entry
+; RV32I-PIC-NEXT: .Lpcrel_hi0:
+; RV32I-PIC-NEXT: auipc a2, %pcrel_hi(.LJTI0_0)
+; RV32I-PIC-NEXT: addi a2, a2, %pcrel_lo(.Lpcrel_hi0)
+; RV32I-PIC-NEXT: slli a0, a0, 2
+; RV32I-PIC-NEXT: add a0, a2, a0
+; RV32I-PIC-NEXT: lw a0, 0(a0)
+; RV32I-PIC-NEXT: add a0, a0, a2
+; RV32I-PIC-NEXT: jr a0
+; RV32I-PIC-NEXT: .LBB0_2: # %bb1
+; RV32I-PIC-NEXT: li a0, 4
+; RV32I-PIC-NEXT: j .LBB0_8
+; RV32I-PIC-NEXT: .LBB0_3: # %bb5
+; RV32I-PIC-NEXT: li a0, 100
+; RV32I-PIC-NEXT: j .LBB0_8
+; RV32I-PIC-NEXT: .LBB0_4: # %bb3
+; RV32I-PIC-NEXT: li a0, 2
+; RV32I-PIC-NEXT: j .LBB0_8
+; RV32I-PIC-NEXT: .LBB0_5: # %bb4
+; RV32I-PIC-NEXT: li a0, 1
+; RV32I-PIC-NEXT: j .LBB0_8
+; RV32I-PIC-NEXT: .LBB0_6: # %bb2
+; RV32I-PIC-NEXT: li a0, 3
+; RV32I-PIC-NEXT: j .LBB0_8
+; RV32I-PIC-NEXT: .LBB0_7: # %bb6
+; RV32I-PIC-NEXT: li a0, 200
+; RV32I-PIC-NEXT: .LBB0_8: # %exit
+; RV32I-PIC-NEXT: sw a0, 0(a1)
+; RV32I-PIC-NEXT: .LBB0_9: # %exit
+; RV32I-PIC-NEXT: ret
+;
+; RV64I-SMALL-LABEL: above_threshold:
+; RV64I-SMALL: # %bb.0: # %entry
+; RV64I-SMALL-NEXT: li a2, 5
+; RV64I-SMALL-NEXT: sext.w a0, a0
+; RV64I-SMALL-NEXT: addi a0, a0, -1
+; RV64I-SMALL-NEXT: bltu a2, a0, .LBB0_9
+; RV64I-SMALL-NEXT: # %bb.1: # %entry
+; RV64I-SMALL-NEXT: lui a2, %hi(.LJTI0_0)
+; RV64I-SMALL-NEXT: addi a2, a2, %lo(.LJTI0_0)
+; RV64I-SMALL-NEXT: slli a0, a0, 2
+; RV64I-SMALL-NEXT: add a0, a2, a0
+; RV64I-SMALL-NEXT: lw a0, 0(a0)
+; RV64I-SMALL-NEXT: jr a0
+; RV64I-SMALL-NEXT: .LBB0_2: # %bb1
+; RV64I-SMALL-NEXT: li a0, 4
+; RV64I-SMALL-NEXT: j .LBB0_8
+; RV64I-SMALL-NEXT: .LBB0_3: # %bb5
+; RV64I-SMALL-NEXT: li a0, 100
+; RV64I-SMALL-NEXT: j .LBB0_8
+; RV64I-SMALL-NEXT: .LBB0_4: # %bb3
+; RV64I-SMALL-NEXT: li a0, 2
+; RV64I-SMALL-NEXT: j .LBB0_8
+; RV64I-SMALL-NEXT: .LBB0_5: # %bb4
+; RV64I-SMALL-NEXT: li a0, 1
+; RV64I-SMALL-NEXT: j .LBB0_8
+; RV64I-SMALL-NEXT: .LBB0_6: # %bb2
+; RV64I-SMALL-NEXT: li a0, 3
+; RV64I-SMALL-NEXT: j .LBB0_8
+; RV64I-SMALL-NEXT: .LBB0_7: # %bb6
+; RV64I-SMALL-NEXT: li a0, 200
+; RV64I-SMALL-NEXT: .LBB0_8: # %exit
+; RV64I-SMALL-NEXT: sw a0, 0(a1)
+; RV64I-SMALL-NEXT: .LBB0_9: # %exit
+; RV64I-SMALL-NEXT: ret
+;
+; RV64I-MEDIUM-LABEL: above_threshold:
+; RV64I-MEDIUM: # %bb.0: # %entry
+; RV64I-MEDIUM-NEXT: li a2, 5
+; RV64I-MEDIUM-NEXT: sext.w a0, a0
+; RV64I-MEDIUM-NEXT: addi a0, a0, -1
+; RV64I-MEDIUM-NEXT: bltu a2, a0, .LBB0_9
+; RV64I-MEDIUM-NEXT: # %bb.1: # %entry
+; RV64I-MEDIUM-NEXT: .Lpcrel_hi0:
+; RV64I-MEDIUM-NEXT: auipc a2, %pcrel_hi(.LJTI0_0)
+; RV64I-MEDIUM-NEXT: addi a2, a2, %pcrel_lo(.Lpcrel_hi0)
+; RV64I-MEDIUM-NEXT: slli a0, a0, 3
+; RV64I-MEDIUM-NEXT: add a0, a2, a0
+; RV64I-MEDIUM-NEXT: ld a0, 0(a0)
+; RV64I-MEDIUM-NEXT: jr a0
+; RV64I-MEDIUM-NEXT: .LBB0_2: # %bb1
+; RV64I-MEDIUM-NEXT: li a0, 4
+; RV64I-MEDIUM-NEXT: j .LBB0_8
+; RV64I-MEDIUM-NEXT: .LBB0_3: # %bb5
+; RV64I-MEDIUM-NEXT: li a0, 100
+; RV64I-MEDIUM-NEXT: j .LBB0_8
+; RV64I-MEDIUM-NEXT: .LBB0_4: # %bb3
+; RV64I-MEDIUM-NEXT: li a0, 2
+; RV64I-MEDIUM-NEXT: j .LBB0_8
+; RV64I-MEDIUM-NEXT: .LBB0_5: # %bb4
+; RV64I-MEDIUM-NEXT: li a0, 1
+; RV64I-MEDIUM-NEXT: j .LBB0_8
+; RV64I-MEDIUM-NEXT: .LBB0_6: # %bb2
+; RV64I-MEDIUM-NEXT: li a0, 3
+; RV64I-MEDIUM-NEXT: j .LBB0_8
+; RV64I-MEDIUM-NEXT: .LBB0_7: # %bb6
+; RV64I-MEDIUM-NEXT: li a0, 200
+; RV64I-MEDIUM-NEXT: .LBB0_8: # %exit
+; RV64I-MEDIUM-NEXT: sw a0, 0(a1)
+; RV64I-MEDIUM-NEXT: .LBB0_9: # %exit
+; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-PIC-LABEL: above_threshold:
+; RV64I-PIC: # %bb.0: # %entry
+; RV64I-PIC-NEXT: li a2, 5
+; RV64I-PIC-NEXT: sext.w a0, a0
+; RV64I-PIC-NEXT: addi a0, a0, -1
+; RV64I-PIC-NEXT: bltu a2, a0, .LBB0_9
+; RV64I-PIC-NEXT: # %bb.1: # %entry
+; RV64I-PIC-NEXT: .Lpcrel_hi0:
+; RV64I-PIC-NEXT: auipc a2, %pcrel_hi(.LJTI0_0)
+; RV64I-PIC-NEXT: addi a2, a2, %pcrel_lo(.Lpcrel_hi0)
+; RV64I-PIC-NEXT: slli a0, a0, 2
+; RV64I-PIC-NEXT: add a0, a2, a0
+; RV64I-PIC-NEXT: lw a0, 0(a0)
+; RV64I-PIC-NEXT: add a0, a0, a2
+; RV64I-PIC-NEXT: jr a0
+; RV64I-PIC-NEXT: .LBB0_2: # %bb1
+; RV64I-PIC-NEXT: li a0, 4
+; RV64I-PIC-NEXT: j .LBB0_8
+; RV64I-PIC-NEXT: .LBB0_3: # %bb5
+; RV64I-PIC-NEXT: li a0, 100
+; RV64I-PIC-NEXT: j .LBB0_8
+; RV64I-PIC-NEXT: .LBB0_4: # %bb3
+; RV64I-PIC-NEXT: li a0, 2
+; RV64I-PIC-NEXT: j .LBB0_8
+; RV64I-PIC-NEXT: .LBB0_5: # %bb4
+; RV64I-PIC-NEXT: li a0, 1
+; RV64I-PIC-NEXT: j .LBB0_8
+; RV64I-PIC-NEXT: .LBB0_6: # %bb2
+; RV64I-PIC-NEXT: li a0, 3
+; RV64I-PIC-NEXT: j .LBB0_8
+; RV64I-PIC-NEXT: .LBB0_7: # %bb6
+; RV64I-PIC-NEXT: li a0, 200
+; RV64I-PIC-NEXT: .LBB0_8: # %exit
+; RV64I-PIC-NEXT: sw a0, 0(a1)
+; RV64I-PIC-NEXT: .LBB0_9: # %exit
+; RV64I-PIC-NEXT: ret
+entry:
+ switch i32 %in, label %exit [
+ i32 1, label %bb1
+ i32 2, label %bb2
+ i32 3, label %bb3
+ i32 4, label %bb4
+ i32 5, label %bb5
+ i32 6, label %bb6
+ ]
+bb1:
+ store i32 4, ptr %out
+ br label %exit
+bb2:
+ store i32 3, ptr %out
+ br label %exit
+bb3:
+ store i32 2, ptr %out
+ br label %exit
+bb4:
+ store i32 1, ptr %out
+ br label %exit
+bb5:
+ store i32 100, ptr %out
+ br label %exit
+bb6:
+ store i32 200, ptr %out
+ br label %exit
+exit:
+ ret void
+}