[llvm] r347318 - [PatternMatch] Handle undef vectors consistently
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 20 08:08:19 PST 2018
Author: spatel
Date: Tue Nov 20 08:08:19 2018
New Revision: 347318
URL: http://llvm.org/viewvc/llvm-project?rev=347318&view=rev
Log:
[PatternMatch] Handle undef vectors consistently
This patch fixes the issue noticed in D54532.
The problem is that cst_pred_ty-based matchers like m_Zero() currently do not match
scalar undefs (as expected), but *do* match vector undefs. This may lead to optimization
inconsistencies in rare cases.
There is only one existing test for which output changes, reverting the change from D53205.
The reason here is that vector fsub undef, %x is no longer matched as an m_FNeg(). While I
think that the new output is technically worse than the previous one, it is consistent with
scalar, and I don't think it's really important either way (generally that undef should have
been folded away prior to reassociation.)
I've also added another test case for this issue based on InstructionSimplify. It took some
effort to find that one, as in most cases undef folds are either checked first -- and in the
cases where they aren't it usually happens to not make a difference in the end. This is the
only case I was able to come up with. Prior to this patch the test case simplified to undef
in the scalar case, but zeroinitializer in the vector case.
Patch by: @nikic (Nikita Popov)
Differential Revision: https://reviews.llvm.org/D54631
Modified:
llvm/trunk/include/llvm/IR/PatternMatch.h
llvm/trunk/test/Transforms/InstSimplify/shr-scalar-vector-consistency.ll
llvm/trunk/test/Transforms/Reassociate/fp-expr.ll
llvm/trunk/unittests/IR/PatternMatch.cpp
Modified: llvm/trunk/include/llvm/IR/PatternMatch.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PatternMatch.h?rev=347318&r1=347317&r2=347318&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/PatternMatch.h (original)
+++ llvm/trunk/include/llvm/IR/PatternMatch.h Tue Nov 20 08:08:19 2018
@@ -215,6 +215,7 @@ template <typename Predicate> struct cst
// Non-splat vector constant: check each element for a match.
unsigned NumElts = V->getType()->getVectorNumElements();
assert(NumElts != 0 && "Constant vector with no elements?");
+ bool HasNonUndefElements = false;
for (unsigned i = 0; i != NumElts; ++i) {
Constant *Elt = C->getAggregateElement(i);
if (!Elt)
@@ -224,8 +225,9 @@ template <typename Predicate> struct cst
auto *CI = dyn_cast<ConstantInt>(Elt);
if (!CI || !this->isValue(CI->getValue()))
return false;
+ HasNonUndefElements = true;
}
- return true;
+ return HasNonUndefElements;
}
}
return false;
@@ -272,6 +274,7 @@ template <typename Predicate> struct cst
// Non-splat vector constant: check each element for a match.
unsigned NumElts = V->getType()->getVectorNumElements();
assert(NumElts != 0 && "Constant vector with no elements?");
+ bool HasNonUndefElements = false;
for (unsigned i = 0; i != NumElts; ++i) {
Constant *Elt = C->getAggregateElement(i);
if (!Elt)
@@ -281,8 +284,9 @@ template <typename Predicate> struct cst
auto *CF = dyn_cast<ConstantFP>(Elt);
if (!CF || !this->isValue(CF->getValueAPF()))
return false;
+ HasNonUndefElements = true;
}
- return true;
+ return HasNonUndefElements;
}
}
return false;
Modified: llvm/trunk/test/Transforms/InstSimplify/shr-scalar-vector-consistency.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/shr-scalar-vector-consistency.ll?rev=347318&r1=347317&r2=347318&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/shr-scalar-vector-consistency.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/shr-scalar-vector-consistency.ll Tue Nov 20 08:08:19 2018
@@ -16,7 +16,7 @@ define i32 @test_scalar(i32 %a, i1 %b) {
define <2 x i32> @test_vector(<2 x i32> %a, <2 x i1> %b) {
; CHECK-LABEL: @test_vector(
-; CHECK-NEXT: ret <2 x i32> zeroinitializer
+; CHECK-NEXT: ret <2 x i32> undef
;
%c = sext <2 x i1> %b to <2 x i32>
%d = ashr <2 x i32> undef, %c
Modified: llvm/trunk/test/Transforms/Reassociate/fp-expr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Reassociate/fp-expr.ll?rev=347318&r1=347317&r2=347318&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/Reassociate/fp-expr.ll (original)
+++ llvm/trunk/test/Transforms/Reassociate/fp-expr.ll Tue Nov 20 08:08:19 2018
@@ -4,8 +4,8 @@
define void @test1() {
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[T1:%.*]] = tail call <4 x float> @blam()
-; CHECK-NEXT: [[T23:%.*]] = fsub fast <4 x float> undef, [[T1]]
-; CHECK-NEXT: [[T24:%.*]] = fadd fast <4 x float> [[T23]], undef
+; CHECK-NEXT: [[T1_NEG:%.*]] = fsub fast <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, [[T1]]
+; CHECK-NEXT: [[T24:%.*]] = fadd fast <4 x float> [[T1_NEG]], undef
; CHECK-NEXT: tail call void @wombat(<4 x float> [[T24]])
; CHECK-NEXT: ret void
;
Modified: llvm/trunk/unittests/IR/PatternMatch.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/PatternMatch.cpp?rev=347318&r1=347317&r2=347318&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/PatternMatch.cpp (original)
+++ llvm/trunk/unittests/IR/PatternMatch.cpp Tue Nov 20 08:08:19 2018
@@ -534,6 +534,62 @@ TEST_F(PatternMatchTest, VectorOps) {
EXPECT_TRUE(A == Val);
}
+TEST_F(PatternMatchTest, VectorUndefInt) {
+ Type *ScalarTy = IRB.getInt8Ty();
+ Type *VectorTy = VectorType::get(ScalarTy, 4);
+ Constant *ScalarUndef = UndefValue::get(ScalarTy);
+ Constant *VectorUndef = UndefValue::get(VectorTy);
+ Constant *ScalarZero = Constant::getNullValue(ScalarTy);
+ Constant *VectorZero = Constant::getNullValue(VectorTy);
+
+ SmallVector<Constant *, 4> Elems;
+ Elems.push_back(ScalarUndef);
+ Elems.push_back(ScalarZero);
+ Elems.push_back(ScalarUndef);
+ Elems.push_back(ScalarZero);
+ Constant *VectorZeroUndef = ConstantVector::get(Elems);
+
+ EXPECT_TRUE(match(ScalarUndef, m_Undef()));
+ EXPECT_TRUE(match(VectorUndef, m_Undef()));
+ EXPECT_FALSE(match(ScalarZero, m_Undef()));
+ EXPECT_FALSE(match(VectorZero, m_Undef()));
+ EXPECT_FALSE(match(VectorZeroUndef, m_Undef()));
+
+ EXPECT_FALSE(match(ScalarUndef, m_Zero()));
+ EXPECT_FALSE(match(VectorUndef, m_Zero()));
+ EXPECT_TRUE(match(ScalarZero, m_Zero()));
+ EXPECT_TRUE(match(VectorZero, m_Zero()));
+ EXPECT_TRUE(match(VectorZeroUndef, m_Zero()));
+}
+
+TEST_F(PatternMatchTest, VectorUndefFloat) {
+ Type *ScalarTy = IRB.getFloatTy();
+ Type *VectorTy = VectorType::get(ScalarTy, 4);
+ Constant *ScalarUndef = UndefValue::get(ScalarTy);
+ Constant *VectorUndef = UndefValue::get(VectorTy);
+ Constant *ScalarZero = Constant::getNullValue(ScalarTy);
+ Constant *VectorZero = Constant::getNullValue(VectorTy);
+
+ SmallVector<Constant *, 4> Elems;
+ Elems.push_back(ScalarUndef);
+ Elems.push_back(ScalarZero);
+ Elems.push_back(ScalarUndef);
+ Elems.push_back(ScalarZero);
+ Constant *VectorZeroUndef = ConstantVector::get(Elems);
+
+ EXPECT_TRUE(match(ScalarUndef, m_Undef()));
+ EXPECT_TRUE(match(VectorUndef, m_Undef()));
+ EXPECT_FALSE(match(ScalarZero, m_Undef()));
+ EXPECT_FALSE(match(VectorZero, m_Undef()));
+ EXPECT_FALSE(match(VectorZeroUndef, m_Undef()));
+
+ EXPECT_FALSE(match(ScalarUndef, m_AnyZeroFP()));
+ EXPECT_FALSE(match(VectorUndef, m_AnyZeroFP()));
+ EXPECT_TRUE(match(ScalarZero, m_AnyZeroFP()));
+ EXPECT_TRUE(match(VectorZero, m_AnyZeroFP()));
+ EXPECT_TRUE(match(VectorZeroUndef, m_AnyZeroFP()));
+}
+
template <typename T> struct MutableConstTest : PatternMatchTest { };
typedef ::testing::Types<std::tuple<Value*, Instruction*>,
More information about the llvm-commits
mailing list