Skip to content

[RISCV][GISel] Move G_BRJT expansion to legalization #73711

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Nov 20, 2024

Conversation

topperc
Copy link
Collaborator

@topperc topperc commented Nov 28, 2023

Instead of custom selecting a bunch of instructions, we can expand to generic MIR during legalization.

@llvmbot
Copy link
Member

llvmbot commented Nov 28, 2023

@llvm/pr-subscribers-llvm-globalisel

@llvm/pr-subscribers-backend-risc-v

Author: Craig Topper (topperc)

Changes

Instead of custom selecting a bunch of instructions, we can expand to generic MIR during legalization.


Patch is 43.86 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/73711.diff

11 Files Affected:

  • (modified) llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp (-52)
  • (modified) llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp (+60-1)
  • (modified) llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h (+1)
  • (removed) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-medium-rv64.mir (-160)
  • (removed) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-pic-rv32.mir (-157)
  • (removed) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-pic-rv64.mir (-161)
  • (removed) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-rv32.mir (-213)
  • (removed) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-small-rv64.mir (-161)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/jumptable.ll (+2-2)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-jump-table-brjt-rv32.mir (+8-2)
  • (removed) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-jump-table-brjt-rv64.mir (-159)
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index 9b4577dec87c570..c7653f882f4030b 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -542,58 +542,6 @@ 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_BRINDIRECT:
     MI.setDesc(TII.get(RISCV::PseudoBRIND));
     MI.addOperand(MachineOperand::CreateImm(0));
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 0a73681acca27fe..3d82a4cffbe629e 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -14,6 +14,7 @@
 #include "RISCVSubtarget.h"
 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/TargetOpcodes.h"
 #include "llvm/CodeGen/ValueTypes.h"
@@ -179,7 +180,7 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
 
   getActionDefinitionsBuilder(G_BRCOND).legalFor({sXLen}).minScalar(0, sXLen);
 
-  getActionDefinitionsBuilder(G_BRJT).legalFor({{p0, sXLen}});
+  getActionDefinitionsBuilder(G_BRJT).customFor({{p0, sXLen}});
 
   getActionDefinitionsBuilder(G_BRINDIRECT).legalFor({p0});
 
@@ -317,6 +318,62 @@ bool RISCVLegalizerInfo::legalizeShlAshrLshr(
   return true;
 }
 
+bool RISCVLegalizerInfo::legalizeBRJT(MachineInstr &MI,
+                                      MachineIRBuilder &MIRBuilder) const {
+  MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
+  auto &MF = *MI.getParent()->getParent();
+  const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
+  unsigned EntrySize = MJTI->getEntrySize(MF.getDataLayout());
+
+  Register PtrReg = MI.getOperand(0).getReg();
+  LLT PtrTy = MRI.getType(PtrReg);
+  Register IndexReg = MI.getOperand(2).getReg();
+  LLT IndexTy = MRI.getType(IndexReg);
+
+  MachineInstrBuilder Index;
+  if (isPowerOf2_32(EntrySize)) {
+    auto ShiftAmt = MIRBuilder.buildConstant(IndexTy, Log2_32(EntrySize));
+    Index = MIRBuilder.buildShl(IndexTy, IndexReg, ShiftAmt);
+  } else
+    return false;
+
+  auto Addr = MIRBuilder.buildPtrAdd(PtrTy, PtrReg, Index);
+
+  MachineMemOperand *MMO = MF.getMachineMemOperand(
+      MachinePointerInfo::getJumpTable(MF), MachineMemOperand::MOLoad,
+      EntrySize, Align(MJTI->getEntryAlignment(MF.getDataLayout())));
+
+  Register TargetReg;
+  switch (MJTI->getEntryKind()) {
+  default:
+    llvm_unreachable("Unexpected jumptable entry kind");
+  case MachineJumpTableInfo::EK_LabelDifference32: {
+    // For PIC, the sequence is:
+    // BRIND(load(Jumptable + index) + RelocBase)
+    // RelocBase can be JumpTable, GOT or some sort of global base.
+    auto Load = MIRBuilder.buildLoadInstr(
+        TargetOpcode::G_LOAD, LLT::scalar(EntrySize * 8), Addr, *MMO);
+    Load = MIRBuilder.buildSExtOrTrunc(IndexTy, Load);
+    TargetReg = MIRBuilder.buildPtrAdd(PtrTy, PtrReg, Load).getReg(0);
+    break;
+  }
+  case MachineJumpTableInfo::EK_Custom32: {
+    auto Load = MIRBuilder.buildLoadInstr(TargetOpcode::G_SEXTLOAD, IndexTy,
+                                          Addr, *MMO);
+    TargetReg = MIRBuilder.buildIntToPtr(PtrTy, Load).getReg(0);
+    break;
+  }
+  case MachineJumpTableInfo::EK_BlockAddress:
+    TargetReg = MIRBuilder.buildLoad(PtrTy, Addr, *MMO).getReg(0);
+    break;
+  }
+
+  MIRBuilder.buildBrIndirect(TargetReg);
+
+  MI.eraseFromParent();
+  return true;
+}
+
 bool RISCVLegalizerInfo::legalizeCustom(LegalizerHelper &Helper,
                                         MachineInstr &MI) const {
   MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
@@ -357,6 +414,8 @@ bool RISCVLegalizerInfo::legalizeCustom(LegalizerHelper &Helper,
     MI.eraseFromParent();
     return true;
   }
+  case TargetOpcode::G_BRJT:
+    return legalizeBRJT(MI, MIRBuilder);
   }
 
   llvm_unreachable("expected switch to return");
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h
index 6a5f49cd98d1842..c2a214cde0be4bc 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h
@@ -35,6 +35,7 @@ class RISCVLegalizerInfo : public LegalizerInfo {
 private:
   bool legalizeShlAshrLshr(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
                            GISelChangeObserver &Observer) const;
+  bool legalizeBRJT(MachineInstr &MI, MachineIRBuilder &MIRBuilder) const;
 };
 } // end namespace llvm
 #endif
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
deleted file mode 100644
index 5d980e7721458e9..000000000000000
--- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-medium-rv64.mir
+++ /dev/null
@@ -1,160 +0,0 @@
-# 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
deleted file mode 100644
index 27fe465ccf696bf..000000000000000
--- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-pic-rv32.mir
+++ /dev/null
@@ -1,157 +0,0 @@
-# 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
deleted file mode 100644
index 77156b913c5e8b4..000000000000000
--- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-pic-rv64.mir
+++ /dev/null
@@ -1,161 +0,0 @@
-# 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 [[P...
[truncated]

Instead of custom selecting a bunch of instructions, we can
expand to generic MIR during legalization.
TargetReg = MIRBuilder.buildPtrAdd(PtrTy, PtrReg, Load).getReg(0);
break;
}
case MachineJumpTableInfo::EK_Custom32: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we treat EK_Custom32 differently from EK_BlockAddress here, but didn't have to in instruction selection?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EK_BlockAddress stores a pointer to the basic block target using a full pointer worth of bits. EK_Custom32 is an RV64 size optimization for the small code model where we assume that the 64 bit pointer is in +/-2GB so fits in 32 bits. Since its 32 bits it's type doesn't match p0(64 bits) so we have to sign extend it and convert it.

In instruction selection, EK_BlockAddress used LW on rv32 and LD on rv64. EK_Custom32 used LW. We distinguished based on the EntrySize.

@@ -317,6 +318,61 @@ bool RISCVLegalizerInfo::legalizeShlAshrLshr(
return true;
}

bool RISCVLegalizerInfo::legalizeBRJT(MachineInstr &MI,
MachineIRBuilder &MIRBuilder) const {
MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can all of this except the Custom32 case go into the generic legalizer?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the EK_LabelDifference32 case might not be generic either. SelectionDAG calls a virtual function getPICJumpTableRelocBase.

From LegalizeDAG.cpp

    if (TLI.isJumpTableRelative()) {                                             
      // For PIC, the sequence is:                                               
      // BRIND(load(Jumptable + index) + RelocBase)                              
      // RelocBase can be JumpTable, GOT or some sort of global base.            
      Addr = DAG.getNode(ISD::ADD, dl, PTy, Addr,                                
                          TLI.getPICJumpTableRelocBase(Table, DAG));             
    }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For that kind of case I think we could just introduce a global isel variant of the same hook. It still saves a lot of common boilerplate

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we take this patch as is and I'll work on a refactoring into the legalizer as a follow up?

@topperc topperc requested a review from arsenm November 20, 2024 20:18
@topperc topperc merged commit 4087b87 into llvm:main Nov 20, 2024
6 of 8 checks passed
@topperc topperc deleted the pr/brjt-legalize branch November 20, 2024 21:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants