diff options
| author | Chris Lattner <sabre@nondot.org> | 2004-10-08 05:07:56 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2004-10-08 05:07:56 +0000 |
| commit | bff91d9a2e556b1aadf274c563cec80a483725a4 (patch) | |
| tree | e3d70604e53f2ff4c977e0458091f1e66ba8dd4d /llvm/lib | |
| parent | 9467062bcf7e06720cc312abf6ffb756b7566838 (diff) | |
| download | bcm5719-llvm-bff91d9a2e556b1aadf274c563cec80a483725a4.tar.gz bcm5719-llvm-bff91d9a2e556b1aadf274c563cec80a483725a4.zip | |
Instcombine (X & FF00) + xx00 -> (X+xx00) & FF00, implementing and.ll:test27
This comes up when doing adds to bitfield elements.
llvm-svn: 16836
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index 3febd1dd46f..1e4baf7db37 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/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)) |

