Skip to content

Commit ef35da8

Browse files
authored
[X86][GlobalISel] Add instruction selection for G_SELECT (#70753)
1 parent 220e095 commit ef35da8

File tree

5 files changed

+835
-89
lines changed

5 files changed

+835
-89
lines changed

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "X86Subtarget.h"
2121
#include "X86TargetMachine.h"
2222
#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
23+
#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
2324
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
2425
#include "llvm/CodeGen/GlobalISel/Utils.h"
2526
#include "llvm/CodeGen/LowLevelType.h"
@@ -116,6 +117,8 @@ class X86InstructionSelector : public InstructionSelector {
116117
bool selectImplicitDefOrPHI(MachineInstr &I, MachineRegisterInfo &MRI) const;
117118
bool selectMulDivRem(MachineInstr &I, MachineRegisterInfo &MRI,
118119
MachineFunction &MF) const;
120+
bool selectSelect(MachineInstr &I, MachineRegisterInfo &MRI,
121+
MachineFunction &MF) const;
119122
bool selectIntrinsicWSideEffects(MachineInstr &I, MachineRegisterInfo &MRI,
120123
MachineFunction &MF) const;
121124

@@ -429,6 +432,8 @@ bool X86InstructionSelector::select(MachineInstr &I) {
429432
case TargetOpcode::G_SREM:
430433
case TargetOpcode::G_UREM:
431434
return selectMulDivRem(I, MRI, MF);
435+
case TargetOpcode::G_SELECT:
436+
return selectSelect(I, MRI, MF);
432437
case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
433438
return selectIntrinsicWSideEffects(I, MRI, MF);
434439
}
@@ -1789,6 +1794,49 @@ bool X86InstructionSelector::selectMulDivRem(MachineInstr &I,
17891794
return true;
17901795
}
17911796

1797+
bool X86InstructionSelector::selectSelect(MachineInstr &I,
1798+
MachineRegisterInfo &MRI,
1799+
MachineFunction &MF) const {
1800+
GSelect &Sel = cast<GSelect>(I);
1801+
unsigned DstReg = Sel.getReg(0);
1802+
BuildMI(*Sel.getParent(), Sel, Sel.getDebugLoc(), TII.get(X86::TEST32rr))
1803+
.addReg(Sel.getCondReg())
1804+
.addReg(Sel.getCondReg());
1805+
1806+
unsigned OpCmp;
1807+
LLT Ty = MRI.getType(DstReg);
1808+
switch (Ty.getSizeInBits()) {
1809+
default:
1810+
return false;
1811+
case 8:
1812+
OpCmp = X86::CMOV_GR8;
1813+
break;
1814+
case 16:
1815+
OpCmp = STI.canUseCMOV() ? X86::CMOV16rr : X86::CMOV_GR16;
1816+
break;
1817+
case 32:
1818+
OpCmp = STI.canUseCMOV() ? X86::CMOV32rr : X86::CMOV_GR32;
1819+
break;
1820+
case 64:
1821+
assert(STI.is64Bit() && STI.canUseCMOV());
1822+
OpCmp = X86::CMOV64rr;
1823+
break;
1824+
}
1825+
BuildMI(*Sel.getParent(), Sel, Sel.getDebugLoc(), TII.get(OpCmp), DstReg)
1826+
.addReg(Sel.getTrueReg())
1827+
.addReg(Sel.getFalseReg())
1828+
.addImm(X86::COND_E);
1829+
1830+
const TargetRegisterClass *DstRC = getRegClass(Ty, DstReg, MRI);
1831+
if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
1832+
LLVM_DEBUG(dbgs() << "Failed to constrain CMOV\n");
1833+
return false;
1834+
}
1835+
1836+
Sel.eraseFromParent();
1837+
return true;
1838+
}
1839+
17921840
bool X86InstructionSelector::selectIntrinsicWSideEffects(
17931841
MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF) const {
17941842

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
2929
: Subtarget(STI) {
3030

3131
bool Is64Bit = Subtarget.is64Bit();
32+
bool HasCMOV = Subtarget.canUseCMOV();
3233
bool HasSSE1 = Subtarget.hasSSE1();
3334
bool HasSSE2 = Subtarget.hasSSE2();
3435
bool HasSSE41 = Subtarget.hasSSE41();
@@ -521,11 +522,10 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
521522

522523
// todo: vectors and address spaces
523524
getActionDefinitionsBuilder(G_SELECT)
524-
.legalFor({{s8, s32}, {s16, s32}, {s32, s32}, {s64, s32},
525-
{p0, s32}})
526-
.widenScalarToNextPow2(0, /*Min=*/8)
527-
.clampScalar(0, s8, sMaxScalar)
528-
.clampScalar(1, s32, s32);
525+
.legalFor({{s8, s32}, {s16, s32}, {s32, s32}, {s64, s32}, {p0, s32}})
526+
.widenScalarToNextPow2(0, /*Min=*/8)
527+
.clampScalar(0, HasCMOV ? s16 : s8, sMaxScalar)
528+
.clampScalar(1, s32, s32);
529529

530530
// memory intrinsics
531531
getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE, G_MEMSET}).libcall();

llvm/test/CodeGen/X86/GlobalISel/legalize-select.mir

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ body: |
4141
; X86-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[SELECT]](s32), [[SELECT1]](s32)
4242
; X86-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY [[MV]](s64)
4343
; X86-NEXT: RET 0, implicit [[COPY]](s64)
44+
;
4445
; X64-LABEL: name: test_select64
4546
; X64: [[DEF:%[0-9]+]]:_(s64) = IMPLICIT_DEF
4647
; X64-NEXT: [[DEF1:%[0-9]+]]:_(s64) = IMPLICIT_DEF
@@ -101,14 +102,26 @@ body: |
101102
name: test_select8
102103
body: |
103104
bb.1:
104-
; CHECK-LABEL: name: test_select8
105-
; CHECK: [[DEF:%[0-9]+]]:_(s8) = IMPLICIT_DEF
106-
; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s8) = IMPLICIT_DEF
107-
; CHECK-NEXT: [[DEF2:%[0-9]+]]:_(s1) = IMPLICIT_DEF
108-
; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[DEF2]](s1)
109-
; CHECK-NEXT: [[SELECT:%[0-9]+]]:_(s8) = G_SELECT [[ZEXT]](s32), [[DEF1]], [[DEF]]
110-
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s8) = COPY [[SELECT]](s8)
111-
; CHECK-NEXT: RET 0, implicit [[COPY]](s8)
105+
; X86-LABEL: name: test_select8
106+
; X86: [[DEF:%[0-9]+]]:_(s8) = IMPLICIT_DEF
107+
; X86-NEXT: [[DEF1:%[0-9]+]]:_(s8) = IMPLICIT_DEF
108+
; X86-NEXT: [[DEF2:%[0-9]+]]:_(s1) = IMPLICIT_DEF
109+
; X86-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[DEF2]](s1)
110+
; X86-NEXT: [[SELECT:%[0-9]+]]:_(s8) = G_SELECT [[ZEXT]](s32), [[DEF1]], [[DEF]]
111+
; X86-NEXT: [[COPY:%[0-9]+]]:_(s8) = COPY [[SELECT]](s8)
112+
; X86-NEXT: RET 0, implicit [[COPY]](s8)
113+
;
114+
; X64-LABEL: name: test_select8
115+
; X64: [[DEF:%[0-9]+]]:_(s8) = IMPLICIT_DEF
116+
; X64-NEXT: [[DEF1:%[0-9]+]]:_(s8) = IMPLICIT_DEF
117+
; X64-NEXT: [[DEF2:%[0-9]+]]:_(s1) = IMPLICIT_DEF
118+
; X64-NEXT: [[ANYEXT:%[0-9]+]]:_(s16) = G_ANYEXT [[DEF1]](s8)
119+
; X64-NEXT: [[ANYEXT1:%[0-9]+]]:_(s16) = G_ANYEXT [[DEF]](s8)
120+
; X64-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[DEF2]](s1)
121+
; X64-NEXT: [[SELECT:%[0-9]+]]:_(s16) = G_SELECT [[ZEXT]](s32), [[ANYEXT]], [[ANYEXT1]]
122+
; X64-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[SELECT]](s16)
123+
; X64-NEXT: [[COPY:%[0-9]+]]:_(s8) = COPY [[TRUNC]](s8)
124+
; X64-NEXT: RET 0, implicit [[COPY]](s8)
112125
%0:_(s8) = IMPLICIT_DEF
113126
%1:_(s8) = IMPLICIT_DEF
114127
%2:_(s1) = IMPLICIT_DEF

llvm/test/CodeGen/X86/fast-isel-select-cmov.ll

Lines changed: 0 additions & 76 deletions
This file was deleted.

0 commit comments

Comments
 (0)