summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Ilseman <milseman@apple.com>2012-11-27 00:46:26 +0000
committerMichael Ilseman <milseman@apple.com>2012-11-27 00:46:26 +0000
commitbe9137a5c5eba6fde096232e6fe908ab0da2579e (patch)
treec3fdd81855bbcf35f9d3c7e4f10410c5a80ccda5
parentc537743984d0f90ddd89f2fa9ebcb51dd55b73cf (diff)
downloadbcm5719-llvm-be9137a5c5eba6fde096232e6fe908ab0da2579e.tar.gz
bcm5719-llvm-be9137a5c5eba6fde096232e6fe908ab0da2579e.zip
Fast-math optimization: fold multiply by zero
Added in first optimization using fast-math flags to serve as an example for following optimizations. SimplifyInstruction will now try to optimize an fmul observing its FastMathFlags to see if it can fold multiply by zero when 'nnan' and 'nsz' flags are set. llvm-svn: 168648
-rw-r--r--llvm/include/llvm/Analysis/InstructionSimplify.h9
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp39
2 files changed, 48 insertions, 0 deletions
diff --git a/llvm/include/llvm/Analysis/InstructionSimplify.h b/llvm/include/llvm/Analysis/InstructionSimplify.h
index 6db400c563d..ce7818184e9 100644
--- a/llvm/include/llvm/Analysis/InstructionSimplify.h
+++ b/llvm/include/llvm/Analysis/InstructionSimplify.h
@@ -25,6 +25,7 @@ namespace llvm {
class DominatorTree;
class Instruction;
class DataLayout;
+ struct FastMathFlags;
class TargetLibraryInfo;
class Type;
class Value;
@@ -43,6 +44,14 @@ namespace llvm {
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
+ /// Given operands for an FMul, see if we can fold the result. If not, this
+ /// returns null.
+ Value *SimplifyFMulInst(Value *LHS, Value *RHS,
+ FastMathFlags FMF,
+ const DataLayout *TD = 0,
+ const TargetLibraryInfo *TLI = 0,
+ const DominatorTree *DT = 0);
+
/// SimplifyMulInst - Given operands for a Mul, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index a76e5ad1b8f..e3fe9240d0f 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -886,6 +886,33 @@ Value *llvm::SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
RecursionLimit);
}
+/// Given the operands for an FMul, see if we can fold the result
+static Value *SimplifyFMulInst(Value *Op0, Value *Op1,
+ FastMathFlags FMF,
+ const Query &Q,
+ unsigned MaxRecurse) {
+ if (Constant *CLHS = dyn_cast<Constant>(Op0)) {
+ if (Constant *CRHS = dyn_cast<Constant>(Op1)) {
+ Constant *Ops[] = { CLHS, CRHS };
+ return ConstantFoldInstOperands(Instruction::FMul, CLHS->getType(),
+ Ops, Q.TD, Q.TLI);
+ }
+ }
+
+ // Check for some fast-math optimizations
+ if (FMF.NoNaNs) {
+ if (FMF.NoSignedZeros) {
+ // fmul N S 0, x ==> 0
+ if (match(Op0, m_Zero()))
+ return Op0;
+ if (match(Op1, m_Zero()))
+ return Op1;
+ }
+ }
+
+ return 0;
+}
+
/// SimplifyMulInst - Given operands for a Mul, see if we can
/// fold the result. If not, this returns null.
static Value *SimplifyMulInst(Value *Op0, Value *Op1, const Query &Q,
@@ -951,6 +978,14 @@ static Value *SimplifyMulInst(Value *Op0, Value *Op1, const Query &Q,
return 0;
}
+Value *llvm::SimplifyFMulInst(Value *Op0, Value *Op1,
+ FastMathFlags FMF,
+ const DataLayout *TD,
+ const TargetLibraryInfo *TLI,
+ const DominatorTree *DT) {
+ return ::SimplifyFMulInst(Op0, Op1, FMF, Query (TD, TLI, DT), RecursionLimit);
+}
+
Value *llvm::SimplifyMulInst(Value *Op0, Value *Op1, const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
@@ -2799,6 +2834,10 @@ Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout *TD,
cast<BinaryOperator>(I)->hasNoUnsignedWrap(),
TD, TLI, DT);
break;
+ case Instruction::FMul:
+ Result = SimplifyFMulInst(I->getOperand(0), I->getOperand(1),
+ I->getFastMathFlags(), TD, TLI, DT);
+ break;
case Instruction::Mul:
Result = SimplifyMulInst(I->getOperand(0), I->getOperand(1), TD, TLI, DT);
break;
OpenPOWER on IntegriCloud