<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - SLPVectorizer finds incorrect reduction value"
   href="https://llvm.org/bugs/show_bug.cgi?id=25787">25787</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>SLPVectorizer finds incorrect reduction value
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Loop Optimizer
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>mattias.v.eriksson@ericsson.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=15424" name="attach_15424" title="reduced input file">attachment 15424</a> <a href="attachment.cgi?id=15424&action=edit" title="reduced input file">[details]</a></span>
reduced input file

The function getReductionValue can return a Value that is not dominated by the
phi-node. This can cause miscompiles.

I found the problem originally in an out-of-tree target with a huge test case.
I have added an assert in the code like this:

 --- a/lib/Transforms/Vectorize/SLPVectorizer.cpp
 +++ b/lib/Transforms/Vectorize/SLPVectorizer.cpp
 @@ -3937,7 +3937,8 @@ static bool PhiTypeSorterFunc(Value *V, Value *V2) {
  ///
  /// \returns A candidate reduction value if possible, or \code nullptr
\endcode
  /// if not possible.
 -static Value *getReductionValue(PHINode *P, BasicBlock *ParentBB,
 +static Value *getReductionValue(const DominatorTree *DT,
 +                                PHINode *P, BasicBlock *ParentBB,
                                  LoopInfo *LI) {
    Value *Rdx = nullptr;

 @@ -3967,6 +3968,12 @@ static Value *getReductionValue(PHINode *P, BasicBlock
*ParentBB,
      Rdx = P->getIncomingValue(1);
    }

 +  assert(!Rdx || !dyn_cast<Instruction>(Rdx) ||
 +         DT->dominates(P->getParent(),
dyn_cast<Instruction>(Rdx)->getParent()));
 +  // if (Rdx && dyn_cast<Instruction>(Rdx) &&
 +  //     !DT->dominates(P->getParent(),
dyn_cast<Instruction>(Rdx)->getParent()))
 +  //   return nullptr;
 +
    return Rdx;
  }

 @@ -4062,7 +4069,7 @@ bool SLPVectorizer::vectorizeChainsInBlock(BasicBlock
*BB, BoUpSLP &R) {
        if (P->getNumIncomingValues() != 2)
          return Changed;

 -      Value *Rdx = getReductionValue(P, BB, LI);
 +      Value *Rdx = getReductionValue(DT, P, BB, LI);

        // Check if this is a Binary Operator.
        BinaryOperator *BI = dyn_cast_or_null<BinaryOperator>(Rdx);


And then reduced the failing test to something that still trigger the assert
(but it no longer miscompiles).

Look at the first phi-node in the dump below. The incoming value from the loop
latch is actually defined in bb2. Is this a valid phi-node? If it is, then
there must be a bug when SLP Vectorizer finds the reduction value "%_tmp279 =
load volatile i16, i16* null".

*** IR Dump Before SLP Vectorizer ***
define i16 @test_spill_stress(i16 %tnr.8.par) #0 {
bb2:
  %_tmp279 = load volatile i16, i16* null, align 32768
  br label %bb_usw4.outer.outer

bb_usw4.outer.outer.loopexit:                     ; preds = %bb_usw4
  br label %bb_usw4.outer.outer

bb_usw4.outer.outer:                              ; preds =
%bb_usw4.outer.outer.loopexit, %bb2
  %f3.351.0.ph.ph = phi i16 [ 0, %bb2 ], [ %_tmp279,
%bb_usw4.outer.outer.loopexit ]
  br label %bb_usw4

bb_usw4:                                          ; preds = %bb_usw4.backedge,
%bb_usw4.outer.outer
  %i__0.358.0 = phi i16 [ 4, %bb_usw4.outer.outer ], [ %i__0.358.0.be,
%bb_usw4.backedge ]
  switch i16 %i__0.358.0, label %bb15 [
    i16 3, label %bb_usw4.outer.outer.loopexit
    i16 5, label %bb_usw4.backedge
  ]

bb15:                                             ; preds = %bb_usw4
  %_tmp1143 = add i16 %i__0.358.0, 1
  %_tmp1145 = icmp slt i16 %_tmp1143, 8
  br i1 %_tmp1145, label %bb_usw4.backedge, label %bb16

bb_usw4.backedge:                                 ; preds = %bb15, %bb_usw4
  %i__0.358.0.be = phi i16 [ %_tmp1143, %bb15 ], [ 6, %bb_usw4 ]
  br label %bb_usw4

bb16:                                             ; preds = %bb15
  %_tmp1161 = icmp eq i16 %f3.351.0.ph.ph, 11584
  %_tmp1162 = zext i1 %_tmp1161 to i16
  %_tmp1163 = tail call i16 @check_i(i16 998, i16 %_tmp1162, i16 1)
  ret i16 2
}

With the added assert, the following command crashes for the attached file:
opt -S -mcpu=swift -mtriple=thumbv7-apple-ios -slp-vectorizer -O3
bugpoint-reduced-simplified.ll</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>