Commit 9c476172 authored by Dávid Bolvanský's avatar Dávid Bolvanský
Browse files

[InstCombine] stpcpy(d,s) -> strcpy(d,s) if the result is not used

parent 7801d796
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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);
}
+5 −0
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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
+5 −5
Original line number Diff line number Diff line
@@ -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