Skip to content

Commit f2d0bba

Browse files
authored
[GISel] Lower scalar G_SELECT in LegalizerHelper (#79342)
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 bb945fc commit f2d0bba

File tree

2 files changed

+56
-10
lines changed

2 files changed

+56
-10
lines changed

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7946,13 +7946,11 @@ LegalizerHelper::lowerISFPCLASS(MachineInstr &MI) {
79467946
}
79477947

79487948
LegalizerHelper::LegalizeResult LegalizerHelper::lowerSelect(MachineInstr &MI) {
7949-
// Implement vector G_SELECT in terms of XOR, AND, OR.
7949+
// Implement 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 = DstTy.getScalarType().isPointer();
79567954
if (IsEltPtr) {
79577955
LLT ScalarPtrTy = LLT::scalar(DstTy.getScalarSizeInBits());
79587956
LLT NewTy = DstTy.changeElementType(ScalarPtrTy);
@@ -7962,7 +7960,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerSelect(MachineInstr &MI) {
79627960
}
79637961

79647962
if (MaskTy.isScalar()) {
7965-
// Turn the scalar condition into a vector condition mask.
7963+
// Turn the scalar condition into a vector condition mask if needed.
79667964

79677965
Register MaskElt = MaskReg;
79687966

@@ -7972,13 +7970,20 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerSelect(MachineInstr &MI) {
79727970
MaskElt = MIRBuilder.buildSExtInReg(MaskTy, MaskElt, 1).getReg(0);
79737971

79747972
// Continue the sign extension (or truncate) to match the data type.
7975-
MaskElt = MIRBuilder.buildSExtOrTrunc(DstTy.getElementType(),
7976-
MaskElt).getReg(0);
7973+
MaskElt =
7974+
MIRBuilder.buildSExtOrTrunc(DstTy.getScalarType(), MaskElt).getReg(0);
79777975

7978-
// Generate a vector splat idiom.
7979-
auto ShufSplat = MIRBuilder.buildShuffleSplat(DstTy, MaskElt);
7980-
MaskReg = ShufSplat.getReg(0);
7976+
if (DstTy.isVector()) {
7977+
// Generate a vector splat idiom.
7978+
auto ShufSplat = MIRBuilder.buildShuffleSplat(DstTy, MaskElt);
7979+
MaskReg = ShufSplat.getReg(0);
7980+
} else {
7981+
MaskReg = MaskElt;
7982+
}
79817983
MaskTy = DstTy;
7984+
} else if (!DstTy.isVector()) {
7985+
// Cannot handle the case that mask is a vector and dst is a scalar.
7986+
return UnableToLegalize;
79827987
}
79837988

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

llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp

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

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

0 commit comments

Comments
 (0)