1; RUN: llc -verify-machineinstrs -march=amdgcn < %s | FileCheck -check-prefix=GCN %s 2; RUN: llc -verify-machineinstrs -march=amdgcn -mcpu=tonga < %s | FileCheck -check-prefix=GCN %s 3 4; When a frame index offset is more than 12-bits, make sure we don't store 5; it in mubuf's offset field. 6 7; Also, make sure we use the same register for storing the scratch buffer addresss 8; for both stores. This register is allocated by the register scavenger, so we 9; should be able to reuse the same regiser for each scratch buffer access. 10 11; GCN-LABEL: {{^}}legal_offset_fi: 12; GCN: v_mov_b32_e32 [[OFFSET:v[0-9]+]], 0{{$}} 13; GCN: buffer_store_dword v{{[0-9]+}}, [[OFFSET]], s[{{[0-9]+}}:{{[0-9]+}}], s{{[0-9]+}} offen 14; GCN: v_mov_b32_e32 [[OFFSET]], 0x8000 15; GCN: buffer_store_dword v{{[0-9]+}}, [[OFFSET]], s[{{[0-9]+}}:{{[0-9]+}}], s{{[0-9]+}} offen{{$}} 16 17define void @legal_offset_fi(i32 addrspace(1)* %out, i32 %cond, i32 %if_offset, i32 %else_offset) { 18entry: 19 %scratch0 = alloca [8192 x i32] 20 %scratch1 = alloca [8192 x i32] 21 22 %scratchptr0 = getelementptr [8192 x i32], [8192 x i32]* %scratch0, i32 0, i32 0 23 store i32 1, i32* %scratchptr0 24 25 %scratchptr1 = getelementptr [8192 x i32], [8192 x i32]* %scratch1, i32 0, i32 0 26 store i32 2, i32* %scratchptr1 27 28 %cmp = icmp eq i32 %cond, 0 29 br i1 %cmp, label %if, label %else 30 31if: 32 %if_ptr = getelementptr [8192 x i32], [8192 x i32]* %scratch0, i32 0, i32 %if_offset 33 %if_value = load i32, i32* %if_ptr 34 br label %done 35 36else: 37 %else_ptr = getelementptr [8192 x i32], [8192 x i32]* %scratch1, i32 0, i32 %else_offset 38 %else_value = load i32, i32* %else_ptr 39 br label %done 40 41done: 42 %value = phi i32 [%if_value, %if], [%else_value, %else] 43 store i32 %value, i32 addrspace(1)* %out 44 ret void 45 46 ret void 47 48} 49 50; GCN-LABEL: {{^}}legal_offset_fi_offset: 51; GCN: buffer_store_dword v{{[0-9]+}}, v{{[0-9]+}}, s[{{[0-9]+}}:{{[0-9]+}}], s{{[0-9]+}} offen{{$}} 52; GCN: v_add_i32_e32 [[OFFSET:v[0-9]+]], vcc, 0x8000 53; GCN: buffer_store_dword v{{[0-9]+}}, [[OFFSET]], s[{{[0-9]+}}:{{[0-9]+}}], s{{[0-9]+}} offen{{$}} 54 55define void @legal_offset_fi_offset(i32 addrspace(1)* %out, i32 %cond, i32 addrspace(1)* %offsets, i32 %if_offset, i32 %else_offset) { 56entry: 57 %scratch0 = alloca [8192 x i32] 58 %scratch1 = alloca [8192 x i32] 59 60 %offset0 = load i32, i32 addrspace(1)* %offsets 61 %scratchptr0 = getelementptr [8192 x i32], [8192 x i32]* %scratch0, i32 0, i32 %offset0 62 store i32 %offset0, i32* %scratchptr0 63 64 %offsetptr1 = getelementptr i32, i32 addrspace(1)* %offsets, i32 1 65 %offset1 = load i32, i32 addrspace(1)* %offsetptr1 66 %scratchptr1 = getelementptr [8192 x i32], [8192 x i32]* %scratch1, i32 0, i32 %offset1 67 store i32 %offset1, i32* %scratchptr1 68 69 %cmp = icmp eq i32 %cond, 0 70 br i1 %cmp, label %if, label %else 71 72if: 73 %if_ptr = getelementptr [8192 x i32], [8192 x i32]* %scratch0, i32 0, i32 %if_offset 74 %if_value = load i32, i32* %if_ptr 75 br label %done 76 77else: 78 %else_ptr = getelementptr [8192 x i32], [8192 x i32]* %scratch1, i32 0, i32 %else_offset 79 %else_value = load i32, i32* %else_ptr 80 br label %done 81 82done: 83 %value = phi i32 [%if_value, %if], [%else_value, %else] 84 store i32 %value, i32 addrspace(1)* %out 85 ret void 86} 87 88; GCN-LABEL: {{^}}neg_vaddr_offset: 89; GCN: buffer_store_dword v{{[0-9]+}}, v{{[0-9]+}}, s[{{[0-9]+:[0-9]+}}], s{{[0-9]+}} offen offset:16{{$}} 90define void @neg_vaddr_offset(i32 %offset) { 91entry: 92 %array = alloca [8192 x i32] 93 %ptr_offset = add i32 %offset, 4 94 %ptr = getelementptr [8192 x i32], [8192 x i32]* %array, i32 0, i32 %ptr_offset 95 store i32 0, i32* %ptr 96 ret void 97} 98 99; GCN-LABEL: {{^}}pos_vaddr_offset: 100; GCN: buffer_store_dword v{{[0-9]+}}, v{{[0-9]+}}, s[{{[0-9]+:[0-9]+}}], s{{[0-9]+}} offen offset:16 101define void @pos_vaddr_offset(i32 addrspace(1)* %out, i32 %offset) { 102entry: 103 %array = alloca [8192 x i32] 104 %ptr = getelementptr [8192 x i32], [8192 x i32]* %array, i32 0, i32 4 105 store i32 0, i32* %ptr 106 %load_ptr = getelementptr [8192 x i32], [8192 x i32]* %array, i32 0, i32 %offset 107 %val = load i32, i32* %load_ptr 108 store i32 %val, i32 addrspace(1)* %out 109 ret void 110} 111