Have SimplifyBinOp dispatch Xor, Add and Sub to the corresponding methods
authorDuncan Sands <baldrick@free.fr>
Mon, 20 Dec 2010 14:47:04 +0000 (14:47 +0000)
committerDuncan Sands <baldrick@free.fr>
Mon, 20 Dec 2010 14:47:04 +0000 (14:47 +0000)
(they had just been forgotten before).  Adding Xor causes "main" in the
existing testcase 2010-11-01-lshr-mask.ll to be hugely more simplified.

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

lib/Analysis/InstructionSimplify.cpp
test/Transforms/InstCombine/2010-11-01-lshr-mask.ll

index 2458d204bcad3c53c7e54deecb776f24c3bbd332..f4636553ca2b5a8133c6162b4f044c72248d8b2e 100644 (file)
@@ -11,7 +11,9 @@
 // that do not require creating new instructions.  This does constant folding
 // ("add i32 1, 1" -> "2") but can also handle non-constant operands, either
 // returning a constant ("and i32 %x, 0" -> "0") or an already existing value
-// ("and i32 %x, %x" -> "%x").
+// ("and i32 %x, %x" -> "%x").  All operands are assumed to have already been
+// simplified: This is usually true and assuming it simplifies the logic (if
+// they have not been simplified then results are correct but maybe suboptimal).
 //
 //===----------------------------------------------------------------------===//
 
@@ -229,8 +231,9 @@ static Value *ThreadCmpOverPHI(CmpInst::Predicate Pred, Value *LHS, Value *RHS,
 
 /// SimplifyAddInst - Given operands for an Add, see if we can
 /// fold the result.  If not, this returns null.
-Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
-                             const TargetData *TD, const DominatorTree *) {
+static Value *SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
+                              const TargetData *TD, const DominatorTree *DT,
+                              unsigned MaxRecurse) {
   if (Constant *CLHS = dyn_cast<Constant>(Op0)) {
     if (Constant *CRHS = dyn_cast<Constant>(Op1)) {
       Constant *Ops[] = { CLHS, CRHS };
@@ -252,6 +255,7 @@ Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
 
   // X + (Y - X) -> Y
   // (Y - X) + X -> Y
+  // Eg: X + -X -> 0
   Value *Y = 0;
   if (match(Op1, m_Sub(m_Value(Y), m_Specific(Op0))) ||
       match(Op0, m_Sub(m_Value(Y), m_Specific(Op1))))
@@ -274,10 +278,16 @@ Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
   return 0;
 }
 
+Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
+                             const TargetData *TD, const DominatorTree *DT) {
+  return ::SimplifyAddInst(Op0, Op1, isNSW, isNUW, TD, DT, RecursionLimit);
+}
+
 /// SimplifySubInst - Given operands for a Sub, see if we can
 /// fold the result.  If not, this returns null.
-Value *llvm::SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
-                             const TargetData *TD, const DominatorTree *) {
+static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
+                              const TargetData *TD, const DominatorTree *,
+                              unsigned MaxRecurse) {
   if (Constant *CLHS = dyn_cast<Constant>(Op0))
     if (Constant *CRHS = dyn_cast<Constant>(Op1)) {
       Constant *Ops[] = { CLHS, CRHS };
@@ -317,6 +327,11 @@ Value *llvm::SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
   return 0;
 }
 
+Value *llvm::SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
+                             const TargetData *TD, const DominatorTree *DT) {
+  return ::SimplifySubInst(Op0, Op1, isNSW, isNUW, TD, DT, RecursionLimit);
+}
+
 /// SimplifyAndInst - Given operands for an And, see if we can
 /// fold the result.  If not, this returns null.
 static Value *SimplifyAndInst(Value *Op0, Value *Op1, const TargetData *TD,
@@ -826,6 +841,13 @@ static Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
   switch (Opcode) {
   case Instruction::And: return SimplifyAndInst(LHS, RHS, TD, DT, MaxRecurse);
   case Instruction::Or:  return SimplifyOrInst(LHS, RHS, TD, DT, MaxRecurse);
+  case Instruction::Xor: return SimplifyXorInst(LHS, RHS, TD, DT, MaxRecurse);
+  case Instruction::Add: return SimplifyAddInst(LHS, RHS, /* isNSW */ false,
+                                                /* isNUW */ false, TD, DT,
+                                                MaxRecurse);
+  case Instruction::Sub: return SimplifySubInst(LHS, RHS, /* isNSW */ false,
+                                                /* isNUW */ false, TD, DT,
+                                                MaxRecurse);
   default:
     if (Constant *CLHS = dyn_cast<Constant>(LHS))
       if (Constant *CRHS = dyn_cast<Constant>(RHS)) {
index 34b165bcbe7ef9a9d98cc7f7026f943ef86ed497..441d5f9b0b6445fc7c2f4ad13c943c3a2bda0927 100644 (file)
@@ -5,14 +5,16 @@
 define i32 @main(i32 %argc) nounwind ssp {
 entry:
   %tmp3151 = trunc i32 %argc to i8
+; CHECK: %tmp3162 = shl i8 %tmp3151, 5
+; CHECK: and i8 %tmp3162, 64
+; CHECK-NOT: shl
+; CHECK-NOT: shr
   %tmp3161 = or i8 %tmp3151, -17
   %tmp3162 = and i8 %tmp3151, 122
   %tmp3163 = xor i8 %tmp3162, -17
   %tmp4114 = shl i8 %tmp3163, 6
   %tmp4115 = xor i8 %tmp4114, %tmp3163
   %tmp4120 = xor i8 %tmp3161, %tmp4115
-; CHECK: lshr i8 %tmp4115, 1
-; CHECK-NOT: shl i8 %tmp4126, 6
   %tmp4126 = lshr i8 %tmp4120, 7
   %tmp4127 = mul i8 %tmp4126, 64
   %tmp4086 = zext i8 %tmp4127 to i32