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.

llvm-svn: 156323
This commit is contained in:
Owen Anderson 2012-05-07 20:47:23 +00:00
parent 4496c44e5f
commit f4f80e1f39
2 changed files with 44 additions and 4 deletions

View File

@ -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

View File

@ -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
}