Index: lib/Transforms/Scalar/IndVarSimplify.cpp =================================================================== --- lib/Transforms/Scalar/IndVarSimplify.cpp +++ lib/Transforms/Scalar/IndVarSimplify.cpp @@ -1583,6 +1583,12 @@ // expect a well-formed cyclic phi-with-increments. i.e. any operand not part // of the phi-SCC dominates the loop entry. Instruction *InsertPt = &L->getHeader()->front(); + + // Make sure it is safe to expand at this point. For example, that we don't + // have division by value which is potentially zero. + if (!isSafeToExpand(AddRec, *SE)) + return nullptr; + WidePhi = cast(Rewriter.expandCodeFor(AddRec, WideType, InsertPt)); // Remembering the WideIV increment generated by SCEVExpander allows @@ -2175,6 +2181,11 @@ // SCEV expression (IVInit) for a pointer type IV value (IndVar). Type *LimitTy = IVCount->getType()->isPointerTy() ? IndVar->getType() : IVCount->getType(); + + // We may end up with unsafe expanding, do not deal with it. + if (!isSafeToExpand(IVLimit, *SE)) + return nullptr; + return Rewriter.expandCodeFor(IVLimit, LimitTy, BI); } } @@ -2213,6 +2224,10 @@ } Value *ExitCnt = genLoopLimit(IndVar, IVCount, L, Rewriter, SE); + // We may end up with nullptr if we failed to expand something. + if (!ExitCnt) + return nullptr; + assert(ExitCnt->getType()->isPointerTy() == IndVar->getType()->isPointerTy() && "genLoopLimit missed a cast"); @@ -2470,9 +2485,6 @@ // pass that uses the SCEVExpander must do it. This does not work well for // loop passes because SCEVExpander makes assumptions about all loops, // while LoopPassManager only forces the current loop to be simplified. - // - // FIXME: SCEV expansion has no way to bail out, so the caller must - // explicitly check any assumptions made by SCEV. Brittle. const SCEVAddRecExpr *AR = dyn_cast(BackedgeTakenCount); if (!AR || AR->getLoop()->getLoopPreheader()) (void)linearFunctionTestReplace(L, BackedgeTakenCount, IndVar, Index: test/Transforms/IndVarSimplify/2017-10-24_unsafe_division.ll =================================================================== --- /dev/null +++ test/Transforms/IndVarSimplify/2017-10-24_unsafe_division.ll @@ -0,0 +1,53 @@ +; RUN: opt -S -indvars < %s | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1" +target triple = "x86_64-unknown-linux-gnu" + +; In this example, we may end up expanding %unsafe. The value of %iv.trunc may +; potentially be zero even despite %iv is always positive, and in %unsafe we +; divide by it. In terms of SCEV expander, expanding such a value is incorrect. + +define void @test_01() { + +; CHECK-LABEL: test_01 +; CHECK: entry: +; CHECK-NEXT: br label %outer_loop +; CHECK: outer_loop: +; CHECK-NEXT: %iv = phi i64 [ 5, %entry ], [ %iv.next, %outer_backedge ] +; CHECK-NEXT: %iv.trunc = trunc i64 %iv to i32 +; CHECK-NEXT: %unsafe = udiv i32 224, %iv.trunc +; CHECK-NEXT: br label %inner_loop +; CHECK: inner_loop: +; CHECK-NEXT: %unsafe_phi = phi i32 [ %unsafe, %outer_loop ], [ %unsafe_phi.next, %inner_loop ] +; CHECK-NEXT: %iv.inner = phi i32 [ 0, %outer_loop ], [ %iv.inner.next, %inner_loop ] +; CHECK-NEXT: %unsafe_phi.next = add nuw nsw i32 %unsafe_phi, 1 +; CHECK-NEXT: %expand.me = zext i32 %unsafe_phi.next to i64 +; CHECK-NEXT: %iv.inner.next = add nuw nsw i32 %iv.inner, 1 +; CHECK-NEXT: %cond.inner = icmp ugt i32 %iv.inner, 1643 +; CHECK-NEXT: br i1 %cond.inner, label %outer_backedge, label %inner_loop +; CHECK: outer_backedge: +; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1 +; CHECK-NEXT: br label %outer_loop + +entry: + br label %outer_loop + +outer_loop: + %iv = phi i64 [ 5, %entry ], [ %iv.next, %outer_backedge ] + %iv.next = add nuw nsw i64 %iv, 1 + %iv.trunc = trunc i64 %iv to i32 + %unsafe = udiv i32 224, %iv.trunc + br label %inner_loop + +inner_loop: + %unsafe_phi = phi i32 [ %unsafe, %outer_loop ], [ %unsafe_phi.next, %inner_loop ] + %iv.inner = phi i32 [ 0, %outer_loop ], [ %iv.inner.next, %inner_loop ] + %unsafe_phi.next = add nuw nsw i32 %unsafe_phi, 1 + %expand.me = zext i32 %unsafe_phi.next to i64 + %iv.inner.next = add nuw nsw i32 %iv.inner, 1 + %cond.inner = icmp ugt i32 %iv.inner, 1643 + br i1 %cond.inner, label %outer_backedge, label %inner_loop + +outer_backedge: + br label %outer_loop +} Index: test/Transforms/IndVarSimplify/udiv.ll =================================================================== --- test/Transforms/IndVarSimplify/udiv.ll +++ test/Transforms/IndVarSimplify/udiv.ll @@ -195,4 +195,42 @@ ret void } + +; Same as foo_02, but we divide by non-constant value which can be zero. But we +; do not need to generate any new instructions for that. SCEV expander will +; prohibit expanding this. + +; CHECK-LABEL: @foo_03( +; CHECK: for.body.preheader: +; CHECK: udiv + +define void @foo_03(double* %p, i64 %n) nounwind { +entry: + %denom = load i64, i64* undef, align 4, !range !1 + %div0 = udiv i64 %n, %denom ; [#uses=1] + %div1 = add i64 %div0, 1 + %cmp2 = icmp ult i64 0, %div1 ; [#uses=1] + br i1 %cmp2, label %for.body.preheader, label %for.end + +for.body.preheader: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.preheader, %for.body + %i.03 = phi i64 [ %inc, %for.body ], [ 0, %for.body.preheader ] ; [#uses=2] + %arrayidx = getelementptr inbounds double, double* %p, i64 %i.03 ; [#uses=1] + store double 0.000000e+00, double* %arrayidx + %inc = add i64 %i.03, 1 ; [#uses=2] + %divx = udiv i64 %n, %denom ; [#uses=1] + %div = add i64 %divx, 1 + %cmp = icmp ult i64 %inc, %div ; [#uses=1] + br i1 %cmp, label %for.body, label %for.end.loopexit + +for.end.loopexit: ; preds = %for.body + br label %for.end + +for.end: ; preds = %for.end.loopexit, %entry + ret void +} + !0 = !{i64 1, i64 10} +!1 = !{i64 0, i64 10}