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 @@ -7194,16 +7194,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) { + 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 (CmpI->hasOneUse() && (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-icmp.ll b/llvm/test/Transforms/CodeGenPrepare/X86/freeze-cmp.ll rename from llvm/test/Transforms/CodeGenPrepare/X86/freeze-icmp.ll rename to llvm/test/Transforms/CodeGenPrepare/X86/freeze-cmp.ll --- a/llvm/test/Transforms/CodeGenPrepare/X86/freeze-icmp.ll +++ b/llvm/test/Transforms/CodeGenPrepare/X86/freeze-cmp.ll @@ -71,5 +71,40 @@ ret void } +define i1 @ptrcmp(i8* %p) { +; CHECK-LABEL: @ptrcmp( +; 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 + ret i1 %fr +} + + +define i1 @fcmp(float %a) { +; CHECK-LABEL: @fcmp( +; 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 + ret i1 %fr +} + +define i1 @fcmp_nan(float %a) { +; CHECK-LABEL: @fcmp_nan( +; CHECK-NEXT: [[C:%.*]] = fcmp nnan oeq float [[A:%.*]], 0.000000e+00 +; CHECK-NEXT: [[FR:%.*]] = freeze i1 [[C]] +; CHECK-NEXT: ret i1 [[FR]] +; + %c = fcmp nnan oeq float %a, 0.0 + %fr = freeze i1 %c + ret i1 %fr +} + + declare void @g1() declare void @g2()