Skip to content

Commit c89e1c4

Browse files
committed
[GISel] Lower scalar G_SELECT in LegalizerHelper
The LegalizerHelper only has support to lower G_SELECT with vector operands. The approach is the same for scalar arguments, which this PR adds.
1 parent 382f70a commit c89e1c4

File tree

2 files changed

+56
-9
lines changed

2 files changed

+56
-9
lines changed

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7949,10 +7949,9 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerSelect(MachineInstr &MI) {
79497949
// Implement vector G_SELECT in terms of XOR, AND, OR.
79507950
auto [DstReg, DstTy, MaskReg, MaskTy, Op1Reg, Op1Ty, Op2Reg, Op2Ty] =
79517951
MI.getFirst4RegLLTs();
7952-
if (!DstTy.isVector())
7953-
return UnableToLegalize;
79547952

7955-
bool IsEltPtr = DstTy.getElementType().isPointer();
7953+
bool IsEltPtr =
7954+
(DstTy.isVector() ? DstTy.getElementType() : DstTy).isPointer();
79567955
if (IsEltPtr) {
79577956
LLT ScalarPtrTy = LLT::scalar(DstTy.getScalarSizeInBits());
79587957
LLT NewTy = DstTy.changeElementType(ScalarPtrTy);
@@ -7962,7 +7961,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerSelect(MachineInstr &MI) {
79627961
}
79637962

79647963
if (MaskTy.isScalar()) {
7965-
// Turn the scalar condition into a vector condition mask.
7964+
// Turn the scalar condition into a vector condition mask if needed.
79667965

79677966
Register MaskElt = MaskReg;
79687967

@@ -7972,13 +7971,22 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerSelect(MachineInstr &MI) {
79727971
MaskElt = MIRBuilder.buildSExtInReg(MaskTy, MaskElt, 1).getReg(0);
79737972

79747973
// Continue the sign extension (or truncate) to match the data type.
7975-
MaskElt = MIRBuilder.buildSExtOrTrunc(DstTy.getElementType(),
7976-
MaskElt).getReg(0);
7974+
MaskElt =
7975+
MIRBuilder
7976+
.buildSExtOrTrunc(DstTy.isVector() ? DstTy.getElementType() : DstTy,
7977+
MaskElt)
7978+
.getReg(0);
79777979

7978-
// Generate a vector splat idiom.
7979-
auto ShufSplat = MIRBuilder.buildShuffleSplat(DstTy, MaskElt);
7980-
MaskReg = ShufSplat.getReg(0);
7980+
if (DstTy.isVector()) {
7981+
// Generate a vector splat idiom.
7982+
auto ShufSplat = MIRBuilder.buildShuffleSplat(DstTy, MaskElt);
7983+
MaskReg = ShufSplat.getReg(0);
7984+
} else
7985+
MaskReg = MaskElt;
79817986
MaskTy = DstTy;
7987+
} else if (!DstTy.isVector()) {
7988+
// Cannot handle the case that mask is a vector and dst is a scalar.
7989+
return UnableToLegalize;
79827990
}
79837991

79847992
if (MaskTy.getSizeInBits() != DstTy.getSizeInBits()) {

llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3431,6 +3431,45 @@ TEST_F(AArch64GISelMITest, LowerUDIVREM) {
34313431
EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
34323432
}
34333433

3434+
// Test G_SELECT lowering.
3435+
TEST_F(AArch64GISelMITest, LowerSelect) {
3436+
setUp();
3437+
if (!TM)
3438+
GTEST_SKIP();
3439+
3440+
// Declare your legalization info
3441+
DefineLegalizerInfo(A, { getActionDefinitionsBuilder(G_SELECT).lower(); });
3442+
3443+
LLT S1 = LLT::scalar(1);
3444+
LLT S32 = LLT::scalar(32);
3445+
auto Tst = B.buildTrunc(S1, Copies[0]);
3446+
auto SrcA = B.buildTrunc(S32, Copies[1]);
3447+
auto SrcB = B.buildTrunc(S32, Copies[2]);
3448+
auto SELECT = B.buildInstr(TargetOpcode::G_SELECT, {S32}, {Tst, SrcA, SrcB});
3449+
3450+
AInfo Info(MF->getSubtarget());
3451+
DummyGISelObserver Observer;
3452+
LegalizerHelper Helper(*MF, Info, Observer, B);
3453+
// Perform Legalization
3454+
EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
3455+
Helper.lower(*SELECT, 0, S32));
3456+
3457+
auto CheckStr = R"(
3458+
CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC
3459+
CHECK: [[TRUE:%[0-9]+]]:_(s32) = G_TRUNC
3460+
CHECK: [[FALSE:%[0-9]+]]:_(s32) = G_TRUNC
3461+
CHECK: [[MSK:%[0-9]+]]:_(s32) = G_SEXT [[TST]]
3462+
CHECK: [[M:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
3463+
CHECK: [[NEGMSK:%[0-9]+]]:_(s32) = G_XOR [[MSK]]:_, [[M]]:_
3464+
CHECK: [[TVAL:%[0-9]+]]:_(s32) = G_AND [[TRUE]]:_, [[MSK]]:_
3465+
CHECK: [[FVAL:%[0-9]+]]:_(s32) = G_AND [[FALSE]]:_, [[NEGMSK]]:_
3466+
CHECK: [[RES:%[0-9]+]]:_(s32) = G_OR [[TVAL]]:_, [[FVAL]]:_
3467+
)";
3468+
3469+
// Check
3470+
EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
3471+
}
3472+
34343473
// Test widening of G_UNMERGE_VALUES
34353474
TEST_F(AArch64GISelMITest, WidenUnmerge) {
34363475
setUp();

0 commit comments

Comments
 (0)