forked from OSchip/llvm-project
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:
parent
4496c44e5f
commit
f4f80e1f39
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue