Commit 11405dfa authored by Tanya Lattner's avatar Tanya Lattner
Browse files

Merge 64579 from mainline.

Fix pr3571: If stride is a value defined by an instruction, make sure it dominates the loop preheader. When IV users are strength reduced, the stride is inserted into the preheader. It could create a use before def situation.

llvm-svn: 64789
parent bc5b640c
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -400,7 +400,7 @@ static bool containsAddRecFromDifferentLoop(SCEVHandle S, Loop *L) {
/// outer loop of the current loop.
static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L,
                                  SCEVHandle &Start, SCEVHandle &Stride,
                                  ScalarEvolution *SE) {
                                  ScalarEvolution *SE, DominatorTree *DT) {
  SCEVHandle TheAddRec = Start;   // Initialize to zero.

  // If the outer level is an AddExpr, the operands are all start values except
@@ -437,9 +437,21 @@ static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L,

  Start = SE->getAddExpr(Start, AddRec->getOperand(0));
  
  if (!isa<SCEVConstant>(AddRec->getOperand(1)))
  if (!isa<SCEVConstant>(AddRec->getOperand(1))) {
    // If stride is an instruction, make sure it dominates the loop header.
    // Otherwise we could end up with a use before def situation.
    if (SCEVUnknown *SU = dyn_cast<SCEVUnknown>(AddRec->getOperand(1))) {
      if (Instruction *I = dyn_cast<Instruction>(SU->getValue())) {
        BasicBlock *StrideBB = I->getParent();
        BasicBlock *Preheader = L->getLoopPreheader();
        if (!DT->dominates(StrideBB, Preheader))
          return false;
      }
    }

    DOUT << "[" << L->getHeader()->getName()
         << "] Variable stride: " << *AddRec << "\n";
  }

  Stride = AddRec->getOperand(1);
  return true;
@@ -547,7 +559,7 @@ bool LoopStrengthReduce::AddUsersIfInteresting(Instruction *I, Loop *L,
  // Get the start and stride for this expression.
  SCEVHandle Start = SE->getIntegerSCEV(0, ISE->getType());
  SCEVHandle Stride = Start;
  if (!getSCEVStartAndStride(ISE, L, Start, Stride, SE))
  if (!getSCEVStartAndStride(ISE, L, Start, Stride, SE, DT))
    return false;  // Non-reducible symbolic expression, bail out.

  std::vector<Instruction *> IUsers;
+27 −0
Original line number Diff line number Diff line
; RUN: llvm-as < %s | opt -loop-reduce | llvm-dis
; PR3571

target triple = "i386-mingw32"
define void @_ZNK18qdesigner_internal10TreeWidget12drawBranchesEP8QPainterRK5QRectRK11QModelIndex() nounwind {
entry:
	br label %_ZNK11QModelIndex7isValidEv.exit.i

bb.i:		; preds = %_ZNK11QModelIndex7isValidEv.exit.i
	%indvar.next = add i32 %result.0.i, 1		; <i32> [#uses=1]
	br label %_ZNK11QModelIndex7isValidEv.exit.i

_ZNK11QModelIndex7isValidEv.exit.i:		; preds = %bb.i, %entry
	%result.0.i = phi i32 [ 0, %entry ], [ %indvar.next, %bb.i ]		; <i32> [#uses=2]
	%0 = load i32** null, align 4		; <%struct.QAbstractItemDelegate*> [#uses=0]
	br i1 false, label %_ZN18qdesigner_internalL5levelEP18QAbstractItemModelRK11QModelIndex.exit, label %bb.i

_ZN18qdesigner_internalL5levelEP18QAbstractItemModelRK11QModelIndex.exit:		; preds = %_ZNK11QModelIndex7isValidEv.exit.i
	%1 = call i32 @_ZNK9QTreeView11indentationEv(i32* null) nounwind		; <i32> [#uses=1]
	%2 = mul i32 %1, %result.0.i		; <i32> [#uses=1]
	%3 = add i32 %2, -2		; <i32> [#uses=1]
	%4 = add i32 %3, 0		; <i32> [#uses=1]
	store i32 %4, i32* null, align 8
	unreachable
}

declare i32 @_ZNK9QTreeView11indentationEv(i32*)