Fix bug: test/Regression/Transforms/InstCombine/2002-08-02-CastTest.ll

Implement feature: Cast's can now be converted to bitwise AND expressions.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3225 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2002-08-02 20:00:25 +00:00
parent 7b572eff48
commit 8fd217cb29

View File

@ -404,14 +404,29 @@ static inline bool isEliminableCastOfCast(const CastInst &CI,
const Type *MidTy = CSrc->getType();
const Type *DstTy = CI.getType();
// It is legal to eliminate the instruction if casting A->B->A
if (SrcTy == DstTy) return true;
// It is legal to eliminate the instruction if casting A->B->A if the sizes
// are identical and the bits don't get reinterpreted (for example
// int->float->int)
if (SrcTy == DstTy && SrcTy->isLosslesslyConvertableTo(MidTy))
return true;
// Allow free casting and conversion of sizes as long as the sign doesn't
// change...
if (SrcTy->isSigned() == MidTy->isSigned() &&
MidTy->isSigned() == DstTy->isSigned())
return true;
if (SrcTy->isIntegral() && MidTy->isIntegral() && DstTy->isIntegral() &&
SrcTy->isSigned() == MidTy->isSigned() &&
MidTy->isSigned() == DstTy->isSigned()) {
// Only accept cases where we are either monotonically increasing the type
// size, or monotonically decreasing it.
//
unsigned SrcSize = SrcTy->getPrimitiveSize();
unsigned MidSize = MidTy->getPrimitiveSize();
unsigned DstSize = DstTy->getPrimitiveSize();
if (SrcSize < MidSize && MidSize < DstSize)
return true;
if (SrcSize > MidSize && MidSize > DstSize)
return true;
}
// Otherwise, we cannot succeed. Specifically we do not want to allow things
// like: short -> ushort -> uint, because this can create wrong results if
@ -432,11 +447,10 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
return &CI;
}
// If casting the result of another cast instruction, try to eliminate this
// one!
//
if (CastInst *CSrc = dyn_cast<CastInst>(CI.getOperand(0)))
if (CastInst *CSrc = dyn_cast<CastInst>(CI.getOperand(0))) {
if (isEliminableCastOfCast(CI, CSrc)) {
// This instruction now refers directly to the cast's src operand. This
// has a good chance of making CSrc dead.
@ -444,6 +458,22 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
return &CI;
}
// If this is an A->B->A cast, and we are dealing with integral types, try
// to convert this into a logical 'and' instruction.
//
if (CSrc->getOperand(0)->getType() == CI.getType() &&
CI.getType()->isIntegral() && CSrc->getType()->isIntegral() &&
CI.getType()->isUnsigned() && CSrc->getType()->isUnsigned() &&
CSrc->getType()->getPrimitiveSize() < CI.getType()->getPrimitiveSize()){
assert(CSrc->getType() != Type::ULongTy &&
"Cannot have type bigger than ulong!");
unsigned AndValue = (1U << CSrc->getType()->getPrimitiveSize()*8)-1;
Constant *AndOp = ConstantUInt::get(CI.getType(), AndValue);
return BinaryOperator::create(Instruction::And, CSrc->getOperand(0),
AndOp);
}
}
return 0;
}