Index: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -595,41 +595,20 @@ !isSafeToExpand(ExitValue, *SE)) continue; - // Computing the value outside of the loop brings no benefit if : - // - it is definitely used inside the loop in a way which can not be - // optimized away. - // - no use outside of the loop can take advantage of hoisting the - // computation out of the loop + // Computing the value outside of the loop brings no benefit if it is + // definitely used inside the loop in a way which can not be optimized + // away. if (ExitValue->getSCEVType()>=scMulExpr) { bool HasHardInternalUses = false; - bool HasSoftExternalUses = false; for (auto *IB : Inst->users()) { Instruction *UseInstr = cast(IB); unsigned Opc = UseInstr->getOpcode(); - if (L->contains(UseInstr)) { - if (Opc == Instruction::Call) - HasHardInternalUses = true; - } else { - if (Opc == Instruction::PHI) { - // Do not count the Phi as a use. LCSSA may have inserted - // plenty of trivial ones. - for (auto *PB : UseInstr->users()) { - unsigned PhiOpc = cast(PB)->getOpcode(); - if (PhiOpc != Instruction::Call && - PhiOpc != Instruction::Ret) { - HasSoftExternalUses = true; - break; - } - } - continue; - } - if (Opc != Instruction::Call && Opc != Instruction::Ret) { - HasSoftExternalUses = true; - break; - } + if (L->contains(UseInstr) && Opc == Instruction::Call) { + HasHardInternalUses = true; + break; } } - if (HasHardInternalUses && !HasSoftExternalUses) + if (HasHardInternalUses) continue; } Index: llvm/trunk/test/Transforms/IndVarSimplify/dont-recompute.ll =================================================================== --- llvm/trunk/test/Transforms/IndVarSimplify/dont-recompute.ll +++ llvm/trunk/test/Transforms/IndVarSimplify/dont-recompute.ll @@ -97,3 +97,29 @@ tail call void @func(i32 %add) ret void } + +; CHECK-LABEL: @test4( +define void @test4(i32 %m) nounwind uwtable { +entry: + br label %for.body + +for.body: ; preds = %for.body, %entry + %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ] + %add = add i32 %a.05, %m +; CHECK: tail call void @func(i32 %add) + tail call void @func(i32 %add) + %inc = add nsw i32 %i.06, 1 + %exitcond = icmp eq i32 %inc, 186 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body +; CHECK: for.end: +; CHECK-NOT: mul i32 %m, 186 +; CHECK:%add.lcssa = phi i32 [ %add, %for.body ] +; CHECK-NEXT: %soft_use = add i32 %add.lcssa, 123 +; CHECK-NEXT: tail call void @func(i32 %soft_use) + %soft_use = add i32 %add, 123 + tail call void @func(i32 %soft_use) + ret void +}