Skip to content

Commit 3863c66

Browse files
committed
[X86][GlobalISel] Enable G_BRJT
1 parent 7c4c274 commit 3863c66

File tree

4 files changed

+261
-0
lines changed

4 files changed

+261
-0
lines changed

llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ class X86InstructionSelector : public InstructionSelector {
107107
MachineFunction &MF) const;
108108
bool selectCondBranch(MachineInstr &I, MachineRegisterInfo &MRI,
109109
MachineFunction &MF) const;
110+
bool selectBrJT(MachineInstr &I, MachineRegisterInfo &MRI,
111+
MachineFunction &MF) const;
110112
bool selectTurnIntoCOPY(MachineInstr &I, MachineRegisterInfo &MRI,
111113
const unsigned DstReg,
112114
const TargetRegisterClass *DstRC,
@@ -421,6 +423,8 @@ bool X86InstructionSelector::select(MachineInstr &I) {
421423
return selectInsert(I, MRI, MF);
422424
case TargetOpcode::G_BRCOND:
423425
return selectCondBranch(I, MRI, MF);
426+
case TargetOpcode::G_BRJT:
427+
return selectBrJT(I, MRI, MF);
424428
case TargetOpcode::G_IMPLICIT_DEF:
425429
case TargetOpcode::G_PHI:
426430
return selectImplicitDefOrPHI(I, MRI);
@@ -1472,6 +1476,44 @@ bool X86InstructionSelector::selectCondBranch(MachineInstr &I,
14721476
return true;
14731477
}
14741478

1479+
bool X86InstructionSelector::selectBrJT(MachineInstr &I,
1480+
MachineRegisterInfo &MRI,
1481+
MachineFunction &MF) const {
1482+
assert((I.getOpcode() == TargetOpcode::G_BRJT) && "unexpected instruction");
1483+
1484+
auto Dst = I.getOperand(0).getReg();
1485+
auto DstTy = MRI.getType(I.getOperand(0).getReg());
1486+
auto JTI = I.getOperand(1).getIndex();
1487+
auto Idx = I.getOperand(2).getReg();
1488+
auto NewDst = MRI.createGenericVirtualRegister(MRI.getType(Dst));
1489+
auto *MMO = MF.getMachineMemOperand(MachinePointerInfo().getJumpTable(MF),
1490+
MachineMemOperand::MOLoad, DstTy,
1491+
Align(DstTy.getSizeInBytes()));
1492+
1493+
auto MovOp = STI.is64Bit() ? X86::MOV64rm : X86::MOV32rm;
1494+
auto JmpOp = STI.is64Bit() ? X86::JMP64r : X86::JMP32r;
1495+
1496+
// TODO: Maybe there is a way to use X86AddressMode
1497+
auto Mov = BuildMI(I.getParent(), I.getDebugLoc(), TII.get(MovOp))
1498+
.addDef(NewDst)
1499+
.addReg(0)
1500+
.addImm(8)
1501+
.addReg(Idx)
1502+
.addJumpTableIndex(JTI)
1503+
.addReg(0)
1504+
.addMemOperand(MMO);
1505+
1506+
auto Jmp =
1507+
BuildMI(I.getParent(), I.getDebugLoc(), TII.get(JmpOp)).addReg(NewDst);
1508+
1509+
I.removeFromParent();
1510+
1511+
if (!constrainSelectedInstRegOperands(*Mov, TII, TRI, RBI) &&
1512+
!constrainSelectedInstRegOperands(*Jmp, TII, TRI, RBI))
1513+
return false;
1514+
return true;
1515+
}
1516+
14751517
bool X86InstructionSelector::materializeFP(MachineInstr &I,
14761518
MachineRegisterInfo &MRI,
14771519
MachineFunction &MF) const {

llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,15 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
326326

327327
getActionDefinitionsBuilder(G_BRCOND).legalFor({s1});
328328

329+
getActionDefinitionsBuilder(G_JUMP_TABLE).legalFor({p0});
330+
getActionDefinitionsBuilder(G_BRJT)
331+
.legalIf([=](const LegalityQuery &Query) -> bool {
332+
return typePairInSet(0, 1, {{p0, s32}})(Query) ||
333+
(Is64Bit && typePairInSet(0, 1, {{p0, s64}})(Query));
334+
})
335+
.widenScalarOrEltToNextPow2(2, 32)
336+
.clampScalar(1, s32, sMaxScalar);
337+
329338
// pointer handling
330339
const std::initializer_list<LLT> PtrTypes32 = {s1, s8, s16, s32};
331340
const std::initializer_list<LLT> PtrTypes64 = {s1, s8, s16, s32, s64};
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
2+
# RUN: llc -mtriple=x86_64-linux-gnu -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL
3+
# RUN: llc -mtriple=i386-linux-gnu -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL
4+
5+
---
6+
name: test
7+
alignment: 16
8+
legalized: false
9+
jumpTable:
10+
kind: block-address
11+
entries:
12+
- id: 0
13+
blocks: [ '%bb.2', '%bb.3', ]
14+
body: |
15+
; ALL-LABEL: name: test
16+
; ALL: bb.0.entry:
17+
; ALL-NEXT: successors: %bb.1(0x40000000), %bb.4(0x40000000)
18+
; ALL-NEXT: liveins: $edi
19+
; ALL-NEXT: {{ $}}
20+
; ALL-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $edi
21+
; ALL-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
22+
; ALL-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
23+
; ALL-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[C1]]
24+
; ALL-NEXT: [[ICMP:%[0-9]+]]:_(s8) = G_ICMP intpred(ugt), [[SUB]](s32), [[C]]
25+
; ALL-NEXT: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[ICMP]](s8)
26+
; ALL-NEXT: G_BRCOND [[TRUNC]](s1), %bb.4
27+
; ALL-NEXT: {{ $}}
28+
; ALL-NEXT: bb.1.entry:
29+
; ALL-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
30+
; ALL-NEXT: {{ $}}
31+
; ALL-NEXT: [[JUMP_TABLE:%[0-9]+]]:_(p0) = G_JUMP_TABLE %jump-table.0
32+
; ALL-NEXT: G_BRJT [[JUMP_TABLE]](p0), %jump-table.0, [[SUB]](s32)
33+
; ALL-NEXT: {{ $}}
34+
; ALL-NEXT: bb.2:
35+
; ALL-NEXT: successors: %bb.5(0x80000000)
36+
; ALL-NEXT: {{ $}}
37+
; ALL-NEXT: G_BR %bb.5
38+
; ALL-NEXT: {{ $}}
39+
; ALL-NEXT: bb.3:
40+
; ALL-NEXT: successors: %bb.5(0x80000000)
41+
; ALL-NEXT: {{ $}}
42+
; ALL-NEXT: G_BR %bb.5
43+
; ALL-NEXT: {{ $}}
44+
; ALL-NEXT: bb.4:
45+
; ALL-NEXT: successors: %bb.5(0x80000000)
46+
; ALL-NEXT: {{ $}}
47+
; ALL-NEXT: bb.5:
48+
; ALL-NEXT: $eax = COPY [[COPY]](s32)
49+
; ALL-NEXT: RET 0, implicit $eax
50+
bb.0.entry:
51+
successors: %bb.1(0x40000000), %bb.4(0x40000000)
52+
liveins: $edi
53+
54+
%0:_(s32) = COPY $edi
55+
%4:_(s32) = G_CONSTANT i32 4
56+
%1:_(s32) = G_CONSTANT i32 0
57+
%2:_(s32) = G_SUB %0, %1
58+
%5:_(s1) = G_ICMP intpred(ugt), %2(s32), %4
59+
G_BRCOND %5(s1), %bb.4
60+
61+
bb.1.entry:
62+
successors: %bb.2(0x1999999a), %bb.3(0x1999999a)
63+
64+
%6:_(p0) = G_JUMP_TABLE %jump-table.0
65+
G_BRJT %6(p0), %jump-table.0, %2(s32)
66+
67+
bb.2:
68+
successors: %bb.5(0x80000000)
69+
70+
G_BR %bb.5
71+
72+
bb.3:
73+
successors: %bb.5(0x80000000)
74+
75+
G_BR %bb.5
76+
77+
bb.4:
78+
successors: %bb.5(0x80000000)
79+
80+
bb.5:
81+
$eax = COPY %0(s32)
82+
RET 0, implicit $eax
83+
84+
...
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
2+
# RUN: llc -mtriple=x86_64-linux-gnu -run-pass=instruction-select %s -o - | FileCheck %s --check-prefix=X64
3+
# RUN: llc -mtriple=i386-linux-gnu -run-pass=instruction-select %s -o - | FileCheck %s --check-prefix=X32
4+
5+
---
6+
name: test
7+
alignment: 16
8+
exposesReturnsTwice: false
9+
legalized: true
10+
regBankSelected: true
11+
selected: false
12+
jumpTable:
13+
kind: block-address
14+
entries:
15+
- id: 0
16+
blocks: [ '%bb.2', '%bb.3' ]
17+
body: |
18+
; X64-LABEL: name: test
19+
; X64: bb.0.entry:
20+
; X64-NEXT: successors: %bb.1(0x40000000), %bb.4(0x40000000)
21+
; X64-NEXT: liveins: $edi
22+
; X64-NEXT: {{ $}}
23+
; X64-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $edi
24+
; X64-NEXT: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 4
25+
; X64-NEXT: [[SUB32ri:%[0-9]+]]:gr32 = SUB32ri [[COPY]], 0, implicit-def dead $eflags
26+
; X64-NEXT: [[COPY1:%[0-9]+]]:gr64_nosp = COPY [[SUB32ri]]
27+
; X64-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY [[COPY1]]
28+
; X64-NEXT: CMP32rr [[COPY2]], [[MOV32ri]], implicit-def $eflags
29+
; X64-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 7, implicit $eflags
30+
; X64-NEXT: TEST8ri [[SETCCr]], 1, implicit-def $eflags
31+
; X64-NEXT: JCC_1 %bb.4, 5, implicit $eflags
32+
; X64-NEXT: {{ $}}
33+
; X64-NEXT: bb.1.entry:
34+
; X64-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
35+
; X64-NEXT: {{ $}}
36+
; X64-NEXT: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm $noreg, 8, [[COPY1]], %jump-table.0, $noreg :: (load (p0) from jump-table)
37+
; X64-NEXT: JMP64r [[MOV64rm]]
38+
; X64-NEXT: {{ $}}
39+
; X64-NEXT: bb.2:
40+
; X64-NEXT: successors: %bb.5(0x80000000)
41+
; X64-NEXT: {{ $}}
42+
; X64-NEXT: JMP_1 %bb.5
43+
; X64-NEXT: {{ $}}
44+
; X64-NEXT: bb.3:
45+
; X64-NEXT: successors: %bb.5(0x80000000)
46+
; X64-NEXT: {{ $}}
47+
; X64-NEXT: JMP_1 %bb.5
48+
; X64-NEXT: {{ $}}
49+
; X64-NEXT: bb.4:
50+
; X64-NEXT: successors: %bb.5(0x80000000)
51+
; X64-NEXT: {{ $}}
52+
; X64-NEXT: bb.5:
53+
; X64-NEXT: $eax = COPY [[COPY]]
54+
; X64-NEXT: RET 0, implicit $eax
55+
;
56+
; X32-LABEL: name: test
57+
; X32: bb.0.entry:
58+
; X32-NEXT: successors: %bb.1(0x40000000), %bb.4(0x40000000)
59+
; X32-NEXT: liveins: $edi
60+
; X32-NEXT: {{ $}}
61+
; X32-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $edi
62+
; X32-NEXT: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 4
63+
; X32-NEXT: [[SUB32ri:%[0-9]+]]:gr32_nosp = SUB32ri [[COPY]], 0, implicit-def dead $eflags
64+
; X32-NEXT: CMP32rr [[SUB32ri]], [[MOV32ri]], implicit-def $eflags
65+
; X32-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 7, implicit $eflags
66+
; X32-NEXT: TEST8ri [[SETCCr]], 1, implicit-def $eflags
67+
; X32-NEXT: JCC_1 %bb.4, 5, implicit $eflags
68+
; X32-NEXT: {{ $}}
69+
; X32-NEXT: bb.1.entry:
70+
; X32-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
71+
; X32-NEXT: {{ $}}
72+
; X32-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm $noreg, 8, [[SUB32ri]], %jump-table.0, $noreg :: (load (p0) from jump-table)
73+
; X32-NEXT: JMP32r [[MOV32rm]]
74+
; X32-NEXT: {{ $}}
75+
; X32-NEXT: bb.2:
76+
; X32-NEXT: successors: %bb.5(0x80000000)
77+
; X32-NEXT: {{ $}}
78+
; X32-NEXT: JMP_1 %bb.5
79+
; X32-NEXT: {{ $}}
80+
; X32-NEXT: bb.3:
81+
; X32-NEXT: successors: %bb.5(0x80000000)
82+
; X32-NEXT: {{ $}}
83+
; X32-NEXT: JMP_1 %bb.5
84+
; X32-NEXT: {{ $}}
85+
; X32-NEXT: bb.4:
86+
; X32-NEXT: successors: %bb.5(0x80000000)
87+
; X32-NEXT: {{ $}}
88+
; X32-NEXT: bb.5:
89+
; X32-NEXT: $eax = COPY [[COPY]]
90+
; X32-NEXT: RET 0, implicit $eax
91+
bb.0.entry:
92+
successors: %bb.1(0x40000000), %bb.4(0x40000000)
93+
liveins: $edi
94+
95+
%0:gpr(s32) = COPY $edi
96+
%4:gpr(s32) = G_CONSTANT i32 4
97+
%1:gpr(s32) = G_CONSTANT i32 0
98+
%2:gpr(s32) = G_SUB %0, %1
99+
%8:gpr(s8) = G_ICMP intpred(ugt), %2(s32), %4
100+
%5:gpr(s1) = G_TRUNC %8(s8)
101+
G_BRCOND %5(s1), %bb.4
102+
103+
bb.1.entry:
104+
successors: %bb.2(0x40000000), %bb.3(0x40000000)
105+
106+
%6:gpr(p0) = G_JUMP_TABLE %jump-table.0
107+
G_BRJT %6(p0), %jump-table.0, %2(s32)
108+
109+
bb.2:
110+
successors: %bb.5(0x80000000)
111+
112+
G_BR %bb.5
113+
114+
bb.3:
115+
successors: %bb.5(0x80000000)
116+
117+
G_BR %bb.5
118+
119+
bb.4:
120+
successors: %bb.5(0x80000000)
121+
122+
bb.5:
123+
$eax = COPY %0(s32)
124+
RET 0, implicit $eax
125+
126+
...

0 commit comments

Comments
 (0)