brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.2 KiB · 91b4446 Raw
606 lines · plain
1; RUN: opt %s -mtriple amdgcn-- -passes='print<uniformity>' -disable-output 2>&1 | FileCheck %s2 3define amdgpu_kernel void @cycle_diverge_enter(i32 %n, i32 %a, i32 %b) #0 {4;      entry(div)5;      /   \6;     H <-> B7;           |8;           X9; CHECK-LABEL: for function 'cycle_diverge_enter':10; CHECK-NOT: DIVERGENT: %uni.11; CHECK-NOT: DIVERGENT: br i1 %uni.12 13entry:14  %tid = call i32 @llvm.amdgcn.workitem.id.x()15  %div.cond = icmp slt i32 %tid, 016  %uni.cond = icmp slt i32 %a, 017  br i1 %div.cond, label %B, label %H  ; divergent branch18 19H:20  %div.merge.h = phi i32 [ 0, %entry ], [ %b, %B ]21  br label %B22; CHECK: DIVERGENT: %div.merge.h23 24B:25  %div.merge.b = phi i32 [ %a, %H ], [1, %entry ]26  %div.cond.b = icmp sgt i32 %div.merge.b, 027  %div.b.inc = add i32 %b, 128  br i1 %div.cond, label %X, label %H ; divergent branch29; CHECK: DIVERGENT: %div.merge.b30 31X:32  %div.use = add i32 %div.merge.b, 133  ret void34; CHECK: DIVERGENT: %div.use =35 36}37 38define amdgpu_kernel void @cycle_diverge_exit(i32 %n, i32 %a, i32 %b) #0 {39;      entry40;      /   \41;     H <-> B(div)42;           |43;           X44;45; CHECK-LABEL: for function 'cycle_diverge_exit':46; CHECK-NOT: DIVERGENT: %uni.47; CHECK-NOT: DIVERGENT: br i1 %uni.48 49entry:50  %tid = call i32 @llvm.amdgcn.workitem.id.x()51  %div.cond = icmp slt i32 %tid, 052  %uni.cond = icmp slt i32 %a, 053  br i1 %uni.cond, label %B, label %H54 55H:56  %uni.merge.h = phi i32 [ 0, %entry ], [ %b, %B ]57  br label %B58 59B:60  %uni.merge.b = phi i32 [ %a, %H ], [1, %entry ]61  %uni.cond.b = icmp sgt i32 %uni.merge.b, 062  %uni.b.inc = add i32 %b, 163  br i1 %div.cond, label %X, label %H ; divergent branch64 65X:66  %div.use = add i32 %uni.merge.b, 167  ret void68; CHECK: DIVERGENT: %div.use =69}70 71define amdgpu_kernel void @cycle_reentrance(i32 %n, i32 %a, i32 %b) #0 {72; For this case, threads enter the cycle from C would take C->D->H,73; at the point of H, diverged threads may continue looping in cycle(H-B-D)74; until all threads exit the cycle(H-B-D) and cause temporal divergence75; exiting at edge H->C. We currently do not analyze such kind of inner76; cycle temporal divergence. Instead, we mark all values in the cycle77; being divergent conservatively.78;      entry--\79;       |     |80;  ---> H(div)|81;  |   / \    /82;  |  B   C<--83;  ^   \ /84;  \----D85;       |86;       X87; CHECK-LABEL: for function 'cycle_reentrance':88; CHECK-NOT: DIVERGENT: %uni.89; CHECK-NOT: DIVERGENT: br i1 %uni.90 91entry:92  %tid = call i32 @llvm.amdgcn.workitem.id.x()93  %div.cond = icmp slt i32 %tid, 094  %uni.cond = icmp slt i32 %a, 095  br i1 %uni.cond, label %H, label %C96 97H:98  %div.merge.h = phi i32 [ 0, %entry ], [ %b, %D ]99  br i1 %div.cond, label %B, label %C  ; divergent branch100 101B:102  %div.inc.b = add i32 %div.merge.h, 1103; CHECK: DIVERGENT: %div.inc.b104  br label %D105 106C:107  %div.merge.c = phi i32 [0, %entry], [%div.merge.h, %H]108  %div.inc.c = add i32 %div.merge.c, 2109; CHECK: DIVERGENT: %div.inc.c110  br label %D111 112D:113  %div.merge.d = phi i32 [ %div.inc.b, %B ], [ %div.inc.c, %C ]114; CHECK: DIVERGENT: %div.merge.d115  br i1 %uni.cond, label %X, label %H116 117X:118  ret void119}120 121define amdgpu_kernel void @cycle_reentrance2(i32 %n, i32 %a, i32 %b) #0 {122; This is mostly the same as cycle_reentrance, the only difference is123; the successor order, thus different dfs visiting order. This is just124; make sure we are doing uniform analysis correctly under different dfs125; order.126;      entry--\127;       |     |128;  ---> H(div)|129;  |   / \    /130;  |  B   C<--131;  ^   \ /132;  \----D133;       |134;       X135; CHECK-LABEL: for function 'cycle_reentrance2':136; CHECK-NOT: DIVERGENT: %uni.137; CHECK-NOT: DIVERGENT: br i1 %uni.138 139entry:140  %tid = call i32 @llvm.amdgcn.workitem.id.x()141  %div.cond = icmp slt i32 %tid, 0142  %uni.cond = icmp slt i32 %a, 0143  br i1 %uni.cond, label %C, label %H144 145H:146  %div.merge.h = phi i32 [ 0, %entry ], [ %b, %D ]147  br i1 %div.cond, label %B, label %C  ; divergent branch148 149B:150  %div.inc.b = add i32 %div.merge.h, 1151; CHECK: DIVERGENT: %div.inc.b152  br label %D153 154C:155  %div.merge.c = phi i32 [0, %entry], [%div.merge.h, %H]156  %div.inc.c = add i32 %div.merge.c, 2157; CHECK: DIVERGENT: %div.inc.c158  br label %D159 160D:161  %div.merge.d = phi i32 [ %div.inc.b, %B ], [ %div.inc.c, %C ]162; CHECK: DIVERGENT: %div.merge.d163  br i1 %uni.cond, label %X, label %H164 165X:166  ret void167}168 169define amdgpu_kernel void @cycle_join_dominated_by_diverge(i32 %n, i32 %a, i32 %b) #0 {170; the join-node D is dominated by diverge point H2171;      entry172;       | |173;  --> H1 |174;  |     \|175;  |      H2(div)176;  |     / \177;  |    B   C178;  ^     \ /179;  \------D180;         |181;         X182; CHECK-LABEL: for function 'cycle_join_dominated_by_diverge':183; CHECK-NOT: DIVERGENT: %uni.184; CHECK-NOT: DIVERGENT: br i1 %uni.185 186entry:187  %tid = call i32 @llvm.amdgcn.workitem.id.x()188  %div.cond = icmp slt i32 %tid, 0189  %uni.cond = icmp slt i32 %a, 0190  br i1 %uni.cond, label %H1, label %H2191 192H1:193  %uni.merge.h1 = phi i32 [ 0, %entry ], [ %b, %D ]194  br label %H2195 196H2:197  %uni.merge.h2 = phi i32 [ 0, %entry ], [ %b, %H1 ]198  br i1 %div.cond, label %B, label %C  ; divergent branch199 200B:201  %uni.inc.b = add i32 %uni.merge.h2, 1202  br label %D203 204C:205  %uni.inc.c = add i32 %uni.merge.h2, 2206  br label %D207 208D:209  %div.merge.d = phi i32 [ %uni.inc.b, %B ], [ %uni.inc.c, %C ]210; CHECK: DIVERGENT: %div.merge.d211  br i1 %uni.cond, label %X, label %H1212 213X:214  ret void215}216 217define amdgpu_kernel void @cycle_join_dominated_by_entry(i32 %n, i32 %a, i32 %b) #0 {218; the join-node D is dominated by cycle entry H2219;      entry220;       | |221;  --> H1 |222;  |     \|223;  |      H2 -----224;  |      |      |225;  |      A(div) |226;  |     / \     v227;  |    B   C   /228;  ^     \ /   /229;  \------D <-/230;         |231;         X232; CHECK-LABEL: for function 'cycle_join_dominated_by_entry':233; CHECK-NOT: DIVERGENT: %uni.234; CHECK-NOT: DIVERGENT: br i1 %uni.235 236entry:237  %tid = call i32 @llvm.amdgcn.workitem.id.x()238  %div.cond = icmp slt i32 %tid, 0239  %uni.cond = icmp slt i32 %a, 0240  br i1 %uni.cond, label %H1, label %H2241 242H1:243  %uni.merge.h1 = phi i32 [ 0, %entry ], [ %b, %D ]244  br label %H2245 246H2:247  %uni.merge.h2 = phi i32 [ 0, %entry ], [ %b, %H1 ]248  br i1 %uni.cond, label %A, label %D249 250A:251  br i1 %div.cond, label %B, label %C  ; divergent branch252 253B:254  %uni.inc.b = add i32 %uni.merge.h2, 1255  br label %D256 257C:258  %uni.inc.c = add i32 %uni.merge.h2, 2259  br label %D260 261D:262  %div.merge.d = phi i32 [ %uni.inc.b, %B ], [ %uni.inc.c, %C ], [%uni.merge.h2, %H2]263; CHECK: DIVERGENT: %div.merge.d264  br i1 %uni.cond, label %X, label %H1265 266X:267  ret void268}269 270define amdgpu_kernel void @cycle_join_not_dominated(i32 %n, i32 %a, i32 %b) #0 {271; if H is the header, the sync label propagation may stop at join node D.272; But join node D is not dominated by divergence starting block C, and also273; not dominated by any entries(H/C). So we conservatively mark all the values274; in the cycle divergent for now.275;      entry276;       |  |277;  ---> H  |278;  |   / \ v279;  |  B<--C(div)280;  ^   \ /281;  \----D282;       |283;       X284; CHECK-LABEL: for function 'cycle_join_not_dominated':285; CHECK-NOT: DIVERGENT: %uni.286 287entry:288  %tid = call i32 @llvm.amdgcn.workitem.id.x()289  %div.cond = icmp slt i32 %tid, 0290  %uni.cond = icmp slt i32 %a, 0291  br i1 %uni.cond, label %C, label %H292 293H:294  %div.merge.h = phi i32 [ 0, %entry ], [ %b, %D ]295  br i1 %uni.cond, label %B, label %C296 297B:298  %div.merge.b = phi i32 [ 0, %H ], [ %b, %C ]299  %div.inc.b = add i32 %div.merge.b, 1300; CHECK: DIVERGENT: %div.inc.b301  br label %D302 303C:304  %div.merge.c = phi i32 [0, %entry], [%div.merge.h, %H]305  %div.inc.c = add i32 %div.merge.c, 2306; CHECK: DIVERGENT: %div.inc.c307  br i1 %div.cond, label %D, label %B  ; divergent branch308 309D:310  %div.merge.d = phi i32 [ %div.inc.b, %B ], [ %div.inc.c, %C ]311; CHECK: DIVERGENT: %div.merge.d312  br i1 %uni.cond, label %X, label %H313 314X:315  ret void316}317 318define amdgpu_kernel void @cycle_join_not_dominated2(i32 %n, i32 %a, i32 %b) #0 {319; This is mostly the same as cycle_join_not_dominated, the only difference is320; the dfs visiting order, so the cycle analysis result is different.321;      entry322;       |  |323;  ---> H  |324;  |   / \ v325;  |  B<--C(div)326;  ^   \ /327;  \----D328;       |329;       X330; CHECK-LABEL: for function 'cycle_join_not_dominated2':331; CHECK-NOT: DIVERGENT: %uni.332 333entry:334  %tid = call i32 @llvm.amdgcn.workitem.id.x()335  %div.cond = icmp slt i32 %tid, 0336  %uni.cond = icmp slt i32 %a, 0337  br i1 %uni.cond, label %H, label %C338 339H:340  %div.merge.h = phi i32 [ 0, %entry ], [ %b, %D ]341  br i1 %uni.cond, label %B, label %C342 343B:344  %div.merge.b = phi i32 [ 0, %H ], [ %b, %C ]345  %div.inc.b = add i32 %div.merge.b, 1346; CHECK: DIVERGENT: %div.inc.b347  br label %D348 349C:350  %div.merge.c = phi i32 [0, %entry], [%div.merge.h, %H]351  %div.inc.c = add i32 %div.merge.c, 2352; CHECK: DIVERGENT: %div.inc.c353  br i1 %div.cond, label %D, label %B  ; divergent branch354 355D:356  %div.merge.d = phi i32 [ %div.inc.b, %B ], [ %div.inc.c, %C ]357; CHECK: DIVERGENT: %div.merge.d358  br i1 %uni.cond, label %X, label %H359 360X:361  ret void362}363 364define amdgpu_kernel void @natural_loop_two_backedges(i32 %n, i32 %a, i32 %b) #0 {365; FIXME: the uni.merge.h can be viewed as uniform.366; CHECK-LABEL: for function 'natural_loop_two_backedges':367 368entry:369  %tid = call i32 @llvm.amdgcn.workitem.id.x()370  %div.cond = icmp slt i32 %tid, 0371  %uni.cond = icmp slt i32 %a, 0372  br label %H373 374H:375  %uni.merge.h = phi i32 [ 0, %entry ], [ %uni.inc, %B ], [ %uni.inc, %C]376  %uni.inc = add i32 %uni.merge.h, 1377  br label %B378 379B:380  br i1 %div.cond, label %C, label %H381 382C:383  br i1 %uni.cond, label %X, label %H384 385X:386  ret void387}388 389define amdgpu_kernel void @natural_loop_two_backedges2(i32 %n, i32 %a, i32 %b) #0 {390; FIXME: the uni.merge.h can be viewed as uniform.391; CHECK-LABEL: for function 'natural_loop_two_backedges2':392 393entry:394  %tid = call i32 @llvm.amdgcn.workitem.id.x()395  %div.cond = icmp slt i32 %tid, 0396  %uni.cond = icmp slt i32 %a, 0397  br label %H398 399H:400  %uni.merge.h = phi i32 [ 0, %entry ], [ %uni.inc, %B ], [ %uni.inc, %C]401  %uni.inc = add i32 %uni.merge.h, 1402  br i1 %uni.cond, label %B, label %D403 404B:405  br i1 %div.cond, label %C, label %H406 407C:408  br label %H409 410D:411  br i1 %uni.cond, label %B, label %X412 413X:414  ret void415}416 417define amdgpu_kernel void @cycle_enter_nested(i32 %n, i32 %a, i32 %b) #0 {418;419;   entry(div)420;       |   \421;   --> H1   |422;  /    |    |423;  | -> H2   |424;  | |  |    /425;  | \--B <--426;  ^    |427;  \----C428;       |429;       X430; CHECK-LABEL: for function 'cycle_enter_nested':431; CHECK-NOT: DIVERGENT: %uni.432; CHECK-NOT: DIVERGENT: br i1 %uni.433 434entry:435  %tid = call i32 @llvm.amdgcn.workitem.id.x()436  %div.cond = icmp slt i32 %tid, 0437  %uni.cond = icmp slt i32 %a, 0438  br i1 %div.cond, label %B, label %H1439 440H1:441  %div.merge.h1 = phi i32 [ 1, %entry ], [ %b, %C ]442  br label %H2443; CHECK: DIVERGENT: %div.merge.h1444 445H2:446  %div.merge.h2 = phi i32 [ 2, %B ], [ %a, %H1 ]447; CHECK: DIVERGENT: %div.merge.h2448  br label %B449 450B:451  %div.merge.b = phi i32 [0, %entry], [%a, %H2]452; CHECK: DIVERGENT: %div.merge.b453  br i1 %uni.cond, label %C, label %H2454 455C:456  br i1 %uni.cond, label %X, label %H1457 458X:459  ret void460}461 462define amdgpu_kernel void @cycle_inner_exit_enter(i32 %n, i32 %a, i32 %b) #0 {463;          entry464;        /      \465;       E1-> A-> E2466;       ^    |    \467;       |    E3-> E4468;       |    ^   /469;       |     \ /470;       C <----B471;       |472;       X473; CHECK-LABEL: for function 'cycle_inner_exit_enter':474; CHECK-NOT: DIVERGENT: %uni.475; CHECK-NOT: DIVERGENT: br i1 %uni.476 477entry:478  %tid = call i32 @llvm.amdgcn.workitem.id.x()479  %div.cond = icmp slt i32 %tid, 0480  %uni.cond = icmp slt i32 %a, 0481  br i1 %uni.cond, label %E2, label %E1482 483E1:484  %div.merge.e1 = phi i32 [ 1, %entry ], [ %b, %C ]485  br label %A486; CHECK: DIVERGENT: %div.merge.e1487 488A:489  br i1 %uni.cond, label %E2, label %E3490 491E2:492  %div.merge.e2 = phi i32 [ 2, %entry ], [ %a, %A ]493; CHECK: DIVERGENT: %div.merge.e2494  br label %E4495 496E3:497  %div.merge.e3 = phi i32 [ 0, %A ], [ %b, %B ]498; CHECK: DIVERGENT: %div.merge.e3499  br label %E4500 501E4:502  %div.merge.e4 = phi i32 [ 0, %E2 ], [ %a, %E3 ]503; CHECK: DIVERGENT: %div.merge.e4504  br label %B505 506B:507  br i1 %div.cond, label %C, label %E3508 509C:510  br i1 %uni.cond, label %X, label %E1511 512X:513  ret void514}515 516define amdgpu_kernel void @cycle_inner_exit_enter2(i32 %n, i32 %a, i32 %b) #0 {517; This case is almost the same as cycle_inner_exit_enter, with only different518; dfs visiting order, thus different cycle hierarchy.519;          entry520;        /      \521;       E1-> A-> E2522;       ^    |    \523;       |    E3-> E4524;       |    ^   /525;       |     \ /526;       C <----B527;       |528;       X529; CHECK-LABEL: for function 'cycle_inner_exit_enter2':530; CHECK-NOT: DIVERGENT: %uni.531; CHECK-NOT: DIVERGENT: br i1 %uni.532 533entry:534  %tid = call i32 @llvm.amdgcn.workitem.id.x()535  %div.cond = icmp slt i32 %tid, 0536  %uni.cond = icmp slt i32 %a, 0537  br i1 %uni.cond, label %E1, label %E2538 539E1:540  %div.merge.e1 = phi i32 [ 1, %entry ], [ %b, %C ]541  br label %A542; CHECK: DIVERGENT: %div.merge.e1543 544A:545  br i1 %uni.cond, label %E2, label %E3546 547E2:548  %div.merge.e2 = phi i32 [ 2, %entry ], [ %a, %A ]549; CHECK: DIVERGENT: %div.merge.e2550  br label %E4551 552E3:553  %div.merge.e3 = phi i32 [ 0, %A ], [ %b, %B ]554; CHECK: DIVERGENT: %div.merge.e3555  br label %E4556 557E4:558  %div.merge.e4 = phi i32 [ 0, %E2 ], [ %a, %E3 ]559; CHECK: DIVERGENT: %div.merge.e4560  br label %B561 562B:563  br i1 %div.cond, label %C, label %E3564 565C:566  br i1 %uni.cond, label %X, label %E1567 568X:569  ret void570}571 572define amdgpu_kernel void @always_uniform() {573; CHECK-LABEL: UniformityInfo for function 'always_uniform':574; CHECK: CYCLES ASSUMED DIVERGENT:575; CHECK:   depth=1: entries(bb2 bb3)576 577bb:578  %inst = tail call i32 @llvm.amdgcn.mbcnt.hi(i32 0, i32 0)579  %inst1 = icmp ugt i32 %inst, 0580  br i1 %inst1, label %bb3, label %bb2581; CHECK:   DIVERGENT:   %inst = tail call i32 @llvm.amdgcn.mbcnt.hi(i32 0, i32 0)582; CHECK:   DIVERGENT:   %inst1 = icmp ugt i32 %inst, 0583; CHECK:   DIVERGENT:   br i1 %inst1, label %bb3, label %bb2584 585bb2:                                              ; preds = %bb3, %bb586  br label %bb3587 588bb3:                                              ; preds = %bb2, %bb589  %inst4 = tail call i64 @llvm.amdgcn.icmp.i64.i16(i16 0, i16 0, i32 0)590  %inst5 = trunc i64 %inst4 to i32591  %inst6 = and i32 0, %inst5592  br label %bb2593; CHECK-LABEL: BLOCK bb3594; CHECK-NOT: DIVERGENT: {{.*}} call i64 @llvm.amdgcn.icmp.i64.i16595; CHECK:   DIVERGENT:   %inst5 = trunc i64 %inst4 to i32596; CHECK:   DIVERGENT:   %inst6 = and i32 0, %inst5597}598 599declare i32 @llvm.amdgcn.mbcnt.hi(i32, i32)600 601declare i64 @llvm.amdgcn.icmp.i64.i16(i16, i16, i32 immarg)602 603declare i32 @llvm.amdgcn.workitem.id.x() #0604 605attributes #0 = { nounwind readnone }606