Skip to content

Commit deaa0dd

Browse files
committedAug 12, 2003
Allow pulling logical operations through shifts.
This implements InstCombine/shift.ll:test14* llvm-svn: 7793
1 parent 98b3ecd commit deaa0dd

File tree

1 file changed

+61
-16
lines changed

1 file changed

+61
-16
lines changed
 

‎llvm/lib/Transforms/Scalar/InstructionCombining.cpp

+61-16
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
// This pass guarantees that the following cannonicalizations are performed on
1616
// the program:
1717
// 1. If a binary operator has a constant operand, it is moved to the RHS
18-
// 2. Logical operators with constant operands are always grouped so that
19-
// 'or's are performed first, then 'and's, then 'xor's.
18+
// 2. Bitwise operators with constant operands are always grouped so that
19+
// shifts are performed first, then or's, then and's, then xor's.
2020
// 3. SetCC instructions are converted from <,>,<=,>= to ==,!= if possible
2121
// 4. All SetCC instructions on boolean values are replaced with logical ops
2222
// N. This list is incomplete
@@ -879,24 +879,76 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) {
879879
Instruction *InstCombiner::visitShiftInst(ShiftInst &I) {
880880
assert(I.getOperand(1)->getType() == Type::UByteTy);
881881
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
882+
bool isLeftShift = I.getOpcode() == Instruction::Shl;
882883

883884
// shl X, 0 == X and shr X, 0 == X
884885
// shl 0, X == 0 and shr 0, X == 0
885886
if (Op1 == Constant::getNullValue(Type::UByteTy) ||
886887
Op0 == Constant::getNullValue(Op0->getType()))
887888
return ReplaceInstUsesWith(I, Op0);
888889

890+
// shr int -1, X = -1 (for any arithmetic shift rights of ~0)
891+
if (!isLeftShift)
892+
if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(Op0))
893+
if (CSI->isAllOnesValue())
894+
return ReplaceInstUsesWith(I, CSI);
895+
889896
if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(Op1)) {
890897
// shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr
891898
// of a signed value.
892899
//
893900
unsigned TypeBits = Op0->getType()->getPrimitiveSize()*8;
894901
if (CUI->getValue() >= TypeBits &&
895-
(!Op0->getType()->isSigned() || I.getOpcode() == Instruction::Shl))
902+
(!Op0->getType()->isSigned() || isLeftShift))
896903
return ReplaceInstUsesWith(I, Constant::getNullValue(Op0->getType()));
897904

905+
// If the operand is an bitwise operator with a constant RHS, and the
906+
// shift is the only use, we can pull it out of the shift.
907+
if (Op0->use_size() == 1)
908+
if (BinaryOperator *Op0BO = dyn_cast<BinaryOperator>(Op0))
909+
if (ConstantInt *Op0C = dyn_cast<ConstantInt>(Op0BO->getOperand(1))) {
910+
bool isValid = true; // Valid only for And, Or, Xor
911+
bool highBitSet = false; // Transform if high bit of constant set?
912+
913+
switch (Op0BO->getOpcode()) {
914+
default: isValid = false; break; // Do not perform transform!
915+
case Instruction::Or:
916+
case Instruction::Xor:
917+
highBitSet = false;
918+
break;
919+
case Instruction::And:
920+
highBitSet = true;
921+
break;
922+
}
923+
924+
// If this is a signed shift right, and the high bit is modified
925+
// by the logical operation, do not perform the transformation.
926+
// The highBitSet boolean indicates the value of the high bit of
927+
// the constant which would cause it to be modified for this
928+
// operation.
929+
//
930+
if (isValid && !isLeftShift && !I.getType()->isUnsigned()) {
931+
uint64_t Val = Op0C->getRawValue();
932+
isValid = ((Val & (1 << (TypeBits-1))) != 0) == highBitSet;
933+
}
934+
935+
if (isValid) {
936+
Constant *NewRHS =
937+
ConstantFoldShiftInstruction(I.getOpcode(), Op0C, CUI);
938+
939+
Instruction *NewShift =
940+
new ShiftInst(I.getOpcode(), Op0BO->getOperand(0), CUI,
941+
Op0BO->getName());
942+
Op0BO->setName("");
943+
InsertNewInstBefore(NewShift, I);
944+
945+
return BinaryOperator::create(Op0BO->getOpcode(), NewShift,
946+
NewRHS);
947+
}
948+
}
949+
898950
// If this is a shift of a shift, see if we can fold the two together...
899-
if (ShiftInst *Op0SI = dyn_cast<ShiftInst>(Op0)) {
951+
if (ShiftInst *Op0SI = dyn_cast<ShiftInst>(Op0))
900952
if (ConstantUInt *ShiftAmt1C =
901953
dyn_cast<ConstantUInt>(Op0SI->getOperand(1))) {
902954
unsigned ShiftAmt1 = ShiftAmt1C->getValue();
@@ -912,13 +964,13 @@ Instruction *InstCombiner::visitShiftInst(ShiftInst &I) {
912964
// Check for (A << c1) >> c2 or visaversa. If we are dealing with
913965
// signed types, we can only support the (A >> c1) << c2 configuration,
914966
// because it can not turn an arbitrary bit of A into a sign bit.
915-
if (I.getType()->isUnsigned() || I.getOpcode() == Instruction::Shl) {
967+
if (I.getType()->isUnsigned() || isLeftShift) {
916968
// Calculate bitmask for what gets shifted off the edge...
917969
Constant *C = ConstantIntegral::getAllOnesValue(I.getType());
918-
if (I.getOpcode() == Instruction::Shr)
919-
C = ConstantExpr::getShift(Instruction::Shr, C, ShiftAmt1C);
920-
else
970+
if (isLeftShift)
921971
C = ConstantExpr::getShift(Instruction::Shl, C, ShiftAmt1C);
972+
else
973+
C = ConstantExpr::getShift(Instruction::Shr, C, ShiftAmt1C);
922974

923975
Instruction *Mask =
924976
BinaryOperator::create(Instruction::And, Op0SI->getOperand(0),
@@ -937,21 +989,14 @@ Instruction *InstCombiner::visitShiftInst(ShiftInst &I) {
937989
}
938990
}
939991
}
940-
}
941992

942993
// Check to see if we are shifting left by 1. If so, turn it into an add
943994
// instruction.
944-
if (I.getOpcode() == Instruction::Shl && CUI->equalsInt(1))
995+
if (isLeftShift && CUI->equalsInt(1))
945996
// Convert 'shl int %X, 1' to 'add int %X, %X'
946997
return BinaryOperator::create(Instruction::Add, Op0, Op0, I.getName());
947998
}
948999

949-
// shr int -1, X = -1 (for any arithmetic shift rights of ~0)
950-
if (I.getOpcode() == Instruction::Shr)
951-
if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(Op0))
952-
if (CSI->isAllOnesValue())
953-
return ReplaceInstUsesWith(I, CSI);
954-
9551000
return 0;
9561001
}
9571002

0 commit comments

Comments
 (0)