Index: lib/IR/AutoUpgrade.cpp =================================================================== --- lib/IR/AutoUpgrade.cpp +++ lib/IR/AutoUpgrade.cpp @@ -1912,19 +1912,14 @@ } std::string Name = CI->getName(); - if (!Name.empty()) - CI->setName(Name + ".old"); - + CallInst *NewCall = nullptr; switch (NewFn->getIntrinsicID()) { default: { // Handle generic mangling change, but nothing else assert( (CI->getCalledFunction()->getName() != NewFn->getName()) && "Unknown function for CallInst upgrade and isn't just a name change"); - SmallVector Args(CI->arg_operands().begin(), - CI->arg_operands().end()); - CI->replaceAllUsesWith(Builder.CreateCall(NewFn, Args)); - CI->eraseFromParent(); + CI->setCalledFunction(NewFn); return; } @@ -1944,47 +1939,39 @@ case Intrinsic::arm_neon_vst4lane: { SmallVector Args(CI->arg_operands().begin(), CI->arg_operands().end()); - CI->replaceAllUsesWith(Builder.CreateCall(NewFn, Args)); - CI->eraseFromParent(); - return; + NewCall = Builder.CreateCall(NewFn, Args); + break; } case Intrinsic::bitreverse: - CI->replaceAllUsesWith(Builder.CreateCall(NewFn, {CI->getArgOperand(0)})); - CI->eraseFromParent(); - return; + NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)}); + break; case Intrinsic::ctlz: case Intrinsic::cttz: assert(CI->getNumArgOperands() == 1 && "Mismatch between function args and call args"); - CI->replaceAllUsesWith(Builder.CreateCall( - NewFn, {CI->getArgOperand(0), Builder.getFalse()}, Name)); - CI->eraseFromParent(); - return; + NewCall = Builder.CreateCall( + NewFn, {CI->getArgOperand(0), Builder.getFalse()}, Name); + break; case Intrinsic::objectsize: - CI->replaceAllUsesWith(Builder.CreateCall( - NewFn, {CI->getArgOperand(0), CI->getArgOperand(1)}, Name)); - CI->eraseFromParent(); - return; + NewCall = Builder.CreateCall( + NewFn, {CI->getArgOperand(0), CI->getArgOperand(1)}, Name); + break; case Intrinsic::ctpop: - CI->replaceAllUsesWith(Builder.CreateCall(NewFn, {CI->getArgOperand(0)})); - CI->eraseFromParent(); - return; + NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)}); + break; case Intrinsic::convert_from_fp16: - CI->replaceAllUsesWith(Builder.CreateCall(NewFn, {CI->getArgOperand(0)})); - CI->eraseFromParent(); - return; + NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)}); + break; case Intrinsic::x86_xop_vfrcz_ss: case Intrinsic::x86_xop_vfrcz_sd: - CI->replaceAllUsesWith( - Builder.CreateCall(NewFn, {CI->getArgOperand(1)}, Name)); - CI->eraseFromParent(); - return; + NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(1)}, Name); + break; case Intrinsic::x86_xop_vpermil2pd: case Intrinsic::x86_xop_vpermil2ps: @@ -1995,9 +1982,8 @@ VectorType *FltIdxTy = cast(Args[2]->getType()); VectorType *IntIdxTy = VectorType::getInteger(FltIdxTy); Args[2] = Builder.CreateBitCast(Args[2], IntIdxTy); - CI->replaceAllUsesWith(Builder.CreateCall(NewFn, Args, Name)); - CI->eraseFromParent(); - return; + NewCall = Builder.CreateCall(NewFn, Args, Name); + break; } case Intrinsic::x86_sse41_ptestc: @@ -2019,10 +2005,8 @@ Value *BC0 = Builder.CreateBitCast(Arg0, NewVecTy, "cast"); Value *BC1 = Builder.CreateBitCast(Arg1, NewVecTy, "cast"); - CallInst *NewCall = Builder.CreateCall(NewFn, {BC0, BC1}, Name); - CI->replaceAllUsesWith(NewCall); - CI->eraseFromParent(); - return; + NewCall = Builder.CreateCall(NewFn, {BC0, BC1}, Name); + break; } case Intrinsic::x86_sse41_insertps: @@ -2038,17 +2022,13 @@ // Replace the last argument with a trunc. Args.back() = Builder.CreateTrunc(Args.back(), Type::getInt8Ty(C), "trunc"); - - CallInst *NewCall = Builder.CreateCall(NewFn, Args); - CI->replaceAllUsesWith(NewCall); - CI->eraseFromParent(); - return; + NewCall = Builder.CreateCall(NewFn, Args); + break; } case Intrinsic::thread_pointer: { - CI->replaceAllUsesWith(Builder.CreateCall(NewFn, {})); - CI->eraseFromParent(); - return; + NewCall = Builder.CreateCall(NewFn, {}); + break; } case Intrinsic::invariant_start: @@ -2057,11 +2037,18 @@ case Intrinsic::masked_store: { SmallVector Args(CI->arg_operands().begin(), CI->arg_operands().end()); - CI->replaceAllUsesWith(Builder.CreateCall(NewFn, Args)); - CI->eraseFromParent(); - return; + NewCall = Builder.CreateCall(NewFn, Args); + break; } } + assert(NewCall && "Should have either set this variable or returned through " + "the default case"); + if (!Name.empty()) { + CI->setName(Name + ".old"); + NewCall->setName(Name); + } + CI->replaceAllUsesWith(NewCall); + CI->eraseFromParent(); } void llvm::UpgradeCallsToIntrinsic(Function *F) { Index: test/CodeGen/Generic/overloaded-intrinsic-name.ll =================================================================== --- test/CodeGen/Generic/overloaded-intrinsic-name.ll +++ test/CodeGen/Generic/overloaded-intrinsic-name.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify -S < %s +; RUN: opt -S < %s | FileCheck %s ; Tests the name mangling performed by the codepath following ; getMangledTypeStr(). Only tests that code with the various manglings @@ -67,7 +68,9 @@ define %i32* @test_broken_names(%i32* %v) gc "statepoint-example" { entry: - %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.deadbeef(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, %i32* %v) + %tok = call fastcc token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.deadbeef(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, %i32* %v) +; Make sure we do not destroy the calling convention when remangling +; CHECK: fastcc %v-new = call %i32* @llvm.experimental.gc.relocate.beefdead(token %tok, i32 7, i32 7) ret %i32* %v-new }