diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -7191,6 +7191,29 @@ return false; } + if (FreezeInst *FI = dyn_cast(I)) { + // br(freeze(icmp a, const)) -> br(icmp (freeze a), const) + // This helps generate efficient conditional jumps. + bool AllUsesAreBr = llvm::all_of(FI->users(), [](const User *U) { + return isa(U); + }); + auto II = dyn_cast(FI->getOperand(0)); + if (AllUsesAreBr && II && II->hasOneUse()) { + auto Op0 = II->getOperand(0), Op1 = II->getOperand(1); + bool Const0 = isa(Op0), Const1 = isa(Op1); + if (Const0 || Const1) { + FI->replaceAllUsesWith(II); + FI->eraseFromParent(); + if (!Const0 || !Const1) { + Instruction *F = new FreezeInst(Const0 ? Op1 : Op0, "fr", II); + II->setOperand(Const0 ? 1 : 0, F); + } + return true; + } + } + return false; + } + if (tryToSinkFreeOperands(I)) return true;