mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-18 14:31:27 +00:00
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:
parent
274ad68cc7
commit
7a34d6c450
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user