Index: lib/CodeGen/CodeGenPrepare.cpp =================================================================== --- lib/CodeGen/CodeGenPrepare.cpp +++ lib/CodeGen/CodeGenPrepare.cpp @@ -854,10 +854,14 @@ /// lose; some adjustment may be wanted there. /// /// Return true if any changes are made. -static bool SinkCmpExpression(CmpInst *CI) { +static bool SinkCmpExpression(CmpInst *CI, const TargetLowering &TLI) { BasicBlock *DefBB = CI->getParent(); - /// Only insert a cmp in each block once. + // Avoid sinking soft-FP comparisons, since this can move them into a loop. + if (TLI.useSoftFloat() && isa(CI)) + return false; + + // Only insert a cmp in each block once. DenseMap InsertedCmps; bool MadeChange = false; @@ -905,8 +909,8 @@ return MadeChange; } -static bool OptimizeCmpExpression(CmpInst *CI) { - if (SinkCmpExpression(CI)) +static bool OptimizeCmpExpression(CmpInst *CI, const TargetLowering &TLI) { + if (SinkCmpExpression(CI, TLI)) return true; if (CombineUAddWithOverflow(CI)) @@ -5145,7 +5149,7 @@ if (CmpInst *CI = dyn_cast(I)) if (!TLI || !TLI->hasMultipleConditionRegisters()) - return OptimizeCmpExpression(CI); + return OptimizeCmpExpression(CI, *TLI); if (LoadInst *LI = dyn_cast(I)) { stripInvariantGroupMetadata(*LI); Index: test/Transforms/CodeGenPrepare/X86/fcmp-sinking.ll =================================================================== --- /dev/null +++ test/Transforms/CodeGenPrepare/X86/fcmp-sinking.ll @@ -0,0 +1,29 @@ +; RUN: opt %s -codegenprepare -mattr=+soft-float -S | FileCheck %s -check-prefix=CHECK -check-prefix=SOFTFP +; RUN: opt %s -codegenprepare -mattr=-soft-float -S | FileCheck %s -check-prefix=CHECK -check-prefix=HARDFP + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; CHECK-LABEL: @foo +; CHECK: entry: +; SOFTFP: fcmp +; HARDFP-NOT: fcmp +; CHECK: body: +; SOFTFP-NOT: fcmp +; HARDFP: fcmp +define void @foo(float %a, float %b) { +entry: + %c = fcmp oeq float %a, %b + br label %head +head: + %IND = phi i32 [ 0, %entry ], [ %IND.new, %body1 ] + %CMP = icmp slt i32 %IND, 1250 + br i1 %CMP, label %body, label %tail +body: + br i1 %c, label %body1, label %tail +body1: + %IND.new = add i32 %IND, 1 + br label %head +tail: + ret void +}