summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Zotov <whitequark@whitequark.org>2016-04-03 16:36:17 +0000
committerPeter Zotov <whitequark@whitequark.org>2016-04-03 16:36:17 +0000
commit0b6d7bc6820702a803ec180435b899e692e8c229 (patch)
treee55dc90f9e79c759d846660834f23c4521edeb7f
parent20d1d4f0454f1e68fb69a710707243f7b50edff8 (diff)
downloadbcm5719-llvm-0b6d7bc6820702a803ec180435b899e692e8c229.tar.gz
bcm5719-llvm-0b6d7bc6820702a803ec180435b899e692e8c229.zip
[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 llvm-svn: 265264
-rw-r--r--llvm/lib/CodeGen/CodeGenPrepare.cpp14
-rw-r--r--llvm/test/Transforms/CodeGenPrepare/X86/fcmp-sinking.ll29
2 files changed, 38 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 8ba52c424a6..afd37a0efe7 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -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);
diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/fcmp-sinking.ll b/llvm/test/Transforms/CodeGenPrepare/X86/fcmp-sinking.ll
new file mode 100644
index 00000000000..94ab74f9e7b
--- /dev/null
+++ b/llvm/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
+}
OpenPOWER on IntegriCloud