[PATCH] D29900: [SLP] Fix for PR31879: vectorize repeated scalar ops that don't get put back into a vector

Alexey Bataev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 13 11:48:38 PST 2017


ABataev created this revision.

Previously the cost of the existing ExtractElement/ExtractValue instructions was considered as a dead cost only if it was detected that they have only one use. But these instructions may be considered dead also if they are used several times in the same instruction, like:

  %x0 = extractelement <2 x float> %x, i32 0
  %x0x0 = fmul float %x0, %x0

Currently `%x0` is considered as having 2 users, though actually there is only one user `%x0x0`. Patch fixes this.


https://reviews.llvm.org/D29900

Files:
  lib/Transforms/Vectorize/SLPVectorizer.cpp
  test/Transforms/SLPVectorizer/X86/extractelement.ll


Index: test/Transforms/SLPVectorizer/X86/extractelement.ll
===================================================================
--- test/Transforms/SLPVectorizer/X86/extractelement.ll
+++ test/Transforms/SLPVectorizer/X86/extractelement.ll
@@ -3,11 +3,10 @@
 
 define float @f(<2 x float> %x) {
 ; CHECK-LABEL: @f(
-; CHECK-NEXT:    [[X0:%.*]] = extractelement <2 x float> [[X:%.*]], i32 0
-; CHECK-NEXT:    [[X1:%.*]] = extractelement <2 x float> [[X]], i32 1
-; CHECK-NEXT:    [[X0X0:%.*]] = fmul float [[X0]], [[X0]]
-; CHECK-NEXT:    [[X1X1:%.*]] = fmul float [[X1]], [[X1]]
-; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[X0X0]], [[X1X1]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fmul <2 x float> [[X:%.*]], [[X]]
+; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <2 x float> [[TMP1]], i32 0
+; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <2 x float> [[TMP1]], i32 1
+; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[TMP2]], [[TMP3]]
 ; CHECK-NEXT:    ret float [[ADD]]
 ;
   %x0 = extractelement <2 x float> %x, i32 0
Index: lib/Transforms/Vectorize/SLPVectorizer.cpp
===================================================================
--- lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -1625,6 +1625,15 @@
   return true;
 }
 
+/// Checks that \p I is used in the single instruction.
+static bool hasOneUse(Instruction *I) {
+  if (I->hasOneUse())
+     return true;
+  User *U0 = *I->user_begin();
+  return std::all_of(I->user_begin(), I->user_end(),
+                     [U0](User *U) -> bool { return U0 == U; });
+}
+
 int BoUpSLP::getEntryCost(TreeEntry *E) {
   ArrayRef<Value*> VL = E->Scalars;
 
@@ -1660,7 +1669,7 @@
         int DeadCost = 0;
         for (unsigned i = 0, e = VL.size(); i < e; ++i) {
           Instruction *E = cast<Instruction>(VL[i]);
-          if (E->hasOneUse())
+          if (hasOneUse(E))
             // Take credit for instruction that will become dead.
             DeadCost +=
                 TTI->getVectorInstrCost(Instruction::ExtractElement, VecTy, i);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D29900.88234.patch
Type: text/x-patch
Size: 2036 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170213/4ce20d18/attachment.bin>


More information about the llvm-commits mailing list