diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -5361,16 +5361,29 @@ } /// Given operands for a Freeze, see if we can fold the result. -static Value *SimplifyFreezeInst(Value *Op0) { +static Value *SimplifyFreezeInst(Value *Op0, const SimplifyQuery &Q) { // Use a utility function defined in ValueTracking. if (llvm::isGuaranteedNotToBeUndefOrPoison(Op0)) return Op0; + + if (Q.CxtI) { + // Given freeze(Op0), if Op0 is ever used as a branch condition, Op0 cannot + // be undef or poison. + // v = freeze(cond) + // br cond, BB1, BB2 + // BB1: + // use(v) -> use(cond) + auto BI = dyn_cast(Q.CxtI->getParent()->getTerminator()); + if (BI && BI->isConditional() && BI->getCondition() == Op0) + return Op0; + } + // We have room for improvement. return nullptr; } Value *llvm::SimplifyFreezeInst(Value *Op0, const SimplifyQuery &Q) { - return ::SimplifyFreezeInst(Op0); + return ::SimplifyFreezeInst(Op0, Q); } /// See if we can compute a simplified version of this instruction. diff --git a/llvm/test/Transforms/InstSimplify/freeze.ll b/llvm/test/Transforms/InstSimplify/freeze.ll --- a/llvm/test/Transforms/InstSimplify/freeze.ll +++ b/llvm/test/Transforms/InstSimplify/freeze.ll @@ -18,3 +18,19 @@ %x = freeze i32 10 ret i32 %x } + +define i1 @brcond(i1 %c) { +; CHECK-LABEL: @brcond( +; CHECK-NEXT: br i1 [[C:%.*]], label [[A:%.*]], label [[B:%.*]] +; CHECK: A: +; CHECK-NEXT: ret i1 [[C]] +; CHECK: B: +; CHECK-NEXT: ret i1 [[C]] +; + %f = freeze i1 %c + br i1 %c, label %A, label %B +A: + ret i1 %f +B: + ret i1 %f +}