[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
clattner at apple.com
Sat Mar 24 16:09:38 PDT 2007
On Mar 23, 2007, at 11:46 AM, Reid Spencer wrote:
> // 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->getZExtValue() >= TypeBits) {
> + if (Op1->getZExtValue() >= TypeBits) { // shift amount always
> <= 32 bits
This isn't safe. Code like:
shl i1024 %A, 123456789123456789123456789123456789
is undefined but legal. The compiler should not crash on it.
> @@ -6462,8 +6460,8 @@
> // operation.
> //
> if (isValid && !isLeftShift && I.getOpcode() ==
> Instruction::AShr) {
> - uint64_t Val = Op0C->getZExtValue();
> - isValid = ((Val & (1 << (TypeBits-1))) != 0) == highBitSet;
> + APInt Val(Op0C->getValue());
> + isValid = ((Val & APInt::getSignBit(TypeBits)) != 0) ==
> highBitSet;
> }
This should use operator[] to get the sign bit, or use isPositive/
isNegative.
>
> if (isValid) {
> @@ -6488,6 +6486,7 @@
>
> if (ShiftOp && isa<ConstantInt>(ShiftOp->getOperand(1))) {
> ConstantInt *ShiftAmt1C = cast<ConstantInt>(ShiftOp->getOperand
> (1));
> + // shift amount always <= 32 bits
Likewise, not safe.
> unsigned ShiftAmt1 = (unsigned)ShiftAmt1C->getZExtValue();
> unsigned ShiftAmt2 = (unsigned)Op1->getZExtValue();
> assert(ShiftAmt2 != 0 && "Should have been simplified earlier");
> @@ -6515,8 +6514,8 @@
> BinaryOperator::createAShr(X, ConstantInt::get(Ty, AmtSum));
> InsertNewInstBefore(Shift, I);
>
> - uint64_t Mask = Ty->getBitMask() >> ShiftAmt2;
> - return BinaryOperator::createAnd(Shift, ConstantInt::get(Ty,
> Mask));
> + APInt Mask(APInt::getAllOnesValue(TypeBits).lshr(ShiftAmt2));
> + return BinaryOperator::createAnd(Shift, ConstantInt::get
> (Mask));
> }
One of many places that need to use the new methods.
> @@ -6538,9 +6537,12 @@
> // generators.
> const Type *SExtType = 0;
> switch (Ty->getBitWidth() - ShiftAmt1) {
> - case 8 : SExtType = Type::Int8Ty; break;
> - case 16: SExtType = Type::Int16Ty; break;
> - case 32: SExtType = Type::Int32Ty; break;
> + case 1 : SExtType = Type::Int1Ty; break;
> + case 8 : SExtType = Type::Int8Ty; break;
> + case 16 : SExtType = Type::Int16Ty; break;
> + case 32 : SExtType = Type::Int32Ty; break;
> + case 64 : SExtType = Type::Int64Ty; break;
> + case 128: SExtType = IntegerType::get(128); break;
> default: break;
It would be more efficient (code size) to do:
switch (Ty->getBitWidth() - ShiftAmt1) {
case 1:
case 8:
case 16:
case 32:
case 64:
case 128:
SExtType = IntegerType::get(Ty->getBitWidth() - ShiftAmt1);
break;
default: break;
> @@ -8191,7 +8193,7 @@
> (ParamTy->isInteger() && ActTy->isInteger() &&
> ParamTy->getPrimitiveSizeInBits() >= ActTy-
> >getPrimitiveSizeInBits()) ||
> (c && ParamTy->getPrimitiveSizeInBits() >= ActTy-
> >getPrimitiveSizeInBits()
> - && c->getSExtValue() > 0);
> + && c->getValue().isPositive());
Doesn't isPositive return true for zero also? If so, this is a bug.
-Chris
More information about the llvm-commits
mailing list