[CodeGenPrepare] Avoid sinking soft-FP comparisons

Sinking comparisons in CGP can undo the job of hoisting them done
earlier by LICM, and soft-FP makes this an expensive mistake.

A common pattern that produces floating point comparisons uniform
over a loop is an explicit check for division by zero. If the divisor
is hoisted out of the loop, the comparison can also be, but hoisting
the function that unwinds is never legal, since it may cause side
effects in the loop body prior to the unwinding to not be executed.

Differential Revision: http://reviews.llvm.org/D18744

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@265264 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Peter Zotov
2016-04-03 16:36:17 +00:00
parent 118386614b
commit 6a4952db2d
2 changed files with 38 additions and 5 deletions
+9 -5
View File
@@ -855,10 +855,14 @@ static bool CombineUAddWithOverflow(CmpInst *CI) {
/// 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<FCmpInst>(CI))
return false;
// Only insert a cmp in each block once.
DenseMap<BasicBlock*, CmpInst*> InsertedCmps;
bool MadeChange = false;
@@ -906,8 +910,8 @@ static bool SinkCmpExpression(CmpInst *CI) {
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))
@@ -5173,7 +5177,7 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, bool& ModifiedDT) {
if (CmpInst *CI = dyn_cast<CmpInst>(I))
if (!TLI || !TLI->hasMultipleConditionRegisters())
return OptimizeCmpExpression(CI);
return OptimizeCmpExpression(CI, *TLI);
if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
stripInvariantGroupMetadata(*LI);
@@ -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
}