From 71d7b18e3d7e81f707caab1e35d5e211c96a941c Mon Sep 17 00:00:00 2001 From: Ahmed Bougacha Date: Wed, 14 Jan 2015 00:55:05 +0000 Subject: [PATCH] [SimplifyLibCalls] Don't try to simplify indirect calls. It turns out, all callsites of the simplifier are guarded by a check for CallInst::getCalledFunction (i.e., to make sure the callee is direct). This check wasn't done when trying to further optimize a simplified fortified libcall, introduced by a refactoring in r225640. Fix that, add a testcase, and document the requirement. llvm-svn: 225895 --- llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h | 2 ++ llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | 3 ++- llvm/test/Transforms/InstCombine/memcpy_chk-1.ll | 13 +++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h index 2abf2d1..d2f096f 100644 --- a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h +++ b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h @@ -46,6 +46,7 @@ public: /// \brief Take the given call instruction and return a more /// optimal value to replace the instruction with or 0 if a more /// optimal form can't be found. + /// The call must not be an indirect call. Value *optimizeCall(CallInst *CI); private: @@ -83,6 +84,7 @@ public: /// be equal to the instruction being optimized. In this case all /// other instructions that use the given instruction were modified /// and the given instruction is dead. + /// The call must not be an indirect call. Value *optimizeCall(CallInst *CI); /// replaceAllUsesWith - This method is used when the library call diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index fac8bb2..5b4647d 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1966,7 +1966,8 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) { // Also try to simplify calls to fortified library functions. if (Value *SimplifiedFortifiedCI = FortifiedSimplifier.optimizeCall(CI)) { // Try to further simplify the result. - if (CallInst *SimplifiedCI = dyn_cast(SimplifiedFortifiedCI)) + CallInst *SimplifiedCI = dyn_cast(SimplifiedFortifiedCI); + if (SimplifiedCI && SimplifiedCI->getCalledFunction()) if (Value *V = optimizeStringMemoryLibCall(SimplifiedCI, Builder)) return V; return SimplifiedFortifiedCI; diff --git a/llvm/test/Transforms/InstCombine/memcpy_chk-1.ll b/llvm/test/Transforms/InstCombine/memcpy_chk-1.ll index 9216ae7..008b838 100644 --- a/llvm/test/Transforms/InstCombine/memcpy_chk-1.ll +++ b/llvm/test/Transforms/InstCombine/memcpy_chk-1.ll @@ -57,4 +57,17 @@ define void @test_no_simplify2() { ret void } +define i8* @test_simplify_return_indcall(i8* ()* %alloc) { +; CHECK-LABEL: @test_simplify_return_indcall( + %src = bitcast %struct.T2* @t2 to i8* + +; CHECK-NEXT: %dst = call i8* %alloc() + %dst = call i8* %alloc() + +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64 + %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824) +; CHECK-NEXT: ret i8* %dst + ret i8* %ret +} + declare i8* @__memcpy_chk(i8*, i8*, i64, i64) -- 2.7.4