[llvm] r227250 - [SimplifyLibCalls] Don't confuse strcpy_chk for stpcpy_chk.
Ahmed Bougacha
ahmed.bougacha at gmail.com
Wed Jan 28 09:21:58 PST 2015
On Tue, Jan 27, 2015 at 7:19 PM, Eric Christopher <echristo at gmail.com> wrote:
> Hi Ahmed,
>
> Question inline:
>
> On Tue Jan 27 2015 at 1:58:17 PM Ahmed Bougacha <ahmed.bougacha at gmail.com>
> wrote:
>>
>> Author: ab
>> Date: Tue Jan 27 15:52:16 2015
>> New Revision: 227250
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=227250&view=rev
>> Log:
>> [SimplifyLibCalls] Don't confuse strcpy_chk for stpcpy_chk.
>>
>> This was introduced in a faulty refactoring (r225640, mea culpa):
>> the tests weren't testing the return values, so, for both
>> __strcpy_chk and __stpcpy_chk, we would return the end of the
>> buffer (matching stpcpy) instead of the beginning (for strcpy).
>>
>> The root cause was the prefix "__" being ignored when comparing,
>> which made us always pick LibFunc::stpcpy_chk.
>> Pass the LibFunc::Func directly to avoid this kind of error.
>> Also, make the testcases as explicit as possible to prevent this.
>>
>> The now-useful testcases expose another, entangled, stpcpy problem,
>> with the further simplification. This was introduced in a
>> refactoring (r225640) to match the original behavior.
>>
>> However, this leads to problems when successive simplifications
>> generate several similar instructions, none of which are removed
>> by the custom replaceAllUsesWith.
>>
>> For instance, InstCombine (the main user) doesn't erase the
>> instruction in its custom RAUW. When trying to simplify say
>> __stpcpy_chk:
>> - first, an stpcpy is created (fortified simplifier),
>> - second, a memcpy is created (normal simplifier), but the
>> stpcpy call isn't removed.
>> - third, InstCombine later revisits the instructions,
>> and simplifies the first stpcpy to a memcpy. We now have
>> two memcpys.
>>
>
> This seems... somewhat concerning.
Indeed, but in case that wasn't clear, it's fixed by this commit.
Ideally, we wouldn't need to delete the intermediate instruction:
the main problem I can think of is that some of those simplifications
return several instructions (the libcall, + a GEP for the return value).
Here, this isn't a problem, because the GEP wouldn't trigger further
simplification.
This part is still on my todo list though, so I'll try to merge both
simplifiers together at the next round.
-Ahmed
> -eric
>
>>
>>
>> Modified:
>> llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h
>> llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
>> llvm/trunk/test/Transforms/InstCombine/memcpy_chk-1.ll
>> llvm/trunk/test/Transforms/InstCombine/memmove_chk-1.ll
>> llvm/trunk/test/Transforms/InstCombine/memset_chk-1.ll
>> llvm/trunk/test/Transforms/InstCombine/stpcpy_chk-1.ll
>> llvm/trunk/test/Transforms/InstCombine/strcpy_chk-1.ll
>> llvm/trunk/test/Transforms/InstCombine/strncpy_chk-1.ll
>>
>> Modified: llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h?rev=227250&r1=227249&r2=227250&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h (original)
>> +++ llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h Tue Jan 27
>> 15:52:16 2015
>> @@ -16,6 +16,7 @@
>> #define LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H
>>
>> #include "llvm/ADT/StringRef.h"
>> +#include "llvm/Analysis/TargetLibraryInfo.h"
>> #include "llvm/IR/IRBuilder.h"
>>
>> namespace llvm {
>> @@ -53,8 +54,10 @@ private:
>> Value *optimizeMemCpyChk(CallInst *CI, IRBuilder<> &B);
>> Value *optimizeMemMoveChk(CallInst *CI, IRBuilder<> &B);
>> Value *optimizeMemSetChk(CallInst *CI, IRBuilder<> &B);
>> - Value *optimizeStrCpyChk(CallInst *CI, IRBuilder<> &B);
>> - Value *optimizeStrNCpyChk(CallInst *CI, IRBuilder<> &B);
>> +
>> + // Str/Stp cpy are similar enough to be handled in the same functions.
>> + Value *optimizeStrpCpyChk(CallInst *CI, IRBuilder<> &B, LibFunc::Func
>> Func);
>> + Value *optimizeStrpNCpyChk(CallInst *CI, IRBuilder<> &B, LibFunc::Func
>> Func);
>>
>> /// \brief Checks whether the call \p CI to a fortified libcall is
>> foldable
>> /// to the non-fortified version.
>>
>> Modified: llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp?rev=227250&r1=227249&r2=227250&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp (original)
>> +++ llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp Tue Jan 27
>> 15:52:16 2015
>> @@ -1968,8 +1968,12 @@ Value *LibCallSimplifier::optimizeCall(C
>> // Try to further simplify the result.
>> CallInst *SimplifiedCI = dyn_cast<CallInst>(SimplifiedFortifiedCI);
>> if (SimplifiedCI && SimplifiedCI->getCalledFunction())
>> - if (Value *V = optimizeStringMemoryLibCall(SimplifiedCI, Builder))
>> + if (Value *V = optimizeStringMemoryLibCall(SimplifiedCI, Builder))
>> {
>> + // If we were able to further simplify, remove the now redundant
>> call.
>> + SimplifiedCI->replaceAllUsesWith(V);
>> + SimplifiedCI->eraseFromParent();
>> return V;
>> + }
>> return SimplifiedFortifiedCI;
>> }
>>
>> @@ -2222,11 +2226,11 @@ Value *FortifiedLibCallSimplifier::optim
>> return nullptr;
>> }
>>
>> -Value *FortifiedLibCallSimplifier::optimizeStrCpyChk(CallInst *CI,
>> IRBuilder<> &B) {
>> +Value *FortifiedLibCallSimplifier::optimizeStrpCpyChk(CallInst *CI,
>> + IRBuilder<> &B,
>> + LibFunc::Func Func)
>> {
>> Function *Callee = CI->getCalledFunction();
>> StringRef Name = Callee->getName();
>> - LibFunc::Func Func =
>> - Name.startswith("str") ? LibFunc::strcpy_chk : LibFunc::stpcpy_chk;
>>
>> if (!checkStringCopyLibFuncSignature(Callee, Func, DL))
>> return nullptr;
>> @@ -2235,7 +2239,7 @@ Value *FortifiedLibCallSimplifier::optim
>> *ObjSize = CI->getArgOperand(2);
>>
>> // __stpcpy_chk(x,x,...) -> x+strlen(x)
>> - if (!OnlyLowerUnknownSize && Dst == Src) {
>> + if (Func == LibFunc::stpcpy_chk && !OnlyLowerUnknownSize && Dst == Src)
>> {
>> Value *StrLen = EmitStrLen(Src, B, DL, TLI);
>> return StrLen ? B.CreateInBoundsGEP(Dst, StrLen) : nullptr;
>> }
>> @@ -2270,11 +2274,11 @@ Value *FortifiedLibCallSimplifier::optim
>> return nullptr;
>> }
>>
>> -Value *FortifiedLibCallSimplifier::optimizeStrNCpyChk(CallInst *CI,
>> IRBuilder<> &B) {
>> +Value *FortifiedLibCallSimplifier::optimizeStrpNCpyChk(CallInst *CI,
>> + IRBuilder<> &B,
>> + LibFunc::Func
>> Func) {
>> Function *Callee = CI->getCalledFunction();
>> StringRef Name = Callee->getName();
>> - LibFunc::Func Func =
>> - Name.startswith("str") ? LibFunc::strncpy_chk :
>> LibFunc::stpncpy_chk;
>>
>> if (!checkStringCopyLibFuncSignature(Callee, Func, DL))
>> return nullptr;
>> @@ -2314,10 +2318,10 @@ Value *FortifiedLibCallSimplifier::optim
>> return optimizeMemSetChk(CI, Builder);
>> case LibFunc::stpcpy_chk:
>> case LibFunc::strcpy_chk:
>> - return optimizeStrCpyChk(CI, Builder);
>> + return optimizeStrpCpyChk(CI, Builder, Func);
>> case LibFunc::stpncpy_chk:
>> case LibFunc::strncpy_chk:
>> - return optimizeStrNCpyChk(CI, Builder);
>> + return optimizeStrpNCpyChk(CI, Builder, Func);
>> default:
>> break;
>> }
>>
>> Modified: llvm/trunk/test/Transforms/InstCombine/memcpy_chk-1.ll
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/memcpy_chk-1.ll?rev=227250&r1=227249&r2=227250&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/test/Transforms/InstCombine/memcpy_chk-1.ll (original)
>> +++ llvm/trunk/test/Transforms/InstCombine/memcpy_chk-1.ll Tue Jan 27
>> 15:52:16 2015
>> @@ -15,46 +15,50 @@ target datalayout = "e-p:64:64:64-i1:8:8
>>
>> ; Check cases where dstlen >= len.
>>
>> -define void @test_simplify1() {
>> +define i8* @test_simplify1() {
>> ; CHECK-LABEL: @test_simplify1(
>> %dst = bitcast %struct.T1* @t1 to i8*
>> %src = bitcast %struct.T2* @t2 to i8*
>>
>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64
>> - call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824)
>> - ret void
>> +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast
>> (%struct.T1* @t1 to i8*), i8* bitcast (%struct.T2* @t2 to i8*), i64 1824,
>> i32 4, i1 false)
>> +; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*)
>> + %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824)
>> + ret i8* %ret
>> }
>>
>> -define void @test_simplify2() {
>> +define i8* @test_simplify2() {
>> ; CHECK-LABEL: @test_simplify2(
>> %dst = bitcast %struct.T1* @t1 to i8*
>> %src = bitcast %struct.T3* @t3 to i8*
>>
>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64
>> - call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 2848)
>> - ret void
>> +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast
>> (%struct.T1* @t1 to i8*), i8* bitcast (%struct.T3* @t3 to i8*), i64 1824,
>> i32 4, i1 false)
>> +; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*)
>> + %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 2848)
>> + ret i8* %ret
>> }
>>
>> ; Check cases where dstlen < len.
>>
>> -define void @test_no_simplify1() {
>> +define i8* @test_no_simplify1() {
>> ; CHECK-LABEL: @test_no_simplify1(
>> %dst = bitcast %struct.T3* @t3 to i8*
>> %src = bitcast %struct.T1* @t1 to i8*
>>
>> -; CHECK-NEXT: call i8* @__memcpy_chk
>> - call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 2848, i64 1824)
>> - ret void
>> +; CHECK-NEXT: %ret = call i8* @__memcpy_chk(i8* bitcast (%struct.T3* @t3
>> to i8*), i8* bitcast (%struct.T1* @t1 to i8*), i64 2848, i64 1824)
>> +; CHECK-NEXT: ret i8* %ret
>> + %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 2848, i64 1824)
>> + ret i8* %ret
>> }
>>
>> -define void @test_no_simplify2() {
>> +define i8* @test_no_simplify2() {
>> ; CHECK-LABEL: @test_no_simplify2(
>> %dst = bitcast %struct.T1* @t1 to i8*
>> %src = bitcast %struct.T2* @t2 to i8*
>>
>> -; CHECK-NEXT: call i8* @__memcpy_chk
>> - call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1024, i64 0)
>> - ret void
>> +; CHECK-NEXT: %ret = call i8* @__memcpy_chk(i8* bitcast (%struct.T1* @t1
>> to i8*), i8* bitcast (%struct.T2* @t2 to i8*), i64 1024, i64 0)
>> +; CHECK-NEXT: ret i8* %ret
>> + %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1024, i64 0)
>> + ret i8* %ret
>> }
>>
>> define i8* @test_simplify_return_indcall(i8* ()* %alloc) {
>>
>> Modified: llvm/trunk/test/Transforms/InstCombine/memmove_chk-1.ll
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/memmove_chk-1.ll?rev=227250&r1=227249&r2=227250&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/test/Transforms/InstCombine/memmove_chk-1.ll (original)
>> +++ llvm/trunk/test/Transforms/InstCombine/memmove_chk-1.ll Tue Jan 27
>> 15:52:16 2015
>> @@ -15,46 +15,50 @@ target datalayout = "e-p:64:64:64-i1:8:8
>>
>> ; Check cases where dstlen >= len.
>>
>> -define void @test_simplify1() {
>> +define i8* @test_simplify1() {
>> ; CHECK-LABEL: @test_simplify1(
>> %dst = bitcast %struct.T1* @t1 to i8*
>> %src = bitcast %struct.T2* @t2 to i8*
>>
>> -; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64
>> - call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1824, i64 1824)
>> - ret void
>> +; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* bitcast
>> (%struct.T1* @t1 to i8*), i8* bitcast (%struct.T2* @t2 to i8*), i64 1824,
>> i32 4, i1 false)
>> +; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*)
>> + %ret = call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1824, i64 1824)
>> + ret i8* %ret
>> }
>>
>> -define void @test_simplify2() {
>> +define i8* @test_simplify2() {
>> ; CHECK-LABEL: @test_simplify2(
>> %dst = bitcast %struct.T1* @t1 to i8*
>> %src = bitcast %struct.T3* @t3 to i8*
>>
>> -; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64
>> - call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1824, i64 2848)
>> - ret void
>> +; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* bitcast
>> (%struct.T1* @t1 to i8*), i8* bitcast (%struct.T3* @t3 to i8*), i64 1824,
>> i32 4, i1 false)
>> +; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*)
>> + %ret = call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1824, i64 2848)
>> + ret i8* %ret
>> }
>>
>> ; Check cases where dstlen < len.
>>
>> -define void @test_no_simplify1() {
>> +define i8* @test_no_simplify1() {
>> ; CHECK-LABEL: @test_no_simplify1(
>> %dst = bitcast %struct.T3* @t3 to i8*
>> %src = bitcast %struct.T1* @t1 to i8*
>>
>> -; CHECK-NEXT: call i8* @__memmove_chk
>> - call i8* @__memmove_chk(i8* %dst, i8* %src, i64 2848, i64 1824)
>> - ret void
>> +; CHECK-NEXT: %ret = call i8* @__memmove_chk(i8* bitcast (%struct.T3* @t3
>> to i8*), i8* bitcast (%struct.T1* @t1 to i8*), i64 2848, i64 1824)
>> +; CHECK-NEXT: ret i8* %ret
>> + %ret = call i8* @__memmove_chk(i8* %dst, i8* %src, i64 2848, i64 1824)
>> + ret i8* %ret
>> }
>>
>> -define void @test_no_simplify2() {
>> +define i8* @test_no_simplify2() {
>> ; CHECK-LABEL: @test_no_simplify2(
>> %dst = bitcast %struct.T1* @t1 to i8*
>> %src = bitcast %struct.T2* @t2 to i8*
>>
>> -; CHECK-NEXT: call i8* @__memmove_chk
>> - call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1024, i64 0)
>> - ret void
>> +; CHECK-NEXT: %ret = call i8* @__memmove_chk(i8* bitcast (%struct.T1* @t1
>> to i8*), i8* bitcast (%struct.T2* @t2 to i8*), i64 1024, i64 0)
>> +; CHECK-NEXT: ret i8* %ret
>> + %ret = call i8* @__memmove_chk(i8* %dst, i8* %src, i64 1024, i64 0)
>> + ret i8* %ret
>> }
>>
>> declare i8* @__memmove_chk(i8*, i8*, i64, i64)
>>
>> Modified: llvm/trunk/test/Transforms/InstCombine/memset_chk-1.ll
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/memset_chk-1.ll?rev=227250&r1=227249&r2=227250&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/test/Transforms/InstCombine/memset_chk-1.ll (original)
>> +++ llvm/trunk/test/Transforms/InstCombine/memset_chk-1.ll Tue Jan 27
>> 15:52:16 2015
>> @@ -11,51 +11,56 @@ target datalayout = "e-p:64:64:64-i1:8:8
>>
>> ; Check cases where dstlen >= len.
>>
>> -define void @test_simplify1() {
>> +define i8* @test_simplify1() {
>> ; CHECK-LABEL: @test_simplify1(
>> %dst = bitcast %struct.T* @t to i8*
>>
>> -; CHECK-NEXT: call void @llvm.memset.p0i8.i64
>> - call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 1824)
>> - ret void
>> +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* bitcast (%struct.T* @t
>> to i8*), i8 0, i64 1824, i32 4, i1 false)
>> +; CHECK-NEXT: ret i8* bitcast (%struct.T* @t to i8*)
>> + %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 1824)
>> + ret i8* %ret
>> }
>>
>> -define void @test_simplify2() {
>> +define i8* @test_simplify2() {
>> ; CHECK-LABEL: @test_simplify2(
>> %dst = bitcast %struct.T* @t to i8*
>>
>> -; CHECK-NEXT: call void @llvm.memset.p0i8.i64
>> - call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 3648)
>> - ret void
>> +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* bitcast (%struct.T* @t
>> to i8*), i8 0, i64 1824, i32 4, i1 false)
>> +; CHECK-NEXT: ret i8* bitcast (%struct.T* @t to i8*)
>> + %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 3648)
>> + ret i8* %ret
>> }
>>
>> -define void @test_simplify3() {
>> +define i8* @test_simplify3() {
>> ; CHECK-LABEL: @test_simplify3(
>> %dst = bitcast %struct.T* @t to i8*
>>
>> -; CHECK-NEXT: call void @llvm.memset.p0i8.i64
>> - call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 -1)
>> - ret void
>> +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* bitcast (%struct.T* @t
>> to i8*), i8 0, i64 1824, i32 4, i1 false)
>> +; CHECK-NEXT: ret i8* bitcast (%struct.T* @t to i8*)
>> + %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 -1)
>> + ret i8* %ret
>> }
>>
>> ; Check cases where dstlen < len.
>>
>> -define void @test_no_simplify1() {
>> +define i8* @test_no_simplify1() {
>> ; CHECK-LABEL: @test_no_simplify1(
>> %dst = bitcast %struct.T* @t to i8*
>>
>> -; CHECK-NEXT: call i8* @__memset_chk
>> - call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 400)
>> - ret void
>> +; CHECK-NEXT: %ret = call i8* @__memset_chk(i8* bitcast (%struct.T* @t to
>> i8*), i32 0, i64 1824, i64 400)
>> +; CHECK-NEXT: ret i8* %ret
>> + %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 400)
>> + ret i8* %ret
>> }
>>
>> -define void @test_no_simplify2() {
>> +define i8* @test_no_simplify2() {
>> ; CHECK-LABEL: @test_no_simplify2(
>> %dst = bitcast %struct.T* @t to i8*
>>
>> -; CHECK-NEXT: call i8* @__memset_chk
>> - call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 0)
>> - ret void
>> +; CHECK-NEXT: %ret = call i8* @__memset_chk(i8* bitcast (%struct.T* @t to
>> i8*), i32 0, i64 1824, i64 0)
>> +; CHECK-NEXT: ret i8* %ret
>> + %ret = call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 0)
>> + ret i8* %ret
>> }
>>
>> declare i8* @__memset_chk(i8*, i32, i64, i64)
>>
>> Modified: llvm/trunk/test/Transforms/InstCombine/stpcpy_chk-1.ll
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/stpcpy_chk-1.ll?rev=227250&r1=227249&r2=227250&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/test/Transforms/InstCombine/stpcpy_chk-1.ll (original)
>> +++ llvm/trunk/test/Transforms/InstCombine/stpcpy_chk-1.ll Tue Jan 27
>> 15:52:16 2015
>> @@ -11,46 +11,50 @@ target datalayout = "e-p:32:32:32-i1:8:8
>>
>> ; Check cases where slen >= strlen (src).
>>
>> -define void @test_simplify1() {
>> +define i8* @test_simplify1() {
>> ; CHECK-LABEL: @test_simplify1(
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>> %src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
>>
>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32
>> - call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 60)
>> - ret void
>> +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr
>> inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x
>> i8]* @.str, i32 0, i32 0), i32 12, i32 1, i1 false)
>> +; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32
>> 11)
>> + %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 60)
>> + ret i8* %ret
>> }
>>
>> -define void @test_simplify2() {
>> +define i8* @test_simplify2() {
>> ; CHECK-LABEL: @test_simplify2(
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>> %src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
>>
>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32
>> - call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 12)
>> - ret void
>> +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr
>> inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x
>> i8]* @.str, i32 0, i32 0), i32 12, i32 1, i1 false)
>> +; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32
>> 11)
>> + %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 12)
>> + ret i8* %ret
>> }
>>
>> -define void @test_simplify3() {
>> +define i8* @test_simplify3() {
>> ; CHECK-LABEL: @test_simplify3(
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>> %src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
>>
>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32
>> - call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 -1)
>> - ret void
>> +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr
>> inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x
>> i8]* @.str, i32 0, i32 0), i32 12, i32 1, i1 false)
>> +; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32
>> 11)
>> + %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 -1)
>> + ret i8* %ret
>> }
>>
>> ; Check cases where there are no string constants.
>>
>> -define void @test_simplify4() {
>> +define i8* @test_simplify4() {
>> ; CHECK-LABEL: @test_simplify4(
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>> %src = getelementptr inbounds [60 x i8]* @b, i32 0, i32 0
>>
>> -; CHECK-NEXT: call i8* @stpcpy
>> - call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 -1)
>> - ret void
>> +; CHECK-NEXT: %stpcpy = call i8* @stpcpy(i8* getelementptr inbounds ([60
>> x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8]* @b, i32 0,
>> i32 0))
>> +; CHECK-NEXT: ret i8* %stpcpy
>> + %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 -1)
>> + ret i8* %ret
>> }
>>
>> ; Check case where the string length is not constant.
>> @@ -60,10 +64,11 @@ define i8* @test_simplify5() {
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>> %src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
>>
>> -; CHECK: @__memcpy_chk
>> +; CHECK-NEXT: %len = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr
>> inbounds ([60 x i8]* @a, i32 0, i32 0), i1 false)
>> +; CHECK-NEXT: %1 = call i8* @__memcpy_chk(i8* getelementptr inbounds ([60
>> x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8]* @.str, i32
>> 0, i32 0), i32 12, i32 %len)
>> +; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32
>> 11)
>> %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false)
>> %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 %len)
>> -; CHECK: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 11)
>> ret i8* %ret
>> }
>>
>> @@ -73,8 +78,9 @@ define i8* @test_simplify6() {
>> ; CHECK-LABEL: @test_simplify6(
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>>
>> -; CHECK: [[LEN:%[a-z]+]] = call i32 @strlen
>> -; CHECK-NEXT: getelementptr inbounds [60 x i8]* @a, i32 0, i32 [[LEN]]
>> +; CHECK-NEXT: %strlen = call i32 @strlen(i8* getelementptr inbounds ([60
>> x i8]* @a, i32 0, i32 0))
>> +; CHECK-NEXT: %1 = getelementptr inbounds [60 x i8]* @a, i32 0, i32
>> %strlen
>> +; CHECK-NEXT: ret i8* %1
>> %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false)
>> %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %dst, i32 %len)
>> ret i8* %ret
>> @@ -82,14 +88,15 @@ define i8* @test_simplify6() {
>>
>> ; Check case where slen < strlen (src).
>>
>> -define void @test_no_simplify1() {
>> +define i8* @test_no_simplify1() {
>> ; CHECK-LABEL: @test_no_simplify1(
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>> %src = getelementptr inbounds [60 x i8]* @b, i32 0, i32 0
>>
>> -; CHECK-NEXT: call i8* @__stpcpy_chk
>> - call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 8)
>> - ret void
>> +; CHECK-NEXT: %ret = call i8* @__stpcpy_chk(i8* getelementptr inbounds
>> ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8]* @b,
>> i32 0, i32 0), i32 8)
>> +; CHECK-NEXT: ret i8* %ret
>> + %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 8)
>> + ret i8* %ret
>> }
>>
>> declare i8* @__stpcpy_chk(i8*, i8*, i32) nounwind
>>
>> Modified: llvm/trunk/test/Transforms/InstCombine/strcpy_chk-1.ll
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strcpy_chk-1.ll?rev=227250&r1=227249&r2=227250&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/test/Transforms/InstCombine/strcpy_chk-1.ll (original)
>> +++ llvm/trunk/test/Transforms/InstCombine/strcpy_chk-1.ll Tue Jan 27
>> 15:52:16 2015
>> @@ -11,59 +11,65 @@ target datalayout = "e-p:32:32:32-i1:8:8
>>
>> ; Check cases where slen >= strlen (src).
>>
>> -define void @test_simplify1() {
>> +define i8* @test_simplify1() {
>> ; CHECK-LABEL: @test_simplify1(
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>> %src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
>>
>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32
>> - call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 60)
>> - ret void
>> +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr
>> inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x
>> i8]* @.str, i32 0, i32 0), i32 12, i32 1, i1 false)
>> +; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32
>> 0)
>> + %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 60)
>> + ret i8* %ret
>> }
>>
>> -define void @test_simplify2() {
>> +define i8* @test_simplify2() {
>> ; CHECK-LABEL: @test_simplify2(
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>> %src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
>>
>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32
>> - call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 12)
>> - ret void
>> +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr
>> inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x
>> i8]* @.str, i32 0, i32 0), i32 12, i32 1, i1 false)
>> +; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32
>> 0)
>> + %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 12)
>> + ret i8* %ret
>> }
>>
>> -define void @test_simplify3() {
>> +define i8* @test_simplify3() {
>> ; CHECK-LABEL: @test_simplify3(
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>> %src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
>>
>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32
>> - call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 -1)
>> - ret void
>> +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr
>> inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x
>> i8]* @.str, i32 0, i32 0), i32 12, i32 1, i1 false)
>> +; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32
>> 0)
>> + %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 -1)
>> + ret i8* %ret
>> }
>>
>> ; Check cases where there are no string constants.
>>
>> -define void @test_simplify4() {
>> +define i8* @test_simplify4() {
>> ; CHECK-LABEL: @test_simplify4(
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>> %src = getelementptr inbounds [60 x i8]* @b, i32 0, i32 0
>>
>> -; CHECK-NEXT: call i8* @strcpy
>> - call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 -1)
>> - ret void
>> +; CHECK-NEXT: %strcpy = call i8* @strcpy(i8* getelementptr inbounds ([60
>> x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8]* @b, i32 0,
>> i32 0))
>> +; CHECK-NEXT: ret i8* %strcpy
>> + %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 -1)
>> + ret i8* %ret
>> }
>>
>> ; Check case where the string length is not constant.
>>
>> -define void @test_simplify5() {
>> +define i8* @test_simplify5() {
>> ; CHECK-LABEL: @test_simplify5(
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>> %src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
>>
>> -; CHECK: @__memcpy_chk
>> +; CHECK-NEXT: %len = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr
>> inbounds ([60 x i8]* @a, i32 0, i32 0), i1 false)
>> +; CHECK-NEXT: %1 = call i8* @__memcpy_chk(i8* getelementptr inbounds ([60
>> x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8]* @.str, i32
>> 0, i32 0), i32 12, i32 %len)
>> +; CHECK-NEXT: ret i8* %1
>> %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false)
>> - call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 %len)
>> - ret void
>> + %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 %len)
>> + ret i8* %ret
>> }
>>
>> ; Check case where the source and destination are the same.
>> @@ -72,7 +78,9 @@ define i8* @test_simplify6() {
>> ; CHECK-LABEL: @test_simplify6(
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>>
>> -; CHECK: getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0)
>> +; CHECK-NEXT: %len = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr
>> inbounds ([60 x i8]* @a, i32 0, i32 0), i1 false)
>> +; CHECK-NEXT: %ret = call i8* @__strcpy_chk(i8* getelementptr inbounds
>> ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8]* @a,
>> i32 0, i32 0), i32 %len)
>> +; CHECK-NEXT: ret i8* %ret
>> %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false)
>> %ret = call i8* @__strcpy_chk(i8* %dst, i8* %dst, i32 %len)
>> ret i8* %ret
>> @@ -80,14 +88,15 @@ define i8* @test_simplify6() {
>>
>> ; Check case where slen < strlen (src).
>>
>> -define void @test_no_simplify1() {
>> +define i8* @test_no_simplify1() {
>> ; CHECK-LABEL: @test_no_simplify1(
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>> %src = getelementptr inbounds [60 x i8]* @b, i32 0, i32 0
>>
>> -; CHECK-NEXT: call i8* @__strcpy_chk
>> - call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 8)
>> - ret void
>> +; CHECK-NEXT: %ret = call i8* @__strcpy_chk(i8* getelementptr inbounds
>> ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8]* @b,
>> i32 0, i32 0), i32 8)
>> +; CHECK-NEXT: ret i8* %ret
>> + %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 8)
>> + ret i8* %ret
>> }
>>
>> declare i8* @__strcpy_chk(i8*, i8*, i32) nounwind
>>
>> Modified: llvm/trunk/test/Transforms/InstCombine/strncpy_chk-1.ll
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strncpy_chk-1.ll?rev=227250&r1=227249&r2=227250&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/test/Transforms/InstCombine/strncpy_chk-1.ll (original)
>> +++ llvm/trunk/test/Transforms/InstCombine/strncpy_chk-1.ll Tue Jan 27
>> 15:52:16 2015
>> @@ -11,56 +11,61 @@ target datalayout = "e-p:32:32:32-i1:8:8
>>
>> ; Check cases where dstlen >= len
>>
>> -define void @test_simplify1() {
>> +define i8* @test_simplify1() {
>> ; CHECK-LABEL: @test_simplify1(
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>> %src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
>>
>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32
>> - call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 60)
>> - ret void
>> +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr
>> inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x
>> i8]* @.str, i32 0, i32 0), i32 12, i32 1, i1 false)
>> +; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32
>> 0)
>> + %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 60)
>> + ret i8* %ret
>> }
>>
>> -define void @test_simplify2() {
>> +define i8* @test_simplify2() {
>> ; CHECK-LABEL: @test_simplify2(
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>> %src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
>>
>> -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32
>> - call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 12)
>> - ret void
>> +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr
>> inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x
>> i8]* @.str, i32 0, i32 0), i32 12, i32 1, i1 false)
>> +; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32
>> 0)
>> + %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 12)
>> + ret i8* %ret
>> }
>>
>> -define void @test_simplify3() {
>> +define i8* @test_simplify3() {
>> ; CHECK-LABEL: @test_simplify3(
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>> %src = getelementptr inbounds [60 x i8]* @b, i32 0, i32 0
>>
>> -; CHECK-NEXT: call i8* @strncpy
>> - call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 60)
>> - ret void
>> +; CHECK-NEXT: %strncpy = call i8* @strncpy(i8* getelementptr inbounds
>> ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8]* @b,
>> i32 0, i32 0), i32 12)
>> +; CHECK-NEXT: ret i8* %strncpy
>> + %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 60)
>> + ret i8* %ret
>> }
>>
>> ; Check cases where dstlen < len
>>
>> -define void @test_no_simplify1() {
>> +define i8* @test_no_simplify1() {
>> ; CHECK-LABEL: @test_no_simplify1(
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>> %src = getelementptr inbounds [12 x i8]* @.str, i32 0, i32 0
>>
>> -; CHECK-NEXT: call i8* @__strncpy_chk
>> - call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 8, i32 4)
>> - ret void
>> +; CHECK-NEXT: %ret = call i8* @__strncpy_chk(i8* getelementptr inbounds
>> ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8]* @.str,
>> i32 0, i32 0), i32 8, i32 4)
>> +; CHECK-NEXT: ret i8* %ret
>> + %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 8, i32 4)
>> + ret i8* %ret
>> }
>>
>> -define void @test_no_simplify2() {
>> +define i8* @test_no_simplify2() {
>> ; CHECK-LABEL: @test_no_simplify2(
>> %dst = getelementptr inbounds [60 x i8]* @a, i32 0, i32 0
>> %src = getelementptr inbounds [60 x i8]* @b, i32 0, i32 0
>>
>> -; CHECK-NEXT: call i8* @__strncpy_chk
>> - call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 8, i32 0)
>> - ret void
>> +; CHECK-NEXT: %ret = call i8* @__strncpy_chk(i8* getelementptr inbounds
>> ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8]* @b,
>> i32 0, i32 0), i32 8, i32 0)
>> +; CHECK-NEXT: ret i8* %ret
>> + %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 8, i32 0)
>> + ret i8* %ret
>> }
>>
>> declare i8* @__strncpy_chk(i8*, i8*, i32, i32)
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list