brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.2 KiB · a2467a5 Raw
223 lines · plain
1; RUN: opt -mtriple amdgcn-unknown-amdhsa -passes='print<uniformity>' -disable-output %s 2>&1 | FileCheck %s2 3; divergent loop (H<header><exiting to X>, B<exiting to Y>)4; the divergent join point in %exit is obscured by uniform control joining in %X5define amdgpu_kernel void @hidden_loop_diverge(i32 %n, i32 %a, i32 %b) #0 {6; CHECK-LABEL: for function 'hidden_loop_diverge':7; CHECK-NOT: DIVERGENT: %uni.8; CHECK-NOT: DIVERGENT: br i1 %uni.9 10entry:11  %tid = call i32 @llvm.amdgcn.workitem.id.x()12  %uni.cond = icmp slt i32 %a, 013  br i1 %uni.cond, label %X, label %H  ; uniform14 15H:16  %uni.merge.h = phi i32 [ 0, %entry ], [ %uni.inc, %B ]17  %div.exitx = icmp slt i32 %tid, 018  br i1 %div.exitx, label %X, label %B ; divergent branch19; CHECK: DIVERGENT: %div.exitx =20; CHECK: DIVERGENT: br i1 %div.exitx,21 22B:23  %uni.inc = add i32 %uni.merge.h, 124  %div.exity = icmp sgt i32 %tid, 025  br i1 %div.exity, label %Y, label %H ; divergent branch26; CHECK: DIVERGENT: %div.exity =27; CHECK: DIVERGENT: br i1 %div.exity,28 29X:30  %div.merge.x = phi i32 [ %a, %entry ], [ %uni.merge.h, %H ] ; temporal divergent phi31  br i1 %uni.cond, label %Y, label %exit32; CHECK: DIVERGENT: %div.merge.x =33 34Y:35  %div.merge.y = phi i32 [ 42, %X ], [ %b, %B ]36  br label %exit37; CHECK: DIVERGENT: %div.merge.y =38 39exit:40  %div.merge.exit = phi i32 [ %a, %X ], [ %b, %Y ]41  ret void42; CHECK: DIVERGENT: %div.merge.exit =43}44 45; divergent loop (H<header><exiting to X>, B<exiting to Y>)46; the phi nodes in X and Y don't actually receive divergent values47define amdgpu_kernel void @unobserved_loop_diverge(i32 %n, i32 %a, i32 %b) #0 {48; CHECK-LABEL: for function 'unobserved_loop_diverge':49; CHECK-NOT: DIVERGENT: %uni.50; CHECK-NOT: DIVERGENT: br i1 %uni.51 52entry:53  %tid = call i32 @llvm.amdgcn.workitem.id.x()54  %uni.cond = icmp slt i32 %a, 055  br i1 %uni.cond, label %X, label %H  ; uniform56 57H:58  %uni.merge.h = phi i32 [ 0, %entry ], [ %uni.inc, %B ]59  %div.exitx = icmp slt i32 %tid, 060  br i1 %div.exitx, label %X, label %B ; divergent branch61; CHECK: DIVERGENT: %div.exitx =62; CHECK: DIVERGENT: br i1 %div.exitx,63 64B:65  %uni.inc = add i32 %uni.merge.h, 166  %div.exity = icmp sgt i32 %tid, 067  br i1 %div.exity, label %Y, label %H ; divergent branch68; CHECK: DIVERGENT: %div.exity =69; CHECK: DIVERGENT: br i1 %div.exity,70 71X:72  %uni.merge.x = phi i32 [ %a, %entry ], [ %b, %H ]73  br label %exit74 75Y:76  %uni.merge.y = phi i32 [ %b, %B ]77  br label %exit78 79exit:80  %div.merge.exit = phi i32 [ %a, %X ], [ %b, %Y ]81  ret void82; CHECK: DIVERGENT: %div.merge.exit =83}84 85; divergent loop (G<header>, L<exiting to D>) inside divergent loop (H<header>, B<exiting to X>, C<exiting to Y>, D, G, L)86; the inner loop has no exit to top level.87; the outer loop becomes divergent as its exiting branch in C is control-dependent on the inner loop's divergent loop exit in D.88define amdgpu_kernel void @hidden_nestedloop_diverge(i32 %n, i32 %a, i32 %b) #0 {89; CHECK-LABEL: for function 'hidden_nestedloop_diverge':90; CHECK-NOT: DIVERGENT: %uni.91; CHECK-NOT: DIVERGENT: br i1 %uni.92 93entry:94  %tid = call i32 @llvm.amdgcn.workitem.id.x()95  %uni.cond = icmp slt i32 %a, 096  %div.exitx = icmp slt i32 %tid, 097  br i1 %uni.cond, label %X, label %H98 99H:100  %uni.merge.h = phi i32 [ 0, %entry ], [ %uni.inc, %D ]101  br i1 %uni.cond, label %G, label %B102; CHECK: DIVERGENT: %div.exitx =103 104B:105  br i1 %uni.cond, label %X, label %C106 107C:108  br i1 %uni.cond, label %Y, label %D109 110D:111  %uni.inc = add i32 %uni.merge.h, 1112  br label %H113 114G:115  br i1 %div.exitx, label %C, label %L116; CHECK: DIVERGENT: br i1 %div.exitx,117 118L:119  br i1 %uni.cond, label %D, label %G120 121X:122  %uni.merge.x = phi i32 [ %a, %entry ], [ %uni.merge.h, %B ]123  br i1 %uni.cond, label %Y, label %exit124 125Y:126  %div.merge.y = phi i32 [ 42, %X ], [ %b, %C ]127  br label %exit128; CHECK: DIVERGENT: %div.merge.y =129 130exit:131  %div.merge.exit = phi i32 [ %a, %X ], [ %b, %Y ]132  ret void133; CHECK: DIVERGENT: %div.merge.exit =134}135 136; divergent loop (G<header>, L<exiting to X>) in divergent loop (H<header>, B<exiting to C>, C, G, L)137; the outer loop has no immediately divergent exiting edge.138; the inner exiting edge is exiting to top-level through the outer loop causing both to become divergent.139define amdgpu_kernel void @hidden_doublebreak_diverge(i32 %n, i32 %a, i32 %b) #0 {140; CHECK-LABEL: for function 'hidden_doublebreak_diverge':141; CHECK-NOT: DIVERGENT: %uni.142; CHECK-NOT: DIVERGENT: br i1 %uni.143 144entry:145  %tid = call i32 @llvm.amdgcn.workitem.id.x()146  %uni.cond = icmp slt i32 %a, 0147  %div.exitx = icmp slt i32 %tid, 0148  br i1 %uni.cond, label %X, label %H149 150H:151  %uni.merge.h = phi i32 [ 0, %entry ], [ %uni.inc, %C ]152  br i1 %uni.cond, label %G, label %B153; CHECK: DIVERGENT: %div.exitx =154 155B:156  br i1 %uni.cond, label %Y, label %C157 158C:159  %uni.inc = add i32 %uni.merge.h, 1160  br label %H161 162G:163  br i1 %div.exitx, label %X, label %L ; two-level break164; CHECK: DIVERGENT: br i1 %div.exitx,165 166L:167  br i1 %uni.cond, label %C, label %G168 169X:170  %div.merge.x = phi i32 [ %a, %entry ], [ %uni.merge.h, %G ] ; temporal divergence171  br label %Y172; CHECK: DIVERGENT: %div.merge.x =173 174Y:175  %div.merge.y = phi i32 [ 42, %X ], [ %b, %B ]176  ret void177; CHECK: DIVERGENT: %div.merge.y =178}179 180; divergent loop (G<header>, L<exiting to D>) contained inside a uniform loop (H<header>, B, G, L , D<exiting to x>)181define amdgpu_kernel void @hidden_containedloop_diverge(i32 %n, i32 %a, i32 %b) #0 {182; CHECK-LABEL: for function 'hidden_containedloop_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  %uni.cond = icmp slt i32 %a, 0189  %div.exitx = icmp slt i32 %tid, 0190  br i1 %uni.cond, label %X, label %H191 192H:193  %uni.merge.h = phi i32 [ 0, %entry ], [ %uni.inc.d, %D ]194  br i1 %uni.cond, label %G, label %B195; CHECK: DIVERGENT: %div.exitx =196 197B:198  %div.merge.b = phi i32 [ 42, %H ], [ %uni.merge.g, %G ]199  br label %D200; CHECK: DIVERGENT: %div.merge.b =201 202G:203  %uni.merge.g = phi i32 [ 123, %H ], [ %uni.inc.l, %L ]204  br i1 %div.exitx, label %B, label %L205; CHECK: DIVERGENT: br i1 %div.exitx,206 207L:208  %uni.inc.l = add i32 %uni.merge.g, 1209  br i1 %uni.cond, label %G, label %D210 211D:212  %uni.inc.d = add i32 %uni.merge.h, 1213  br i1 %uni.cond, label %X, label %H214 215X:216  %uni.merge.x = phi i32 [ %a, %entry ], [ %uni.inc.d, %D ]217  ret void218}219 220declare i32 @llvm.amdgcn.workitem.id.x() #0221 222attributes #0 = { nounwind readnone }223