-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[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
Conversation
@llvm/pr-subscribers-llvm-globalisel @llvm/pr-subscribers-backend-risc-v Author: Craig Topper (topperc) ChangesInstead 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:
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.
6b2650c
to
faac67b
Compare
TargetReg = MIRBuilder.buildPtrAdd(PtrTy, PtrReg, Load).getReg(0); | ||
break; | ||
} | ||
case MachineJumpTableInfo::EK_Custom32: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we treat EK_Custom32 differently from EK_BlockAddress here, but didn't have to in instruction selection?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can all of this except the Custom32 case go into the generic legalizer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I 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));
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we take this patch as is and I'll work on a refactoring into the legalizer as a follow up?
Instead of custom selecting a bunch of instructions, we can expand to generic MIR during legalization.