78 lines · plain
1; Make sure that the CGSCC pass manager can handle when instcombine simplifies2; 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 invaliadtion7; that can trigger infinite CGSCC refinement if not handled correctly.8;9; RUN: opt -passes='cgscc(inline,function(instcombine,invalidate<all>))' -S < %s | FileCheck %s10 11define ptr @wibble(ptr %arg1, ptr %arg2) {12; CHECK-LABEL: define ptr @wibble(13bb:14 %tmp = alloca [1024 x i8], align 1615 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: call20; CHECK: call ptr @strncpy(ptr noundef nonnull dereferenceable(1) %arg2, ptr noundef nonnull dereferenceable(1) %tmp, i64 1023)21 22; CHECK-NOT: call23 24 ret ptr %tmp425; CHECK: ret26}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 %result33}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 call44; graph wrong once we handle libcalls in the call graph specially to address45; the above case.46define i32 @hoge(ptr %arg1) {47; CHECK-LABEL: define i32 @hoge(48bb:49 %tmp41 = load ptr, ptr null50 %tmp6 = load i32, ptr %arg151 %tmp7 = call i32 @ntohl(i32 %tmp6)52; CHECK-NOT: call i32 @ntohl53 ret i32 %tmp754; CHECK: ret i3255}56 57; Even though this function is not used, it should be retained as it may be58; 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, 863 %shr = and i32 %and2, 6528064 ret i32 %shr65}66 67define i64 @write(i32 %i, ptr %p, i64 %j) {68entry:69 %val = call i64 @write_wrapper(i32 %i, ptr %p, i64 %j) noinline70 ret i64 %val71}72 73define i64 @write_wrapper(i32 %i, ptr %p, i64 %j) {74entry:75 %val = call i64 @write(i32 %i, ptr %p, i64 %j) noinline76 ret i64 %val77}78