bool operator()(std::pair<const Loop *, const SCEV *> LHS,
std::pair<const Loop *, const SCEV *> RHS) const {
+ // Keep pointer operands sorted at the end.
+ if (LHS.second->getType()->isPointerTy() !=
+ RHS.second->getType()->isPointerTy())
+ return LHS.second->getType()->isPointerTy();
+
// Compare loops with PickMostRelevantLoop.
if (LHS.first != RHS.first)
return PickMostRelevantLoop(LHS.first, RHS.first, DT) != LHS.first;
// The running sum expression is a pointer. Try to form a getelementptr
// at this level with that as the base.
SmallVector<const SCEV *, 4> NewOps;
- for (; I != E && I->first == CurLoop; ++I)
- NewOps.push_back(I->second);
+ for (; I != E && I->first == CurLoop; ++I) {
+ // If the operand is SCEVUnknown and not instructions, peek through
+ // it, to enable more of it to be folded into the GEP.
+ const SCEV *X = I->second;
+ if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(X))
+ if (!isa<Instruction>(U->getValue()))
+ X = SE.getSCEV(U->getValue());
+ NewOps.push_back(X);
+ }
Sum = expandAddToGEP(NewOps.begin(), NewOps.end(), PTy, Ty, Sum);
} else if (const PointerType *PTy = dyn_cast<PointerType>(Op->getType())) {
// The running sum is an integer, and there's a pointer at this level.
--- /dev/null
+; RUN: opt -indvars -S | not grep uglygep
+; rdar://8197217
+
+; Indvars should be able to emit a clean GEP here, not an uglygep.
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-apple-darwin11.0"
+
+@numf2s = external global i32 ; <i32*> [#uses=1]
+@numf1s = external global i32 ; <i32*> [#uses=1]
+@tds = external global double** ; <double***> [#uses=1]
+
+define void @init_td(i32 %tmp7) nounwind {
+entry:
+ br label %bb4
+
+bb4: ; preds = %bb3, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %tmp9, %bb3 ] ; <i32> [#uses=3]
+ br label %bb
+
+bb: ; preds = %bb4
+ br label %bb2
+
+bb2: ; preds = %bb1, %bb
+ %j.0 = phi i32 [ 0, %bb ], [ %tmp6, %bb1 ] ; <i32> [#uses=3]
+ %tmp8 = icmp slt i32 %j.0, %tmp7 ; <i1> [#uses=1]
+ br i1 %tmp8, label %bb1, label %bb3
+
+bb1: ; preds = %bb2
+ %tmp = load double*** @tds, align 8 ; <double**> [#uses=1]
+ %tmp1 = sext i32 %i.0 to i64 ; <i64> [#uses=1]
+ %tmp2 = getelementptr inbounds double** %tmp, i64 %tmp1 ; <double**> [#uses=1]
+ %tmp3 = load double** %tmp2, align 1 ; <double*> [#uses=1]
+ %tmp6 = add nsw i32 %j.0, 1 ; <i32> [#uses=1]
+ br label %bb2
+
+bb3: ; preds = %bb2
+ %tmp9 = add nsw i32 %i.0, 1 ; <i32> [#uses=1]
+ br label %bb4
+}