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() {
/// 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()));
}
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 =
br label %if.end
}
+; This would infinite loop because we failed to match a
+; vector constant with constant expression elements as
+; a constant expression.
+
+@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}
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.