brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.3 KiB · aafd38d Raw
342 lines · plain
1; RUN: opt -aa-pipeline=basic-aa -passes='cgscc(function-attrs,function(simplifycfg))' -S < %s | FileCheck %s2 3declare void @readnone() nofree nosync readnone4declare void @unknown()5declare void @reference_function_pointer(ptr) nofree nosync readnone6 7; The @test1_* set of functions checks that when we mutate functions with8; simplifycfg to delete call edges and this ends up splitting both the SCCs9; and the RefSCCs that those functions are in, we re-run the CGSCC passes to10; observe the refined call graph structure.11 12; CHECK: define void @test1_a() {13define void @test1_a() {14  call void @test1_b1()15  call void @test1_b2()16  call void @test1_b3()17  call void @test1_b4()18  ret void19}20 21; CHECK: define void @test1_b1() #0 {22define void @test1_b1() {23  call void @readnone()24  ret void25}26 27; CHECK: define void @test1_b2() #0 {28define void @test1_b2() {29  call void @readnone()30  br i1 false, label %dead, label %exit31 32dead:33  call void @test1_a()34  br label %exit35 36exit:37  ret void38}39 40; CHECK: define void @test1_b3() {41define void @test1_b3() {42  call void @unknown()43  br i1 false, label %dead, label %exit44 45dead:46  call void @test1_a()47  br label %exit48 49exit:50  ret void51}52 53; CHECK: define void @test1_b4() #0 {54define void @test1_b4() {55  call void @readnone()56  br i1 false, label %dead, label %exit57 58dead:59  call void @test1_a()60  br label %exit61 62exit:63  ret void64}65 66 67; The @test2_* set of functions provide similar checks to @test1_* but only68; splitting the SCCs while leaving the RefSCC intact. This is accomplished by69; having dummy ref edges to the root function.70 71; CHECK: define void @test2_a() {72define void @test2_a() {73  call void @test2_b1()74  call void @test2_b2()75  call void @test2_b3()76  call void @test2_b4()77  ret void78}79 80; CHECK: define void @test2_b1() #0 {81define void @test2_b1() {82  call void @readnone()83  ret void84}85 86; CHECK: define void @test2_b2() #0 {87define void @test2_b2() {88  call void @reference_function_pointer(ptr @test2_a)89  br i1 false, label %dead, label %exit90 91dead:92  call void @test2_a()93  br label %exit94 95exit:96  ret void97}98 99; CHECK: define void @test2_b3() {100define void @test2_b3() {101  call void @reference_function_pointer(ptr @test2_a)102  call void @unknown()103  br i1 false, label %dead, label %exit104 105dead:106  call void @test2_a()107  br label %exit108 109exit:110  ret void111}112 113; CHECK: define void @test2_b4() #0 {114define void @test2_b4() {115  call void @reference_function_pointer(ptr @test2_a)116  br i1 false, label %dead, label %exit117 118dead:119  call void @test2_a()120  br label %exit121 122exit:123  ret void124}125 126 127; The @test3_* set of functions are the same challenge as @test1_* but with128; multiple layers that have to be traversed in the correct order instead of129; a single node.130 131; CHECK: define void @test3_a() {132define void @test3_a() {133  call void @test3_b11()134  call void @test3_b21()135  call void @test3_b31()136  call void @test3_b41()137  ret void138}139 140; CHECK: define void @test3_b11() #0 {141define void @test3_b11() {142  call void @test3_b12()143  ret void144}145 146; CHECK: define void @test3_b12() #0 {147define void @test3_b12() {148  call void @test3_b13()149  ret void150}151 152; CHECK: define void @test3_b13() #0 {153define void @test3_b13() {154  call void @readnone()155  ret void156}157 158; CHECK: define void @test3_b21() #0 {159define void @test3_b21() {160  call void @test3_b22()161  ret void162}163 164; CHECK: define void @test3_b22() #0 {165define void @test3_b22() {166  call void @test3_b23()167  ret void168}169 170; CHECK: define void @test3_b23() #0 {171define void @test3_b23() {172  call void @readnone()173  br i1 false, label %dead, label %exit174 175dead:176  call void @test3_a()177  br label %exit178 179exit:180  ret void181}182 183; CHECK: define void @test3_b31() {184define void @test3_b31() {185  call void @test3_b32()186  ret void187}188 189; CHECK: define void @test3_b32() {190define void @test3_b32() {191  call void @test3_b33()192  ret void193}194 195; CHECK: define void @test3_b33() {196define void @test3_b33() {197  call void @unknown()198  br i1 false, label %dead, label %exit199 200dead:201  call void @test3_a()202  br label %exit203 204exit:205  ret void206}207 208; CHECK: define void @test3_b41() #0 {209define void @test3_b41() {210  call void @test3_b42()211  ret void212}213 214; CHECK: define void @test3_b42() #0 {215define void @test3_b42() {216  call void @test3_b43()217  ret void218}219 220; CHECK: define void @test3_b43() #0 {221define void @test3_b43() {222  call void @readnone()223  br i1 false, label %dead, label %exit224 225dead:226  call void @test3_a()227  br label %exit228 229exit:230  ret void231}232 233 234; The @test4_* functions exercise the same core challenge as the @test2_*235; functions, but again include long chains instead of single nodes and ensure236; we traverse the chains in the correct order.237 238; CHECK: define void @test4_a() {239define void @test4_a() {240  call void @test4_b11()241  call void @test4_b21()242  call void @test4_b31()243  call void @test4_b41()244  ret void245}246 247; CHECK: define void @test4_b11() #0 {248define void @test4_b11() {249  call void @test4_b12()250  ret void251}252 253; CHECK: define void @test4_b12() #0 {254define void @test4_b12() {255  call void @test4_b13()256  ret void257}258 259; CHECK: define void @test4_b13() #0 {260define void @test4_b13() {261  call void @readnone()262  ret void263}264 265; CHECK: define void @test4_b21() #0 {266define void @test4_b21() {267  call void @test4_b22()268  ret void269}270 271; CHECK: define void @test4_b22() #0 {272define void @test4_b22() {273  call void @test4_b23()274  ret void275}276 277; CHECK: define void @test4_b23() #0 {278define void @test4_b23() {279  call void @reference_function_pointer(ptr @test4_a)280  br i1 false, label %dead, label %exit281 282dead:283  call void @test4_a()284  br label %exit285 286exit:287  ret void288}289 290; CHECK: define void @test4_b31() {291define void @test4_b31() {292  call void @test4_b32()293  ret void294}295 296; CHECK: define void @test4_b32() {297define void @test4_b32() {298  call void @test4_b33()299  ret void300}301 302; CHECK: define void @test4_b33() {303define void @test4_b33() {304  call void @reference_function_pointer(ptr @test4_a)305  call void @unknown()306  br i1 false, label %dead, label %exit307 308dead:309  call void @test4_a()310  br label %exit311 312exit:313  ret void314}315 316; CHECK: define void @test4_b41() #0 {317define void @test4_b41() {318  call void @test4_b42()319  ret void320}321 322; CHECK: define void @test4_b42() #0 {323define void @test4_b42() {324  call void @test4_b43()325  ret void326}327 328; CHECK: define void @test4_b43() #0 {329define void @test4_b43() {330  call void @reference_function_pointer(ptr @test4_a)331  br i1 false, label %dead, label %exit332 333dead:334  call void @test4_a()335  br label %exit336 337exit:338  ret void339}340 341; CHECK: attributes #0 = { nofree nosync memory(none) }342