[llvm] [InstCombine] Fix behavior for `(fmul (sitfp x), 0)` (PR #85298)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 14 13:23:44 PDT 2024
https://github.com/goldsteinn updated https://github.com/llvm/llvm-project/pull/85298
>From 6451085ebe828e40d725c3883426c8247524c59d Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Thu, 14 Mar 2024 14:22:47 -0500
Subject: [PATCH 1/2] [InstCombine] Add test for `(fmul (sitfp x), 0)`; NFC
---
.../Transforms/InstCombine/binop-itofp.ll | 112 ++++++++++++++++++
1 file changed, 112 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/binop-itofp.ll b/llvm/test/Transforms/InstCombine/binop-itofp.ll
index f796273c84e082..b2945180a5bec8 100644
--- a/llvm/test/Transforms/InstCombine/binop-itofp.ll
+++ b/llvm/test/Transforms/InstCombine/binop-itofp.ll
@@ -1004,3 +1004,115 @@ define float @test_ui_add_with_signed_constant(i32 %shr.i) {
%add = fadd float %sub, -16383.0
ret float %add
}
+
+
+;; Reduced form of bug noticed due to #82555
+define float @missed_nonzero_check_on_constant_for_si_fmul(i1 %c, i1 %.b, ptr %g_2345) {
+; CHECK-LABEL: @missed_nonzero_check_on_constant_for_si_fmul(
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i32 65529, i32 53264
+; CHECK-NEXT: store i32 [[SEL]], ptr [[G_2345:%.*]], align 4
+; CHECK-NEXT: ret float 0.000000e+00
+;
+ %sel = select i1 %c, i32 65529, i32 53264
+ %conv.i = trunc i32 %sel to i16
+ %conv1.i = sitofp i16 %conv.i to float
+ %mul3.i.i = fmul float %conv1.i, 0.000000e+00
+ store i32 %sel, ptr %g_2345, align 4
+ ret float %mul3.i.i
+}
+
+define <2 x float> @missed_nonzero_check_on_constant_for_si_fmul_vec(i1 %c, i1 %.b, ptr %g_2345) {
+; CHECK-LABEL: @missed_nonzero_check_on_constant_for_si_fmul_vec(
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i32 65529, i32 53264
+; CHECK-NEXT: store i32 [[SEL]], ptr [[G_2345:%.*]], align 4
+; CHECK-NEXT: ret <2 x float> zeroinitializer
+;
+ %sel = select i1 %c, i32 65529, i32 53264
+ %conv.i.s = trunc i32 %sel to i16
+ %conv.i.v = insertelement <2 x i16> poison, i16 %conv.i.s, i64 0
+ %conv.i = insertelement <2 x i16> %conv.i.v, i16 %conv.i.s, i64 1
+ %conv1.i = sitofp <2 x i16> %conv.i to <2 x float>
+ %mul3.i.i = fmul <2 x float> %conv1.i, zeroinitializer
+ store i32 %sel, ptr %g_2345, align 4
+ ret <2 x float> %mul3.i.i
+}
+
+define float @negzero_check_on_constant_for_si_fmul(i1 %c, i1 %.b, ptr %g_2345) {
+; CHECK-LABEL: @negzero_check_on_constant_for_si_fmul(
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i32 65529, i32 53264
+; CHECK-NEXT: [[CONV_I:%.*]] = trunc i32 [[SEL]] to i16
+; CHECK-NEXT: [[CONV1_I:%.*]] = sitofp i16 [[CONV_I]] to float
+; CHECK-NEXT: [[MUL3_I_I:%.*]] = fmul float [[CONV1_I]], -0.000000e+00
+; CHECK-NEXT: store i32 [[SEL]], ptr [[G_2345:%.*]], align 4
+; CHECK-NEXT: ret float [[MUL3_I_I]]
+;
+ %sel = select i1 %c, i32 65529, i32 53264
+ %conv.i = trunc i32 %sel to i16
+ %conv1.i = sitofp i16 %conv.i to float
+ %mul3.i.i = fmul float %conv1.i, -0.000000e+00
+ store i32 %sel, ptr %g_2345, align 4
+ ret float %mul3.i.i
+}
+
+define <2 x float> @nonzero_check_on_constant_for_si_fmul_vec_w_undef(i1 %c, i1 %.b, ptr %g_2345) {
+; CHECK-LABEL: @nonzero_check_on_constant_for_si_fmul_vec_w_undef(
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i32 65529, i32 53264
+; CHECK-NEXT: [[CONV_I_S:%.*]] = trunc i32 [[SEL]] to i16
+; CHECK-NEXT: [[CONV_I_V:%.*]] = insertelement <2 x i16> poison, i16 [[CONV_I_S]], i64 0
+; CHECK-NEXT: [[CONV_I:%.*]] = shufflevector <2 x i16> [[CONV_I_V]], <2 x i16> poison, <2 x i32> zeroinitializer
+; CHECK-NEXT: [[CONV1_I:%.*]] = sitofp <2 x i16> [[CONV_I]] to <2 x float>
+; CHECK-NEXT: [[MUL3_I_I:%.*]] = fmul <2 x float> [[CONV1_I]], <float undef, float 0.000000e+00>
+; CHECK-NEXT: store i32 [[SEL]], ptr [[G_2345:%.*]], align 4
+; CHECK-NEXT: ret <2 x float> [[MUL3_I_I]]
+;
+ %sel = select i1 %c, i32 65529, i32 53264
+ %conv.i.s = trunc i32 %sel to i16
+ %conv.i.v = insertelement <2 x i16> poison, i16 %conv.i.s, i64 0
+ %conv.i = insertelement <2 x i16> %conv.i.v, i16 %conv.i.s, i64 1
+ %conv1.i = sitofp <2 x i16> %conv.i to <2 x float>
+ %mul3.i.i = fmul <2 x float> %conv1.i, <float undef, float 0.000000e+00>
+ store i32 %sel, ptr %g_2345, align 4
+ ret <2 x float> %mul3.i.i
+}
+
+define <2 x float> @nonzero_check_on_constant_for_si_fmul_nz_vec_w_undef(i1 %c, i1 %.b, ptr %g_2345) {
+; CHECK-LABEL: @nonzero_check_on_constant_for_si_fmul_nz_vec_w_undef(
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i32 65529, i32 53264
+; CHECK-NEXT: [[CONV_I_S:%.*]] = trunc i32 [[SEL]] to i16
+; CHECK-NEXT: [[CONV_I_V:%.*]] = insertelement <2 x i16> poison, i16 [[CONV_I_S]], i64 0
+; CHECK-NEXT: [[CONV_I:%.*]] = shufflevector <2 x i16> [[CONV_I_V]], <2 x i16> poison, <2 x i32> zeroinitializer
+; CHECK-NEXT: [[CONV1_I:%.*]] = sitofp <2 x i16> [[CONV_I]] to <2 x float>
+; CHECK-NEXT: [[MUL3_I_I:%.*]] = fmul <2 x float> [[CONV1_I]], <float undef, float 1.000000e+00>
+; CHECK-NEXT: store i32 [[SEL]], ptr [[G_2345:%.*]], align 4
+; CHECK-NEXT: ret <2 x float> [[MUL3_I_I]]
+;
+ %sel = select i1 %c, i32 65529, i32 53264
+ %conv.i.s = trunc i32 %sel to i16
+ %conv.i.v = insertelement <2 x i16> poison, i16 %conv.i.s, i64 0
+ %conv.i = insertelement <2 x i16> %conv.i.v, i16 %conv.i.s, i64 1
+ %conv1.i = sitofp <2 x i16> %conv.i to <2 x float>
+ %mul3.i.i = fmul <2 x float> %conv1.i, <float undef, float 1.000000e+00>
+ store i32 %sel, ptr %g_2345, align 4
+ ret <2 x float> %mul3.i.i
+}
+
+define <2 x float> @nonzero_check_on_constant_for_si_fmul_negz_vec_w_undef(i1 %c, i1 %.b, ptr %g_2345) {
+; CHECK-LABEL: @nonzero_check_on_constant_for_si_fmul_negz_vec_w_undef(
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i32 65529, i32 53264
+; CHECK-NEXT: [[CONV_I_S:%.*]] = trunc i32 [[SEL]] to i16
+; CHECK-NEXT: [[CONV_I_V:%.*]] = insertelement <2 x i16> poison, i16 [[CONV_I_S]], i64 0
+; CHECK-NEXT: [[CONV_I:%.*]] = shufflevector <2 x i16> [[CONV_I_V]], <2 x i16> poison, <2 x i32> zeroinitializer
+; CHECK-NEXT: [[CONV1_I:%.*]] = sitofp <2 x i16> [[CONV_I]] to <2 x float>
+; CHECK-NEXT: [[MUL3_I_I:%.*]] = fmul <2 x float> [[CONV1_I]], <float undef, float -0.000000e+00>
+; CHECK-NEXT: store i32 [[SEL]], ptr [[G_2345:%.*]], align 4
+; CHECK-NEXT: ret <2 x float> [[MUL3_I_I]]
+;
+ %sel = select i1 %c, i32 65529, i32 53264
+ %conv.i.s = trunc i32 %sel to i16
+ %conv.i.v = insertelement <2 x i16> poison, i16 %conv.i.s, i64 0
+ %conv.i = insertelement <2 x i16> %conv.i.v, i16 %conv.i.s, i64 1
+ %conv1.i = sitofp <2 x i16> %conv.i to <2 x float>
+ %mul3.i.i = fmul <2 x float> %conv1.i, <float undef, float -0.000000e+00>
+ store i32 %sel, ptr %g_2345, align 4
+ ret <2 x float> %mul3.i.i
+}
>From bf7aef8fc49b9c9b48713b6184edde472899d5e0 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Thu, 14 Mar 2024 14:22:50 -0500
Subject: [PATCH 2/2] [InstCombine] Fix behavior for `(fmul (sitfp x), 0)`
Bug was introduced in #82555
We where missing check that the constant was non-zero for signed + mul
transform.
---
llvm/include/llvm/IR/PatternMatch.h | 50 ++++++++--
.../InstCombine/InstructionCombining.cpp | 5 +
.../Transforms/InstCombine/binop-itofp.ll | 12 ++-
llvm/unittests/IR/PatternMatch.cpp | 96 +++++++++++++++++++
4 files changed, 151 insertions(+), 12 deletions(-)
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 487ae170210de9..9c76acd0f8131c 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -330,14 +330,15 @@ template <int64_t Val> inline constantint_match<Val> m_ConstantInt() {
/// This helper class is used to match constant scalars, vector splats,
/// and fixed width vectors that satisfy a specified predicate.
/// For fixed width vector constants, undefined elements are ignored.
-template <typename Predicate, typename ConstantVal>
+template <typename Predicate, typename ConstantVal, bool AllowUndef>
struct cstval_pred_ty : public Predicate {
template <typename ITy> bool match(ITy *V) {
if (const auto *CV = dyn_cast<ConstantVal>(V))
return this->isValue(CV->getValue());
if (const auto *VTy = dyn_cast<VectorType>(V->getType())) {
if (const auto *C = dyn_cast<Constant>(V)) {
- if (const auto *CV = dyn_cast_or_null<ConstantVal>(C->getSplatValue()))
+ if (const auto *CV =
+ dyn_cast_or_null<ConstantVal>(C->getSplatValue(AllowUndef)))
return this->isValue(CV->getValue());
// Number of elements of a scalable vector unknown at compile time
@@ -353,8 +354,11 @@ struct cstval_pred_ty : public Predicate {
Constant *Elt = C->getAggregateElement(i);
if (!Elt)
return false;
- if (isa<UndefValue>(Elt))
+ if (isa<UndefValue>(Elt)) {
+ if (!AllowUndef)
+ return false;
continue;
+ }
auto *CV = dyn_cast<ConstantVal>(Elt);
if (!CV || !this->isValue(CV->getValue()))
return false;
@@ -368,19 +372,20 @@ struct cstval_pred_ty : public Predicate {
};
/// specialization of cstval_pred_ty for ConstantInt
-template <typename Predicate>
-using cst_pred_ty = cstval_pred_ty<Predicate, ConstantInt>;
+template <typename Predicate, bool AllowUndef = true>
+using cst_pred_ty = cstval_pred_ty<Predicate, ConstantInt, AllowUndef>;
/// specialization of cstval_pred_ty for ConstantFP
-template <typename Predicate>
-using cstfp_pred_ty = cstval_pred_ty<Predicate, ConstantFP>;
+template <typename Predicate, bool AllowUndef = true>
+using cstfp_pred_ty = cstval_pred_ty<Predicate, ConstantFP, AllowUndef>;
/// This helper class is used to match scalar and vector constants that
/// satisfy a specified predicate, and bind them to an APInt.
template <typename Predicate> struct api_pred_ty : public Predicate {
const APInt *&Res;
-
- api_pred_ty(const APInt *&R) : Res(R) {}
+ bool AllowUndef;
+ api_pred_ty(const APInt *&R, bool AllowUndef = true)
+ : Res(R), AllowUndef(AllowUndef) {}
template <typename ITy> bool match(ITy *V) {
if (const auto *CI = dyn_cast<ConstantInt>(V))
@@ -390,7 +395,8 @@ template <typename Predicate> struct api_pred_ty : public Predicate {
}
if (V->getType()->isVectorTy())
if (const auto *C = dyn_cast<Constant>(V))
- if (auto *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue()))
+ if (auto *CI =
+ dyn_cast_or_null<ConstantInt>(C->getSplatValue(AllowUndef)))
if (this->isValue(CI->getValue())) {
Res = &CI->getValue();
return true;
@@ -544,6 +550,30 @@ struct is_zero {
/// For vectors, this includes constants with undefined elements.
inline is_zero m_Zero() { return is_zero(); }
+struct is_non_zero {
+ bool isValue(const APInt &C) { return !C.isZero(); }
+};
+
+/// Match any constant s.t all elements are non-zero. For a scalar, this is the
+/// same as !m_Zero. For vectors is ensures that !m_Zero holds for all elements.
+/// This does not include undefined elements.
+inline cst_pred_ty<is_non_zero, false> m_NonZero() {
+ return cst_pred_ty<is_non_zero, /*AllowUndef=*/false>();
+}
+inline api_pred_ty<is_non_zero> m_NonZero(const APInt *&V) {
+ return api_pred_ty<is_non_zero>(V, /*AllowUndef=*/false);
+}
+
+/// Match any constant s.t all elements are non-zero. For a scalar, this is the
+/// same as !m_Zero. For vectors is ensures that !m_Zero holds for all elements.
+/// This includes undefined elements.
+inline cst_pred_ty<is_non_zero> m_NonZeroAllowUndef() {
+ return cst_pred_ty<is_non_zero>();
+}
+inline api_pred_ty<is_non_zero> m_NonZeroAllowUndef(const APInt *&V) {
+ return V;
+}
+
struct is_power2 {
bool isValue(const APInt &C) { return C.isPowerOf2(); }
};
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 90a18fcc125c45..13d01f83d12630 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1491,6 +1491,11 @@ Instruction *InstCombinerImpl::foldFBinOpOfIntCastsFromSign(
Op1IntC, FPTy, DL) != Op1FpC)
return nullptr;
+ // Signed + Mul req non-zero
+ if (OpsFromSigned && BO.getOpcode() == Instruction::FMul &&
+ !match(Op1IntC, m_NonZero()))
+ return nullptr;
+
// First try to keep sign of cast the same.
IntOps[1] = Op1IntC;
}
diff --git a/llvm/test/Transforms/InstCombine/binop-itofp.ll b/llvm/test/Transforms/InstCombine/binop-itofp.ll
index b2945180a5bec8..c72e4ac413a3ed 100644
--- a/llvm/test/Transforms/InstCombine/binop-itofp.ll
+++ b/llvm/test/Transforms/InstCombine/binop-itofp.ll
@@ -1010,8 +1010,11 @@ define float @test_ui_add_with_signed_constant(i32 %shr.i) {
define float @missed_nonzero_check_on_constant_for_si_fmul(i1 %c, i1 %.b, ptr %g_2345) {
; CHECK-LABEL: @missed_nonzero_check_on_constant_for_si_fmul(
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i32 65529, i32 53264
+; CHECK-NEXT: [[CONV_I:%.*]] = trunc i32 [[SEL]] to i16
+; CHECK-NEXT: [[CONV1_I:%.*]] = sitofp i16 [[CONV_I]] to float
+; CHECK-NEXT: [[MUL3_I_I:%.*]] = fmul float [[CONV1_I]], 0.000000e+00
; CHECK-NEXT: store i32 [[SEL]], ptr [[G_2345:%.*]], align 4
-; CHECK-NEXT: ret float 0.000000e+00
+; CHECK-NEXT: ret float [[MUL3_I_I]]
;
%sel = select i1 %c, i32 65529, i32 53264
%conv.i = trunc i32 %sel to i16
@@ -1024,8 +1027,13 @@ define float @missed_nonzero_check_on_constant_for_si_fmul(i1 %c, i1 %.b, ptr %g
define <2 x float> @missed_nonzero_check_on_constant_for_si_fmul_vec(i1 %c, i1 %.b, ptr %g_2345) {
; CHECK-LABEL: @missed_nonzero_check_on_constant_for_si_fmul_vec(
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i32 65529, i32 53264
+; CHECK-NEXT: [[CONV_I_S:%.*]] = trunc i32 [[SEL]] to i16
+; CHECK-NEXT: [[CONV_I_V:%.*]] = insertelement <2 x i16> poison, i16 [[CONV_I_S]], i64 0
+; CHECK-NEXT: [[CONV_I:%.*]] = shufflevector <2 x i16> [[CONV_I_V]], <2 x i16> poison, <2 x i32> zeroinitializer
+; CHECK-NEXT: [[CONV1_I:%.*]] = sitofp <2 x i16> [[CONV_I]] to <2 x float>
+; CHECK-NEXT: [[MUL3_I_I:%.*]] = fmul <2 x float> [[CONV1_I]], zeroinitializer
; CHECK-NEXT: store i32 [[SEL]], ptr [[G_2345:%.*]], align 4
-; CHECK-NEXT: ret <2 x float> zeroinitializer
+; CHECK-NEXT: ret <2 x float> [[MUL3_I_I]]
;
%sel = select i1 %c, i32 65529, i32 53264
%conv.i.s = trunc i32 %sel to i16
diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp
index 533a30bfba45dd..4e3be07549c78f 100644
--- a/llvm/unittests/IR/PatternMatch.cpp
+++ b/llvm/unittests/IR/PatternMatch.cpp
@@ -614,6 +614,102 @@ TEST_F(PatternMatchTest, Power2) {
EXPECT_TRUE(m_NegatedPower2OrZero().match(CZero));
}
+TEST_F(PatternMatchTest, NonZero) {
+ Type *I8Ty = IRB.getInt8Ty();
+
+ EXPECT_FALSE(m_NonZero().match(ConstantInt::get(I8Ty, 0)));
+ EXPECT_TRUE(m_NonZero().match(ConstantInt::get(I8Ty, 1)));
+ EXPECT_FALSE(m_NonZeroAllowUndef().match(ConstantInt::get(I8Ty, 0)));
+ EXPECT_TRUE(m_NonZeroAllowUndef().match(ConstantInt::get(I8Ty, 1)));
+
+ EXPECT_FALSE(m_NonZero().match(UndefValue::get(I8Ty)));
+ EXPECT_FALSE(m_NonZero().match(PoisonValue::get(I8Ty)));
+ EXPECT_FALSE(m_NonZeroAllowUndef().match(UndefValue::get(I8Ty)));
+ EXPECT_FALSE(m_NonZeroAllowUndef().match(PoisonValue::get(I8Ty)));
+
+ {
+ SmallVector<Constant *, 2> VecElemIdxs;
+ VecElemIdxs.push_back(ConstantInt::get(I8Ty, 0));
+ VecElemIdxs.push_back(ConstantInt::get(I8Ty, 1));
+ EXPECT_FALSE(m_NonZero().match(ConstantVector::get(VecElemIdxs)));
+ EXPECT_FALSE(m_NonZeroAllowUndef().match(ConstantVector::get(VecElemIdxs)));
+ }
+
+ {
+ SmallVector<Constant *, 2> VecElemIdxs;
+ VecElemIdxs.push_back(ConstantInt::get(I8Ty, 0));
+ VecElemIdxs.push_back(ConstantInt::get(I8Ty, 0));
+ EXPECT_FALSE(m_NonZero().match(ConstantVector::get(VecElemIdxs)));
+ EXPECT_FALSE(m_NonZeroAllowUndef().match(ConstantVector::get(VecElemIdxs)));
+ }
+
+ {
+ SmallVector<Constant *, 2> VecElemIdxs;
+ VecElemIdxs.push_back(ConstantInt::get(I8Ty, 1));
+ VecElemIdxs.push_back(ConstantInt::get(I8Ty, 2));
+ EXPECT_TRUE(m_NonZero().match(ConstantVector::get(VecElemIdxs)));
+ EXPECT_TRUE(m_NonZeroAllowUndef().match(ConstantVector::get(VecElemIdxs)));
+ }
+
+ {
+ SmallVector<Constant *, 2> VecElemIdxs;
+ VecElemIdxs.push_back(UndefValue::get(I8Ty));
+ VecElemIdxs.push_back(ConstantInt::get(I8Ty, 2));
+ EXPECT_FALSE(m_NonZero().match(ConstantVector::get(VecElemIdxs)));
+ EXPECT_TRUE(m_NonZeroAllowUndef().match(ConstantVector::get(VecElemIdxs)));
+ }
+
+ {
+ SmallVector<Constant *, 3> VecElemIdxs;
+ VecElemIdxs.push_back(UndefValue::get(I8Ty));
+ VecElemIdxs.push_back(ConstantInt::get(I8Ty, 2));
+ VecElemIdxs.push_back(ConstantInt::get(I8Ty, 3));
+ EXPECT_FALSE(m_NonZero().match(ConstantVector::get(VecElemIdxs)));
+ EXPECT_TRUE(m_NonZeroAllowUndef().match(ConstantVector::get(VecElemIdxs)));
+ }
+
+ {
+ SmallVector<Constant *, 2> VecElemIdxs;
+ VecElemIdxs.push_back(PoisonValue::get(I8Ty));
+ VecElemIdxs.push_back(ConstantInt::get(I8Ty, 2));
+ EXPECT_FALSE(m_NonZero().match(ConstantVector::get(VecElemIdxs)));
+ EXPECT_TRUE(m_NonZeroAllowUndef().match(ConstantVector::get(VecElemIdxs)));
+ }
+
+ {
+ SmallVector<Constant *, 3> VecElemIdxs;
+ VecElemIdxs.push_back(PoisonValue::get(I8Ty));
+ VecElemIdxs.push_back(ConstantInt::get(I8Ty, 2));
+ VecElemIdxs.push_back(ConstantInt::get(I8Ty, 3));
+ EXPECT_FALSE(m_NonZero().match(ConstantVector::get(VecElemIdxs)));
+ EXPECT_TRUE(m_NonZeroAllowUndef().match(ConstantVector::get(VecElemIdxs)));
+ }
+
+ {
+ SmallVector<Constant *, 2> VecElemIdxs;
+ VecElemIdxs.push_back(UndefValue::get(I8Ty));
+ VecElemIdxs.push_back(ConstantInt::get(I8Ty, 0));
+ EXPECT_FALSE(m_NonZero().match(ConstantVector::get(VecElemIdxs)));
+ EXPECT_FALSE(m_NonZeroAllowUndef().match(ConstantVector::get(VecElemIdxs)));
+ }
+
+ {
+ SmallVector<Constant *, 2> VecElemIdxs;
+ VecElemIdxs.push_back(PoisonValue::get(I8Ty));
+ VecElemIdxs.push_back(ConstantInt::get(I8Ty, 0));
+ EXPECT_FALSE(m_NonZero().match(ConstantVector::get(VecElemIdxs)));
+ EXPECT_FALSE(m_NonZeroAllowUndef().match(ConstantVector::get(VecElemIdxs)));
+ }
+
+ {
+ SmallVector<Constant *, 2> VecElemIdxs;
+ VecElemIdxs.push_back(PoisonValue::get(I8Ty));
+ VecElemIdxs.push_back(UndefValue::get(I8Ty));
+ EXPECT_FALSE(m_NonZero().match(ConstantVector::get(VecElemIdxs)));
+ EXPECT_FALSE(m_NonZeroAllowUndef().match(ConstantVector::get(VecElemIdxs)));
+ }
+}
+
TEST_F(PatternMatchTest, Not) {
Value *C1 = IRB.getInt32(1);
Value *C2 = IRB.getInt32(2);
More information about the llvm-commits
mailing list