From 61d6dc41fac11d6ff1923ca0f7c34c09e5a70285 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225895 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Transforms/Utils/SimplifyLibCalls.h | 2 ++ lib/Transforms/Utils/SimplifyLibCalls.cpp | 3 ++- test/Transforms/InstCombine/memcpy_chk-1.ll | 13 +++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/include/llvm/Transforms/Utils/SimplifyLibCalls.h index 2abf2d1e16a..d2f096fd1ef 100644 --- a/include/llvm/Transforms/Utils/SimplifyLibCalls.h +++ b/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/lib/Transforms/Utils/SimplifyLibCalls.cpp b/lib/Transforms/Utils/SimplifyLibCalls.cpp index fac8bb21e7f..5b4647ddcb5 100644 --- a/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/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/test/Transforms/InstCombine/memcpy_chk-1.ll b/test/Transforms/InstCombine/memcpy_chk-1.ll index 9216ae7fe95..008b838201e 100644 --- a/test/Transforms/InstCombine/memcpy_chk-1.ll +++ b/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.34.1