enhance getNoopInput to know about vector<->vector bitcasts of legal

types, as well as int<->ptr casts.  This allows us to tailcall functions
with some trivial casts between the call and return (i.e. because the
return types disagree).

llvm-svn: 157798
This commit is contained in:
Chris Lattner 2012-06-01 05:16:33 +00:00
parent 22afea7689
commit 182fe3eef1
2 changed files with 60 additions and 10 deletions

View File

@ -210,23 +210,51 @@ ISD::CondCode llvm::getICmpCondCode(ICmpInst::Predicate Pred) {
///
static const Value *getNoopInput(const Value *V, const TargetLowering &TLI) {
// If V is not an instruction, it can't be looked through.
const Instruction *U = dyn_cast<Instruction>(V);
if (U == 0 || !U->hasOneUse()) return V;
const Instruction *I = dyn_cast<Instruction>(V);
if (I == 0 || !I->hasOneUse() || I->getNumOperands() == 0) return V;
Value *Op = I->getOperand(0);
// Look through truly no-op truncates.
if (isa<TruncInst>(U) &&
TLI.isTruncateFree(U->getOperand(0)->getType(), U->getType()))
return getNoopInput(U->getOperand(0), TLI);
if (isa<TruncInst>(I) &&
TLI.isTruncateFree(I->getOperand(0)->getType(), I->getType()))
return getNoopInput(I->getOperand(0), TLI);
// Look through truly no-op bitcasts.
if (isa<BitCastInst>(U)) {
Value *Op = U->getOperand(0);
if (Op->getType() == U->getType() || // No type change.
if (isa<BitCastInst>(I)) {
// No type change at all.
if (Op->getType() == I->getType())
return getNoopInput(Op, TLI);
// Pointer to pointer cast.
(Op->getType()->isPointerTy() && U->getType()->isPointerTy()))
if (Op->getType()->isPointerTy() && I->getType()->isPointerTy())
return getNoopInput(Op, TLI);
if (isa<VectorType>(Op->getType()) && isa<VectorType>(I->getType()) &&
TLI.isTypeLegal(EVT::getEVT(Op->getType())) &&
TLI.isTypeLegal(EVT::getEVT(I->getType())))
return getNoopInput(Op, TLI);
}
// Look through inttoptr.
if (isa<IntToPtrInst>(I) && !isa<VectorType>(I->getType())) {
// Make sure this isn't a truncating or extending cast. We could support
// this eventually, but don't bother for now.
if (TLI.getPointerTy().getSizeInBits() ==
cast<IntegerType>(Op->getType())->getBitWidth())
return getNoopInput(Op, TLI);
}
// Look through ptrtoint.
if (isa<PtrToIntInst>(I) && !isa<VectorType>(I->getType())) {
// Make sure this isn't a truncating or extending cast. We could support
// this eventually, but don't bother for now.
if (TLI.getPointerTy().getSizeInBits() ==
cast<IntegerType>(I->getType())->getBitWidth())
return getNoopInput(Op, TLI);
}
// Otherwise it's not something we can look through.
return V;
}

View File

@ -19,3 +19,25 @@ define i64 @test_noop_bitcast() {
}
; CHECK: test_noop_bitcast:
; CHECK: jmp _testi ## TAILCALL
; Tail call shouldn't be blocked by no-op inttoptr.
define i8* @test_inttoptr() {
%A = tail call i64 @testi()
%B = inttoptr i64 %A to i8*
ret i8* %B
}
; CHECK: test_inttoptr:
; CHECK: jmp _testi ## TAILCALL
declare <4 x float> @testv()
define <4 x i32> @test_vectorbitcast() {
%A = tail call <4 x float> @testv()
%B = bitcast <4 x float> %A to <4 x i32>
ret <4 x i32> %B
}
; CHECK: test_vectorbitcast:
; CHECK: jmp _testv ## TAILCALL