1; RUN: opt -mtriple amdgcn-unknown-amdhsa -passes='print<uniformity>' -disable-output %s 2>&1 | FileCheck %s 2 3; CHECK-LABEL: for function 'readfirstlane': 4define amdgpu_kernel void @readfirstlane() { 5 %id.x = call i32 @llvm.amdgcn.workitem.id.x() 6; CHECK: DIVERGENT: %id.x = call i32 @llvm.amdgcn.workitem.id.x() 7 %first.lane = call i32 @llvm.amdgcn.readfirstlane(i32 %id.x) 8; CHECK-NOT: DIVERGENT: %first.lane = call i32 @llvm.amdgcn.readfirstlane(i32 %id.x) 9 ret void 10} 11 12; CHECK-LABEL: for function 'icmp': 13define amdgpu_kernel void @icmp(i32 inreg %x) { 14; CHECK-NOT: DIVERGENT: %icmp = call i64 @llvm.amdgcn.icmp.i32 15 %icmp = call i64 @llvm.amdgcn.icmp.i32(i32 %x, i32 0, i32 33) 16 ret void 17} 18 19; CHECK-LABEL: for function 'fcmp': 20define amdgpu_kernel void @fcmp(float inreg %x, float inreg %y) { 21; CHECK-NOT: DIVERGENT: %fcmp = call i64 @llvm.amdgcn.fcmp.i32 22 %fcmp = call i64 @llvm.amdgcn.fcmp.i32(float %x, float %y, i32 33) 23 ret void 24} 25 26; CHECK-LABEL: for function 'ballot': 27define amdgpu_kernel void @ballot(i1 inreg %x) { 28; CHECK-NOT: DIVERGENT: %ballot = call i64 @llvm.amdgcn.ballot.i32 29 %ballot = call i64 @llvm.amdgcn.ballot.i32(i1 %x) 30 ret void 31} 32 33; SGPR asm outputs are uniform regardless of the input operands. 34; CHECK-LABEL: for function 'asm_sgpr': 35; CHECK: DIVERGENT: i32 %divergent 36; CHECK-NOT: DIVERGENT 37define i32 @asm_sgpr(i32 %divergent) { 38 %sgpr = call i32 asm "; def $0, $1","=s,v"(i32 %divergent) 39 ret i32 %sgpr 40} 41 42; SGPR asm outputs are uniform regardless of the input operands. 43; Argument not divergent if marked inreg. 44; CHECK-LABEL: for function 'asm_sgpr_inreg_arg': 45; CHECK-NOT: DIVERGENT 46define i32 @asm_sgpr_inreg_arg(i32 inreg %divergent) { 47 %sgpr = call i32 asm "; def $0, $1","=s,v"(i32 %divergent) 48 ret i32 %sgpr 49} 50 51; CHECK-LABEL: for function 'asm_mixed_sgpr_vgpr': 52; CHECK: DIVERGENT: %asm = call { i32, i32 } asm "; def $0, $1, $2", "=s,=v,v"(i32 %divergent) 53; CHECK-NEXT: {{^[ \t]+}}%sgpr = extractvalue { i32, i32 } %asm, 0 54; CHECK-NEXT: DIVERGENT: %vgpr = extractvalue { i32, i32 } %asm, 1 55define void @asm_mixed_sgpr_vgpr(i32 %divergent) { 56 %asm = call { i32, i32 } asm "; def $0, $1, $2","=s,=v,v"(i32 %divergent) 57 %sgpr = extractvalue { i32, i32 } %asm, 0 58 %vgpr = extractvalue { i32, i32 } %asm, 1 59 store i32 %sgpr, ptr addrspace(1) undef 60 store i32 %vgpr, ptr addrspace(1) undef 61 ret void 62} 63 64; CHECK-LABEL: for function 'single_lane_func_arguments': 65; CHECK-NOT: DIVERGENT 66define void @single_lane_func_arguments(i32 %i32, i1 %i1) #2 { 67 ret void 68} 69 70; CHECK-LABEL: for function 'divergent_args': 71; CHECK: DIVERGENT ARGUMENTS 72define void @divergent_args(i32 %i32, i1 %i1) { 73 ret void 74} 75 76; CHECK-LABEL: for function 'no_divergent_args_if_inreg': 77; CHECK-NOT: DIVERGENT 78define void @no_divergent_args_if_inreg(i32 inreg %i32, i1 inreg %i1) { 79 ret void 80} 81 82; CHECK-LABEL: for function 'workgroup_id_x': 83; CHECK: ALL VALUES UNIFORM 84define void @workgroup_id_x(ptr addrspace(1) inreg %out) { 85 %result = call i32 @llvm.amdgcn.workgroup.id.x() 86 store i32 %result, ptr addrspace(1) %out, align 4 87 ret void 88} 89 90; CHECK-LABEL: for function 'workgroup_id_y': 91; CHECK: ALL VALUES UNIFORM 92define void @workgroup_id_y(ptr addrspace(1) inreg %out) { 93 %result = call i32 @llvm.amdgcn.workgroup.id.y() 94 store i32 %result, ptr addrspace(1) %out, align 4 95 ret void 96} 97 98; CHECK-LABEL: for function 'workgroup_id_z': 99; CHECK: ALL VALUES UNIFORM 100define void @workgroup_id_z(ptr addrspace(1) inreg %out) { 101 %result = call i32 @llvm.amdgcn.workgroup.id.z() 102 store i32 %result, ptr addrspace(1) %out, align 4 103 ret void 104} 105 106; CHECK-LABEL: for function 's_getpc': 107; CHECK: ALL VALUES UNIFORM 108define void @s_getpc(ptr addrspace(1) inreg %out) { 109 %result = call i64 @llvm.amdgcn.s.getpc() 110 store i64 %result, ptr addrspace(1) %out, align 8 111 ret void 112} 113 114; CHECK-LABEL: for function 's_getreg': 115; CHECK: ALL VALUES UNIFORM 116define void @s_getreg(ptr addrspace(1) inreg %out) { 117 %result = call i32 @llvm.amdgcn.s.getreg(i32 123) 118 store i32 %result, ptr addrspace(1) %out, align 4 119 ret void 120} 121 122; CHECK-LABEL: for function 's_memtime': 123; CHECK: ALL VALUES UNIFORM 124define void @s_memtime(ptr addrspace(1) inreg %out) { 125 %result = call i64 @llvm.amdgcn.s.memtime() 126 store i64 %result, ptr addrspace(1) %out, align 8 127 ret void 128} 129 130; CHECK-LABEL: for function 's_memrealtime': 131; CHECK: ALL VALUES UNIFORM 132define void @s_memrealtime(ptr addrspace(1) inreg %out) { 133 %result = call i64 @llvm.amdgcn.s.memrealtime() 134 store i64 %result, ptr addrspace(1) %out, align 8 135 ret void 136} 137 138 139declare i32 @llvm.amdgcn.workitem.id.x() #0 140declare i32 @llvm.amdgcn.readfirstlane(i32) #0 141declare i64 @llvm.amdgcn.icmp.i32(i32, i32, i32) #1 142declare i64 @llvm.amdgcn.fcmp.i32(float, float, i32) #1 143declare i64 @llvm.amdgcn.ballot.i32(i1) #1 144declare i32 @llvm.amdgcn.workgroup.id.x() #0 145declare i32 @llvm.amdgcn.workgroup.id.y() #0 146declare i32 @llvm.amdgcn.workgroup.id.z() #0 147 148attributes #0 = { nounwind readnone } 149attributes #1 = { nounwind readnone convergent } 150attributes #2 = { "amdgpu-flat-work-group-size"="1,1" } 151