Thread divisions over selects and phis. This doesn't fire much and has basically
authorDuncan Sands <baldrick@free.fr>
Fri, 28 Jan 2011 18:50:50 +0000 (18:50 +0000)
committerDuncan Sands <baldrick@free.fr>
Fri, 28 Jan 2011 18:50:50 +0000 (18:50 +0000)
zero effect on the testsuite (it improves two Ada testcases).

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

lib/Analysis/InstructionSimplify.cpp

index 790b619814ccc2270c05a6eec16c941b23b751ef..54dc6e6148e58a558ca5d105a96ba1fbce4a412d 100644 (file)
@@ -759,6 +759,8 @@ static Value *SimplifyDiv(unsigned Opcode, Value *Op0, Value *Op1,
     }
   }
 
+  bool isSigned = Opcode == Instruction::SDiv;
+
   // X / undef -> undef
   if (isa<UndefValue>(Op1))
     return Op1;
@@ -795,7 +797,6 @@ static Value *SimplifyDiv(unsigned Opcode, Value *Op0, Value *Op1,
     if (Y != Op1) std::swap(X, Y); // Ensure expression is (X * Y) / Y, Y = Op1
     BinaryOperator *Mul = dyn_cast<BinaryOperator>(Op0);
     // If the Mul knows it does not overflow, then we are good to go.
-    bool isSigned = Opcode == Instruction::SDiv;
     if ((isSigned && Mul->hasNoSignedWrap()) ||
         (!isSigned && Mul->hasNoUnsignedWrap()))
       return X;
@@ -805,6 +806,23 @@ static Value *SimplifyDiv(unsigned Opcode, Value *Op0, Value *Op1,
         return X;
   }
 
+  // (X rem Y) / Y -> 0
+  if ((isSigned && match(Op0, m_SRem(m_Value(), m_Specific(Op1)))) ||
+      (!isSigned && match(Op0, m_URem(m_Value(), m_Specific(Op1)))))
+    return Constant::getNullValue(Op0->getType());
+
+  // If the operation is with the result of a select instruction, check whether
+  // operating on either branch of the select always yields the same value.
+  if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1))
+    if (Value *V = ThreadBinOpOverSelect(Opcode, Op0, Op1, TD, DT, MaxRecurse))
+      return V;
+
+  // If the operation is with the result of a phi instruction, check whether
+  // operating on all incoming values of the phi always yields the same value.
+  if (isa<PHINode>(Op0) || isa<PHINode>(Op1))
+    if (Value *V = ThreadBinOpOverPHI(Opcode, Op0, Op1, TD, DT, MaxRecurse))
+      return V;
+
   return 0;
 }
 
@@ -815,10 +833,6 @@ static Value *SimplifySDivInst(Value *Op0, Value *Op1, const TargetData *TD,
   if (Value *V = SimplifyDiv(Instruction::SDiv, Op0, Op1, TD, DT, MaxRecurse))
     return V;
 
-  // (X rem Y) / Y -> 0
-  if (match(Op0, m_SRem(m_Value(), m_Specific(Op1))))
-    return Constant::getNullValue(Op0->getType());
-
   return 0;
 }
 
@@ -834,10 +848,6 @@ static Value *SimplifyUDivInst(Value *Op0, Value *Op1, const TargetData *TD,
   if (Value *V = SimplifyDiv(Instruction::UDiv, Op0, Op1, TD, DT, MaxRecurse))
     return V;
 
-  // (X rem Y) / Y -> 0
-  if (match(Op0, m_URem(m_Value(), m_Specific(Op1))))
-    return Constant::getNullValue(Op0->getType());
-
   return 0;
 }