[llvm] 78c09f0 - [PatternMatch][InstCombine] match a vector with constant expression element(s) as a constant expression
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 21 12:24:08 PDT 2022
Author: Sanjay Patel
Date: 2022-07-21T15:23:57-04:00
New Revision: 78c09f0f24b6af6d17aeef93c13c54e251e57e8c
URL: https://github.com/llvm/llvm-project/commit/78c09f0f24b6af6d17aeef93c13c54e251e57e8c
DIFF: https://github.com/llvm/llvm-project/commit/78c09f0f24b6af6d17aeef93c13c54e251e57e8c.diff
LOG: [PatternMatch][InstCombine] match a vector with constant expression element(s) as a constant expression
The InstCombine test is reduced from issue #56601. Without the more
liberal match for ConstantExpr, we try to rearrange constants in
Negator forever.
Alternatively, we could adjust the definition of m_ImmConstant to be
more conservative, but that's probably a larger patch, and I don't
see any downside to changing m_ConstantExpr. We never capture and
modify a ConstantExpr; transforms just want to avoid it.
Differential Revision: https://reviews.llvm.org/D130286
Added:
Modified:
llvm/include/llvm/IR/PatternMatch.h
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
llvm/test/Transforms/InstCombine/sub-of-negatible.ll
llvm/unittests/IR/PatternMatch.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 7f0695b552e1..31ff63c8b660 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -153,10 +153,16 @@ inline class_match<ConstantFP> m_ConstantFP() {
return class_match<ConstantFP>();
}
-/// Match an arbitrary ConstantExpr and ignore it.
-inline class_match<ConstantExpr> m_ConstantExpr() {
- return class_match<ConstantExpr>();
-}
+struct constantexpr_match {
+ template <typename ITy> bool match(ITy *V) {
+ auto *C = dyn_cast<Constant>(V);
+ return C && (isa<ConstantExpr>(C) || C->containsConstantExpression());
+ }
+};
+
+/// Match a constant expression or a constant that contains a constant
+/// expression.
+inline constantexpr_match m_ConstantExpr() { return constantexpr_match(); }
/// Match an arbitrary basic block value and ignore it.
inline class_match<BasicBlock> m_BasicBlock() {
@@ -741,14 +747,14 @@ inline bind_ty<const BasicBlock> m_BasicBlock(const BasicBlock *&V) {
/// Match an arbitrary immediate Constant and ignore it.
inline match_combine_and<class_match<Constant>,
- match_unless<class_match<ConstantExpr>>>
+ match_unless<constantexpr_match>>
m_ImmConstant() {
return m_CombineAnd(m_Constant(), m_Unless(m_ConstantExpr()));
}
/// Match an immediate Constant, capturing the value if we match.
inline match_combine_and<bind_ty<Constant>,
- match_unless<class_match<ConstantExpr>>>
+ match_unless<constantexpr_match>>
m_ImmConstant(Constant *&C) {
return m_CombineAnd(m_Constant(C), m_Unless(m_ConstantExpr()));
}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 33ee905e149c..bc01d2ef7fe2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1539,8 +1539,7 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
Type *Ty = II->getType();
unsigned BitWidth = Ty->getScalarSizeInBits();
Constant *ShAmtC;
- if (match(II->getArgOperand(2), m_ImmConstant(ShAmtC)) &&
- !ShAmtC->containsConstantExpression()) {
+ if (match(II->getArgOperand(2), m_ImmConstant(ShAmtC))) {
// Canonicalize a shift amount constant operand to modulo the bit-width.
Constant *WidthC = ConstantInt::get(Ty, BitWidth);
Constant *ModuloC =
diff --git a/llvm/test/Transforms/InstCombine/sub-of-negatible.ll b/llvm/test/Transforms/InstCombine/sub-of-negatible.ll
index 4971f80af13e..066007ab4af4 100644
--- a/llvm/test/Transforms/InstCombine/sub-of-negatible.ll
+++ b/llvm/test/Transforms/InstCombine/sub-of-negatible.ll
@@ -1426,5 +1426,28 @@ if.end:
br label %if.end
}
+; This would infinite loop because we failed to match a
+; vector constant with constant expression elements as
+; a constant expression.
+
+ at g = external hidden global [1 x [1 x double]]
+
+define <1 x i64> @PR56601(<1 x i64> %x, <1 x i64> %y) {
+; CHECK-LABEL: @PR56601(
+; CHECK-NEXT: [[M1:%.*]] = mul nsw <1 x i64> [[X:%.*]], <i64 42>
+; CHECK-NEXT: [[M2:%.*]] = mul nsw <1 x i64> [[Y:%.*]], <i64 12>
+; CHECK-NEXT: [[A1:%.*]] = add <1 x i64> [[M1]], <i64 add (i64 ptrtoint (ptr @g to i64), i64 -4)>
+; CHECK-NEXT: [[A2:%.*]] = add <1 x i64> [[M2]], <i64 add (i64 ptrtoint (ptr @g to i64), i64 -3)>
+; CHECK-NEXT: [[R:%.*]] = sub <1 x i64> [[A1]], [[A2]]
+; CHECK-NEXT: ret <1 x i64> [[R]]
+;
+ %m1 = mul nsw <1 x i64> %x, <i64 42>
+ %m2 = mul nsw <1 x i64> %y, <i64 12>
+ %a1 = add <1 x i64> %m1, <i64 add (i64 ptrtoint (ptr @g to i64), i64 -4)>
+ %a2 = add <1 x i64> %m2, <i64 add (i64 ptrtoint (ptr @g to i64), i64 -3)>
+ %r = sub <1 x i64> %a1, %a2
+ ret <1 x i64> %r
+}
+
; CHECK: !0 = !{!"branch_weights", i32 40, i32 1}
!0 = !{!"branch_weights", i32 40, i32 1}
diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp
index 9314e6799b8f..05456ee698c8 100644
--- a/llvm/unittests/IR/PatternMatch.cpp
+++ b/llvm/unittests/IR/PatternMatch.cpp
@@ -1798,8 +1798,10 @@ TEST_F(PatternMatchTest, ConstExpr) {
PoisonValue *P = PoisonValue::get(VecTy);
Constant *V = ConstantExpr::getInsertElement(P, S, IRB.getInt32(0));
+ // The match succeeds on a constant that is a constant expression itself
+ // or a constant that contains a constant expression.
EXPECT_TRUE(match(S, m_ConstantExpr()));
- EXPECT_FALSE(match(V, m_ConstantExpr()));
+ EXPECT_TRUE(match(V, m_ConstantExpr()));
}
} // anonymous namespace.
More information about the llvm-commits
mailing list