-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[InstCombine] Match scalable splats in m_ImmConstant #132522
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
[InstCombine] Match scalable splats in m_ImmConstant #132522
Conversation
… again However this meant that FoldShiftByConstant no longer kicked in for scalable vectors because scalable splats are represented by ConstantExprs. This fixes it by explicitly allowing splats of ConstantInts, it's not the prettiest so open to any suggestions. But I'm also hoping that UseConstantIntForScalableSplat will eventually remove the need for this. I noticed this when trying to reverse a combine on RISC-V in llvm#132245, and saw that the resulting vector and scalar forms were different.
|
@llvm/pr-subscribers-llvm-ir @llvm/pr-subscribers-llvm-transforms Author: Luke Lau (lukel97) ChangesHowever this meant that FoldShiftByConstant no longer kicked in for scalable vectors because scalable splats are represented by ConstantExprs. This fixes it by explicitly allowing splats of ConstantInts, it's not the prettiest so open to any suggestions. But I'm also hoping that UseConstantIntForScalableSplat will eventually remove the need for this. I noticed this when trying to reverse a combine on RISC-V in #132245, and saw that the resulting vector and scalar forms were different. Full diff: https://github.com/llvm/llvm-project/pull/132522.diff 3 Files Affected:
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 90cd279e8a457..91174cc79cd2b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -428,7 +428,10 @@ Instruction *InstCombinerImpl::commonShiftTransforms(BinaryOperator &I) {
return R;
Constant *CUI;
- if (match(Op1, m_ImmConstant(CUI)))
+ if (match(Op1, m_Constant(CUI)) &&
+ (!isa<ConstantExpr>(CUI) ||
+ (Ty->isVectorTy() &&
+ isa_and_present<ConstantInt>(CUI->getSplatValue()))))
if (Instruction *Res = FoldShiftByConstant(Op0, CUI, I))
return Res;
diff --git a/llvm/test/Transforms/InstCombine/shl-bo.ll b/llvm/test/Transforms/InstCombine/shl-bo.ll
index c32ac2eacb25a..5ee8716d5d119 100644
--- a/llvm/test/Transforms/InstCombine/shl-bo.ll
+++ b/llvm/test/Transforms/InstCombine/shl-bo.ll
@@ -656,3 +656,14 @@ define <16 x i8> @test_FoldShiftByConstant_CreateAnd(<16 x i8> %in0) {
%vshl_n = shl <16 x i8> %tmp, <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
ret <16 x i8> %vshl_n
}
+
+define <vscale x 1 x i8> @test_FoldShiftByConstant_CreateAnd_scalable(<vscale x 1 x i8> %x) {
+; CHECK-LABEL: @test_FoldShiftByConstant_CreateAnd_scalable(
+; CHECK-NEXT: [[TMP1:%.*]] = shl <vscale x 1 x i8> [[X:%.*]], splat (i8 2)
+; CHECK-NEXT: [[TMP2:%.*]] = and <vscale x 1 x i8> [[TMP1]], splat (i8 8)
+; CHECK-NEXT: ret <vscale x 1 x i8> [[TMP2]]
+;
+ %1 = and <vscale x 1 x i8> %x, splat (i8 2)
+ %2 = shl <vscale x 1 x i8> %1, splat (i8 2)
+ ret <vscale x 1 x i8> %2
+}
diff --git a/llvm/test/Transforms/InstCombine/shl-twice-constant.ll b/llvm/test/Transforms/InstCombine/shl-twice-constant.ll
index bbdd7fa3d1c40..151db29fe3e5f 100644
--- a/llvm/test/Transforms/InstCombine/shl-twice-constant.ll
+++ b/llvm/test/Transforms/InstCombine/shl-twice-constant.ll
@@ -14,3 +14,14 @@ define i64 @testfunc() {
%shl2 = shl i64 %shl1, ptrtoint (ptr @c to i64)
ret i64 %shl2
}
+
+define <vscale x 1 x i64> @scalable() {
+; CHECK-LABEL: @scalable(
+; CHECK-NEXT: [[SHL1:%.*]] = shl nuw <vscale x 1 x i64> splat (i64 1), shufflevector (<vscale x 1 x i64> insertelement (<vscale x 1 x i64> poison, i64 ptrtoint (ptr @c2 to i64), i64 0), <vscale x 1 x i64> poison, <vscale x 1 x i32> zeroinitializer)
+; CHECK-NEXT: [[SHL2:%.*]] = shl <vscale x 1 x i64> [[SHL1]], shufflevector (<vscale x 1 x i64> insertelement (<vscale x 1 x i64> poison, i64 ptrtoint (ptr @c to i64), i64 0), <vscale x 1 x i64> poison, <vscale x 1 x i32> zeroinitializer)
+; CHECK-NEXT: ret <vscale x 1 x i64> [[SHL2]]
+;
+ %shl1 = shl <vscale x 1 x i64> splat (i64 1), splat (i64 ptrtoint (ptr @c2 to i64))
+ %shl2 = shl <vscale x 1 x i64> %shl1, splat (i64 ptrtoint (ptr @c to i64))
+ ret <vscale x 1 x i64> %shl2
+}
|
dtcxzyw
left a comment
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.
I am ok with this workaround.
| Constant *CUI; | ||
| if (match(Op1, m_ImmConstant(CUI))) | ||
| if (match(Op1, m_Constant(CUI)) && | ||
| (!isa<ConstantExpr>(CUI) || |
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.
Can you add a fixme here to note that we should remove this special case after we use ConstantInt to represent a scalable vector splat by default?
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.
Done in the matcher for a0f4ac6
nikic
left a comment
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.
Can we generally accept scalable splats in m_ImmConstant? I doubt this is the only place with this problem.
I am afraid that it will cause new infinite loop bugs :( |
b7d69b0 to
a0f4ac6
Compare
I've reworked m_ImmConstant to accept scalable splats, so the changes in InstCombineShifts are gone now. I had to create two separate structs to help match it, because one binds and the other doesn't (and I couldn't seem to reuse cstval_pred_ty because it's not polymorphic and needs to be specicialized to either ConstantInt or ConstantFP). It was tempting to try and create one binding matcher and declare a dummy Constant for the non-binding m_ImmConstant(), but it looks like everything here is trying to be tail callable so I avoided it. |
In this new version I've added a check to make sure that the splat value also doesn't contain any ConstantExprs, I think that should be enough? |
|
Ping |
dtcxzyw
left a comment
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.
LG
Co-authored-by: Yingwei Zheng <[email protected]>
nikic
left a comment
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.
LGTM
|
Hi, Could this be the cause of these test-suite failures ? https://lab.llvm.org/buildbot/#/builders/41/builds/5897 I am not sure at all about this. This is just because the issue seems to be in the InstCombine area |
Oh thanks for pointing that out, I didn't notice the InstructionSimplify failure. Yesterday I mainly saw some errors about a missing |
This reverts commit df9e5ae. This is triggering an assertion failure on llvm-test-suite with -enable-vplan-native-path: https://lab.llvm.org/buildbot/#/builders/198/builds/3365
|
thanks @lukel97 |
|
It looks like the crash is caused by casts of m_ImmConstant splats not being folded by ConstantFoldCastOperand, triggering the "Constant-fold of ImmConstant should not fail" assertion. But #133207 actually fixes that, so I'll land that first. |
…" (#134262) This reapplies #132522. Previously casts of scalable m_ImmConstant splats weren't being folded by ConstantFoldCastOperand, triggering the "Constant-fold of ImmConstant should not fail" assertion. There are no changes to the code in this PR, instead we just needed #133207 to land first. A test has been added for the assertion in llvm/test/Transforms/InstSimplify/vec-icmp-of-cast.ll @icmp_ult_sext_scalable_splat_is_true. <hr/> #118806 fixed an infinite loop in FoldShiftByConstant that could occur when the shift amount was a ConstantExpr. However this meant that FoldShiftByConstant no longer kicked in for scalable vectors because scalable splats are represented by ConstantExprs. This fixes it by allowing scalable splats of non-ConstantExprs in m_ImmConstant, which also fixes a few other test cases where scalable splats were being missed. But I'm also hoping that UseConstantIntForScalableSplat will eventually remove the need for this. I noticed this when trying to reverse a combine on RISC-V in #132245, and saw that the resulting vector and scalar forms were different.
Local branch origin/amd-gfx 01fc438 Merged main:52f3cad9ffa3 into origin/amd-gfx:31272f8ef7f7 Remote branch main b61e387 Revert "[InstCombine] Match scalable splats in m_ImmConstant (llvm#132522)"
#118806 fixed an infinite loop in FoldShiftByConstant that could occur when the shift amount was a ConstantExpr.
However this meant that FoldShiftByConstant no longer kicked in for scalable vectors because scalable splats are represented by ConstantExprs.
This fixes it by allowing scalable splats of non-ConstantExprs in m_ImmConstant, which also fixes a few other test cases where scalable splats were being missed.
But I'm also hoping that UseConstantIntForScalableSplat will eventually remove the need for this.
I noticed this when trying to reverse a combine on RISC-V in #132245, and saw that the resulting vector and scalar forms were different.