Fast-math optimization: fold multiply by zero
authorMichael Ilseman <milseman@apple.com>
Tue, 27 Nov 2012 00:46:26 +0000 (00:46 +0000)
committerMichael Ilseman <milseman@apple.com>
Tue, 27 Nov 2012 00:46:26 +0000 (00:46 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168648 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/InstructionSimplify.h
lib/Analysis/InstructionSimplify.cpp

index 6db400c563d6f758b0ca1a2472bb75e58a42ad72..ce7818184e9a634306d94c27bc1dbbae7b49f39d 100644 (file)
@@ -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,
index a76e5ad1b8f88621c63a590687251bd7b7b4a0ec..e3fe9240d0fdf990210ceecd63dec7b35ddc6441 100644 (file)
@@ -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;