aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-10-08 05:07:56 +0000
committerChris Lattner <sabre@nondot.org>2004-10-08 05:07:56 +0000
commitb99d6b1cac36d4b24aa3e520c87826012eaffe45 (patch)
tree35ca363b54db9f36a00c35192a1b7a9492938157 /lib
parent8797f5975878b7daab4ef15787dc649f6088c073 (diff)
downloadexternal_llvm-b99d6b1cac36d4b24aa3e520c87826012eaffe45.zip
external_llvm-b99d6b1cac36d4b24aa3e520c87826012eaffe45.tar.gz
external_llvm-b99d6b1cac36d4b24aa3e520c87826012eaffe45.tar.bz2
Instcombine (X & FF00) + xx00 -> (X+xx00) & FF00, implementing and.ll:test27
This comes up when doing adds to bitfield elements. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16836 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 3febd1d..1e4baf7 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -623,6 +623,31 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
return BinaryOperator::createSub(C, X);
}
+ // (X & FF00) + xx00 -> (X+xx00) & FF00
+ if (LHS->hasOneUse() && match(LHS, m_And(m_Value(X), m_ConstantInt(C2)))) {
+ Constant *Anded = ConstantExpr::getAnd(CRHS, C2);
+ if (Anded == CRHS) {
+ // See if all bits from the first bit set in the Add RHS up are included
+ // in the mask. First, get the rightmost bit.
+ uint64_t AddRHSV = CRHS->getRawValue();
+
+ // Form a mask of all bits from the lowest bit added through the top.
+ uint64_t AddRHSHighBits = ~((AddRHSV & -AddRHSV)-1);
+ AddRHSHighBits &= (1ULL << C2->getType()->getPrimitiveSize()*8)-1;
+
+ // See if the and mask includes all of these bits.
+ uint64_t AddRHSHighBitsAnd = AddRHSHighBits & C2->getRawValue();
+
+ if (AddRHSHighBits == AddRHSHighBitsAnd) {
+ // Okay, the xform is safe. Insert the new add pronto.
+ Value *NewAdd = InsertNewInstBefore(BinaryOperator::createAdd(X, CRHS,
+ LHS->getName()), I);
+ return BinaryOperator::createAnd(NewAdd, C2);
+ }
+ }
+ }
+
+
// Try to fold constant add into select arguments.
if (SelectInst *SI = dyn_cast<SelectInst>(LHS))
if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))