-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[GlobalIsel] Add combine for select with constants #121088
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
[GlobalIsel] Add combine for select with constants #121088
Conversation
The SelectionDAG Isel supports the both version of combines : select Cond, Pow2, 0 --> (zext Cond) << log2(Pow2) select Cond, 0, Pow2 --> (zext !Cond) << log2(Pow2) But, here we add the latter missing combine for select in globalIsel.
@llvm/pr-subscribers-backend-aarch64 Author: Vikash Gupta (vg0204) ChangesThe SelectionDAG Isel supports the both version of combines mentioned below :
But, here we add the latter missing combine for select in globalIsel. Full diff: https://github.com/llvm/llvm-project/pull/121088.diff 2 Files Affected:
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index b46d4baf72a269..c94e642a47b500 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -6823,6 +6823,23 @@ bool CombinerHelper::tryFoldSelectOfConstants(GSelect *Select,
};
return true;
}
+
+ // select Cond, 0, Pow2 --> (zext (!Cond)) << log2(Pow2)
+ if (FalseValue.isPowerOf2() && TrueValue.isZero()) {
+ MatchInfo = [=](MachineIRBuilder &B) {
+ B.setInstrAndDebugLoc(*Select);
+ Register Not = MRI.createGenericVirtualRegister(CondTy);
+ B.buildNot(Not, Cond);
+ Register Inner = MRI.createGenericVirtualRegister(TrueTy);
+ B.buildZExtOrTrunc(Inner, Not);
+ // The shift amount must be scalar.
+ LLT ShiftTy = TrueTy.isVector() ? TrueTy.getElementType() : TrueTy;
+ auto ShAmtC = B.buildConstant(ShiftTy, FalseValue.exactLogBase2());
+ B.buildShl(Dest, Inner, ShAmtC, Flags);
+ };
+ return true;
+ }
+
// select Cond, -1, C --> or (sext Cond), C
if (TrueValue.isAllOnes()) {
MatchInfo = [=](MachineIRBuilder &B) {
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir
index 86fa12aa064acb..4afa0d4378fe12 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir
@@ -436,6 +436,36 @@ body: |
$w0 = COPY %ext(s32)
...
---
+# select cond, 0, 64 --> (zext (!Cond)) << log2(Pow2)
+name: select_cond_0_64_to_shift
+body: |
+ bb.1:
+ liveins: $x0, $x1, $x2
+ ; CHECK-LABEL: name: select_cond_0_64_to_shift
+ ; CHECK: liveins: $x0, $x1, $x2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK-NEXT: %c:_(s1) = G_TRUNC [[COPY]](s64)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s1) = G_XOR %c, [[C]]
+ ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s8) = G_ZEXT [[XOR]](s1)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 6
+ ; CHECK-NEXT: %sel:_(s8) = G_SHL [[ZEXT]], [[C1]](s8)
+ ; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %sel(s8)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ %0:_(s64) = COPY $x0
+ %1:_(s64) = COPY $x1
+ %2:_(s64) = COPY $x2
+ %c:_(s1) = G_TRUNC %0
+ %t:_(s1) = G_TRUNC %1
+ %f:_(s1) = G_TRUNC %2
+ %two:_(s8) = G_CONSTANT i8 0
+ %one:_(s8) = G_CONSTANT i8 64
+ %sel:_(s8) = G_SELECT %c, %two, %one
+ %ext:_(s32) = G_ANYEXT %sel
+ $w0 = COPY %ext(s32)
+...
+---
# select cond, -1, 0 --> sext Cond
name: select_cond_minus_1_0_to_sext_cond
body: |
|
@llvm/pr-subscribers-llvm-globalisel Author: Vikash Gupta (vg0204) ChangesThe SelectionDAG Isel supports the both version of combines mentioned below :
But, here we add the latter missing combine for select in globalIsel. Full diff: https://github.com/llvm/llvm-project/pull/121088.diff 2 Files Affected:
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index b46d4baf72a269..c94e642a47b500 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -6823,6 +6823,23 @@ bool CombinerHelper::tryFoldSelectOfConstants(GSelect *Select,
};
return true;
}
+
+ // select Cond, 0, Pow2 --> (zext (!Cond)) << log2(Pow2)
+ if (FalseValue.isPowerOf2() && TrueValue.isZero()) {
+ MatchInfo = [=](MachineIRBuilder &B) {
+ B.setInstrAndDebugLoc(*Select);
+ Register Not = MRI.createGenericVirtualRegister(CondTy);
+ B.buildNot(Not, Cond);
+ Register Inner = MRI.createGenericVirtualRegister(TrueTy);
+ B.buildZExtOrTrunc(Inner, Not);
+ // The shift amount must be scalar.
+ LLT ShiftTy = TrueTy.isVector() ? TrueTy.getElementType() : TrueTy;
+ auto ShAmtC = B.buildConstant(ShiftTy, FalseValue.exactLogBase2());
+ B.buildShl(Dest, Inner, ShAmtC, Flags);
+ };
+ return true;
+ }
+
// select Cond, -1, C --> or (sext Cond), C
if (TrueValue.isAllOnes()) {
MatchInfo = [=](MachineIRBuilder &B) {
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir
index 86fa12aa064acb..4afa0d4378fe12 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir
@@ -436,6 +436,36 @@ body: |
$w0 = COPY %ext(s32)
...
---
+# select cond, 0, 64 --> (zext (!Cond)) << log2(Pow2)
+name: select_cond_0_64_to_shift
+body: |
+ bb.1:
+ liveins: $x0, $x1, $x2
+ ; CHECK-LABEL: name: select_cond_0_64_to_shift
+ ; CHECK: liveins: $x0, $x1, $x2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK-NEXT: %c:_(s1) = G_TRUNC [[COPY]](s64)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s1) = G_XOR %c, [[C]]
+ ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s8) = G_ZEXT [[XOR]](s1)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 6
+ ; CHECK-NEXT: %sel:_(s8) = G_SHL [[ZEXT]], [[C1]](s8)
+ ; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %sel(s8)
+ ; CHECK-NEXT: $w0 = COPY %ext(s32)
+ %0:_(s64) = COPY $x0
+ %1:_(s64) = COPY $x1
+ %2:_(s64) = COPY $x2
+ %c:_(s1) = G_TRUNC %0
+ %t:_(s1) = G_TRUNC %1
+ %f:_(s1) = G_TRUNC %2
+ %two:_(s8) = G_CONSTANT i8 0
+ %one:_(s8) = G_CONSTANT i8 64
+ %sel:_(s8) = G_SELECT %c, %two, %one
+ %ext:_(s32) = G_ANYEXT %sel
+ $w0 = COPY %ext(s32)
+...
+---
# select cond, -1, 0 --> sext Cond
name: select_cond_minus_1_0_to_sext_cond
body: |
|
This description is ambiguous. Does GlobalISel currently support only the latter? |
It's still a WIP patch. Noted. |
Ping! |
Remove the WIP tag from the PR heading if it is ready for review. |
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.
Would be nice if we could succinctly handle both cases in the same combine.
Can be done, but just followed the format by which other select with constants combine had been handled in such scenarios! |
@aemerson, would be better if we handle it separately for all such pairs of cases separately, once this PR gets merged? |
Yes you don't have to do it in this PR, was just a minor suggestion. |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/11/builds/10362 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/136/builds/2211 Here is the relevant piece of the build log for the reference
|
The SelectionDAG Isel supports the both version of combines mentioned below :
The GlobalIsel for now only supports the first one defined in it's generic combinerHelper.cpp. This patch adds the missing second one.