diff --git a/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/include/llvm/Transforms/Utils/SimplifyLibCalls.h index fb3beb2ab2d..08358e14130 100644 --- a/include/llvm/Transforms/Utils/SimplifyLibCalls.h +++ b/include/llvm/Transforms/Utils/SimplifyLibCalls.h @@ -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. diff --git a/lib/Transforms/Utils/SimplifyLibCalls.cpp b/lib/Transforms/Utils/SimplifyLibCalls.cpp index 13c2365e1ef..fb1d83fc333 100644 --- a/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1968,8 +1968,12 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) { // Try to further simplify the result. CallInst *SimplifiedCI = dyn_cast(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::optimizeMemSetChk(CallInst *CI, IRBuilder<> & 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::optimizeStrCpyChk(CallInst *CI, IRBuilder<> & *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::optimizeStrCpyChk(CallInst *CI, IRBuilder<> & 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::optimizeCall(CallInst *CI) { 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; } diff --git a/test/Transforms/InstCombine/memcpy_chk-1.ll b/test/Transforms/InstCombine/memcpy_chk-1.ll index 008b838201e..ddaaf82a8e2 100644 --- a/test/Transforms/InstCombine/memcpy_chk-1.ll +++ b/test/Transforms/InstCombine/memcpy_chk-1.ll @@ -15,46 +15,50 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3 ; 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) { diff --git a/test/Transforms/InstCombine/memmove_chk-1.ll b/test/Transforms/InstCombine/memmove_chk-1.ll index 6d93bbbf959..e4e1f6eedf3 100644 --- a/test/Transforms/InstCombine/memmove_chk-1.ll +++ b/test/Transforms/InstCombine/memmove_chk-1.ll @@ -15,46 +15,50 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3 ; 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) diff --git a/test/Transforms/InstCombine/memset_chk-1.ll b/test/Transforms/InstCombine/memset_chk-1.ll index 47cc7db998e..27f7293a6bc 100644 --- a/test/Transforms/InstCombine/memset_chk-1.ll +++ b/test/Transforms/InstCombine/memset_chk-1.ll @@ -11,51 +11,56 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3 ; 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) diff --git a/test/Transforms/InstCombine/stpcpy_chk-1.ll b/test/Transforms/InstCombine/stpcpy_chk-1.ll index 8a02529c61c..393c5d96d10 100644 --- a/test/Transforms/InstCombine/stpcpy_chk-1.ll +++ b/test/Transforms/InstCombine/stpcpy_chk-1.ll @@ -11,46 +11,50 @@ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f3 ; 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 diff --git a/test/Transforms/InstCombine/strcpy_chk-1.ll b/test/Transforms/InstCombine/strcpy_chk-1.ll index 8e7fec76ef5..e3f163fd087 100644 --- a/test/Transforms/InstCombine/strcpy_chk-1.ll +++ b/test/Transforms/InstCombine/strcpy_chk-1.ll @@ -11,59 +11,65 @@ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f3 ; 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 diff --git a/test/Transforms/InstCombine/strncpy_chk-1.ll b/test/Transforms/InstCombine/strncpy_chk-1.ll index 90b4173ced7..9242a8acdbb 100644 --- a/test/Transforms/InstCombine/strncpy_chk-1.ll +++ b/test/Transforms/InstCombine/strncpy_chk-1.ll @@ -11,56 +11,61 @@ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f3 ; 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)