[PATCH] D54631: Handle undef vectors consistently in pattern matching

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 16 07:04:15 PST 2018


nikic created this revision.
nikic added a reviewer: spatel.
Herald added a subscriber: llvm-commits.

This patch fixes the issue noticed in https://reviews.llvm.org/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, revert the change from https://reviews.llvm.org/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.


Repository:
  rL LLVM

https://reviews.llvm.org/D54631

Files:
  include/llvm/IR/PatternMatch.h
  test/Transforms/InstSimplify/shr-scalar-vector-consistency.ll
  test/Transforms/Reassociate/fp-expr.ll


Index: test/Transforms/Reassociate/fp-expr.ll
===================================================================
--- test/Transforms/Reassociate/fp-expr.ll
+++ test/Transforms/Reassociate/fp-expr.ll
@@ -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
 ;
Index: test/Transforms/InstSimplify/shr-scalar-vector-consistency.ll
===================================================================
--- /dev/null
+++ test/Transforms/InstSimplify/shr-scalar-vector-consistency.ll
@@ -0,0 +1,24 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -instsimplify -S | FileCheck %s
+
+; This tests checks optimization consistency for scalar and vector code.
+; If m_Zero() is able to match a vector undef, but not a scalar undef,
+; the two cases will simplify differently.
+
+define i32 @test_scalar(i32 %a, i1 %b) {
+; CHECK-LABEL: @test_scalar(
+; CHECK-NEXT:    ret i32 undef
+;
+  %c = sext i1 %b to i32
+  %d = ashr i32 undef, %c
+  ret i32 %d
+}
+
+define <2 x i32> @test_vector(<2 x i32> %a, <2 x i1> %b) {
+; CHECK-LABEL: @test_vector(
+; CHECK-NEXT:    ret <2 x i32> undef
+;
+  %c = sext <2 x i1> %b to <2 x i32>
+  %d = ashr <2 x i32> undef, %c
+  ret <2 x i32> %d
+}
Index: include/llvm/IR/PatternMatch.h
===================================================================
--- include/llvm/IR/PatternMatch.h
+++ include/llvm/IR/PatternMatch.h
@@ -215,6 +215,7 @@
         // 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 @@
           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 @@
         // 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 @@
           auto *CF = dyn_cast<ConstantFP>(Elt);
           if (!CF || !this->isValue(CF->getValueAPF()))
             return false;
+          HasNonUndefElements = true;
         }
-        return true;
+        return HasNonUndefElements;
       }
     }
     return false;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D54631.174369.patch
Type: text/x-patch
Size: 3292 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181116/e0314432/attachment.bin>


More information about the llvm-commits mailing list