Skip to content

Commit 22d9a0f

Browse files
committed
[X86][GlobalISel] Enable G_BRJT
1 parent 7c4c274 commit 22d9a0f

File tree

8 files changed

+531
-1
lines changed

8 files changed

+531
-1
lines changed

llvm/include/llvm/Target/GenericOpcodes.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1374,7 +1374,7 @@ def G_BRCOND : GenericInstruction {
13741374
// Generic indirect branch.
13751375
def G_BRINDIRECT : GenericInstruction {
13761376
let OutOperandList = (outs);
1377-
let InOperandList = (ins type0:$src1);
1377+
let InOperandList = (ins ptype0:$src1);
13781378
let hasSideEffects = false;
13791379
let isBranch = true;
13801380
let isTerminator = true;

llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ let IfConvergent = G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS in {
131131

132132
def : GINodeEquiv<G_BR, br>;
133133
def : GINodeEquiv<G_BRCOND, brcond>;
134+
def : GINodeEquiv<G_BRINDIRECT, brind>;
134135
def : GINodeEquiv<G_BSWAP, bswap>;
135136
def : GINodeEquiv<G_BITREVERSE, bitreverse>;
136137
def : GINodeEquiv<G_FSHL, fshl>;

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

Lines changed: 31 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 selectJumpTable(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_JUMP_TABLE:
427+
return selectJumpTable(I, MRI, MF);
424428
case TargetOpcode::G_IMPLICIT_DEF:
425429
case TargetOpcode::G_PHI:
426430
return selectImplicitDefOrPHI(I, MRI);
@@ -1472,6 +1476,33 @@ bool X86InstructionSelector::selectCondBranch(MachineInstr &I,
14721476
return true;
14731477
}
14741478

1479+
bool X86InstructionSelector::selectJumpTable(MachineInstr &I,
1480+
MachineRegisterInfo &MRI,
1481+
MachineFunction &MF) const {
1482+
auto Dst = I.getOperand(0).getReg();
1483+
auto JTI = I.getOperand(1).getIndex();
1484+
auto OpCode = STI.is64Bit() ? X86::LEA64r : X86::LEA32r;
1485+
1486+
auto *TLI = STI.getTargetLowering();
1487+
1488+
MachineInstr &Lea =
1489+
*BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCode), Dst)
1490+
.addReg(TLI->isJumpTableRelative()
1491+
? (STI.is64Bit() ? X86::RIP : X86::EIP)
1492+
: 0)
1493+
.addImm(1)
1494+
.addReg(0)
1495+
.addJumpTableIndex(JTI)
1496+
.addReg(0)
1497+
.getInstr();
1498+
1499+
constrainSelectedInstRegOperands(Lea, TII, TRI, RBI);
1500+
1501+
I.removeFromParent();
1502+
1503+
return true;
1504+
}
1505+
14751506
bool X86InstructionSelector::materializeFP(MachineInstr &I,
14761507
MachineRegisterInfo &MRI,
14771508
MachineFunction &MF) const {

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

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,16 @@
1414
#include "X86Subtarget.h"
1515
#include "X86TargetMachine.h"
1616
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
17+
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
18+
#include "llvm/CodeGen/MachineFunction.h"
19+
#include "llvm/CodeGen/MachineJumpTableInfo.h"
20+
#include "llvm/CodeGen/TargetLowering.h"
1721
#include "llvm/CodeGen/TargetOpcodes.h"
1822
#include "llvm/CodeGen/ValueTypes.h"
1923
#include "llvm/IR/DerivedTypes.h"
2024
#include "llvm/IR/Type.h"
25+
#include "llvm/Support/ErrorHandling.h"
26+
#include "llvm/Support/MathExtras.h"
2127

2228
using namespace llvm;
2329
using namespace TargetOpcode;
@@ -326,6 +332,10 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
326332

327333
getActionDefinitionsBuilder(G_BRCOND).legalFor({s1});
328334

335+
getActionDefinitionsBuilder(G_BRINDIRECT).legalFor({p0});
336+
getActionDefinitionsBuilder(G_JUMP_TABLE).legalFor({p0});
337+
getActionDefinitionsBuilder(G_BRJT).custom();
338+
329339
// pointer handling
330340
const std::initializer_list<LLT> PtrTypes32 = {s1, s8, s16, s32};
331341
const std::initializer_list<LLT> PtrTypes64 = {s1, s8, s16, s32, s64};
@@ -549,6 +559,64 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
549559
verify(*STI.getInstrInfo());
550560
}
551561

562+
bool X86LegalizerInfo::legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI,
563+
LostDebugLocObserver &LocObserver) const {
564+
switch (MI.getOpcode()) {
565+
case G_BRJT:
566+
return legalizeBrJT(Helper, MI);
567+
default:
568+
llvm_unreachable("instruction is not in switch");
569+
}
570+
}
571+
572+
bool X86LegalizerInfo::legalizeBrJT(LegalizerHelper &Helper,
573+
MachineInstr &MI) const {
574+
MachineIRBuilder &MIB = Helper.MIRBuilder;
575+
MachineFunction &MF = *MI.getMF();
576+
MachineRegisterInfo &MRI = *MIB.getMRI();
577+
const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
578+
579+
unsigned EntrySize = MJTI->getEntrySize(MF.getDataLayout());
580+
581+
auto PtrReg = MI.getOperand(0).getReg();
582+
auto PtrTy = MRI.getType(PtrReg);
583+
auto IdxReg = MI.getOperand(2).getReg();
584+
auto IdxTy = MRI.getType(IdxReg);
585+
586+
MachineMemOperand *MMO = MF.getMachineMemOperand(
587+
MachinePointerInfo::getJumpTable(MF), MachineMemOperand::MOLoad,
588+
PtrTy.getSizeInBytes(), Align(EntrySize));
589+
590+
auto ShiftAmt = MIB.buildConstant(IdxTy, Log2_32(PtrTy.getSizeInBytes()));
591+
auto Shift = MIB.buildShl(IdxTy, IdxReg, ShiftAmt);
592+
auto Target =
593+
MIB.buildPtrAdd(PtrTy, PtrReg, Shift->getOperand(0).getReg()).getReg(0);
594+
595+
switch (MJTI->getEntryKind()) {
596+
default:
597+
return false;
598+
case MachineJumpTableInfo::EK_BlockAddress: {
599+
Target = MIB.buildLoad(PtrTy, Target, *MMO).getReg(0);
600+
break;
601+
}
602+
case MachineJumpTableInfo::EK_LabelDifference64:
603+
assert(Subtarget.is64Bit());
604+
[[fallthrough]];
605+
case MachineJumpTableInfo::EK_LabelDifference32:
606+
auto Load = MIB.buildLoadInstr(
607+
TargetOpcode::G_LOAD, LLT::scalar(PtrTy.getSizeInBits()), Target, *MMO);
608+
Load = MIB.buildSExtOrTrunc(IdxTy, Load);
609+
Target = MIB.buildPtrAdd(PtrTy, PtrReg, Load).getReg(0);
610+
break;
611+
}
612+
613+
MIB.buildBrIndirect(Target);
614+
615+
MI.removeFromParent();
616+
617+
return true;
618+
}
619+
552620
bool X86LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
553621
MachineInstr &MI) const {
554622
return true;

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ class X86LegalizerInfo : public LegalizerInfo {
3030
public:
3131
X86LegalizerInfo(const X86Subtarget &STI, const X86TargetMachine &TM);
3232

33+
bool legalizeBrJT(LegalizerHelper &Helper, MachineInstr &MI) const;
34+
35+
bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI,
36+
LostDebugLocObserver &LocObserver) const override;
3337
bool legalizeIntrinsic(LegalizerHelper &Helper,
3438
MachineInstr &MI) const override;
3539
};
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
2+
# RUN: split-file %s %t
3+
# RUN: llc -mtriple=x86_64-linux-gnu -run-pass=legalizer %t/x64.mir -o - | FileCheck %t/x64.mir
4+
# RUN: llc -mtriple=i386-linux-gnu -run-pass=legalizer %t/x32.mir -o - | FileCheck %t/x32.mir
5+
6+
#--- x64.mir
7+
---
8+
name: test64
9+
alignment: 16
10+
legalized: false
11+
registers:
12+
- { id: 0, class: _, preferred-register: '' }
13+
- { id: 1, class: _, preferred-register: '' }
14+
body: |
15+
bb.1.entry:
16+
successors:
17+
liveins: $rdi
18+
19+
; CHECK-LABEL: name: test64
20+
; CHECK: liveins: $rdi
21+
; CHECK-NEXT: {{ $}}
22+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $rdi
23+
; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[COPY]](s64)
24+
; CHECK-NEXT: G_BRINDIRECT [[INTTOPTR]](p0)
25+
%0(s64) = COPY $rdi
26+
%1(p0) = G_INTTOPTR %0(s64)
27+
G_BRINDIRECT %1(p0)
28+
29+
...
30+
31+
#--- x32.mir
32+
---
33+
name: test32
34+
alignment: 16
35+
legalized: false
36+
registers:
37+
- { id: 0, class: _, preferred-register: '' }
38+
- { id: 1, class: _, preferred-register: '' }
39+
body: |
40+
bb.1.entry:
41+
successors:
42+
liveins: $edi
43+
44+
; CHECK-LABEL: name: test32
45+
; CHECK: liveins: $edi
46+
; CHECK-NEXT: {{ $}}
47+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $edi
48+
; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[COPY]](s32)
49+
; CHECK-NEXT: G_BRINDIRECT [[INTTOPTR]](p0)
50+
%0(s32) = COPY $edi
51+
%1(p0) = G_INTTOPTR %0(s32)
52+
G_BRINDIRECT %1(p0)
53+
54+
...
55+

0 commit comments

Comments
 (0)