llvm.org GIT mirror llvm / 40bfd6f
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@347318 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjay Patel 9 months ago
4 changed file(s) with 65 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
214214 // Non-splat vector constant: check each element for a match.
215215 unsigned NumElts = V->getType()->getVectorNumElements();
216216 assert(NumElts != 0 && "Constant vector with no elements?");
217 bool HasNonUndefElements = false;
217218 for (unsigned i = 0; i != NumElts; ++i) {
218219 Constant *Elt = C->getAggregateElement(i);
219220 if (!Elt)
223224 auto *CI = dyn_cast(Elt);
224225 if (!CI || !this->isValue(CI->getValue()))
225226 return false;
227 HasNonUndefElements = true;
226228 }
227 return true;
229 return HasNonUndefElements;
228230 }
229231 }
230232 return false;
271273 // Non-splat vector constant: check each element for a match.
272274 unsigned NumElts = V->getType()->getVectorNumElements();
273275 assert(NumElts != 0 && "Constant vector with no elements?");
276 bool HasNonUndefElements = false;
274277 for (unsigned i = 0; i != NumElts; ++i) {
275278 Constant *Elt = C->getAggregateElement(i);
276279 if (!Elt)
280283 auto *CF = dyn_cast(Elt);
281284 if (!CF || !this->isValue(CF->getValueAPF()))
282285 return false;
286 HasNonUndefElements = true;
283287 }
284 return true;
288 return HasNonUndefElements;
285289 }
286290 }
287291 return false;
1515
1616 define <2 x i32> @test_vector(<2 x i32> %a, <2 x i1> %b) {
1717 ; CHECK-LABEL: @test_vector(
18 ; CHECK-NEXT: ret <2 x i32> zeroinitializer
18 ; CHECK-NEXT: ret <2 x i32> undef
1919 ;
2020 %c = sext <2 x i1> %b to <2 x i32>
2121 %d = ashr <2 x i32> undef, %c
33 define void @test1() {
44 ; CHECK-LABEL: @test1(
55 ; CHECK-NEXT: [[T1:%.*]] = tail call <4 x float> @blam()
6 ; CHECK-NEXT: [[T23:%.*]] = fsub fast <4 x float> undef, [[T1]]
7 ; CHECK-NEXT: [[T24:%.*]] = fadd fast <4 x float> [[T23]], undef
6 ; CHECK-NEXT: [[T1_NEG:%.*]] = fsub fast <4 x float> , [[T1]]
7 ; CHECK-NEXT: [[T24:%.*]] = fadd fast <4 x float> [[T1_NEG]], undef
88 ; CHECK-NEXT: tail call void @wombat(<4 x float> [[T24]])
99 ; CHECK-NEXT: ret void
1010 ;
533533 EXPECT_TRUE(A == Val);
534534 }
535535
536 TEST_F(PatternMatchTest, VectorUndefInt) {
537 Type *ScalarTy = IRB.getInt8Ty();
538 Type *VectorTy = VectorType::get(ScalarTy, 4);
539 Constant *ScalarUndef = UndefValue::get(ScalarTy);
540 Constant *VectorUndef = UndefValue::get(VectorTy);
541 Constant *ScalarZero = Constant::getNullValue(ScalarTy);
542 Constant *VectorZero = Constant::getNullValue(VectorTy);
543
544 SmallVector Elems;
545 Elems.push_back(ScalarUndef);
546 Elems.push_back(ScalarZero);
547 Elems.push_back(ScalarUndef);
548 Elems.push_back(ScalarZero);
549 Constant *VectorZeroUndef = ConstantVector::get(Elems);
550
551 EXPECT_TRUE(match(ScalarUndef, m_Undef()));
552 EXPECT_TRUE(match(VectorUndef, m_Undef()));
553 EXPECT_FALSE(match(ScalarZero, m_Undef()));
554 EXPECT_FALSE(match(VectorZero, m_Undef()));
555 EXPECT_FALSE(match(VectorZeroUndef, m_Undef()));
556
557 EXPECT_FALSE(match(ScalarUndef, m_Zero()));
558 EXPECT_FALSE(match(VectorUndef, m_Zero()));
559 EXPECT_TRUE(match(ScalarZero, m_Zero()));
560 EXPECT_TRUE(match(VectorZero, m_Zero()));
561 EXPECT_TRUE(match(VectorZeroUndef, m_Zero()));
562 }
563
564 TEST_F(PatternMatchTest, VectorUndefFloat) {
565 Type *ScalarTy = IRB.getFloatTy();
566 Type *VectorTy = VectorType::get(ScalarTy, 4);
567 Constant *ScalarUndef = UndefValue::get(ScalarTy);
568 Constant *VectorUndef = UndefValue::get(VectorTy);
569 Constant *ScalarZero = Constant::getNullValue(ScalarTy);
570 Constant *VectorZero = Constant::getNullValue(VectorTy);
571
572 SmallVector Elems;
573 Elems.push_back(ScalarUndef);
574 Elems.push_back(ScalarZero);
575 Elems.push_back(ScalarUndef);
576 Elems.push_back(ScalarZero);
577 Constant *VectorZeroUndef = ConstantVector::get(Elems);
578
579 EXPECT_TRUE(match(ScalarUndef, m_Undef()));
580 EXPECT_TRUE(match(VectorUndef, m_Undef()));
581 EXPECT_FALSE(match(ScalarZero, m_Undef()));
582 EXPECT_FALSE(match(VectorZero, m_Undef()));
583 EXPECT_FALSE(match(VectorZeroUndef, m_Undef()));
584
585 EXPECT_FALSE(match(ScalarUndef, m_AnyZeroFP()));
586 EXPECT_FALSE(match(VectorUndef, m_AnyZeroFP()));
587 EXPECT_TRUE(match(ScalarZero, m_AnyZeroFP()));
588 EXPECT_TRUE(match(VectorZero, m_AnyZeroFP()));
589 EXPECT_TRUE(match(VectorZeroUndef, m_AnyZeroFP()));
590 }
591
536592 template struct MutableConstTest : PatternMatchTest { };
537593
538594 typedef ::testing::Types,