-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GISel] Lower scalar G_SELECT in LegalizerHelper #79342
Conversation
@llvm/pr-subscribers-llvm-globalisel Author: Kai Nacke (redstar) ChangesThe LegalizerHelper only has support to lower G_SELECT with Full diff: https://github.com/llvm/llvm-project/pull/79342.diff 2 Files Affected:
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 3b2cf3191092734..089c3b6945a02a7 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -7949,10 +7949,9 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerSelect(MachineInstr &MI) {
// Implement vector G_SELECT in terms of XOR, AND, OR.
auto [DstReg, DstTy, MaskReg, MaskTy, Op1Reg, Op1Ty, Op2Reg, Op2Ty] =
MI.getFirst4RegLLTs();
- if (!DstTy.isVector())
- return UnableToLegalize;
- bool IsEltPtr = DstTy.getElementType().isPointer();
+ bool IsEltPtr =
+ (DstTy.isVector() ? DstTy.getElementType() : DstTy).isPointer();
if (IsEltPtr) {
LLT ScalarPtrTy = LLT::scalar(DstTy.getScalarSizeInBits());
LLT NewTy = DstTy.changeElementType(ScalarPtrTy);
@@ -7962,7 +7961,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerSelect(MachineInstr &MI) {
}
if (MaskTy.isScalar()) {
- // Turn the scalar condition into a vector condition mask.
+ // Turn the scalar condition into a vector condition mask if needed.
Register MaskElt = MaskReg;
@@ -7972,13 +7971,22 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerSelect(MachineInstr &MI) {
MaskElt = MIRBuilder.buildSExtInReg(MaskTy, MaskElt, 1).getReg(0);
// Continue the sign extension (or truncate) to match the data type.
- MaskElt = MIRBuilder.buildSExtOrTrunc(DstTy.getElementType(),
- MaskElt).getReg(0);
+ MaskElt =
+ MIRBuilder
+ .buildSExtOrTrunc(DstTy.isVector() ? DstTy.getElementType() : DstTy,
+ MaskElt)
+ .getReg(0);
- // Generate a vector splat idiom.
- auto ShufSplat = MIRBuilder.buildShuffleSplat(DstTy, MaskElt);
- MaskReg = ShufSplat.getReg(0);
+ if (DstTy.isVector()) {
+ // Generate a vector splat idiom.
+ auto ShufSplat = MIRBuilder.buildShuffleSplat(DstTy, MaskElt);
+ MaskReg = ShufSplat.getReg(0);
+ } else
+ MaskReg = MaskElt;
MaskTy = DstTy;
+ } else if (!DstTy.isVector()) {
+ // Cannot handle the case that mask is a vector and dst is a scalar.
+ return UnableToLegalize;
}
if (MaskTy.getSizeInBits() != DstTy.getSizeInBits()) {
diff --git a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
index d7876b7ce87490c..b7e8e9ae57d1a35 100644
--- a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
+++ b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
@@ -3431,6 +3431,46 @@ TEST_F(AArch64GISelMITest, LowerUDIVREM) {
EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
}
+// Test G_SELECT lowering.
+TEST_F(AArch64GISelMITest, LowerSelect) {
+ setUp();
+ if (!TM)
+ GTEST_SKIP();
+
+ // Declare your legalization info
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_SELECT).lower(); });
+
+ LLT S1 = LLT::scalar(1);
+ LLT S32 = LLT::scalar(32);
+ auto Tst = B.buildTrunc(S1, Copies[0]);
+ auto SrcA = B.buildTrunc(S32, Copies[1]);
+ auto SrcB = B.buildTrunc(S32, Copies[2]);
+ auto SELECT = B.buildInstr(TargetOpcode::G_SELECT, {S32}, {Tst, SrcA, SrcB});
+
+ AInfo Info(MF->getSubtarget());
+ DummyGISelObserver Observer;
+ LegalizerHelper Helper(*MF, Info, Observer, B);
+ // Perform Legalization
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.lower(*SELECT, 0, S32));
+
+ auto CheckStr = R"(
+ CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC
+ CHECK: [[TRUE:%[0-9]+]]:_(s32) = G_TRUNC
+ CHECK: [[FALSE:%[0-9]+]]:_(s32) = G_TRUNC
+ CHECK: [[MSK:%[0-9]+]]:_(s32) = G_SEXT [[TST]]
+ CHECK: [[M:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ CHECK: [[NEGMSK:%[0-9]+]]:_(s32) = G_XOR [[MSK]]:_, [[M]]:_
+ CHECK: [[TVAL:%[0-9]+]]:_(s32) = G_AND [[TRUE]]:_, [[MSK]]:_
+ CHECK: [[FVAL:%[0-9]+]]:_(s32) = G_AND [[FALSE]]:_, [[NEGMSK]]:_
+ CHECK: [[RES:%[0-9]+]]:_(s32) = G_OR [[TVAL]]:_, [[FVAL]]:_
+ )";
+
+ // Check
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
// Test widening of G_UNMERGE_VALUES
TEST_F(AArch64GISelMITest, WidenUnmerge) {
setUp();
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
7a4a152
to
c89e1c4
Compare
|
||
bool IsEltPtr = DstTy.getElementType().isPointer(); | ||
bool IsEltPtr = | ||
(DstTy.isVector() ? DstTy.getElementType() : DstTy).isPointer(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DstTy.getScalarType().isPointer()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I totally overlooked getScalarType()
.
MaskElt).getReg(0); | ||
MaskElt = | ||
MIRBuilder | ||
.buildSExtOrTrunc(DstTy.isVector() ? DstTy.getElementType() : DstTy, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DstTy.getScalarType()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed.
@@ -7949,10 +7949,9 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerSelect(MachineInstr &MI) { | |||
// Implement vector G_SELECT in terms of XOR, AND, OR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vector
is not true anymore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
@@ -3431,6 +3431,45 @@ TEST_F(AArch64GISelMITest, LowerUDIVREM) { | |||
EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; | |||
} | |||
|
|||
// Test G_SELECT lowering. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be good to add a comment to say we don't expect to legalize scalar selects on aarch64 like this, but it is useful for testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, added a comment.
The LegalizerHelper only has support to lower G_SELECT with vector operands. The approach is the same for scalar arguments, which this PR adds.
c163182
to
f2f8480
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks
The LegalizerHelper only has support to lower G_SELECT with
vector operands. The approach is the same for scalar arguments,
which this PR adds.