[llvm] [RISCV][GISel] Instruction selection for G_JUMP_TABLE and G_BRJT. (PR #71987)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 10 13:42:51 PST 2023


https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/71987

>From 34e998a69593b8c5b3fe65016211f69f2acf34ea Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Fri, 10 Nov 2023 11:43:50 -0800
Subject: [PATCH 1/2] [RISCV][GISel] Instruction selection for G_JUMP_TABLE and
 G_BRJT.

---
 .../RISCV/GISel/RISCVInstructionSelector.cpp  | 139 +++++++++
 .../jump-table-brjt-medium-rv64.mir           | 161 +++++++++++
 .../jump-table-brjt-pic-rv32.mir              | 158 +++++++++++
 .../jump-table-brjt-pic-rv64.mir              | 163 +++++++++++
 .../jump-table-brjt-rv32.mir                  | 215 ++++++++++++++
 .../jump-table-brjt-small-rv64.mir            | 163 +++++++++++
 .../CodeGen/RISCV/GlobalISel/jumptable.ll     | 263 ++++++++++++++++++
 7 files changed, 1262 insertions(+)
 create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-medium-rv64.mir
 create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-pic-rv32.mir
 create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-pic-rv64.mir
 create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-rv32.mir
 create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-small-rv64.mir
 create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/jumptable.ll

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index b8acd98939b9fc7..a07c6dedbeb7570 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 @@ class RISCVInstructionSelector : public InstructionSelector {
   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;
@@ -397,6 +400,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: {
     // TODO: Fold with G_ICMP.
     auto Bcc =
@@ -405,6 +410,49 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
     MI.eraseFromParent();
     return constrainSelectedInstRegOperands(*Bcc, TII, TRI, RBI);
   }
+  case TargetOpcode::G_BRJT: {
+    unsigned EntrySize =
+        MF.getJumpTableInfo()->getEntrySize(MF.getDataLayout());
+    assert((EntrySize == 4 || (Subtarget->is64Bit() && EntrySize == 8)) &&
+           "Unsupported jump-table entry size");
+
+    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.
+    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(EntrySize)));
+    if (!Dest.constrainAllUses(TII, TRI, RBI))
+      return false;
+
+    if (MF.getTarget().isPositionIndependent()) {
+      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: {
@@ -696,6 +744,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 000000000000000..edd071cb96a8912
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-medium-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=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:   [[ADDIW:%[0-9]+]]:gpr = ADDIW [[COPY]], 0
+  ; CHECK-NEXT:   [[ADDI:%[0-9]+]]:gpr = ADDI [[ADDIW]], -1
+  ; CHECK-NEXT:   [[SLTIU:%[0-9]+]]:gpr = SLTIU [[ADDI]], 6
+  ; CHECK-NEXT:   [[XORI:%[0-9]+]]:gpr = XORI [[SLTIU]], 1
+  ; CHECK-NEXT:   BNE [[XORI]], $x0, %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 [[ADDI]], 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:   [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 4
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI1]]
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.3.bb2:
+  ; CHECK-NEXT:   [[ADDI2:%[0-9]+]]:gpr = ADDI $x0, 3
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI2]]
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.4.bb3:
+  ; CHECK-NEXT:   [[ADDI3:%[0-9]+]]:gpr = ADDI $x0, 2
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI3]]
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.5.bb4:
+  ; CHECK-NEXT:   [[ADDI4:%[0-9]+]]:gpr = ADDI $x0, 1
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI4]]
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.6.bb5:
+  ; CHECK-NEXT:   [[ADDI5:%[0-9]+]]:gpr = ADDI $x0, 100
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI5]]
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.7.bb6:
+  ; CHECK-NEXT:   [[ADDI6:%[0-9]+]]:gpr = ADDI $x0, 200
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI6]]
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.8.default:
+  ; CHECK-NEXT:   [[ADDI7:%[0-9]+]]:gpr = ADDI $x0, 1000
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI7]]
+  ; 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 000000000000000..44073e2b4997704
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-pic-rv32.mir
@@ -0,0 +1,158 @@
+# 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, 200
+  ; CHECK-NEXT:   [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 100
+  ; CHECK-NEXT:   [[ADDI2:%[0-9]+]]:gpr = ADDI $x0, 1
+  ; CHECK-NEXT:   [[ADDI3:%[0-9]+]]:gpr = ADDI $x0, 2
+  ; CHECK-NEXT:   [[ADDI4:%[0-9]+]]:gpr = ADDI $x0, 3
+  ; CHECK-NEXT:   [[ADDI5:%[0-9]+]]:gpr = ADDI $x0, 4
+  ; CHECK-NEXT:   [[ADDI6:%[0-9]+]]:gpr = ADDI $x0, 1000
+  ; CHECK-NEXT:   [[ADDI7:%[0-9]+]]:gpr = ADDI [[COPY]], -1
+  ; CHECK-NEXT:   [[SLTIU:%[0-9]+]]:gpr = SLTIU [[ADDI7]], 6
+  ; CHECK-NEXT:   [[XORI:%[0-9]+]]:gpr = XORI [[SLTIU]], 1
+  ; CHECK-NEXT:   BNE [[XORI]], $x0, %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 [[ADDI7]], 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 [[ADDI5]]
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.3.bb2:
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI4]]
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.4.bb3:
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI3]]
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.5.bb4:
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI2]]
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.6.bb5:
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI1]]
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.7.bb6:
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI]]
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.8.default:
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI6]]
+  ; 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 000000000000000..24492028a97da10
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-pic-rv64.mir
@@ -0,0 +1,163 @@
+# 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
+alignment:       4
+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:   [[ADDIW:%[0-9]+]]:gpr = ADDIW [[COPY]], 0
+  ; CHECK-NEXT:   [[ADDI:%[0-9]+]]:gpr = ADDI [[ADDIW]], -1
+  ; CHECK-NEXT:   [[SLTIU:%[0-9]+]]:gpr = SLTIU [[ADDI]], 6
+  ; CHECK-NEXT:   [[XORI:%[0-9]+]]:gpr = XORI [[SLTIU]], 1
+  ; CHECK-NEXT:   BNE [[XORI]], $x0, %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 [[ADDI]], 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:   [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 4
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI1]]
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.3.bb2:
+  ; CHECK-NEXT:   [[ADDI2:%[0-9]+]]:gpr = ADDI $x0, 3
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI2]]
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.4.bb3:
+  ; CHECK-NEXT:   [[ADDI3:%[0-9]+]]:gpr = ADDI $x0, 2
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI3]]
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.5.bb4:
+  ; CHECK-NEXT:   [[ADDI4:%[0-9]+]]:gpr = ADDI $x0, 1
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI4]]
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.6.bb5:
+  ; CHECK-NEXT:   [[ADDI5:%[0-9]+]]:gpr = ADDI $x0, 100
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI5]]
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.7.bb6:
+  ; CHECK-NEXT:   [[ADDI6:%[0-9]+]]:gpr = ADDI $x0, 200
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI6]]
+  ; CHECK-NEXT:   PseudoRET implicit $x10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.8.default:
+  ; CHECK-NEXT:   [[ADDI7:%[0-9]+]]:gpr = ADDI $x0, 1000
+  ; CHECK-NEXT:   $x10 = COPY [[ADDI7]]
+  ; 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 000000000000000..0d3c7b196c78f41
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-rv32.mir
@@ -0,0 +1,215 @@
+# 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, 200
+  ; RV32-SMALL-NEXT:   [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 100
+  ; RV32-SMALL-NEXT:   [[ADDI2:%[0-9]+]]:gpr = ADDI $x0, 1
+  ; RV32-SMALL-NEXT:   [[ADDI3:%[0-9]+]]:gpr = ADDI $x0, 2
+  ; RV32-SMALL-NEXT:   [[ADDI4:%[0-9]+]]:gpr = ADDI $x0, 3
+  ; RV32-SMALL-NEXT:   [[ADDI5:%[0-9]+]]:gpr = ADDI $x0, 4
+  ; RV32-SMALL-NEXT:   [[ADDI6:%[0-9]+]]:gpr = ADDI $x0, 1000
+  ; RV32-SMALL-NEXT:   [[ADDI7:%[0-9]+]]:gpr = ADDI [[COPY]], -1
+  ; RV32-SMALL-NEXT:   [[SLTIU:%[0-9]+]]:gpr = SLTIU [[ADDI7]], 6
+  ; RV32-SMALL-NEXT:   [[XORI:%[0-9]+]]:gpr = XORI [[SLTIU]], 1
+  ; RV32-SMALL-NEXT:   BNE [[XORI]], $x0, %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:   [[ADDI8:%[0-9]+]]:gpr = ADDI [[LUI]], target-flags(riscv-lo) %jump-table.0
+  ; RV32-SMALL-NEXT:   [[SLLI:%[0-9]+]]:gpr = SLLI [[ADDI7]], 2
+  ; RV32-SMALL-NEXT:   [[ADD:%[0-9]+]]:gpr = ADD [[ADDI8]], [[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 [[ADDI5]]
+  ; RV32-SMALL-NEXT:   PseudoRET implicit $x10
+  ; RV32-SMALL-NEXT: {{  $}}
+  ; RV32-SMALL-NEXT: bb.3.bb2:
+  ; RV32-SMALL-NEXT:   $x10 = COPY [[ADDI4]]
+  ; RV32-SMALL-NEXT:   PseudoRET implicit $x10
+  ; RV32-SMALL-NEXT: {{  $}}
+  ; RV32-SMALL-NEXT: bb.4.bb3:
+  ; RV32-SMALL-NEXT:   $x10 = COPY [[ADDI3]]
+  ; RV32-SMALL-NEXT:   PseudoRET implicit $x10
+  ; RV32-SMALL-NEXT: {{  $}}
+  ; RV32-SMALL-NEXT: bb.5.bb4:
+  ; RV32-SMALL-NEXT:   $x10 = COPY [[ADDI2]]
+  ; RV32-SMALL-NEXT:   PseudoRET implicit $x10
+  ; RV32-SMALL-NEXT: {{  $}}
+  ; RV32-SMALL-NEXT: bb.6.bb5:
+  ; RV32-SMALL-NEXT:   $x10 = COPY [[ADDI1]]
+  ; RV32-SMALL-NEXT:   PseudoRET implicit $x10
+  ; RV32-SMALL-NEXT: {{  $}}
+  ; RV32-SMALL-NEXT: bb.7.bb6:
+  ; RV32-SMALL-NEXT:   $x10 = COPY [[ADDI]]
+  ; RV32-SMALL-NEXT:   PseudoRET implicit $x10
+  ; RV32-SMALL-NEXT: {{  $}}
+  ; RV32-SMALL-NEXT: bb.8.default:
+  ; RV32-SMALL-NEXT:   $x10 = COPY [[ADDI6]]
+  ; 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, 200
+  ; RV32-MEDIUM-NEXT:   [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 100
+  ; RV32-MEDIUM-NEXT:   [[ADDI2:%[0-9]+]]:gpr = ADDI $x0, 1
+  ; RV32-MEDIUM-NEXT:   [[ADDI3:%[0-9]+]]:gpr = ADDI $x0, 2
+  ; RV32-MEDIUM-NEXT:   [[ADDI4:%[0-9]+]]:gpr = ADDI $x0, 3
+  ; RV32-MEDIUM-NEXT:   [[ADDI5:%[0-9]+]]:gpr = ADDI $x0, 4
+  ; RV32-MEDIUM-NEXT:   [[ADDI6:%[0-9]+]]:gpr = ADDI $x0, 1000
+  ; RV32-MEDIUM-NEXT:   [[ADDI7:%[0-9]+]]:gpr = ADDI [[COPY]], -1
+  ; RV32-MEDIUM-NEXT:   [[SLTIU:%[0-9]+]]:gpr = SLTIU [[ADDI7]], 6
+  ; RV32-MEDIUM-NEXT:   [[XORI:%[0-9]+]]:gpr = XORI [[SLTIU]], 1
+  ; RV32-MEDIUM-NEXT:   BNE [[XORI]], $x0, %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 [[ADDI7]], 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 [[ADDI5]]
+  ; RV32-MEDIUM-NEXT:   PseudoRET implicit $x10
+  ; RV32-MEDIUM-NEXT: {{  $}}
+  ; RV32-MEDIUM-NEXT: bb.3.bb2:
+  ; RV32-MEDIUM-NEXT:   $x10 = COPY [[ADDI4]]
+  ; RV32-MEDIUM-NEXT:   PseudoRET implicit $x10
+  ; RV32-MEDIUM-NEXT: {{  $}}
+  ; RV32-MEDIUM-NEXT: bb.4.bb3:
+  ; RV32-MEDIUM-NEXT:   $x10 = COPY [[ADDI3]]
+  ; RV32-MEDIUM-NEXT:   PseudoRET implicit $x10
+  ; RV32-MEDIUM-NEXT: {{  $}}
+  ; RV32-MEDIUM-NEXT: bb.5.bb4:
+  ; RV32-MEDIUM-NEXT:   $x10 = COPY [[ADDI2]]
+  ; RV32-MEDIUM-NEXT:   PseudoRET implicit $x10
+  ; RV32-MEDIUM-NEXT: {{  $}}
+  ; RV32-MEDIUM-NEXT: bb.6.bb5:
+  ; RV32-MEDIUM-NEXT:   $x10 = COPY [[ADDI1]]
+  ; RV32-MEDIUM-NEXT:   PseudoRET implicit $x10
+  ; RV32-MEDIUM-NEXT: {{  $}}
+  ; RV32-MEDIUM-NEXT: bb.7.bb6:
+  ; RV32-MEDIUM-NEXT:   $x10 = COPY [[ADDI]]
+  ; RV32-MEDIUM-NEXT:   PseudoRET implicit $x10
+  ; RV32-MEDIUM-NEXT: {{  $}}
+  ; RV32-MEDIUM-NEXT: bb.8.default:
+  ; RV32-MEDIUM-NEXT:   $x10 = COPY [[ADDI6]]
+  ; 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 000000000000000..94c76d923b5a034
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-small-rv64.mir
@@ -0,0 +1,163 @@
+# 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
+alignment:       4
+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:   [[ADDIW:%[0-9]+]]:gpr = ADDIW [[COPY]], 0
+  ; CHECK-NEXT:   [[ADDI:%[0-9]+]]:gpr = ADDI [[ADDIW]], -1
+  ; CHECK-NEXT:   [[SLTIU:%[0-9]+]]:gpr = SLTIU [[ADDI]], 6
+  ; CHECK-NEXT:   [[XORI:%[0-9]+]]:gpr = XORI [[SLTIU]], 1
+  ; CHECK-NEXT:   BNE [[XORI]], $x0, %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:   [[ADDI1:%[0-9]+]]:gpr = ADDI [[LUI]], target-flags(riscv-lo) %jump-table.0
+  ; CHECK-NEXT:   [[SLLI:%[0-9]+]]:gpr = SLLI [[ADDI]], 2
+  ; CHECK-NEXT:   [[ADD:%[0-9]+]]:gpr = ADD [[ADDI1]], [[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:   [[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/jumptable.ll b/llvm/test/CodeGen/RISCV/GlobalISel/jumptable.ll
new file mode 100644
index 000000000000000..24769447685caca
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/jumptable.ll
@@ -0,0 +1,263 @@
+; 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:    addi a0, a0, -1
+; RV32I-SMALL-NEXT:    sltiu a2, a0, 6
+; RV32I-SMALL-NEXT:    xori a2, a2, 1
+; RV32I-SMALL-NEXT:    bnez a2, .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:    addi a0, a0, -1
+; RV32I-MEDIUM-NEXT:    sltiu a2, a0, 6
+; RV32I-MEDIUM-NEXT:    xori a2, a2, 1
+; RV32I-MEDIUM-NEXT:    bnez a2, .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:    addi a0, a0, -1
+; RV32I-PIC-NEXT:    sltiu a2, a0, 6
+; RV32I-PIC-NEXT:    xori a2, a2, 1
+; RV32I-PIC-NEXT:    bnez a2, .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:    sext.w a0, a0
+; RV64I-SMALL-NEXT:    addi a0, a0, -1
+; RV64I-SMALL-NEXT:    sltiu a2, a0, 6
+; RV64I-SMALL-NEXT:    xori a2, a2, 1
+; RV64I-SMALL-NEXT:    bnez a2, .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:    sext.w a0, a0
+; RV64I-MEDIUM-NEXT:    addi a0, a0, -1
+; RV64I-MEDIUM-NEXT:    sltiu a2, a0, 6
+; RV64I-MEDIUM-NEXT:    xori a2, a2, 1
+; RV64I-MEDIUM-NEXT:    bnez a2, .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:    sext.w a0, a0
+; RV64I-PIC-NEXT:    addi a0, a0, -1
+; RV64I-PIC-NEXT:    sltiu a2, a0, 6
+; RV64I-PIC-NEXT:    xori a2, a2, 1
+; RV64I-PIC-NEXT:    bnez a2, .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
+}

>From a0c52d69b6d3dd899511fa477f83b06d2a09c5fd Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Fri, 10 Nov 2023 13:42:38 -0800
Subject: [PATCH 2/2] Add some more FIXMEs.

---
 llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index a07c6dedbeb7570..ce5ba99c88978e6 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -411,6 +411,7 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
     return constrainSelectedInstRegOperands(*Bcc, TII, TRI, RBI);
   }
   case TargetOpcode::G_BRJT: {
+    // FIXME: Move to legalization?
     unsigned EntrySize =
         MF.getJumpTableInfo()->getEntrySize(MF.getDataLayout());
     assert((EntrySize == 4 || (Subtarget->is64Bit() && EntrySize == 8)) &&
@@ -422,7 +423,7 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
     if (!SLL.constrainAllUses(TII, TRI, RBI))
       return false;
 
-    // TODO: Use SHXADD.
+    // 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))



More information about the llvm-commits mailing list