140 lines · plain
1; RUN: opt %s -mtriple amdgcn-- -passes='print<uniformity>' -disable-output 2>&1 | FileCheck %s2 3; CHECK=LABEL: UniformityInfo for function 'basic':4; CHECK-NOT: CYCLES ASSUMED DIVERGENT:5; CHECK: CYCLES WITH DIVERGENT EXIT:6; CHECK: depth=1: entries(P T) Q7define amdgpu_kernel void @basic(i32 %a, i32 %b, i32 %c) {8entry:9 %cond.uni = icmp slt i32 %a, 010 %tid = call i32 @llvm.amdgcn.workitem.id.x()11 %cond.div = icmp slt i32 %tid, 012 br i1 %cond.uni, label %T, label %P13 14P:15 %pp.phi.1 = phi i32 [ %a, %entry], [ %b, %T ]16 %pp.phi.2 = phi i32 [ %a, %entry], [ %tt.phi, %T ]17 %pp = add i32 %b, 118 br label %Q19 20Q:21 %qq = add i32 %b, 122 %qq.div.1 = add i32 %pp.phi.2, 123 %qq.div.2 = add i32 %pp.phi.2, 124 br i1 %cond.div, label %T, label %exit25 26T:27 %tt.phi = phi i32 [ %qq, %Q ], [ %a, %entry ]28 %tt = add i32 %b, 129 br label %P30 31exit:32; CHECK: DIVERGENT: %ee.1 =33; CHECK: DIVERGENT: %xx.2 =34; CHECK-NOT: DIVERGENT: %ee.3 =35 %ee.1 = add i32 %pp.phi.1, 136 %xx.2 = add i32 %pp.phi.2, 137 %ee.3 = add i32 %b, 138 ret void39}40 41; CHECK-LABEL: UniformityInfo for function 'outer_reducible':42; CHECK-NOT: CYCLES ASSUMED DIVERGENT:43; CHECK: CYCLES WITH DIVERGENT EXIT:44; CHECK: depth=1: entries(H) P T R Q45define amdgpu_kernel void @outer_reducible(i32 %a, i32 %b, i32 %c) {46entry:47 %cond.uni = icmp slt i32 %a, 048 %tid = call i32 @llvm.amdgcn.workitem.id.x()49 %cond.div = icmp slt i32 %tid, 050 br label %H51 52H:53 br i1 %cond.uni, label %T, label %P54 55P:56 %pp.phi.1 = phi i32 [ %a, %H], [ %b, %T ]57 %pp.phi.2 = phi i32 [ %a, %H], [ %tt.phi, %T ]58 %pp = add i32 %b, 159 br label %Q60 61Q:62 %qq = add i32 %b, 163 %qq.div.1 = add i32 %pp.phi.2, 164 %qq.div.2 = add i32 %pp.phi.2, 165 br i1 %cond.div, label %R, label %exit66 67R:68 br i1 %cond.uni, label %T, label %H69 70 71T:72 %tt.phi = phi i32 [ %qq, %R ], [ %a, %H ]73 %tt = add i32 %b, 174 br label %P75 76exit:77; CHECK: DIVERGENT: %ee.1 =78; CHECK: DIVERGENT: %xx.2 =79; CHECK-NOT: DIVERGENT: %ee.3 =80 %ee.1 = add i32 %pp.phi.1, 181 %xx.2 = add i32 %pp.phi.2, 182 %ee.3 = add i32 %b, 183 ret void84}85 86; entry(div)87; | \88; H -> B89; ^ /|90; \--C |91; \|92; X93;94; This has a divergent cycle due to the external divergent branch, but95; there are no divergent exits. Hence a use at X is not divergent96; unless the def itself is divergent.97;98; CHECK-LABEL: UniformityInfo for function 'no_divergent_exit':99; CHECK: CYCLES ASSUMED DIVERGENT:100; CHECK: depth=1: entries(H B) C101; CHECK-NOT: CYCLES WITH DIVERGENT EXIT:102define amdgpu_kernel void @no_divergent_exit(i32 %n, i32 %a, i32 %b) #0 {103entry:104 %tid = call i32 @llvm.amdgcn.workitem.id.x()105 %div.cond = icmp slt i32 %tid, 0106 %uni.cond = icmp slt i32 %a, 0107 br i1 %div.cond, label %B, label %H108 109H: ; preds = %C, %entry110; CHECK: DIVERGENT: %div.merge.h =111 %div.merge.h = phi i32 [ 0, %entry ], [ %b, %C ]112 br label %B113 114B: ; preds = %H, %entry115; CHECK: DIVERGENT: %div.merge.b =116 %div.merge.b = phi i32 [ %a, %H ], [ 1, %entry ]117; CHECK-NOT: DIVERGENT %bb =118 %bb = add i32 %a, 1119; CHECK-NOT: DIVERGENT: br i1 %uni.cond, label %X, label %C120 br i1 %uni.cond, label %X, label %C121 122C: ; preds = %B123; CHECK-NOT: DIVERGENT %cc =124 %cc = add i32 %a, 1125; CHECK-NOT: DIVERGENT: br i1 %uni.cond, label %X, label %H126 br i1 %uni.cond, label %X, label %H127 128; CHECK-LABEL: BLOCK X129X: ; preds = %C, %B130; CHECK: DIVERGENT: %uni.merge.x =131 %uni.merge.x = phi i32 [ %bb, %B ], [%cc, %C ]132; CHECK: DIVERGENT: %div.merge.x =133 %div.merge.x = phi i32 [ %div.merge.b, %B ], [%cc, %C ]134 ret void135}136 137declare i32 @llvm.amdgcn.workitem.id.x() #0138 139attributes #0 = { nounwind readnone }140