[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
lattner at cs.uiuc.edu
Fri Sep 19 10:36:02 PDT 2003
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.119 -> 1.120
---
Log message:
Implement InstCombine/add.ll:test(15|16)
---
Diffs of the changes:
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.119 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.120
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.119 Thu Sep 11 17:24:54 2003
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri Sep 19 10:35:42 2003
@@ -764,6 +764,43 @@
return BinaryOperator::create(Instruction::And, Or, RHS);
}
}
+ } else if (Op0I->getOpcode() == Instruction::Add &&
+ Op0I->use_size() == 1) {
+ // Adding a one to a single bit bit-field should be turned into an XOR
+ // of the bit. First thing to check is to see if this AND is with a
+ // single bit constant.
+ unsigned long long AndRHS = cast<ConstantInt>(RHS)->getRawValue();
+
+ // Clear bits that are not part of the constant.
+ AndRHS &= (1ULL << RHS->getType()->getPrimitiveSize()*8)-1;
+
+ // If there is only one bit set...
+ if ((AndRHS & (AndRHS-1)) == 0) {
+ // Ok, at this point, we know that we are masking the result of the
+ // ADD down to exactly one bit. If the constant we are adding has
+ // no bits set below this bit, then we can eliminate the ADD.
+ unsigned long long AddRHS = cast<ConstantInt>(Op0CI)->getRawValue();
+
+ // Check to see if any bits below the one bit set in AndRHS are set.
+ if ((AddRHS & (AndRHS-1)) == 0) {
+ // If not, the only thing that can effect the output of the AND is
+ // the bit specified by AndRHS. If that bit is set, the effect of
+ // the XOR is to toggle the bit. If it is clear, then the ADD has
+ // no effect.
+ if ((AddRHS & AndRHS) == 0) { // Bit is not set, noop
+ I.setOperand(0, Op0I->getOperand(0));
+ return &I;
+ } else {
+ std::string Name = Op0I->getName(); Op0I->setName("");
+ // Pull the XOR out of the AND.
+ Instruction *NewAnd =
+ BinaryOperator::create(Instruction::And, Op0I->getOperand(0),
+ RHS, Name);
+ InsertNewInstBefore(NewAnd, I);
+ return BinaryOperator::create(Instruction::Xor, NewAnd, RHS);
+ }
+ }
+ }
}
}
}
More information about the llvm-commits
mailing list