Move InstCombine's knowledge of fdiv to SimplifyInstruction().
authorFrits van Bommel <fvbommel@gmail.com>
Sat, 29 Jan 2011 15:26:31 +0000 (15:26 +0000)
committerFrits van Bommel <fvbommel@gmail.com>
Sat, 29 Jan 2011 15:26:31 +0000 (15:26 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124534 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/InstructionSimplify.h
lib/Analysis/InstructionSimplify.cpp
lib/Transforms/InstCombine/InstCombine.h
lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
test/Transforms/InstSimplify/fdiv.ll [new file with mode: 0644]

index d39432d072bab704c35473ab84db8320f8a865ac..9ad7bc6e8a5766a34719dad4c535b03cac693731 100644 (file)
@@ -48,7 +48,12 @@ namespace llvm {
   /// SimplifyUDivInst - Given operands for a UDiv, see if we can
   /// fold the result.  If not, this returns null.
   Value *SimplifyUDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
-                         const DominatorTree *DT = 0);
+                          const DominatorTree *DT = 0);
+
+  /// SimplifyFDivInst - Given operands for an FDiv, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifyFDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+                          const DominatorTree *DT = 0);
 
   /// SimplifyShlInst - Given operands for a Shl, see if we can
   /// fold the result.  If not, this returns null.
index 16cdfeb838f877dfb53e7e7cf82ab1e3c6fa1f25..c1fa6fcca63ff9baf212cba7021e46b53bbffda6 100644 (file)
@@ -837,7 +837,7 @@ static Value *SimplifySDivInst(Value *Op0, Value *Op1, const TargetData *TD,
 }
 
 Value *llvm::SimplifySDivInst(Value *Op0, Value *Op1, const TargetData *TD,
-                             const DominatorTree *DT) {
+                              const DominatorTree *DT) {
   return ::SimplifySDivInst(Op0, Op1, TD, DT, RecursionLimit);
 }
 
@@ -852,10 +852,28 @@ static Value *SimplifyUDivInst(Value *Op0, Value *Op1, const TargetData *TD,
 }
 
 Value *llvm::SimplifyUDivInst(Value *Op0, Value *Op1, const TargetData *TD,
-                             const DominatorTree *DT) {
+                              const DominatorTree *DT) {
   return ::SimplifyUDivInst(Op0, Op1, TD, DT, RecursionLimit);
 }
 
+static Value *SimplifyFDivInst(Value *Op0, Value *Op1, const TargetData *TD,
+                               const DominatorTree *DT, unsigned MaxRecurse) {
+  // undef / X -> undef    (the undef could be a snan).
+  if (isa<UndefValue>(Op0))
+    return Op0;
+
+  // X / undef -> undef
+  if (isa<UndefValue>(Op1))
+    return Op1;
+
+  return 0;
+}
+
+Value *llvm::SimplifyFDivInst(Value *Op0, Value *Op1, const TargetData *TD,
+                              const DominatorTree *DT) {
+  return ::SimplifyFDivInst(Op0, Op1, TD, DT, RecursionLimit);
+}
+
 /// SimplifyShift - Given operands for an Shl, LShr or AShr, see if we can
 /// fold the result.  If not, this returns null.
 static Value *SimplifyShift(unsigned Opcode, Value *Op0, Value *Op1,
@@ -1760,6 +1778,7 @@ static Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
   case Instruction::Mul: return SimplifyMulInst(LHS, RHS, TD, DT, MaxRecurse);
   case Instruction::SDiv: return SimplifySDivInst(LHS, RHS, TD, DT, MaxRecurse);
   case Instruction::UDiv: return SimplifyUDivInst(LHS, RHS, TD, DT, MaxRecurse);
+  case Instruction::FDiv: return SimplifyFDivInst(LHS, RHS, TD, DT, MaxRecurse);
   case Instruction::Shl: return SimplifyShlInst(LHS, RHS, TD, DT, MaxRecurse);
   case Instruction::LShr: return SimplifyLShrInst(LHS, RHS, TD, DT, MaxRecurse);
   case Instruction::AShr: return SimplifyAShrInst(LHS, RHS, TD, DT, MaxRecurse);
@@ -1847,6 +1866,9 @@ Value *llvm::SimplifyInstruction(Instruction *I, const TargetData *TD,
   case Instruction::UDiv:
     Result = SimplifyUDivInst(I->getOperand(0), I->getOperand(1), TD, DT);
     break;
+  case Instruction::FDiv:
+    Result = SimplifyFDivInst(I->getOperand(0), I->getOperand(1), TD, DT);
+    break;
   case Instruction::Shl:
     Result = SimplifyShlInst(I->getOperand(0), I->getOperand(1), TD, DT);
     break;
index 450e7f0a398bcb1ceec404f554b188aae45cd41a..ef49790d148b3d1ac032ace5b35cd089ffe6f1a4 100644 (file)
@@ -118,7 +118,6 @@ public:
   Instruction *commonIDivTransforms(BinaryOperator &I);
   Instruction *visitUDiv(BinaryOperator &I);
   Instruction *visitSDiv(BinaryOperator &I);
-  Instruction *visitFDiv(BinaryOperator &I);
   Value *FoldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS);
   Value *FoldAndOfFCmps(FCmpInst *LHS, FCmpInst *RHS);
   Instruction *visitAnd(BinaryOperator &I);
index b5b98411f596731c2d1153fa869bcc8e0560d2c6..32b2a0ac0eea607fadbc863032f76dfb87f401c8 100644 (file)
@@ -473,20 +473,6 @@ Instruction *InstCombiner::visitSDiv(BinaryOperator &I) {
   return 0;
 }
 
-Instruction *InstCombiner::visitFDiv(BinaryOperator &I) {
-  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
-
-  // undef / X -> undef    (the undef could be a snan).
-  if (isa<UndefValue>(Op0))
-    return ReplaceInstUsesWith(I, Op0);
-
-  // X / undef -> undef
-  if (isa<UndefValue>(Op1))
-    return ReplaceInstUsesWith(I, Op1);
-
-  return 0;
-}
-
 /// This function implements the transforms on rem instructions that work
 /// regardless of the kind of rem instruction it is (urem, srem, or frem). It 
 /// is used by the visitors to those instructions.
diff --git a/test/Transforms/InstSimplify/fdiv.ll b/test/Transforms/InstSimplify/fdiv.ll
new file mode 100644 (file)
index 0000000..9d85154
--- /dev/null
@@ -0,0 +1,17 @@
+; RUN: opt < %s -instsimplify -S | FileCheck %s
+
+define double @fdiv_of_undef(double %X) {
+; CHECK: @fdiv_of_undef
+; undef / X -> undef
+  %r = fdiv double undef, %X
+  ret double %r
+; CHECK: ret double undef
+}
+
+define double @fdiv_by_undef(double %X) {
+; CHECK: @fdiv_by_undef
+; X / undef -> undef
+  %r = fdiv double %X, undef
+  ret double %r
+; CHECK: ret double undef
+}