[InstCombine] stpcpy(d,s) -> strcpy(d,s) if the result is not used
This commit is contained in:
parent
7801d7963d
commit
9c476172b9
|
@ -1268,7 +1268,7 @@ Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,
|
|||
|
||||
Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilderBase &B,
|
||||
const TargetLibraryInfo *TLI) {
|
||||
Type *I8Ptr = B.getInt8PtrTy();
|
||||
Type *I8Ptr = Dst->getType();
|
||||
return emitLibCall(LibFunc_strcpy, I8Ptr, {I8Ptr, I8Ptr},
|
||||
{castToCStr(Dst, B), castToCStr(Src, B)}, B, TLI);
|
||||
}
|
||||
|
|
|
@ -517,6 +517,11 @@ Value *LibCallSimplifier::optimizeStrCpy(CallInst *CI, IRBuilderBase &B) {
|
|||
Value *LibCallSimplifier::optimizeStpCpy(CallInst *CI, IRBuilderBase &B) {
|
||||
Function *Callee = CI->getCalledFunction();
|
||||
Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1);
|
||||
|
||||
// stpcpy(d,s) -> strcpy(d,s) if the result is not used.
|
||||
if (CI->use_empty())
|
||||
return emitStrCpy(Dst, Src, B, TLI);
|
||||
|
||||
if (Dst == Src) { // stpcpy(x,x) -> x+strlen(x)
|
||||
Value *StrLen = emitStrLen(Src, B, DL, TLI);
|
||||
return StrLen ? B.CreateInBoundsGEP(B.getInt8Ty(), Dst, StrLen) : nullptr;
|
||||
|
|
|
@ -38,7 +38,7 @@ define i8* @test_simplify2() {
|
|||
|
||||
define void @test_simplify3(i8* %dst) {
|
||||
; CHECK-LABEL: @test_simplify3(
|
||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(80) [[DST:%.*]], i8* noundef nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false)
|
||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(6) [[DST:%.*]], i8* noundef nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false)
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0
|
||||
|
|
|
@ -13,7 +13,7 @@ declare i8 addrspace(200)* @stpncpy(i8 addrspace(200)*, i8 addrspace(200)*, i64)
|
|||
|
||||
define void @test_strcpy_to_memcpy(i8 addrspace(200)* %dst) addrspace(200) nounwind {
|
||||
; CHECK-LABEL: define {{[^@]+}}@test_strcpy_to_memcpy
|
||||
; CHECK-SAME: (i8 addrspace(200)* [[DST:%.*]]) addrspace(200) [[ATTR0:#.*]] {
|
||||
; CHECK-SAME: (i8 addrspace(200)* [[DST:%.*]]) addrspace(200) #[[ATTR1:[0-9]+]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: call addrspace(200) void @llvm.memcpy.p200i8.p200i8.i64(i8 addrspace(200)* noundef align 1 dereferenceable(17) [[DST]], i8 addrspace(200)* noundef align 1 dereferenceable(17) getelementptr inbounds ([17 x i8], [17 x i8] addrspace(200)* @str, i64 0, i64 0), i64 17, i1 false)
|
||||
; CHECK-NEXT: ret void
|
||||
|
@ -25,9 +25,9 @@ entry:
|
|||
|
||||
define void @test_stpcpy_to_memcpy(i8 addrspace(200)* %dst) addrspace(200) nounwind {
|
||||
; CHECK-LABEL: define {{[^@]+}}@test_stpcpy_to_memcpy
|
||||
; CHECK-SAME: (i8 addrspace(200)* [[DST:%.*]]) addrspace(200) [[ATTR0]] {
|
||||
; CHECK-SAME: (i8 addrspace(200)* [[DST:%.*]]) addrspace(200) #[[ATTR1]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: call addrspace(200) void @llvm.memcpy.p200i8.p200i8.i128(i8 addrspace(200)* noundef align 1 dereferenceable(17) [[DST]], i8 addrspace(200)* noundef align 1 dereferenceable(17) getelementptr inbounds ([17 x i8], [17 x i8] addrspace(200)* @str, i64 0, i64 0), i128 17, i1 false)
|
||||
; CHECK-NEXT: call addrspace(200) void @llvm.memcpy.p200i8.p200i8.i64(i8 addrspace(200)* noundef align 1 dereferenceable(17) [[DST]], i8 addrspace(200)* noundef align 1 dereferenceable(17) getelementptr inbounds ([17 x i8], [17 x i8] addrspace(200)* @str, i64 0, i64 0), i64 17, i1 false)
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
|
@ -37,7 +37,7 @@ entry:
|
|||
|
||||
define void @test_strncpy_to_memcpy(i8 addrspace(200)* %dst) addrspace(200) nounwind {
|
||||
; CHECK-LABEL: define {{[^@]+}}@test_strncpy_to_memcpy
|
||||
; CHECK-SAME: (i8 addrspace(200)* [[DST:%.*]]) addrspace(200) [[ATTR0]] {
|
||||
; CHECK-SAME: (i8 addrspace(200)* [[DST:%.*]]) addrspace(200) #[[ATTR1]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: call addrspace(200) void @llvm.memcpy.p200i8.p200i8.i128(i8 addrspace(200)* noundef align 1 dereferenceable(17) [[DST]], i8 addrspace(200)* noundef align 1 dereferenceable(17) getelementptr inbounds ([17 x i8], [17 x i8] addrspace(200)* @str, i64 0, i64 0), i128 17, i1 false)
|
||||
; CHECK-NEXT: ret void
|
||||
|
@ -50,7 +50,7 @@ entry:
|
|||
; Note: stpncpy is not handled by SimplifyLibcalls yet, so this should not be changed.
|
||||
define void @test_stpncpy_to_memcpy(i8 addrspace(200)* %dst) addrspace(200) nounwind {
|
||||
; CHECK-LABEL: define {{[^@]+}}@test_stpncpy_to_memcpy
|
||||
; CHECK-SAME: (i8 addrspace(200)* [[DST:%.*]]) addrspace(200) [[ATTR0]] {
|
||||
; CHECK-SAME: (i8 addrspace(200)* [[DST:%.*]]) addrspace(200) #[[ATTR1]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call addrspace(200) i8 addrspace(200)* @stpncpy(i8 addrspace(200)* [[DST]], i8 addrspace(200)* getelementptr inbounds ([17 x i8], [17 x i8] addrspace(200)* @str, i64 0, i64 0), i64 17)
|
||||
; CHECK-NEXT: ret void
|
||||
|
|
Loading…
Reference in a new issue