diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -1436,7 +1436,11 @@ // 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(); - WidePhi = cast(Rewriter.expandCodeFor(AddRec, WideType, InsertPt)); + WidePhi = dyn_cast(Rewriter.expandCodeFor(AddRec, WideType, InsertPt)); + // If the wide phi is not a phi node, for example a cast node, like bitcast, + // inttoptr, ptrtoint, just skip for now. + if (!WidePhi) + return nullptr; // Remembering the WideIV increment generated by SCEVExpander allows // widenIVUse to reuse it when widening the narrow IV's increment. We don't diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp --- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp @@ -53,7 +53,12 @@ // Since we don't know the builder's insertion point is actually // where the uses will be added (only that it dominates it), we are // not allowed to move it. - BasicBlock::iterator BIP = Builder.GetInsertPoint(); + Instruction *BIP = &*Builder.GetInsertPoint(); + + // IndVarSimplify sometimes sets the insertion point at the block start, even + // when there are PHIs at that point. We must correct for this. + if (isa(*BIP)) + BIP = &*BIP->getParent()->getFirstNonPHI(); Instruction *Ret = nullptr; @@ -65,7 +70,7 @@ // If the cast isn't where we want it, create a new cast at IP. // Likewise, do not reuse a cast at BIP because it must dominate // instructions that might be inserted before BIP. - if (BasicBlock::iterator(CI) != IP || BIP == IP) { + if (BasicBlock::iterator(CI) != IP || BIP == &*IP) { // Create a new cast, and leave the old cast in place in case // it is being used as an insert point. Ret = CastInst::Create(Op, V, Ty, "", &*IP); @@ -84,7 +89,7 @@ // We assert at the end of the function since IP might point to an // instruction with different dominance properties than a cast // (an invoke for example) and not dominate BIP (but the cast does). - assert(SE.DT.dominates(Ret, &*BIP)); + assert(SE.DT.dominates(Ret, BIP)); rememberInstruction(Ret); return Ret; diff --git a/llvm/test/Transforms/IndVarSimplify/widen-i32-i8ptr.ll b/llvm/test/Transforms/IndVarSimplify/widen-i32-i8ptr.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/IndVarSimplify/widen-i32-i8ptr.ll @@ -0,0 +1,24 @@ +; RUN: opt < %s -indvars -S | FileCheck %s + +target datalayout = "e-m:e-i64:64-n32:64" + +define dso_local void @Widen_i32_i8ptr() local_unnamed_addr { +; CHECK-LABEL: @Widen_i32_i8ptr( +; CHECK: phi i8* +; CHECK: phi i32 +entry: + %ptrids = alloca [15 x i8*], align 8 + %arraydecay2032 = getelementptr inbounds [15 x i8*], [15 x i8*]* %ptrids, i64 0, i64 0 + store i8** %arraydecay2032, i8*** inttoptr (i64 8 to i8***), align 8 + br label %for.cond2106 + +for.cond2106: ; preds = %for.cond2106, %entry + %gid.0 = phi i8* [ null, %entry ], [ %incdec.ptr, %for.cond2106 ] + %i.0 = phi i32 [ 0, %entry ], [ %inc2117, %for.cond2106 ] + %incdec.ptr = getelementptr inbounds i8, i8* %gid.0, i64 1 + %idxprom2114 = zext i32 %i.0 to i64 + %arrayidx2115 = getelementptr inbounds [15 x i8*], [15 x i8*]* %ptrids, i64 0, i64 %idxprom2114 + store i8* %gid.0, i8** %arrayidx2115, align 8 + %inc2117 = add nuw nsw i32 %i.0, 1 + br label %for.cond2106 +}