Implement Transforms/InstCombine/xor.ll:test19
authorChris Lattner <sabre@nondot.org>
Mon, 16 Feb 2004 01:20:27 +0000 (01:20 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 16 Feb 2004 01:20:27 +0000 (01:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11490 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp

index 773441f53838fb84721b83c1bbf3ba29ec0ea8af..15c894508918336a42dc27fd2bef08f4fe7ddaab 100644 (file)
@@ -1002,15 +1002,26 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
   return Changed ? &I : 0;
 }
 
+// XorSelf - Implements: X ^ X --> 0
+struct XorSelf {
+  Value *RHS;
+  XorSelf(Value *rhs) : RHS(rhs) {}
+  bool shouldApply(Value *LHS) const { return LHS == RHS; }
+  Instruction *apply(BinaryOperator &Xor) const {
+    return &Xor;
+  }
+};
 
 
 Instruction *InstCombiner::visitXor(BinaryOperator &I) {
   bool Changed = SimplifyCommutative(I);
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
 
-  // xor X, X = 0
-  if (Op0 == Op1)
+  // xor X, X = 0, even if X is nested in a sequence of Xor's.
+  if (Instruction *Result = AssociativeOpt(I, XorSelf(Op1))) {
+    assert(Result == &I && "AssociativeOpt didn't work?");
     return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+  }
 
   if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1)) {
     // xor X, 0 == X