brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.0 KiB · f1121fa Raw
185 lines · plain
1; RUN: opt < %s -aa-pipeline=basic-aa -passes='cgscc(function-attrs,inline)' -S | FileCheck %s2; This test runs the inliner and the function attribute deduction. It ensures3; that when the inliner mutates the call graph it correctly updates the CGSCC4; iteration so that we can compute refined function attributes. In this way it5; is leveraging function attribute computation to observe correct call graph6; updates.7 8; Boring unknown external function call.9; CHECK: declare void @unknown()10declare void @unknown()11 12; Basic correctness check: this should get annotated as memory(none).13; CHECK: Function Attrs: nounwind memory(none)14; CHECK-NEXT: declare void @readnone()15declare void @readnone() readnone nounwind16 17; The 'test1_' prefixed functions are designed to trigger forming a new direct18; call in the inlined body of the function. After that, we form a new SCC and19; using that can deduce precise function attrs.20 21; This function should no longer exist.22; CHECK-NOT: @test1_f()23define internal void @test1_f(ptr %p) {24entry:25  call void %p()26  ret void27}28 29; This function should have had 'memory(none)' deduced for its SCC.30; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none)31; CHECK-NEXT: define void @test1_g()32define void @test1_g() noinline {33entry:34  call void @test1_f(ptr @test1_h)35  ret void36}37 38; This function should have had 'memory(none)' deduced for its SCC.39; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none)40; CHECK-NEXT: define void @test1_h()41define void @test1_h() noinline {42entry:43  call void @test1_g()44  call void @readnone()45  ret void46}47 48 49; The 'test2_' prefixed functions are designed to trigger forming a new direct50; call due to RAUW-ing the returned value of a called function into the caller.51; This too should form a new SCC which can then be reasoned about to compute52; precise function attrs.53 54; This function should no longer exist.55; CHECK-NOT: @test2_f()56define internal ptr @test2_f() {57entry:58  ret ptr @test2_h59}60 61; This function should have had 'memory(none)' deduced for its SCC.62; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none)63; CHECK-NEXT: define void @test2_g()64define void @test2_g() noinline {65entry:66  %p = call ptr @test2_f()67  call void %p()68  ret void69}70 71; This function should have had 'memory(none)' deduced for its SCC.72; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none)73; CHECK-NEXT: define void @test2_h()74define void @test2_h() noinline {75entry:76  call void @test2_g()77  call void @readnone()78  ret void79}80 81 82; The 'test3_' prefixed functions are designed to inline in a way that causes83; call sites to become trivially dead during the middle of inlining callsites of84; a single function to make sure that the inliner does not get confused by this85; pattern.86 87; CHECK-NOT: @test3_maybe_unknown(88define internal void @test3_maybe_unknown(i1 %b) {89entry:90  br i1 %b, label %then, label %exit91 92then:93  call void @unknown()94  br label %exit95 96exit:97  ret void98}99 100; CHECK-NOT: @test3_f(101define internal i1 @test3_f() {102entry:103  ret i1 false104}105 106; CHECK-NOT: @test3_g(107define internal i1 @test3_g(i1 %b) {108entry:109  br i1 %b, label %then1, label %if2110 111then1:112  call void @test3_maybe_unknown(i1 true)113  br label %if2114 115if2:116  %f = call i1 @test3_f()117  br i1 %f, label %then2, label %exit118 119then2:120  call void @test3_maybe_unknown(i1 true)121  br label %exit122 123exit:124  ret i1 false125}126 127; FIXME: Currently the inliner doesn't successfully mark this as readnone128; because while it simplifies trivially dead CFGs when inlining callees it129; doesn't simplify the caller's trivially dead CFG and so we end with a dead130; block calling @unknown.131; CHECK-NOT: Function Attrs: readnone132; CHECK: define void @test3_h()133define void @test3_h() {134entry:135  %g = call i1 @test3_g(i1 false)136  br i1 %g, label %then, label %exit137 138then:139  call void @test3_maybe_unknown(i1 true)140  br label %exit141 142exit:143  call void @test3_maybe_unknown(i1 false)144  ret void145}146 147 148; The 'test4_' prefixed functions are designed to trigger forming a new direct149; call in the inlined body of the function similar to 'test1_'. However, after150; that we continue to inline another edge of the graph forcing us to do a more151; interesting call graph update for the new call edge. Eventually, we still152; form a new SCC and should use that can deduce precise function attrs.153 154; This function should have had 'memory(none)' deduced for its SCC.155; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none)156; CHECK-NEXT: define void @test4_f1()157define void @test4_f1() noinline {158entry:159  call void @test4_h()160  ret void161}162 163; CHECK-NOT: @test4_f2164define internal void @test4_f2() {165entry:166  call void @test4_f1()167  ret void168}169 170; CHECK-NOT: @test4_g171define internal void @test4_g(ptr %p) {172entry:173  call void %p()174  ret void175}176 177; This function should have had 'memory(none)' deduced for its SCC.178; CHECK: Function Attrs: nofree noinline nosync nounwind memory(none)179; CHECK-NEXT: define void @test4_h()180define void @test4_h() noinline {181entry:182  call void @test4_g(ptr @test4_f2)183  ret void184}185