1; Make sure that the CGSCC pass manager can handle when instcombine simplifies 2; one libcall into an unrelated libcall and update the call graph accordingly. 3; 4; Also check that it can handle inlining *removing* a libcall entirely. 5; 6; Finally, we include some recursive patterns and forced analysis invaliadtion 7; that can trigger infinite CGSCC refinement if not handled correctly. 8; 9; RUN: opt -passes='cgscc(inline,function(instcombine,invalidate<all>))' -S < %s | FileCheck %s 10 11define ptr @wibble(ptr %arg1, ptr %arg2) { 12; CHECK-LABEL: define ptr @wibble( 13bb: 14 %tmp = alloca [1024 x i8], align 16 15 call void @llvm.memcpy.p0.p0.i64(ptr %tmp, ptr %arg1, i64 1024, i1 false) 16; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(1024) 17 %tmp3 = call i64 @llvm.objectsize.i64.p0(ptr %tmp, i1 false, i1 true, i1 false) 18 %tmp4 = call ptr @__strncpy_chk(ptr %arg2, ptr %tmp, i64 1023, i64 %tmp3) 19; CHECK-NOT: call 20; CHECK: call ptr @strncpy(ptr noundef nonnull dereferenceable(1) %arg2, ptr noundef nonnull dereferenceable(1) %tmp, i64 1023) 21 22; CHECK-NOT: call 23 24 ret ptr %tmp4 25; CHECK: ret 26} 27 28define ptr @strncpy(ptr %arg1, ptr %arg2, i64 %size) noinline { 29bb: 30; CHECK: call ptr @my_special_strncpy(ptr %arg1, ptr %arg2, i64 %size) 31 %result = call ptr @my_special_strncpy(ptr %arg1, ptr %arg2, i64 %size) 32 ret ptr %result 33} 34 35declare ptr @my_special_strncpy(ptr %arg1, ptr %arg2, i64 %size) 36 37declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1) 38 39declare ptr @__strncpy_chk(ptr, ptr, i64, i64) 40 41declare void @llvm.memcpy.p0.p0.i64(ptr nocapture writeonly, ptr nocapture readonly, i64, i1) 42 43; Check that even when we completely remove a libcall we don't get the call 44; graph wrong once we handle libcalls in the call graph specially to address 45; the above case. 46define i32 @hoge(ptr %arg1) { 47; CHECK-LABEL: define i32 @hoge( 48bb: 49 %tmp41 = load ptr, ptr null 50 %tmp6 = load i32, ptr %arg1 51 %tmp7 = call i32 @ntohl(i32 %tmp6) 52; CHECK-NOT: call i32 @ntohl 53 ret i32 %tmp7 54; CHECK: ret i32 55} 56 57; Even though this function is not used, it should be retained as it may be 58; used when doing further libcall transformations. 59define internal i32 @ntohl(i32 %x) { 60; CHECK-LABEL: define internal i32 @ntohl( 61entry: 62 %and2 = lshr i32 %x, 8 63 %shr = and i32 %and2, 65280 64 ret i32 %shr 65} 66 67define i64 @write(i32 %i, ptr %p, i64 %j) { 68entry: 69 %val = call i64 @write_wrapper(i32 %i, ptr %p, i64 %j) noinline 70 ret i64 %val 71} 72 73define i64 @write_wrapper(i32 %i, ptr %p, i64 %j) { 74entry: 75 %val = call i64 @write(i32 %i, ptr %p, i64 %j) noinline 76 ret i64 %val 77} 78