aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2012-05-07 20:47:23 +0000
committerOwen Anderson <resistor@mac.com>2012-05-07 20:47:23 +0000
commit423f19f2dadee9325766008b63c1faf3c644043b (patch)
treec5d3cd7233f546183e248c5a7d53886bdbbad02a
parent754935418133ece1f51d1857a61d538797c34891 (diff)
Teach reassociate to commute FMul's and FAdd's in order to canonicalize the order of their operands across instructions. This allows for greater CSE opportunities.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156323 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/Reassociate.cpp32
-rw-r--r--test/Transforms/Reassociate/fp-commute.ll16
2 files changed, 44 insertions, 4 deletions
diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp
index cc98ba0f21..010f17aae0 100644
--- a/lib/Transforms/Scalar/Reassociate.cpp
+++ b/lib/Transforms/Scalar/Reassociate.cpp
@@ -1212,10 +1212,34 @@ void Reassociate::ReassociateInst(BasicBlock::iterator &BBI) {
BI = NI;
}
- // Reject cases where it is pointless to do this.
- if (!isa<BinaryOperator>(BI) || BI->getType()->isFloatingPointTy() ||
- BI->getType()->isVectorTy())
- return; // Floating point ops are not associative.
+ // Floating point binary operators are not associative, but we can still
+ // commute (some) of them, to canonicalize the order of their operands.
+ // This can potentially expose more CSE opportunities, and makes writing
+ // other transformations simpler.
+ if (isa<BinaryOperator>(BI) &&
+ (BI->getType()->isFloatingPointTy() || BI->getType()->isVectorTy())) {
+ // FAdd and FMul can be commuted.
+ if (BI->getOpcode() != Instruction::FMul &&
+ BI->getOpcode() != Instruction::FAdd)
+ return;
+
+ Value *LHS = BI->getOperand(0);
+ Value *RHS = BI->getOperand(1);
+ unsigned LHSRank = getRank(LHS);
+ unsigned RHSRank = getRank(RHS);
+
+ // Sort the operands by rank.
+ if (RHSRank < LHSRank) {
+ BI->setOperand(0, RHS);
+ BI->setOperand(1, LHS);
+ }
+
+ return;
+ }
+
+ // Do not reassociate operations that we do not understand.
+ if (!isa<BinaryOperator>(BI))
+ return;
// Do not reassociate boolean (i1) expressions. We want to preserve the
// original order of evaluation for short-circuited comparisons that
diff --git a/test/Transforms/Reassociate/fp-commute.ll b/test/Transforms/Reassociate/fp-commute.ll
new file mode 100644
index 0000000000..5644f7ca70
--- /dev/null
+++ b/test/Transforms/Reassociate/fp-commute.ll
@@ -0,0 +1,16 @@
+; RUN: opt -reassociate -S < %s | FileCheck %s
+
+target triple = "armv7-apple-ios"
+
+; CHECK: test
+define float @test(float %x, float %y) {
+entry:
+; CHECK: fmul float %x, %y
+; CHECK: fmul float %x, %y
+ %0 = fmul float %x, %y
+ %1 = fmul float %y, %x
+ %2 = fsub float %0, %1
+ ret float %1
+}
+
+