more rearrangement and cleanup, fix my test failure.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@92792 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2010-01-05 22:21:18 +00:00
parent 274ad68cc7
commit 7a34d6c450
2 changed files with 108 additions and 122 deletions

View File

@ -439,59 +439,6 @@ Instruction *InstCombiner::commonCastTransforms(CastInst &CI) {
return 0; return 0;
} }
/// @brief Implement the transforms for cast of pointer (bitcast/ptrtoint)
Instruction *InstCombiner::commonPointerCastTransforms(CastInst &CI) {
Value *Src = CI.getOperand(0);
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Src)) {
// If casting the result of a getelementptr instruction with no offset, turn
// this into a cast of the original pointer!
if (GEP->hasAllZeroIndices()) {
// Changing the cast operand is usually not a good idea but it is safe
// here because the pointer operand is being replaced with another
// pointer operand so the opcode doesn't need to change.
Worklist.Add(GEP);
CI.setOperand(0, GEP->getOperand(0));
return &CI;
}
// If the GEP has a single use, and the base pointer is a bitcast, and the
// GEP computes a constant offset, see if we can convert these three
// instructions into fewer. This typically happens with unions and other
// non-type-safe code.
if (TD && GEP->hasOneUse() && isa<BitCastInst>(GEP->getOperand(0))) {
if (GEP->hasAllConstantIndices()) {
// We are guaranteed to get a constant from EmitGEPOffset.
ConstantInt *OffsetV = cast<ConstantInt>(EmitGEPOffset(GEP));
int64_t Offset = OffsetV->getSExtValue();
// Get the base pointer input of the bitcast, and the type it points to.
Value *OrigBase = cast<BitCastInst>(GEP->getOperand(0))->getOperand(0);
const Type *GEPIdxTy =
cast<PointerType>(OrigBase->getType())->getElementType();
SmallVector<Value*, 8> NewIndices;
if (FindElementAtOffset(GEPIdxTy, Offset, NewIndices)) {
// If we were able to index down into an element, create the GEP
// and bitcast the result. This eliminates one bitcast, potentially
// two.
Value *NGEP = cast<GEPOperator>(GEP)->isInBounds() ?
Builder->CreateInBoundsGEP(OrigBase,
NewIndices.begin(), NewIndices.end()) :
Builder->CreateGEP(OrigBase, NewIndices.begin(), NewIndices.end());
NGEP->takeName(GEP);
if (isa<BitCastInst>(CI))
return new BitCastInst(NGEP, CI.getType());
assert(isa<PtrToIntInst>(CI));
return new PtrToIntInst(NGEP, CI.getType());
}
}
}
}
return commonCastTransforms(CI);
}
/// commonIntCastTransforms - This function implements the common transforms /// commonIntCastTransforms - This function implements the common transforms
/// for trunc, zext, and sext. /// for trunc, zext, and sext.
Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) { Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) {
@ -634,8 +581,8 @@ Instruction *InstCombiner::visitTrunc(TruncInst &CI) {
Value *Src = CI.getOperand(0); Value *Src = CI.getOperand(0);
const Type *DestTy = CI.getType(); const Type *DestTy = CI.getType();
// Canonicalize trunc x to i1 -> (icmp ne (and x, 1), 0) // Canonicalize trunc x to i1 -> (icmp ne (and x, 1), 0), likewise for vector.
if (DestTy->isInteger(1)) { if (DestTy->getScalarSizeInBits() == 1) {
Constant *One = ConstantInt::get(Src->getType(), 1); Constant *One = ConstantInt::get(Src->getType(), 1);
Src = Builder->CreateAnd(Src, One, "tmp"); Src = Builder->CreateAnd(Src, One, "tmp");
Value *Zero = Constant::getNullValue(Src->getType()); Value *Zero = Constant::getNullValue(Src->getType());
@ -1072,24 +1019,6 @@ Instruction *InstCombiner::visitSIToFP(CastInst &CI) {
return commonCastTransforms(CI); return commonCastTransforms(CI);
} }
Instruction *InstCombiner::visitPtrToInt(PtrToIntInst &CI) {
// If the destination integer type is smaller than the intptr_t type for
// this target, do a ptrtoint to intptr_t then do a trunc. This allows the
// trunc to be exposed to other transforms. Don't do this for extending
// ptrtoint's, because we don't know if the target sign or zero extends its
// pointers.
if (TD &&
CI.getType()->getScalarSizeInBits() < TD->getPointerSizeInBits()) {
Value *P = Builder->CreatePtrToInt(CI.getOperand(0),
TD->getIntPtrType(CI.getContext()),
"tmp");
return new TruncInst(P, CI.getType());
}
return commonPointerCastTransforms(CI);
}
Instruction *InstCombiner::visitIntToPtr(IntToPtrInst &CI) { Instruction *InstCombiner::visitIntToPtr(IntToPtrInst &CI) {
// If the source integer type is larger than the intptr_t type for // If the source integer type is larger than the intptr_t type for
// this target, do a trunc to the intptr_t type, then inttoptr of it. This // this target, do a trunc to the intptr_t type, then inttoptr of it. This
@ -1109,6 +1038,75 @@ Instruction *InstCombiner::visitIntToPtr(IntToPtrInst &CI) {
return 0; return 0;
} }
/// @brief Implement the transforms for cast of pointer (bitcast/ptrtoint)
Instruction *InstCombiner::commonPointerCastTransforms(CastInst &CI) {
Value *Src = CI.getOperand(0);
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Src)) {
// If casting the result of a getelementptr instruction with no offset, turn
// this into a cast of the original pointer!
if (GEP->hasAllZeroIndices()) {
// Changing the cast operand is usually not a good idea but it is safe
// here because the pointer operand is being replaced with another
// pointer operand so the opcode doesn't need to change.
Worklist.Add(GEP);
CI.setOperand(0, GEP->getOperand(0));
return &CI;
}
// If the GEP has a single use, and the base pointer is a bitcast, and the
// GEP computes a constant offset, see if we can convert these three
// instructions into fewer. This typically happens with unions and other
// non-type-safe code.
if (TD && GEP->hasOneUse() && isa<BitCastInst>(GEP->getOperand(0)) &&
GEP->hasAllConstantIndices()) {
// We are guaranteed to get a constant from EmitGEPOffset.
ConstantInt *OffsetV = cast<ConstantInt>(EmitGEPOffset(GEP));
int64_t Offset = OffsetV->getSExtValue();
// Get the base pointer input of the bitcast, and the type it points to.
Value *OrigBase = cast<BitCastInst>(GEP->getOperand(0))->getOperand(0);
const Type *GEPIdxTy =
cast<PointerType>(OrigBase->getType())->getElementType();
SmallVector<Value*, 8> NewIndices;
if (FindElementAtOffset(GEPIdxTy, Offset, NewIndices)) {
// If we were able to index down into an element, create the GEP
// and bitcast the result. This eliminates one bitcast, potentially
// two.
Value *NGEP = cast<GEPOperator>(GEP)->isInBounds() ?
Builder->CreateInBoundsGEP(OrigBase,
NewIndices.begin(), NewIndices.end()) :
Builder->CreateGEP(OrigBase, NewIndices.begin(), NewIndices.end());
NGEP->takeName(GEP);
if (isa<BitCastInst>(CI))
return new BitCastInst(NGEP, CI.getType());
assert(isa<PtrToIntInst>(CI));
return new PtrToIntInst(NGEP, CI.getType());
}
}
}
return commonCastTransforms(CI);
}
Instruction *InstCombiner::visitPtrToInt(PtrToIntInst &CI) {
// If the destination integer type is smaller than the intptr_t type for
// this target, do a ptrtoint to intptr_t then do a trunc. This allows the
// trunc to be exposed to other transforms. Don't do this for extending
// ptrtoint's, because we don't know if the target sign or zero extends its
// pointers.
if (TD &&
CI.getType()->getScalarSizeInBits() < TD->getPointerSizeInBits()) {
Value *P = Builder->CreatePtrToInt(CI.getOperand(0),
TD->getIntPtrType(CI.getContext()),
"tmp");
return new TruncInst(P, CI.getType());
}
return commonPointerCastTransforms(CI);
}
Instruction *InstCombiner::visitBitCast(BitCastInst &CI) { Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
// If the operands are integer typed then apply the integer transforms, // If the operands are integer typed then apply the integer transforms,
// otherwise just apply the common ones. // otherwise just apply the common ones.
@ -1116,15 +1114,6 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
const Type *SrcTy = Src->getType(); const Type *SrcTy = Src->getType();
const Type *DestTy = CI.getType(); const Type *DestTy = CI.getType();
if (isa<PointerType>(SrcTy)) {
if (Instruction *I = commonPointerCastTransforms(CI))
return I;
} else {
if (Instruction *Result = commonCastTransforms(CI))
return Result;
}
// Get rid of casts from one type to the same type. These are useless and can // Get rid of casts from one type to the same type. These are useless and can
// be replaced by the operand. // be replaced by the operand.
if (DestTy == Src->getType()) if (DestTy == Src->getType())
@ -1165,57 +1154,54 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
if (SrcElTy == DstElTy) { if (SrcElTy == DstElTy) {
SmallVector<Value*, 8> Idxs(NumZeros+1, ZeroUInt); SmallVector<Value*, 8> Idxs(NumZeros+1, ZeroUInt);
return GetElementPtrInst::CreateInBounds(Src, Idxs.begin(), Idxs.end(),"", return GetElementPtrInst::CreateInBounds(Src, Idxs.begin(), Idxs.end(),"",
((Instruction*) NULL)); ((Instruction*)NULL));
} }
} }
if (const VectorType *DestVTy = dyn_cast<VectorType>(DestTy)) { if (const VectorType *DestVTy = dyn_cast<VectorType>(DestTy)) {
if (DestVTy->getNumElements() == 1) { if (DestVTy->getNumElements() == 1 && !isa<VectorType>(SrcTy)) {
if (!isa<VectorType>(SrcTy)) { Value *Elem = Builder->CreateBitCast(Src, DestVTy->getElementType());
Value *Elem = Builder->CreateBitCast(Src, DestVTy->getElementType()); return InsertElementInst::Create(UndefValue::get(DestTy), Elem,
return InsertElementInst::Create(UndefValue::get(DestTy), Elem,
Constant::getNullValue(Type::getInt32Ty(CI.getContext()))); Constant::getNullValue(Type::getInt32Ty(CI.getContext())));
}
// FIXME: Canonicalize bitcast(insertelement) -> insertelement(bitcast) // FIXME: Canonicalize bitcast(insertelement) -> insertelement(bitcast)
} }
} }
if (const VectorType *SrcVTy = dyn_cast<VectorType>(SrcTy)) { if (const VectorType *SrcVTy = dyn_cast<VectorType>(SrcTy)) {
if (SrcVTy->getNumElements() == 1) { if (SrcVTy->getNumElements() == 1 && !isa<VectorType>(DestTy)) {
if (!isa<VectorType>(DestTy)) { Value *Elem =
Value *Elem = Builder->CreateExtractElement(Src,
Builder->CreateExtractElement(Src, Constant::getNullValue(Type::getInt32Ty(CI.getContext())));
Constant::getNullValue(Type::getInt32Ty(CI.getContext()))); return CastInst::Create(Instruction::BitCast, Elem, DestTy);
return CastInst::Create(Instruction::BitCast, Elem, DestTy);
}
} }
} }
if (ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(Src)) { if (ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(Src)) {
if (SVI->hasOneUse()) { // Okay, we have (bitcast (shuffle ..)). Check to see if this is
// Okay, we have (bitconvert (shuffle ..)). Check to see if this is // a bitconvert to a vector with the same # elts.
// a bitconvert to a vector with the same # elts. if (SVI->hasOneUse() && isa<VectorType>(DestTy) &&
if (isa<VectorType>(DestTy) && cast<VectorType>(DestTy)->getNumElements() ==
cast<VectorType>(DestTy)->getNumElements() == SVI->getType()->getNumElements() &&
SVI->getType()->getNumElements() && SVI->getType()->getNumElements() ==
SVI->getType()->getNumElements() == cast<VectorType>(SVI->getOperand(0)->getType())->getNumElements()) {
cast<VectorType>(SVI->getOperand(0)->getType())->getNumElements()) { BitCastInst *Tmp;
CastInst *Tmp; // If either of the operands is a cast from CI.getType(), then
// If either of the operands is a cast from CI.getType(), then // evaluating the shuffle in the casted destination's type will allow
// evaluating the shuffle in the casted destination's type will allow // us to eliminate at least one cast.
// us to eliminate at least one cast. if (((Tmp = dyn_cast<BitCastInst>(SVI->getOperand(0))) &&
if (((Tmp = dyn_cast<CastInst>(SVI->getOperand(0))) && Tmp->getOperand(0)->getType() == DestTy) ||
Tmp->getOperand(0)->getType() == DestTy) || ((Tmp = dyn_cast<BitCastInst>(SVI->getOperand(1))) &&
((Tmp = dyn_cast<CastInst>(SVI->getOperand(1))) && Tmp->getOperand(0)->getType() == DestTy)) {
Tmp->getOperand(0)->getType() == DestTy)) { Value *LHS = Builder->CreateBitCast(SVI->getOperand(0), DestTy);
Value *LHS = Builder->CreateBitCast(SVI->getOperand(0), DestTy); Value *RHS = Builder->CreateBitCast(SVI->getOperand(1), DestTy);
Value *RHS = Builder->CreateBitCast(SVI->getOperand(1), DestTy); // Return a new shuffle vector. Use the same element ID's, as we
// Return a new shuffle vector. Use the same element ID's, as we // know the vector types match #elts.
// know the vector types match #elts. return new ShuffleVectorInst(LHS, RHS, SVI->getOperand(2));
return new ShuffleVectorInst(LHS, RHS, SVI->getOperand(2));
}
} }
} }
} }
return 0;
if (isa<PointerType>(SrcTy))
return commonPointerCastTransforms(CI);
return commonCastTransforms(CI);
} }

View File

@ -55,8 +55,8 @@ define i32 @test6(i64 %A) {
%c1 = trunc i64 %A to i32 ; <i32> [#uses=1] %c1 = trunc i64 %A to i32 ; <i32> [#uses=1]
%res = bitcast i32 %c1 to i32 ; <i32> [#uses=1] %res = bitcast i32 %c1 to i32 ; <i32> [#uses=1]
ret i32 %res ret i32 %res
; CHECK: %res = trunc i64 %A to i32 ; CHECK: trunc i64 %A to i32
; CHECK: ret i32 %res ; CHECK-NEXT: ret i32
} }
define i64 @test7(i1 %A) { define i64 @test7(i1 %A) {
@ -71,8 +71,8 @@ define i64 @test8(i8 %A) {
%c1 = sext i8 %A to i64 ; <i64> [#uses=1] %c1 = sext i8 %A to i64 ; <i64> [#uses=1]
%res = bitcast i64 %c1 to i64 ; <i64> [#uses=1] %res = bitcast i64 %c1 to i64 ; <i64> [#uses=1]
ret i64 %res ret i64 %res
; CHECK: %res = sext i8 %A to i64 ; CHECK: = sext i8 %A to i64
; CHECK: ret i64 %res ; CHECK-NEXT: ret i64
} }
define i16 @test9(i16 %A) { define i16 @test9(i16 %A) {