1; RUN: opt -mtriple amdgcn-mesa-mesa3d -passes='print<uniformity>' -disable-output %s 2>&1 | FileCheck %s 2 3; Tests control flow intrinsics that should be treated as uniform 4 5; CHECK: for function 'test_if_break': 6; CHECK: DIVERGENT: %cond = icmp eq i32 %arg0, 0 7; CHECK-NOT: DIVERGENT 8; CHECK: ret void 9define amdgpu_ps void @test_if_break(i32 %arg0, i64 inreg %saved) { 10entry: 11 %cond = icmp eq i32 %arg0, 0 12 %break = call i64 @llvm.amdgcn.if.break.i64.i64(i1 %cond, i64 %saved) 13 store volatile i64 %break, ptr addrspace(1) undef 14 ret void 15} 16 17; CHECK: for function 'test_if': 18; CHECK: DIVERGENT: %cond = icmp eq i32 %arg0, 0 19; CHECK-NEXT: DIVERGENT: %if = call { i1, i64 } @llvm.amdgcn.if.i64(i1 %cond) 20; CHECK-NEXT: DIVERGENT: %if.bool = extractvalue { i1, i64 } %if, 0 21; CHECK-NOT: DIVERGENT 22; CHECK: DIVERGENT: %if.bool.ext = zext i1 %if.bool to i32 23define void @test_if(i32 %arg0) { 24entry: 25 %cond = icmp eq i32 %arg0, 0 26 %if = call { i1, i64 } @llvm.amdgcn.if.i64(i1 %cond) 27 %if.bool = extractvalue { i1, i64 } %if, 0 28 %if.mask = extractvalue { i1, i64 } %if, 1 29 %if.bool.ext = zext i1 %if.bool to i32 30 store volatile i32 %if.bool.ext, ptr addrspace(1) undef 31 store volatile i64 %if.mask, ptr addrspace(1) undef 32 ret void 33} 34 35; The result should still be treated as divergent, even with a uniform source. 36; CHECK: for function 'test_if_uniform': 37; CHECK-NOT: DIVERGENT 38; CHECK: DIVERGENT: %if = call { i1, i64 } @llvm.amdgcn.if.i64(i1 %cond) 39; CHECK-NEXT: DIVERGENT: %if.bool = extractvalue { i1, i64 } %if, 0 40; CHECK-NOT: DIVERGENT 41; CHECK: DIVERGENT: %if.bool.ext = zext i1 %if.bool to i32 42define amdgpu_ps void @test_if_uniform(i32 inreg %arg0) { 43entry: 44 %cond = icmp eq i32 %arg0, 0 45 %if = call { i1, i64 } @llvm.amdgcn.if.i64(i1 %cond) 46 %if.bool = extractvalue { i1, i64 } %if, 0 47 %if.mask = extractvalue { i1, i64 } %if, 1 48 %if.bool.ext = zext i1 %if.bool to i32 49 store volatile i32 %if.bool.ext, ptr addrspace(1) undef 50 store volatile i64 %if.mask, ptr addrspace(1) undef 51 ret void 52} 53 54; CHECK: for function 'test_loop_uniform': 55; CHECK: DIVERGENT: %loop = call i1 @llvm.amdgcn.loop.i64(i64 %mask) 56define amdgpu_ps void @test_loop_uniform(i64 inreg %mask) { 57entry: 58 %loop = call i1 @llvm.amdgcn.loop.i64(i64 %mask) 59 %loop.ext = zext i1 %loop to i32 60 store volatile i32 %loop.ext, ptr addrspace(1) undef 61 ret void 62} 63 64; CHECK: for function 'test_else': 65; CHECK: DIVERGENT: %else = call { i1, i64 } @llvm.amdgcn.else.i64.i64(i64 %mask) 66; CHECK: DIVERGENT: %else.bool = extractvalue { i1, i64 } %else, 0 67; CHECK: {{^[ \t]+}}%else.mask = extractvalue { i1, i64 } %else, 1 68define amdgpu_ps void @test_else(i64 inreg %mask) { 69entry: 70 %else = call { i1, i64 } @llvm.amdgcn.else.i64.i64(i64 %mask) 71 %else.bool = extractvalue { i1, i64 } %else, 0 72 %else.mask = extractvalue { i1, i64 } %else, 1 73 %else.bool.ext = zext i1 %else.bool to i32 74 store volatile i32 %else.bool.ext, ptr addrspace(1) undef 75 store volatile i64 %else.mask, ptr addrspace(1) undef 76 ret void 77} 78 79; This case is probably always broken 80; CHECK: for function 'test_else_divergent_mask': 81; CHECK: DIVERGENT: %if = call { i1, i64 } @llvm.amdgcn.else.i64.i64(i64 %mask) 82; CHECK-NEXT: DIVERGENT: %if.bool = extractvalue { i1, i64 } %if, 0 83; CHECK-NOT: DIVERGENT 84; CHECK: DIVERGENT: %if.bool.ext = zext i1 %if.bool to i32 85define void @test_else_divergent_mask(i64 %mask) { 86entry: 87 %if = call { i1, i64 } @llvm.amdgcn.else.i64.i64(i64 %mask) 88 %if.bool = extractvalue { i1, i64 } %if, 0 89 %if.mask = extractvalue { i1, i64 } %if, 1 90 %if.bool.ext = zext i1 %if.bool to i32 91 store volatile i32 %if.bool.ext, ptr addrspace(1) undef 92 store volatile i64 %if.mask, ptr addrspace(1) undef 93 ret void 94} 95 96declare { i1, i64 } @llvm.amdgcn.if.i64(i1) #0 97declare { i1, i64 } @llvm.amdgcn.else.i64.i64(i64) #0 98declare i64 @llvm.amdgcn.if.break.i64.i64(i1, i64) #1 99declare i1 @llvm.amdgcn.loop.i64(i64) #1 100 101attributes #0 = { convergent nounwind } 102attributes #1 = { convergent nounwind readnone } 103