[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
lattner at cs.uiuc.edu
Thu Jan 5 23:12:47 PST 2006
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.406 -> 1.407
---
Log message:
Extract a bunch of code out of visitShiftInst into FoldShiftByConstant. No
functionality changes.
---
Diffs of the changes: (+190 -181)
InstructionCombining.cpp | 371 ++++++++++++++++++++++++-----------------------
1 files changed, 190 insertions(+), 181 deletions(-)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.406 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.407
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.406 Sat Nov 5 03:21:28 2005
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri Jan 6 01:12:35 2006
@@ -119,6 +119,8 @@
Instruction *FoldGEPSetCC(User *GEPLHS, Value *RHS,
Instruction::BinaryOps Cond, Instruction &I);
Instruction *visitShiftInst(ShiftInst &I);
+ Instruction *FoldShiftByConstant(Value *Op0, ConstantUInt *Op1,
+ ShiftInst &I);
Instruction *visitCastInst(CastInst &CI);
Instruction *FoldSelectOpOp(SelectInst &SI, Instruction *TI,
Instruction *FI);
@@ -3438,75 +3440,84 @@
}
}
- if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(Op1)) {
- // shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr
- // of a signed value.
- //
- unsigned TypeBits = Op0->getType()->getPrimitiveSizeInBits();
- if (CUI->getValue() >= TypeBits) {
- if (!Op0->getType()->isSigned() || isLeftShift)
- return ReplaceInstUsesWith(I, Constant::getNullValue(Op0->getType()));
- else {
- I.setOperand(1, ConstantUInt::get(Type::UByteTy, TypeBits-1));
- return &I;
- }
- }
-
- // ((X*C1) << C2) == (X * (C1 << C2))
- if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Op0))
- if (BO->getOpcode() == Instruction::Mul && isLeftShift)
- if (Constant *BOOp = dyn_cast<Constant>(BO->getOperand(1)))
- return BinaryOperator::createMul(BO->getOperand(0),
- ConstantExpr::getShl(BOOp, CUI));
+ if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(Op1))
+ if (Instruction *Res = FoldShiftByConstant(Op0, CUI, I))
+ return Res;
+ return 0;
+}
- // Try to fold constant and into select arguments.
- if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
- if (Instruction *R = FoldOpIntoSelect(I, SI, this))
- return R;
- if (isa<PHINode>(Op0))
- if (Instruction *NV = FoldOpIntoPhi(I))
- return NV;
+Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantUInt *Op1,
+ ShiftInst &I) {
+ bool isLeftShift = I.getOpcode() == Instruction::Shl;
- if (Op0->hasOneUse()) {
- // If this is a SHL of a sign-extending cast, see if we can turn the input
- // into a zero extending cast (a simple strength reduction).
- if (CastInst *CI = dyn_cast<CastInst>(Op0)) {
- const Type *SrcTy = CI->getOperand(0)->getType();
- if (isLeftShift && SrcTy->isInteger() && SrcTy->isSigned() &&
- SrcTy->getPrimitiveSizeInBits() <
- CI->getType()->getPrimitiveSizeInBits()) {
- // We can change it to a zero extension if we are shifting out all of
- // the sign extended bits. To check this, form a mask of all of the
- // sign extend bits, then shift them left and see if we have anything
- // left.
- Constant *Mask = ConstantIntegral::getAllOnesValue(SrcTy); // 1111
- Mask = ConstantExpr::getZeroExtend(Mask, CI->getType()); // 00001111
- Mask = ConstantExpr::getNot(Mask); // 1's in the sign bits: 11110000
- if (ConstantExpr::getShl(Mask, CUI)->isNullValue()) {
- // If the shift is nuking all of the sign bits, change this to a
- // zero extension cast. To do this, cast the cast input to
- // unsigned, then to the requested size.
- Value *CastOp = CI->getOperand(0);
- Instruction *NC =
- new CastInst(CastOp, CastOp->getType()->getUnsignedVersion(),
- CI->getName()+".uns");
- NC = InsertNewInstBefore(NC, I);
- // Finally, insert a replacement for CI.
- NC = new CastInst(NC, CI->getType(), CI->getName());
- CI->setName("");
- NC = InsertNewInstBefore(NC, I);
- WorkList.push_back(CI); // Delete CI later.
- I.setOperand(0, NC);
- return &I; // The SHL operand was modified.
- }
+ // shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr
+ // of a signed value.
+ //
+ unsigned TypeBits = Op0->getType()->getPrimitiveSizeInBits();
+ if (Op1->getValue() >= TypeBits) {
+ if (!Op0->getType()->isSigned() || isLeftShift)
+ return ReplaceInstUsesWith(I, Constant::getNullValue(Op0->getType()));
+ else {
+ I.setOperand(1, ConstantUInt::get(Type::UByteTy, TypeBits-1));
+ return &I;
+ }
+ }
+
+ // ((X*C1) << C2) == (X * (C1 << C2))
+ if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Op0))
+ if (BO->getOpcode() == Instruction::Mul && isLeftShift)
+ if (Constant *BOOp = dyn_cast<Constant>(BO->getOperand(1)))
+ return BinaryOperator::createMul(BO->getOperand(0),
+ ConstantExpr::getShl(BOOp, Op1));
+
+ // Try to fold constant and into select arguments.
+ if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
+ if (Instruction *R = FoldOpIntoSelect(I, SI, this))
+ return R;
+ if (isa<PHINode>(Op0))
+ if (Instruction *NV = FoldOpIntoPhi(I))
+ return NV;
+
+ if (Op0->hasOneUse()) {
+ // If this is a SHL of a sign-extending cast, see if we can turn the input
+ // into a zero extending cast (a simple strength reduction).
+ if (CastInst *CI = dyn_cast<CastInst>(Op0)) {
+ const Type *SrcTy = CI->getOperand(0)->getType();
+ if (isLeftShift && SrcTy->isInteger() && SrcTy->isSigned() &&
+ SrcTy->getPrimitiveSizeInBits() <
+ CI->getType()->getPrimitiveSizeInBits()) {
+ // We can change it to a zero extension if we are shifting out all of
+ // the sign extended bits. To check this, form a mask of all of the
+ // sign extend bits, then shift them left and see if we have anything
+ // left.
+ Constant *Mask = ConstantIntegral::getAllOnesValue(SrcTy); // 1111
+ Mask = ConstantExpr::getZeroExtend(Mask, CI->getType()); // 00001111
+ Mask = ConstantExpr::getNot(Mask); // 1's in the sign bits: 11110000
+ if (ConstantExpr::getShl(Mask, Op1)->isNullValue()) {
+ // If the shift is nuking all of the sign bits, change this to a
+ // zero extension cast. To do this, cast the cast input to
+ // unsigned, then to the requested size.
+ Value *CastOp = CI->getOperand(0);
+ Instruction *NC =
+ new CastInst(CastOp, CastOp->getType()->getUnsignedVersion(),
+ CI->getName()+".uns");
+ NC = InsertNewInstBefore(NC, I);
+ // Finally, insert a replacement for CI.
+ NC = new CastInst(NC, CI->getType(), CI->getName());
+ CI->setName("");
+ NC = InsertNewInstBefore(NC, I);
+ WorkList.push_back(CI); // Delete CI later.
+ I.setOperand(0, NC);
+ return &I; // The SHL operand was modified.
}
}
-
- if (BinaryOperator *Op0BO = dyn_cast<BinaryOperator>(Op0)) {
- // Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C)
- Value *V1, *V2;
- ConstantInt *CC;
- switch (Op0BO->getOpcode()) {
+ }
+
+ if (BinaryOperator *Op0BO = dyn_cast<BinaryOperator>(Op0)) {
+ // Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C)
+ Value *V1, *V2;
+ ConstantInt *CC;
+ switch (Op0BO->getOpcode()) {
default: break;
case Instruction::Add:
case Instruction::And:
@@ -3516,85 +3527,85 @@
// Turn (Y + (X >> C)) << C -> (X + (Y << C)) & (~0 << C)
if (isLeftShift && Op0BO->getOperand(1)->hasOneUse() &&
match(Op0BO->getOperand(1),
- m_Shr(m_Value(V1), m_ConstantInt(CC))) && CC == CUI) {
+ m_Shr(m_Value(V1), m_ConstantInt(CC))) && CC == Op1) {
Instruction *YS = new ShiftInst(Instruction::Shl,
- Op0BO->getOperand(0), CUI,
+ Op0BO->getOperand(0), Op1,
Op0BO->getName());
InsertNewInstBefore(YS, I); // (Y << C)
Instruction *X = BinaryOperator::create(Op0BO->getOpcode(), YS,
V1,
- Op0BO->getOperand(1)->getName());
+ Op0BO->getOperand(1)->getName());
InsertNewInstBefore(X, I); // (X + (Y << C))
Constant *C2 = ConstantInt::getAllOnesValue(X->getType());
- C2 = ConstantExpr::getShl(C2, CUI);
+ C2 = ConstantExpr::getShl(C2, Op1);
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()) {
+ m_ConstantInt(CC))) && V2 == Op1 &&
+ cast<BinaryOperator>(Op0BO->getOperand(1))->getOperand(0)->hasOneUse()) {
Instruction *YS = new ShiftInst(Instruction::Shl,
- Op0BO->getOperand(0), CUI,
+ Op0BO->getOperand(0), Op1,
Op0BO->getName());
InsertNewInstBefore(YS, I); // (Y << C)
Instruction *XM =
- BinaryOperator::createAnd(V1, ConstantExpr::getShl(CC, CUI),
+ BinaryOperator::createAnd(V1, ConstantExpr::getShl(CC, Op1),
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 (isLeftShift && Op0BO->getOperand(0)->hasOneUse() &&
match(Op0BO->getOperand(0),
- m_Shr(m_Value(V1), m_ConstantInt(CC))) && CC == CUI) {
+ m_Shr(m_Value(V1), m_ConstantInt(CC))) && CC == Op1) {
Instruction *YS = new ShiftInst(Instruction::Shl,
- Op0BO->getOperand(1), CUI,
+ Op0BO->getOperand(1), Op1,
Op0BO->getName());
InsertNewInstBefore(YS, I); // (Y << C)
Instruction *X = BinaryOperator::create(Op0BO->getOpcode(), YS,
V1,
- Op0BO->getOperand(0)->getName());
+ Op0BO->getOperand(0)->getName());
InsertNewInstBefore(X, I); // (X + (Y << C))
Constant *C2 = ConstantInt::getAllOnesValue(X->getType());
- C2 = ConstantExpr::getShl(C2, CUI);
+ C2 = ConstantExpr::getShl(C2, Op1);
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()) {
+ m_ConstantInt(CC))) && V2 == Op1 &&
+ cast<BinaryOperator>(Op0BO->getOperand(0))->getOperand(0)->hasOneUse()) {
Instruction *YS = new ShiftInst(Instruction::Shl,
- Op0BO->getOperand(1), CUI,
+ Op0BO->getOperand(1), Op1,
Op0BO->getName());
InsertNewInstBefore(YS, I); // (Y << C)
Instruction *XM =
- BinaryOperator::createAnd(V1, ConstantExpr::getShl(CC, CUI),
+ BinaryOperator::createAnd(V1, ConstantExpr::getShl(CC, Op1),
V1->getName()+".mask");
InsertNewInstBefore(XM, I); // X & (CC << C)
return BinaryOperator::create(Op0BO->getOpcode(), YS, XM);
}
-
+
break;
- }
-
-
- // If the operand is an bitwise operator with a constant RHS, and the
- // shift is the only use, we can pull it out of the shift.
- if (ConstantInt *Op0C = dyn_cast<ConstantInt>(Op0BO->getOperand(1))) {
- bool isValid = true; // Valid only for And, Or, Xor
- bool highBitSet = false; // Transform if high bit of constant set?
-
- switch (Op0BO->getOpcode()) {
+ }
+
+
+ // If the operand is an bitwise operator with a constant RHS, and the
+ // shift is the only use, we can pull it out of the shift.
+ if (ConstantInt *Op0C = dyn_cast<ConstantInt>(Op0BO->getOperand(1))) {
+ bool isValid = true; // Valid only for And, Or, Xor
+ bool highBitSet = false; // Transform if high bit of constant set?
+
+ switch (Op0BO->getOpcode()) {
default: isValid = false; break; // Do not perform transform!
case Instruction::Add:
isValid = isLeftShift;
@@ -3606,99 +3617,97 @@
case Instruction::And:
highBitSet = true;
break;
- }
-
- // If this is a signed shift right, and the high bit is modified
- // by the logical operation, do not perform the transformation.
- // The highBitSet boolean indicates the value of the high bit of
- // the constant which would cause it to be modified for this
- // operation.
- //
- if (isValid && !isLeftShift && !I.getType()->isUnsigned()) {
- uint64_t Val = Op0C->getRawValue();
- isValid = ((Val & (1 << (TypeBits-1))) != 0) == highBitSet;
- }
-
- if (isValid) {
- Constant *NewRHS = ConstantExpr::get(I.getOpcode(), Op0C, CUI);
-
- Instruction *NewShift =
- new ShiftInst(I.getOpcode(), Op0BO->getOperand(0), CUI,
- Op0BO->getName());
- Op0BO->setName("");
- InsertNewInstBefore(NewShift, I);
-
- return BinaryOperator::create(Op0BO->getOpcode(), NewShift,
- NewRHS);
- }
+ }
+
+ // If this is a signed shift right, and the high bit is modified
+ // by the logical operation, do not perform the transformation.
+ // The highBitSet boolean indicates the value of the high bit of
+ // the constant which would cause it to be modified for this
+ // operation.
+ //
+ if (isValid && !isLeftShift && !I.getType()->isUnsigned()) {
+ uint64_t Val = Op0C->getRawValue();
+ isValid = ((Val & (1 << (TypeBits-1))) != 0) == highBitSet;
+ }
+
+ if (isValid) {
+ Constant *NewRHS = ConstantExpr::get(I.getOpcode(), Op0C, Op1);
+
+ Instruction *NewShift =
+ new ShiftInst(I.getOpcode(), Op0BO->getOperand(0), Op1,
+ Op0BO->getName());
+ Op0BO->setName("");
+ InsertNewInstBefore(NewShift, I);
+
+ return BinaryOperator::create(Op0BO->getOpcode(), NewShift,
+ NewRHS);
}
}
}
-
- // If this is a shift of a shift, see if we can fold the two together...
- if (ShiftInst *Op0SI = dyn_cast<ShiftInst>(Op0))
- if (ConstantUInt *ShiftAmt1C =
- dyn_cast<ConstantUInt>(Op0SI->getOperand(1))) {
- unsigned ShiftAmt1 = (unsigned)ShiftAmt1C->getValue();
- unsigned ShiftAmt2 = (unsigned)CUI->getValue();
-
- // Check for (A << c1) << c2 and (A >> c1) >> c2
- if (I.getOpcode() == Op0SI->getOpcode()) {
- unsigned Amt = ShiftAmt1+ShiftAmt2; // Fold into one big shift...
- if (Op0->getType()->getPrimitiveSizeInBits() < Amt)
- Amt = Op0->getType()->getPrimitiveSizeInBits();
- return new ShiftInst(I.getOpcode(), Op0SI->getOperand(0),
- ConstantUInt::get(Type::UByteTy, Amt));
- }
-
- // Check for (A << c1) >> c2 or visaversa. If we are dealing with
- // signed types, we can only support the (A >> c1) << c2 configuration,
- // because it can not turn an arbitrary bit of A into a sign bit.
- if (I.getType()->isUnsigned() || isLeftShift) {
- // Calculate bitmask for what gets shifted off the edge...
- Constant *C = ConstantIntegral::getAllOnesValue(I.getType());
- if (isLeftShift)
- C = ConstantExpr::getShl(C, ShiftAmt1C);
- else
- C = ConstantExpr::getShr(C, ShiftAmt1C);
-
- Instruction *Mask =
- BinaryOperator::createAnd(Op0SI->getOperand(0), C,
- Op0SI->getOperand(0)->getName()+".mask");
- InsertNewInstBefore(Mask, I);
-
- // Figure out what flavor of shift we should use...
- if (ShiftAmt1 == ShiftAmt2)
- return ReplaceInstUsesWith(I, Mask); // (A << c) >> c === A & c2
- else if (ShiftAmt1 < ShiftAmt2) {
- return new ShiftInst(I.getOpcode(), Mask,
- ConstantUInt::get(Type::UByteTy, ShiftAmt2-ShiftAmt1));
- } else {
- return new ShiftInst(Op0SI->getOpcode(), Mask,
- ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2));
- }
+ }
+
+ // If this is a shift of a shift, see if we can fold the two together.
+ if (ShiftInst *Op0SI = dyn_cast<ShiftInst>(Op0))
+ if (ConstantUInt *ShiftAmt1C =
+ dyn_cast<ConstantUInt>(Op0SI->getOperand(1))) {
+ unsigned ShiftAmt1 = (unsigned)ShiftAmt1C->getValue();
+ unsigned ShiftAmt2 = (unsigned)Op1->getValue();
+
+ // Check for (A << c1) << c2 and (A >> c1) >> c2
+ if (I.getOpcode() == Op0SI->getOpcode()) {
+ unsigned Amt = ShiftAmt1+ShiftAmt2; // Fold into one big shift.
+ if (Op0->getType()->getPrimitiveSizeInBits() < Amt)
+ Amt = Op0->getType()->getPrimitiveSizeInBits();
+ return new ShiftInst(I.getOpcode(), Op0SI->getOperand(0),
+ ConstantUInt::get(Type::UByteTy, Amt));
+ }
+
+ // Check for (A << c1) >> c2 or visaversa. If we are dealing with
+ // signed types, we can only support the (A >> c1) << c2 configuration,
+ // because it can not turn an arbitrary bit of A into a sign bit.
+ if (I.getType()->isUnsigned() || isLeftShift) {
+ // Calculate bitmask for what gets shifted off the edge...
+ Constant *C = ConstantIntegral::getAllOnesValue(I.getType());
+ if (isLeftShift)
+ C = ConstantExpr::getShl(C, ShiftAmt1C);
+ else
+ C = ConstantExpr::getShr(C, ShiftAmt1C);
+
+ Instruction *Mask =
+ BinaryOperator::createAnd(Op0SI->getOperand(0), C,
+ Op0SI->getOperand(0)->getName()+".mask");
+ InsertNewInstBefore(Mask, I);
+
+ // Figure out what flavor of shift we should use...
+ if (ShiftAmt1 == ShiftAmt2)
+ return ReplaceInstUsesWith(I, Mask); // (A << c) >> c === A & c2
+ else if (ShiftAmt1 < ShiftAmt2) {
+ return new ShiftInst(I.getOpcode(), Mask,
+ ConstantUInt::get(Type::UByteTy, ShiftAmt2-ShiftAmt1));
} else {
- // We can handle signed (X << C1) >> C2 if it's a sign extend. In
- // this case, C1 == C2 and C1 is 8, 16, or 32.
- if (ShiftAmt1 == ShiftAmt2) {
- const Type *SExtType = 0;
- switch (ShiftAmt1) {
- case 8 : SExtType = Type::SByteTy; break;
- case 16: SExtType = Type::ShortTy; break;
- case 32: SExtType = Type::IntTy; break;
- }
-
- if (SExtType) {
- Instruction *NewTrunc = new CastInst(Op0SI->getOperand(0),
- SExtType, "sext");
- InsertNewInstBefore(NewTrunc, I);
- return new CastInst(NewTrunc, I.getType());
- }
+ return new ShiftInst(Op0SI->getOpcode(), Mask,
+ ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2));
+ }
+ } else {
+ // We can handle signed (X << C1) >> C2 if it's a sign extend. In
+ // this case, C1 == C2 and C1 is 8, 16, or 32.
+ if (ShiftAmt1 == ShiftAmt2) {
+ const Type *SExtType = 0;
+ switch (ShiftAmt1) {
+ case 8 : SExtType = Type::SByteTy; break;
+ case 16: SExtType = Type::ShortTy; break;
+ case 32: SExtType = Type::IntTy; break;
+ }
+
+ if (SExtType) {
+ Instruction *NewTrunc = new CastInst(Op0SI->getOperand(0),
+ SExtType, "sext");
+ InsertNewInstBefore(NewTrunc, I);
+ return new CastInst(NewTrunc, I.getType());
}
}
}
- }
-
+ }
return 0;
}
More information about the llvm-commits
mailing list