summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-09-18 06:30:59 +0000
committerChris Lattner <sabre@nondot.org>2005-09-18 06:30:59 +0000
commit797dee77053e4bbf0b95ae02ab725b279cf817ef (patch)
tree907280b0f7a80507b57bed54ec2eaa1ec299f455 /llvm/lib/Transforms
parent01f56c68e947157ab3aa6a3bfde7ebde73d18821 (diff)
downloadbcm5719-llvm-797dee77053e4bbf0b95ae02ab725b279cf817ef.tar.gz
bcm5719-llvm-797dee77053e4bbf0b95ae02ab725b279cf817ef.zip
Compile
struct S { unsigned int i : 6, j : 11, k : 15; } b; void plus2 (unsigned int x) { b.j += x; } to: plus2: mov %EAX, DWORD PTR [b] mov %ECX, %EAX and %ECX, 131008 mov %EDX, DWORD PTR [%ESP + 4] shl %EDX, 6 add %EDX, %ECX and %EDX, 131008 and %EAX, -131009 or %EDX, %EAX mov DWORD PTR [b], %EDX ret instead of: plus2: mov %EAX, DWORD PTR [b] mov %ECX, %EAX shr %ECX, 6 and %ECX, 2047 add %ECX, DWORD PTR [%ESP + 4] shl %ECX, 6 and %ECX, 131008 and %EAX, -131009 or %ECX, %EAX mov DWORD PTR [b], %ECX ret llvm-svn: 23385
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Scalar/InstructionCombining.cpp101
1 files changed, 70 insertions, 31 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
index 5468a5665b0..cd02410705d 100644
--- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -3364,6 +3364,8 @@ Instruction *InstCombiner::visitShiftInst(ShiftInst &I) {
if (BinaryOperator *Op0BO = dyn_cast<BinaryOperator>(Op0)) {
// Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C)
+ Value *V1, *V2, *V3;
+ ConstantInt *CC;
switch (Op0BO->getOpcode()) {
default: break;
case Instruction::Add:
@@ -3372,39 +3374,76 @@ Instruction *InstCombiner::visitShiftInst(ShiftInst &I) {
case Instruction::Xor:
// These operators commute.
// Turn (Y + (X >> C)) << C -> (X + (Y << C)) & (~0 << C)
- if (ShiftInst *XS = dyn_cast<ShiftInst>(Op0BO->getOperand(1)))
- if (isLeftShift && XS->hasOneUse() && XS->getOperand(1) == CUI &&
- XS->getOpcode() == Instruction::Shr) {
- Instruction *YS = new ShiftInst(Instruction::Shl,
- Op0BO->getOperand(0), CUI,
- Op0BO->getName());
- InsertNewInstBefore(YS, I); // (Y << C)
- Instruction *X = BinaryOperator::create(Op0BO->getOpcode(), YS,
- XS->getOperand(0),
- XS->getName());
- InsertNewInstBefore(X, I); // (X + (Y << C))
- Constant *C2 = ConstantInt::getAllOnesValue(X->getType());
- C2 = ConstantExpr::getShl(C2, CUI);
- return BinaryOperator::createAnd(X, C2);
- }
- // Fall through.
+ if (isLeftShift && Op0BO->getOperand(1)->hasOneUse() &&
+ match(Op0BO->getOperand(1),
+ m_Shr(m_Value(V1), m_ConstantInt(CC))) && CC == CUI) {
+ Instruction *YS = new ShiftInst(Instruction::Shl,
+ Op0BO->getOperand(0), CUI,
+ Op0BO->getName());
+ InsertNewInstBefore(YS, I); // (Y << C)
+ Instruction *X = BinaryOperator::create(Op0BO->getOpcode(), YS,
+ V1,
+ Op0BO->getOperand(1)->getName());
+ InsertNewInstBefore(X, I); // (X + (Y << C))
+ Constant *C2 = ConstantInt::getAllOnesValue(X->getType());
+ C2 = ConstantExpr::getShl(C2, CUI);
+ return BinaryOperator::createAnd(X, C2);
+ }
+
+ // Turn (Y + ((X >> C) & CC)) << C -> ((X & (CC << C)) + (Y << C))
+ if (isLeftShift && Op0BO->getOperand(1)->hasOneUse() &&
+ match(Op0BO->getOperand(1),
+ m_And(m_Shr(m_Value(V1), m_Value(V2)),
+ m_ConstantInt(CC))) && V2 == CUI &&
+ cast<BinaryOperator>(Op0BO->getOperand(1))->getOperand(0)->hasOneUse()) {
+ Instruction *YS = new ShiftInst(Instruction::Shl,
+ Op0BO->getOperand(0), CUI,
+ Op0BO->getName());
+ InsertNewInstBefore(YS, I); // (Y << C)
+ Instruction *XM =
+ BinaryOperator::createAnd(V1, ConstantExpr::getShl(CC, CUI),
+ V1->getName()+".mask");
+ InsertNewInstBefore(XM, I); // X & (CC << C)
+
+ return BinaryOperator::create(Op0BO->getOpcode(), YS, XM);
+ }
+
+ // FALL THROUGH.
case Instruction::Sub:
// Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C)
- if (ShiftInst *XS = dyn_cast<ShiftInst>(Op0BO->getOperand(0)))
- if (isLeftShift && XS->hasOneUse() && XS->getOperand(1) == CUI &&
- XS->getOpcode() == Instruction::Shr) {
- Instruction *YS = new ShiftInst(Instruction::Shl,
- Op0BO->getOperand(1), CUI,
- Op0BO->getName());
- InsertNewInstBefore(YS, I); // (Y << C)
- Instruction *X = BinaryOperator::create(Op0BO->getOpcode(), YS,
- XS->getOperand(0),
- XS->getName());
- InsertNewInstBefore(X, I); // (X + (Y << C))
- Constant *C2 = ConstantInt::getAllOnesValue(X->getType());
- C2 = ConstantExpr::getShl(C2, CUI);
- return BinaryOperator::createAnd(X, C2);
- }
+ if (isLeftShift && Op0BO->getOperand(0)->hasOneUse() &&
+ match(Op0BO->getOperand(0),
+ m_Shr(m_Value(V1), m_ConstantInt(CC))) && CC == CUI) {
+ Instruction *YS = new ShiftInst(Instruction::Shl,
+ Op0BO->getOperand(1), CUI,
+ Op0BO->getName());
+ InsertNewInstBefore(YS, I); // (Y << C)
+ Instruction *X = BinaryOperator::create(Op0BO->getOpcode(), YS,
+ V1,
+ Op0BO->getOperand(0)->getName());
+ InsertNewInstBefore(X, I); // (X + (Y << C))
+ Constant *C2 = ConstantInt::getAllOnesValue(X->getType());
+ C2 = ConstantExpr::getShl(C2, CUI);
+ return BinaryOperator::createAnd(X, C2);
+ }
+
+ if (isLeftShift && Op0BO->getOperand(0)->hasOneUse() &&
+ match(Op0BO->getOperand(0),
+ m_And(m_Shr(m_Value(V1), m_Value(V2)),
+ m_ConstantInt(CC))) && V2 == CUI &&
+ cast<BinaryOperator>(Op0BO->getOperand(0))->getOperand(0)->hasOneUse()) {
+ Instruction *YS = new ShiftInst(Instruction::Shl,
+ Op0BO->getOperand(1), CUI,
+ Op0BO->getName());
+ InsertNewInstBefore(YS, I); // (Y << C)
+ Instruction *XM =
+ BinaryOperator::createAnd(V1, ConstantExpr::getShl(CC, CUI),
+ V1->getName()+".mask");
+ InsertNewInstBefore(XM, I); // X & (CC << C)
+
+ return BinaryOperator::create(Op0BO->getOpcode(), YS, XM);
+ }
+
break;
}
OpenPOWER on IntegriCloud