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 @@ -7198,16 +7198,25 @@ if (FreezeInst *FI = dyn_cast(I)) { // br(freeze(icmp a, const)) -> br(icmp (freeze a), const) // This helps generate efficient conditional jumps. - if (ICmpInst *II = dyn_cast(FI->getOperand(0))) { - auto Op0 = II->getOperand(0), Op1 = II->getOperand(1); - bool Const0 = isa(Op0), Const1 = isa(Op1); - if (II->hasOneUse() && (Const0 || Const1)) { + Instruction *CmpI = nullptr; + if (ICmpInst *II = dyn_cast(FI->getOperand(0))) + CmpI = II; + else if (FCmpInst *F = dyn_cast(FI->getOperand(0))) + CmpI = F->getFastMathFlags().none() ? F : nullptr; + + if (CmpI && CmpI->hasOneUse()) { + auto Op0 = CmpI->getOperand(0), Op1 = CmpI->getOperand(1); + bool Const0 = isa(Op0) || isa(Op0) || + isa(Op0); + bool Const1 = isa(Op1) || isa(Op1) || + isa(Op1); + if (Const0 || Const1) { if (!Const0 || !Const1) { - auto *F = new FreezeInst(Const0 ? Op1 : Op0, "", II); + auto *F = new FreezeInst(Const0 ? Op1 : Op0, "", CmpI); F->takeName(FI); - II->setOperand(Const0 ? 1 : 0, F); + CmpI->setOperand(Const0 ? 1 : 0, F); } - FI->replaceAllUsesWith(II); + FI->replaceAllUsesWith(CmpI); FI->eraseFromParent(); return true; } diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/freeze-cmp.ll b/llvm/test/Transforms/CodeGenPrepare/X86/freeze-cmp.ll --- a/llvm/test/Transforms/CodeGenPrepare/X86/freeze-cmp.ll +++ b/llvm/test/Transforms/CodeGenPrepare/X86/freeze-cmp.ll @@ -73,9 +73,9 @@ define i1 @ptrcmp(i8* %p) { ; CHECK-LABEL: @ptrcmp( -; CHECK-NEXT: [[C:%.*]] = icmp eq i8* [[P:%.*]], null -; CHECK-NEXT: [[FR:%.*]] = freeze i1 [[C]] -; CHECK-NEXT: ret i1 [[FR]] +; CHECK-NEXT: [[FR:%.*]] = freeze i8* [[P:%.*]] +; CHECK-NEXT: [[C:%.*]] = icmp eq i8* [[FR]], null +; CHECK-NEXT: ret i1 [[C]] ; %c = icmp eq i8* %p, null %fr = freeze i1 %c @@ -85,9 +85,9 @@ define i1 @fcmp(float %a) { ; CHECK-LABEL: @fcmp( -; CHECK-NEXT: [[C:%.*]] = fcmp oeq float [[A:%.*]], 0.000000e+00 -; CHECK-NEXT: [[FR:%.*]] = freeze i1 [[C]] -; CHECK-NEXT: ret i1 [[FR]] +; CHECK-NEXT: [[FR:%.*]] = freeze float [[A:%.*]] +; CHECK-NEXT: [[C:%.*]] = fcmp oeq float [[FR]], 0.000000e+00 +; CHECK-NEXT: ret i1 [[C]] ; %c = fcmp oeq float %a, 0.0 %fr = freeze i1 %c @@ -104,5 +104,6 @@ %fr = freeze i1 %c ret i1 %fr } + declare void @g1() declare void @g2()