Index: lib/Transforms/Scalar/IndVarSimplify.cpp =================================================================== --- lib/Transforms/Scalar/IndVarSimplify.cpp +++ lib/Transforms/Scalar/IndVarSimplify.cpp @@ -600,36 +600,35 @@ // - no use outside of the loop can take advantage of hoisting the // computation out of the loop if (ExitValue->getSCEVType()>=scMulExpr) { - unsigned NumHardInternalUses = 0; - unsigned NumSoftExternalUses = 0; - unsigned NumUses = 0; - for (auto IB = Inst->user_begin(), IE = Inst->user_end(); - IB != IE && NumUses <= 6; ++IB) { - Instruction *UseInstr = cast(*IB); + bool HasHardInternalUses = false; + bool HasSoftExternalUses = false; + for (auto *IB : Inst->users()) { + Instruction *UseInstr = cast(IB); unsigned Opc = UseInstr->getOpcode(); - NumUses++; if (L->contains(UseInstr)) { if (Opc == Instruction::Call) - NumHardInternalUses++; + HasHardInternalUses = true; } else { if (Opc == Instruction::PHI) { // Do not count the Phi as a use. LCSSA may have inserted // plenty of trivial ones. - NumUses--; - for (auto PB = UseInstr->user_begin(), - PE = UseInstr->user_end(); - PB != PE && NumUses <= 6; ++PB, ++NumUses) { - unsigned PhiOpc = cast(*PB)->getOpcode(); - if (PhiOpc != Instruction::Call && PhiOpc != Instruction::Ret) - NumSoftExternalUses++; + 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) - NumSoftExternalUses++; + if (Opc != Instruction::Call && Opc != Instruction::Ret) { + HasSoftExternalUses = true; + break; + } } } - if (NumUses <= 6 && NumHardInternalUses && !NumSoftExternalUses) + if (HasHardInternalUses && !HasSoftExternalUses) continue; } Index: test/Transforms/IndVarSimplify/dont-recompute.ll =================================================================== --- test/Transforms/IndVarSimplify/dont-recompute.ll +++ test/Transforms/IndVarSimplify/dont-recompute.ll @@ -67,3 +67,33 @@ ; CHECK-NEXT: ret i32 %add.lcssa ret i32 %add } + +; CHECK-LABEL: @test3( +define void @test3(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 + mul i32 %add, 1 + mul i32 %add, 1 + mul i32 %add, 1 + mul i32 %add, 1 + mul i32 %add, 1 + mul i32 %add, 1 +; 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: tail call void @func(i32 %add.lcssa) + tail call void @func(i32 %add) + ret void +}