diff --git a/lib/Transforms/Scalar/LICM.cpp b/lib/Transforms/Scalar/LICM.cpp index e461c887ea2..e795aa9c0c5 100644 --- a/lib/Transforms/Scalar/LICM.cpp +++ b/lib/Transforms/Scalar/LICM.cpp @@ -800,24 +800,15 @@ void LICM::FindPromotableValuesInLoop( break; } - // Do not promote null values because it may be unsafe to do so. - if (isa(V)) - PointerOk = false; - - if (GetElementPtrInst *GEP = dyn_cast(V)) { - // If GEP base is NULL then the calculated address used by Store or - // Load instruction is invalid. Do not promote this value because - // it may expose load and store instruction that are covered by - // condition which may not yet folded. - if (isa(GEP->getOperand(0))) - PointerOk = false; - } - - // If value V use is not dominating loop exit then promoting - // it may expose unsafe load and store instructions unconditinally. - if (PointerOk) + // If one use of value V inside the loop is safe then it is OK to promote + // this value. On the otherside if there is not any unsafe use inside the + // looop then also it is OK to promote this value. Otherwise it is + // unsafe to promote this value. + if (PointerOk) { + bool oneSafeUse = false; + bool oneUnsafeUse = false; for(Value::use_iterator UI = V->use_begin(), UE = V->use_end(); - UI != UE && PointerOk; ++UI) { + UI != UE; ++UI) { Instruction *Use = dyn_cast(*UI); if (!Use || !CurLoop->contains(Use->getParent())) continue; @@ -825,16 +816,25 @@ void LICM::FindPromotableValuesInLoop( ExitI = LoopExits.begin(), ExitE = LoopExits.end(); ExitI != ExitE; ++ExitI) { Instruction *Ex = *ExitI; - if (!DT->dominates(Use, Ex)){ - PointerOk = false; + if (!isa(Use) && DT->dominates(Use, Ex)) { + oneSafeUse = true; break; } + else + oneUnsafeUse = true; } - - if (!PointerOk) + + if (oneSafeUse) break; } - + + if (oneSafeUse) + PointerOk = true; + else if (!oneUnsafeUse) + PointerOk = true; + else + PointerOk = false; + } if (PointerOk) { const Type *Ty = cast(V->getType())->getElementType(); diff --git a/test/Transforms/LICM/2007-10-01-PromoteSafeValue.ll b/test/Transforms/LICM/2007-10-01-PromoteSafeValue.ll new file mode 100644 index 00000000000..7359cc0695a --- /dev/null +++ b/test/Transforms/LICM/2007-10-01-PromoteSafeValue.ll @@ -0,0 +1,21 @@ +; RUN: llvm-as < %s | opt -licm | llvm-dis | grep promoted +; Promote value if at least one use is safe + + +define i32 @f2(i32* %p, i8* %q) { +entry: + br label %loop.head + +loop.head: ; preds = %cond.true, %entry + store i32 20, i32* %p + %tmp3.i = icmp eq i8* null, %q ; [#uses=1] + br i1 %tmp3.i, label %exit, label %cond.true + +cond.true: ; preds = %loop.head + store i32 40, i32* %p + br label %loop.head + +exit: ; preds = %loop.head + ret i32 0 +} +