diff --git a/lib/CodeGen/Analysis.cpp b/lib/CodeGen/Analysis.cpp index f8492f092d6..dd11d15975c 100644 --- a/lib/CodeGen/Analysis.cpp +++ b/lib/CodeGen/Analysis.cpp @@ -210,22 +210,50 @@ 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(V); - if (U == 0 || !U->hasOneUse()) return V; + const Instruction *I = dyn_cast(V); + if (I == 0 || !I->hasOneUse() || I->getNumOperands() == 0) return V; + Value *Op = I->getOperand(0); + // Look through truly no-op truncates. - if (isa(U) && - TLI.isTruncateFree(U->getOperand(0)->getType(), U->getType())) - return getNoopInput(U->getOperand(0), TLI); + if (isa(I) && + TLI.isTruncateFree(I->getOperand(0)->getType(), I->getType())) + return getNoopInput(I->getOperand(0), TLI); // Look through truly no-op bitcasts. - if (isa(U)) { - Value *Op = U->getOperand(0); - if (Op->getType() == U->getType() || // No type change. - // Pointer to pointer cast. - (Op->getType()->isPointerTy() && U->getType()->isPointerTy())) + if (isa(I)) { + // No type change at all. + if (Op->getType() == I->getType()) + return getNoopInput(Op, TLI); + + // Pointer to pointer cast. + if (Op->getType()->isPointerTy() && I->getType()->isPointerTy()) + return getNoopInput(Op, TLI); + + if (isa(Op->getType()) && isa(I->getType()) && + TLI.isTypeLegal(EVT::getEVT(Op->getType())) && + TLI.isTypeLegal(EVT::getEVT(I->getType()))) return getNoopInput(Op, TLI); } + + // Look through inttoptr. + if (isa(I) && !isa(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(Op->getType())->getBitWidth()) + return getNoopInput(Op, TLI); + } + + // Look through ptrtoint. + if (isa(I) && !isa(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(I->getType())->getBitWidth()) + return getNoopInput(Op, TLI); + } + // Otherwise it's not something we can look through. return V; diff --git a/test/CodeGen/X86/tailcall-64.ll b/test/CodeGen/X86/tailcall-64.ll index 569a67c2530..a3ef2dc8ef4 100644 --- a/test/CodeGen/X86/tailcall-64.ll +++ b/test/CodeGen/X86/tailcall-64.ll @@ -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