1; RUN: llc -march=amdgcn -mcpu=gfx1030 -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s 2; RUN: llc -march=amdgcn -mcpu=gfx1013 -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s 3; RUN: not --crash llc -march=amdgcn -mcpu=gfx1012 -verify-machineinstrs < %s 2>&1 | FileCheck -check-prefix=ERR %s 4 5; uint4 llvm.amdgcn.image.bvh.intersect.ray.i32.v4f32(uint node_ptr, float ray_extent, float4 ray_origin, float4 ray_dir, float4 ray_inv_dir, uint4 texture_descr) 6; uint4 llvm.amdgcn.image.bvh.intersect.ray.i32.v4f16(uint node_ptr, float ray_extent, float4 ray_origin, half4 ray_dir, half4 ray_inv_dir, uint4 texture_descr) 7; uint4 llvm.amdgcn.image.bvh.intersect.ray.i64.v4f32(ulong node_ptr, float ray_extent, float4 ray_origin, float4 ray_dir, float4 ray_inv_dir, uint4 texture_descr) 8; uint4 llvm.amdgcn.image.bvh.intersect.ray.i64.v4f16(ulong node_ptr, float ray_extent, float4 ray_origin, half4 ray_dir, half4 ray_inv_dir, uint4 texture_descr) 9 10declare <4 x i32> @llvm.amdgcn.image.bvh.intersect.ray.i32.v4f32(i32, float, <4 x float>, <4 x float>, <4 x float>, <4 x i32>) 11declare <4 x i32> @llvm.amdgcn.image.bvh.intersect.ray.i32.v4f16(i32, float, <4 x float>, <4 x half>, <4 x half>, <4 x i32>) 12declare <4 x i32> @llvm.amdgcn.image.bvh.intersect.ray.i64.v4f32(i64, float, <4 x float>, <4 x float>, <4 x float>, <4 x i32>) 13declare <4 x i32> @llvm.amdgcn.image.bvh.intersect.ray.i64.v4f16(i64, float, <4 x float>, <4 x half>, <4 x half>, <4 x i32>) 14 15; GCN-LABEL: {{^}}image_bvh_intersect_ray: 16; GCN: image_bvh_intersect_ray v[0:3], v[0:15], s[0:3]{{$}} 17; ERR: in function image_bvh_intersect_ray{{.*}}intrinsic not supported on subtarget 18; Arguments are flattened to represent the actual VGPR_A layout, so we have no 19; extra moves in the generated kernel. 20define amdgpu_ps <4 x float> @image_bvh_intersect_ray(i32 %node_ptr, float %ray_extent, float %ray_origin_x, float %ray_origin_y, float %ray_origin_z, float %ray_dir_x, float %ray_dir_y, float %ray_dir_z, float %ray_inv_dir_x, float %ray_inv_dir_y, float %ray_inv_dir_z, <4 x i32> inreg %tdescr) { 21main_body: 22 %ray_origin0 = insertelement <4 x float> undef, float %ray_origin_x, i32 0 23 %ray_origin1 = insertelement <4 x float> %ray_origin0, float %ray_origin_y, i32 1 24 %ray_origin = insertelement <4 x float> %ray_origin1, float %ray_origin_z, i32 2 25 %ray_dir0 = insertelement <4 x float> undef, float %ray_dir_x, i32 0 26 %ray_dir1 = insertelement <4 x float> %ray_dir0, float %ray_dir_y, i32 1 27 %ray_dir = insertelement <4 x float> %ray_dir1, float %ray_dir_z, i32 2 28 %ray_inv_dir0 = insertelement <4 x float> undef, float %ray_inv_dir_x, i32 0 29 %ray_inv_dir1 = insertelement <4 x float> %ray_inv_dir0, float %ray_inv_dir_y, i32 1 30 %ray_inv_dir = insertelement <4 x float> %ray_inv_dir1, float %ray_inv_dir_z, i32 2 31 %v = call <4 x i32> @llvm.amdgcn.image.bvh.intersect.ray.i32.v4f32(i32 %node_ptr, float %ray_extent, <4 x float> %ray_origin, <4 x float> %ray_dir, <4 x float> %ray_inv_dir, <4 x i32> %tdescr) 32 %r = bitcast <4 x i32> %v to <4 x float> 33 ret <4 x float> %r 34} 35 36; GCN-LABEL: {{^}}image_bvh_intersect_ray_a16: 37; GCN: image_bvh_intersect_ray v[0:3], v[{{[0-9:]+}}], s[{{[0-9:]+}}] a16{{$}} 38define amdgpu_ps <4 x float> @image_bvh_intersect_ray_a16(i32 inreg %node_ptr, float inreg %ray_extent, <4 x float> inreg %ray_origin, <4 x half> inreg %ray_dir, <4 x half> inreg %ray_inv_dir, <4 x i32> inreg %tdescr) { 39main_body: 40 %v = call <4 x i32> @llvm.amdgcn.image.bvh.intersect.ray.i32.v4f16(i32 %node_ptr, float %ray_extent, <4 x float> %ray_origin, <4 x half> %ray_dir, <4 x half> %ray_inv_dir, <4 x i32> %tdescr) 41 %r = bitcast <4 x i32> %v to <4 x float> 42 ret <4 x float> %r 43} 44 45; GCN-LABEL: {{^}}image_bvh64_intersect_ray: 46; GCN: image_bvh64_intersect_ray v[0:3], v[0:15], s[0:3]{{$}} 47; Arguments are flattened to represent the actual VGPR_A layout, so we have no 48; extra moves in the generated kernel. 49define amdgpu_ps <4 x float> @image_bvh64_intersect_ray(<2 x i32> %node_ptr_vec, float %ray_extent, float %ray_origin_x, float %ray_origin_y, float %ray_origin_z, float %ray_dir_x, float %ray_dir_y, float %ray_dir_z, float %ray_inv_dir_x, float %ray_inv_dir_y, float %ray_inv_dir_z, <4 x i32> inreg %tdescr) { 50main_body: 51 %node_ptr = bitcast <2 x i32> %node_ptr_vec to i64 52 %ray_origin0 = insertelement <4 x float> undef, float %ray_origin_x, i32 0 53 %ray_origin1 = insertelement <4 x float> %ray_origin0, float %ray_origin_y, i32 1 54 %ray_origin = insertelement <4 x float> %ray_origin1, float %ray_origin_z, i32 2 55 %ray_dir0 = insertelement <4 x float> undef, float %ray_dir_x, i32 0 56 %ray_dir1 = insertelement <4 x float> %ray_dir0, float %ray_dir_y, i32 1 57 %ray_dir = insertelement <4 x float> %ray_dir1, float %ray_dir_z, i32 2 58 %ray_inv_dir0 = insertelement <4 x float> undef, float %ray_inv_dir_x, i32 0 59 %ray_inv_dir1 = insertelement <4 x float> %ray_inv_dir0, float %ray_inv_dir_y, i32 1 60 %ray_inv_dir = insertelement <4 x float> %ray_inv_dir1, float %ray_inv_dir_z, i32 2 61 %v = call <4 x i32> @llvm.amdgcn.image.bvh.intersect.ray.i64.v4f32(i64 %node_ptr, float %ray_extent, <4 x float> %ray_origin, <4 x float> %ray_dir, <4 x float> %ray_inv_dir, <4 x i32> %tdescr) 62 %r = bitcast <4 x i32> %v to <4 x float> 63 ret <4 x float> %r 64} 65 66; GCN-LABEL: {{^}}image_bvh64_intersect_ray_a16: 67; GCN: image_bvh64_intersect_ray v[0:3], v[{{[0-9:]+}}], s[{{[0-9:]+}}] a16{{$}} 68define amdgpu_ps <4 x float> @image_bvh64_intersect_ray_a16(i64 inreg %node_ptr, float inreg %ray_extent, <4 x float> inreg %ray_origin, <4 x half> inreg %ray_dir, <4 x half> inreg %ray_inv_dir, <4 x i32> inreg %tdescr) { 69main_body: 70 %v = call <4 x i32> @llvm.amdgcn.image.bvh.intersect.ray.i64.v4f16(i64 %node_ptr, float %ray_extent, <4 x float> %ray_origin, <4 x half> %ray_dir, <4 x half> %ray_inv_dir, <4 x i32> %tdescr) 71 %r = bitcast <4 x i32> %v to <4 x float> 72 ret <4 x float> %r 73} 74 75; TODO: NSA reassign is very limited and cannot work with VGPR tuples and subregs. 76 77; GCN-LABEL: {{^}}image_bvh_intersect_ray_nsa_reassign: 78; GCN: image_bvh_intersect_ray v[{{[0-9:]+}}], v[{{[0-9:]+}}], s[{{[0-9:]+}}]{{$}} 79define amdgpu_kernel void @image_bvh_intersect_ray_nsa_reassign(i32* %p_node_ptr, float* %p_ray, <4 x i32> inreg %tdescr) { 80main_body: 81 %lid = tail call i32 @llvm.amdgcn.workitem.id.x() 82 %gep_node_ptr = getelementptr inbounds i32, i32* %p_node_ptr, i32 %lid 83 %node_ptr = load i32, i32* %gep_node_ptr, align 4 84 %gep_ray = getelementptr inbounds float, float* %p_ray, i32 %lid 85 %ray_extent = load float, float* %gep_ray, align 4 86 %ray_origin0 = insertelement <4 x float> undef, float 0.0, i32 0 87 %ray_origin1 = insertelement <4 x float> %ray_origin0, float 1.0, i32 1 88 %ray_origin = insertelement <4 x float> %ray_origin1, float 2.0, i32 2 89 %ray_dir0 = insertelement <4 x float> undef, float 3.0, i32 0 90 %ray_dir1 = insertelement <4 x float> %ray_dir0, float 4.0, i32 1 91 %ray_dir = insertelement <4 x float> %ray_dir1, float 5.0, i32 2 92 %ray_inv_dir0 = insertelement <4 x float> undef, float 6.0, i32 0 93 %ray_inv_dir1 = insertelement <4 x float> %ray_inv_dir0, float 7.0, i32 1 94 %ray_inv_dir = insertelement <4 x float> %ray_inv_dir1, float 8.0, i32 2 95 %v = call <4 x i32> @llvm.amdgcn.image.bvh.intersect.ray.i32.v4f32(i32 %node_ptr, float %ray_extent, <4 x float> %ray_origin, <4 x float> %ray_dir, <4 x float> %ray_inv_dir, <4 x i32> %tdescr) 96 store <4 x i32> %v, <4 x i32>* undef 97 ret void 98} 99 100; GCN-LABEL: {{^}}image_bvh_intersect_ray_a16_nsa_reassign: 101; GCN: image_bvh_intersect_ray v[{{[0-9:]+}}], v[{{[0-9:]+}}], s[{{[0-9:]+}}] a16{{$}} 102define amdgpu_kernel void @image_bvh_intersect_ray_a16_nsa_reassign(i32* %p_node_ptr, float* %p_ray, <4 x i32> inreg %tdescr) { 103main_body: 104 %lid = tail call i32 @llvm.amdgcn.workitem.id.x() 105 %gep_node_ptr = getelementptr inbounds i32, i32* %p_node_ptr, i32 %lid 106 %node_ptr = load i32, i32* %gep_node_ptr, align 4 107 %gep_ray = getelementptr inbounds float, float* %p_ray, i32 %lid 108 %ray_extent = load float, float* %gep_ray, align 4 109 %ray_origin0 = insertelement <4 x float> undef, float 0.0, i32 0 110 %ray_origin1 = insertelement <4 x float> %ray_origin0, float 1.0, i32 1 111 %ray_origin = insertelement <4 x float> %ray_origin1, float 2.0, i32 2 112 %ray_dir0 = insertelement <4 x half> undef, half 3.0, i32 0 113 %ray_dir1 = insertelement <4 x half> %ray_dir0, half 4.0, i32 1 114 %ray_dir = insertelement <4 x half> %ray_dir1, half 5.0, i32 2 115 %ray_inv_dir0 = insertelement <4 x half> undef, half 6.0, i32 0 116 %ray_inv_dir1 = insertelement <4 x half> %ray_inv_dir0, half 7.0, i32 1 117 %ray_inv_dir = insertelement <4 x half> %ray_inv_dir1, half 8.0, i32 2 118 %v = call <4 x i32> @llvm.amdgcn.image.bvh.intersect.ray.i32.v4f16(i32 %node_ptr, float %ray_extent, <4 x float> %ray_origin, <4 x half> %ray_dir, <4 x half> %ray_inv_dir, <4 x i32> %tdescr) 119 store <4 x i32> %v, <4 x i32>* undef 120 ret void 121} 122 123; GCN-LABEL: {{^}}image_bvh64_intersect_ray_nsa_reassign: 124; GCN: image_bvh64_intersect_ray v[{{[0-9:]+}}], v[{{[0-9:]+}}], s[{{[0-9:]+}}]{{$}} 125define amdgpu_kernel void @image_bvh64_intersect_ray_nsa_reassign(float* %p_ray, <4 x i32> inreg %tdescr) { 126main_body: 127 %lid = tail call i32 @llvm.amdgcn.workitem.id.x() 128 %gep_ray = getelementptr inbounds float, float* %p_ray, i32 %lid 129 %ray_extent = load float, float* %gep_ray, align 4 130 %ray_origin0 = insertelement <4 x float> undef, float 0.0, i32 0 131 %ray_origin1 = insertelement <4 x float> %ray_origin0, float 1.0, i32 1 132 %ray_origin = insertelement <4 x float> %ray_origin1, float 2.0, i32 2 133 %ray_dir0 = insertelement <4 x float> undef, float 3.0, i32 0 134 %ray_dir1 = insertelement <4 x float> %ray_dir0, float 4.0, i32 1 135 %ray_dir = insertelement <4 x float> %ray_dir1, float 5.0, i32 2 136 %ray_inv_dir0 = insertelement <4 x float> undef, float 6.0, i32 0 137 %ray_inv_dir1 = insertelement <4 x float> %ray_inv_dir0, float 7.0, i32 1 138 %ray_inv_dir = insertelement <4 x float> %ray_inv_dir1, float 8.0, i32 2 139 %v = call <4 x i32> @llvm.amdgcn.image.bvh.intersect.ray.i64.v4f32(i64 1111111111111, float %ray_extent, <4 x float> %ray_origin, <4 x float> %ray_dir, <4 x float> %ray_inv_dir, <4 x i32> %tdescr) 140 store <4 x i32> %v, <4 x i32>* undef 141 ret void 142} 143 144; GCN-LABEL: {{^}}image_bvh64_intersect_ray_a16_nsa_reassign: 145; GCN: image_bvh64_intersect_ray v[{{[0-9:]+}}], v[{{[0-9:]+}}], s[{{[0-9:]+}}] a16{{$}} 146define amdgpu_kernel void @image_bvh64_intersect_ray_a16_nsa_reassign(float* %p_ray, <4 x i32> inreg %tdescr) { 147main_body: 148 %lid = tail call i32 @llvm.amdgcn.workitem.id.x() 149 %gep_ray = getelementptr inbounds float, float* %p_ray, i32 %lid 150 %ray_extent = load float, float* %gep_ray, align 4 151 %ray_origin0 = insertelement <4 x float> undef, float 0.0, i32 0 152 %ray_origin1 = insertelement <4 x float> %ray_origin0, float 1.0, i32 1 153 %ray_origin = insertelement <4 x float> %ray_origin1, float 2.0, i32 2 154 %ray_dir0 = insertelement <4 x half> undef, half 3.0, i32 0 155 %ray_dir1 = insertelement <4 x half> %ray_dir0, half 4.0, i32 1 156 %ray_dir = insertelement <4 x half> %ray_dir1, half 5.0, i32 2 157 %ray_inv_dir0 = insertelement <4 x half> undef, half 6.0, i32 0 158 %ray_inv_dir1 = insertelement <4 x half> %ray_inv_dir0, half 7.0, i32 1 159 %ray_inv_dir = insertelement <4 x half> %ray_inv_dir1, half 8.0, i32 2 160 %v = call <4 x i32> @llvm.amdgcn.image.bvh.intersect.ray.i64.v4f16(i64 1111111111110, float %ray_extent, <4 x float> %ray_origin, <4 x half> %ray_dir, <4 x half> %ray_inv_dir, <4 x i32> %tdescr) 161 store <4 x i32> %v, <4 x i32>* undef 162 ret void 163} 164 165declare i32 @llvm.amdgcn.workitem.id.x() 166