[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Reid Spencer
rspencer at reidspencer.com
Wed Dec 13 09:20:13 PST 2006
Hi Chris,
Feedback below ...
On Tue, 2006-12-12 at 22:42 -0800, Chris Lattner wrote:
> This code (around line 2173):
>
> CastInst *BoolCast = 0;
> if (CastInst *CI = dyn_cast<CastInst>(I.getOperand(0)))
> if (CI->getOperand(0)->getType() == Type::BoolTy)
> BoolCast = CI;
> if (!BoolCast)
> if (CastInst *CI = dyn_cast<CastInst>(I.getOperand(1)))
> if (CI->getOperand(0)->getType() == Type::BoolTy)
> BoolCast = CI;
>
> Should *only* allow zext from bool (not any cast). This is a serious
> bug from the original cast patch.
Committed last night.
>
>
> > @@ -2190,7 +2193,7 @@
> > SCOpTy-
> > >getPrimitiveSizeInBits()-1);
> > if (SCIOp0->getType()->isUnsigned()) {
> > const Type *NewTy = SCIOp0->getType()->getSignedVersion();
> > - SCIOp0 = InsertCastBefore(SCIOp0, NewTy, I);
> > + SCIOp0 = InsertCastBefore(Instruction::BitCast, SCIOp0,
> > NewTy, I);
> > }
>
> This cast be removed now that ashr is signless.
Right. Fixed. When SETCC finally gets in, I'll be looking for all kinds
of useless casts, and not only in InstCombine.
>
>
> > @@ -2863,12 +2872,14 @@
> > Constant *ShrMask = ConstantExpr::getLShr(AllOne, OpRHS);
> > Constant *CI = ConstantExpr::getAnd(AndRHS, ShrMask);
> > if (CI == AndRHS) { // Masking out bits shifted in.
> > + // (Val ashr C1) & C2 -> (Val lshr C1) & C2
> > // Make the argument unsigned.
> > Value *ShVal = Op->getOperand(0);
> > ShVal = InsertNewInstBefore(new ShiftInst
> > (Instruction::LShr, ShVal,
> > OpRHS, Op-
> > >getName()),
> > TheAnd);
> > - Value *AndRHS2 = ConstantExpr::getCast(AndRHS, ShVal-
> > >getType());
> > + Value *AndRHS2 = ConstantExpr::getBitCast(AndRHS, ShVal-
> > >getType());
> > +
>
> This cast looks completely dead, if so, it should just be removed.
Removed.
>
> > @@ -2897,9 +2908,9 @@
> > InsertNewInstBefore(Add, IB);
> > // Convert to unsigned for the comparison.
> > const Type *UnsType = Add->getType()->getUnsignedVersion();
> > - Value *OffsetVal = InsertCastBefore(Add, UnsType, IB);
> > + Value *OffsetVal = InsertCastBefore(Instruction::BitCast, Add,
> > UnsType, IB);
> > AddCST = ConstantExpr::getAdd(AddCST, Hi);
> > - AddCST = ConstantExpr::getCast(AddCST, UnsType);
> > + AddCST = ConstantExpr::getBitCast(AddCST, UnsType);
> > return new SetCondInst(Instruction::SetLT, OffsetVal, AddCST);
>
> If only we had signless comparisons! :-)
Indeed. I'd like to get back to finishing it off :)
>
> > @@ -3917,11 +3930,11 @@
> > for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i, +
> > +GTI) {
> > Value *Op = GEP->getOperand(i);
> > uint64_t Size = TD.getTypeSize(GTI.getIndexedType()) &
> > PtrSizeMask;
> > - Constant *Scale = ConstantExpr::getCast(ConstantInt::get
> > (UIntPtrTy, Size),
> > + Constant *Scale = ConstantExpr::getBitCast(ConstantInt::get
> > (UIntPtrTy, Size),
> > SIntPtrTy);
>
> This doesn't fit in 80 columns.
Fixed.
> Further, you can just use:
>
> > Constant *Scale = ConstantInt::get(SIntPtrTy, Size);
>
> Now that Constant[SU]Int got merged into ConstantInt.
Yup. Done.
>
>
> This code:
> // Check to see if there is a noop-cast between the shift
> and the and.
> if (!Shift) {
> if (CastInst *CI = dyn_cast<CastInst>(LHSI->getOperand(0)))
> if (CI->getOperand(0)->getType()->isIntegral() &&
> CI->getOperand(0)->getType()-
> >getPrimitiveSizeInBits() ==
> CI->getType()->getPrimitiveSizeInBits())
> Shift = dyn_cast<ShiftInst>(CI->getOperand(0));
> }
>
> Should check for bitcast with integral src/dest instead of checking
> sizes etc.
Done.
>
>
> This code:
>
> // Make sure we insert a logical shift.
> Constant *NewAndCST = AndCST;
> if (AndCST->getType()->isSigned())
> NewAndCST = ConstantExpr::getBitCast(AndCST,
> AndCST->getType()-
> >getUnsignedVersion());
> NS = new ShiftInst(Instruction::LShr, NewAndCST,
> Shift->getOperand(1), "tmp");
>
> You can drop the cast now that the shift is signless.
Yup. Done.
>
>
> The two casts here can be eliminated now that shifts are signless:
>
> // (X >>s C1) << C2 where C1 > C2 === (X >>s (C1-C2)) & mask
> Op = InsertCastBefore(Instruction::BitCast, Mask,
> I.getType()->getSignedVersion(), I);
> Instruction *Shift =
> new ShiftInst(ShiftOp->getOpcode(), Op,
> ConstantInt::get(Type::UByteTy, ShiftAmt1-
> ShiftAmt2));
> InsertNewInstBefore(Shift, I);
>
> C = ConstantIntegral::getAllOnesValue(Shift->getType());
> C = ConstantExpr::getShl(C, Op1);
> Mask = BinaryOperator::createAnd(Shift, C, Op->getName()
> +".mask");
> InsertNewInstBefore(Mask, I);
> return CastInst::create(Instruction::BitCast, Mask, I.getType
> ());
Done.
>
>
> > @@ -5874,10 +5893,15 @@
> > if (DestBitSize == SrcBitSize ||
> > !ValueRequiresCast(Op1, DestTy,TD) ||
> > !ValueRequiresCast(Op0, DestTy, TD)) {
> > - Value *Op0c = InsertOperandCastBefore(Op0, DestTy, SrcI);
> > - Value *Op1c = InsertOperandCastBefore(Op1, DestTy, SrcI);
> > - return BinaryOperator::create(cast<BinaryOperator>(SrcI)
> > - ->getOpcode(), Op0c, Op1c);
> > + unsigned Op0BitSize = Op0->getType()-
> > >getPrimitiveSizeInBits();
> > + Instruction::CastOps opcode =
> > + (Op0BitSize > DestBitSize ? Instruction::Trunc :
> > + (Op0BitSize == DestBitSize ? Instruction::BitCast :
> > + Op0->getType()->isSigned() ?
> > Instruction::SExt :Instruction::ZExt));
>
> This is a serious bug. You can't look at the type of the operand to
> determine the type of the cast! Replace this with:
>
> Instruction::CastOps opcode = CI.getOpcode();
Done.
>
> > @@ -6014,13 +6042,18 @@
> >
> > // Get a mask for the bits shifting in.
> > uint64_t Mask = (~0ULL >> (64-ShAmt)) << DestBitWidth;
> > - if (SrcI->hasOneUse() && MaskedValueIsZero(SrcI->getOperand
> > (0), Mask)) {
> > + Value* SrcIOp0 = SrcI->getOperand(0);
> > + if (SrcI->hasOneUse() && MaskedValueIsZero(SrcIOp0, Mask)) {
> > if (ShAmt >= DestBitWidth) // All zeros.
> > return ReplaceInstUsesWith(CI, Constant::getNullValue
> > (Ty));
> >
> > // Okay, we can shrink this. Truncate the input, then
> > return a new
> > // shift.
> > - Value *V = InsertCastBefore(SrcI->getOperand(0), Ty, CI);
> > + Instruction::CastOps opcode =
> > + (SrcIOp0->getType()->getPrimitiveSizeInBits() ==
> > + Ty->getPrimitiveSizeInBits() ? Instruction::BitCast :
> > + Instruction::Trunc);
>
> This is always trunc.
>
>
> > @@ -7316,15 +7355,18 @@
> > return 0;
> > }
> >
> > -static Value *InsertSignExtendToPtrTy(Value *V, const Type *DTy,
> > - Instruction *InsertPoint,
> > - InstCombiner *IC) {
> > - unsigned PS = IC->getTargetData().getPointerSize();
> > - const Type *VTy = V->getType();
> > - if (!VTy->isSigned() && VTy->getPrimitiveSize() < PS)
> > - // We must insert a cast to ensure we sign-extend.
> > - V = IC->InsertCastBefore(V, VTy->getSignedVersion(),
> > *InsertPoint);
> > - return IC->InsertCastBefore(V, DTy, *InsertPoint);
> > +static Value *InsertCastToIntPtrTy(Value *V, const Type *DTy,
> > + Instruction *InsertPoint,
> > + InstCombiner *IC) {
>
> Why did you rename this?
Because the name doesn't match its action. SExt is only one possibility.
The type of Value* can be larger, smaller, or equal in size to DTy so it
can be SExt, Trunc, or BitCast. I figured
InsertSignExtendOrTruncateOrBitCastToPtrTy was a bit long.
> The previous name was better (indicated
> sign extension).
The previous name is misleading. It doesn't always do a SExt. Consider
long GEP index on a 32-bit platform. The cast needed is a Trunc.
>
> > + unsigned PtrSize = IC->getTargetData().getPointerSize();
>
> This isn't right. Two callers pass in intptr_t, but two pass in
> something else. You should use DTy->getPrimitiveSize() instead of
> TD.getPointerSize()
Okay, missed that. Thanks.
>
> > + unsigned VTySize = V->getType()->getPrimitiveSize();
> > + // We must cast correctly to the pointer type. Ensure that we
> > + // sign extend the integer value if it is smaller as this is
> > + // used for address computation.
> > + Instruction::CastOps opcode =
> > + (VTySize < PtrSize ? Instruction::SExt :
> > + (VTySize == PtrSize ? Instruction::BitCast :
> > Instruction::Trunc));
> > + return IC->InsertCastBefore(opcode, V, DTy, *InsertPoint);
> > }
>
>
> > @@ -8677,8 +8721,8 @@
> > std::vector<Value*> Ops(CE->op_begin()+1, CE->op_end());
> > uint64_t Offset = TD->getIndexedOffset(Ptr->getType(), Ops);
> > Constant *C = ConstantInt::get(Type::ULongTy, Offset);
> > + C = ConstantExpr::getIntegerCast(C, TD->getIntPtrType(),
> > true /*SExt*/);
>
> Just use:
>
> > Constant *C = ConstantInt::get(TD->getIntPtrType(), Offset);
Done.
>
> -Chris
>
More information about the llvm-commits
mailing list