diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/llvm/lib/Transforms/Scalar/LICM.cpp @@ -1231,10 +1231,6 @@ return MSSA->isLiveOnEntryDef(Source) || !CurLoop->contains(Source->getBlock()); } - } else if (isa(&I)) { - // Freeze instruction cannot be sunk into a loop because it may yield a - // different value for each iteration after sinking. - return !Flags->IsSink; } assert(!I.mayReadOrWriteMemory() && "unhandled aliasing"); @@ -1949,7 +1945,7 @@ // Note that proving a load safe to speculate requires proving // sufficient alignment at the target location. Proving it guaranteed // to execute does as well. Thus we can increase our guaranteed - // alignment as well. + // alignment as well. if (!DereferenceableInPH || (InstAlignment > Alignment)) if (isSafeToExecuteUnconditionally(*Load, DT, CurLoop, SafetyInfo, ORE, Preheader->getTerminator())) { diff --git a/llvm/test/Transforms/LICM/freeze.ll b/llvm/test/Transforms/LICM/freeze.ll --- a/llvm/test/Transforms/LICM/freeze.ll +++ b/llvm/test/Transforms/LICM/freeze.ll @@ -1,8 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -licm -S < %s | FileCheck %s -define void @licm(i1 %a) { -; CHECK-LABEL: @licm( +define void @hoist(i1 %a) { +; CHECK-LABEL: @hoist( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[B:%.*]] = freeze i1 [[A:%.*]] ; CHECK-NEXT: br label [[LOOP:%.*]] @@ -18,4 +18,26 @@ br label %loop } +define i1 @sink(i1 %a) { +; CHECK-LABEL: @sink( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: [[FR_LE:%.*]] = freeze i1 [[A:%.*]] +; CHECK-NEXT: ret i1 [[FR_LE]] +; +entry: + br label %loop +loop: + %fr = freeze i1 %a + %c = call i1 @cond() + br i1 %c, label %loop, label %exit +exit: + ret i1 %fr +} + +declare i1 @cond() declare void @use(i1)