1; RUN: llc < %s -march=r600 -mcpu=verde -verify-machineinstrs | FileCheck %s 2 3; On Southern Islands GPUs the local address space(3) uses 32-bit pointers and 4; the global address space(1) uses 64-bit pointers. These tests check to make sure 5; the correct pointer size is used for the local address space. 6 7; The e{{32|64}} suffix on the instructions refers to the encoding size and not 8; the size of the operands. The operand size is denoted in the instruction name. 9; Instructions with B32, U32, and I32 in their name take 32-bit operands, while 10; instructions with B64, U64, and I64 take 64-bit operands. 11 12; CHECK-LABEL: @local_address_load 13; CHECK: V_MOV_B32_e{{32|64}} [[PTR:v[0-9]]] 14; CHECK: DS_READ_B32 [[PTR]] 15define void @local_address_load(i32 addrspace(1)* %out, i32 addrspace(3)* %in) { 16entry: 17 %0 = load i32 addrspace(3)* %in 18 store i32 %0, i32 addrspace(1)* %out 19 ret void 20} 21 22; CHECK-LABEL: @local_address_gep 23; CHECK: S_ADD_I32 [[SPTR:s[0-9]]] 24; CHECK: V_MOV_B32_e32 [[VPTR:v[0-9]+]], [[SPTR]] 25; CHECK: DS_READ_B32 [[VPTR]] 26define void @local_address_gep(i32 addrspace(1)* %out, i32 addrspace(3)* %in, i32 %offset) { 27entry: 28 %0 = getelementptr i32 addrspace(3)* %in, i32 %offset 29 %1 = load i32 addrspace(3)* %0 30 store i32 %1, i32 addrspace(1)* %out 31 ret void 32} 33 34; CHECK-LABEL: @local_address_gep_const_offset 35; CHECK: S_ADD_I32 [[SPTR:s[0-9]]] 36; CHECK: V_MOV_B32_e32 [[VPTR:v[0-9]+]], [[SPTR]] 37; CHECK: DS_READ_B32 [[VPTR]] 38define void @local_address_gep_const_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %in) { 39entry: 40 %0 = getelementptr i32 addrspace(3)* %in, i32 1 41 %1 = load i32 addrspace(3)* %0 42 store i32 %1, i32 addrspace(1)* %out 43 ret void 44} 45 46; CHECK-LABEL: @null_32bit_lds_ptr: 47; CHECK: V_CMP_NE_I32 48; CHECK-NOT: V_CMP_NE_I32 49; CHECK: V_CNDMASK_B32 50define void @null_32bit_lds_ptr(i32 addrspace(1)* %out, i32 addrspace(3)* %lds) nounwind { 51 %cmp = icmp ne i32 addrspace(3)* %lds, null 52 %x = select i1 %cmp, i32 123, i32 456 53 store i32 %x, i32 addrspace(1)* %out 54 ret void 55} 56 57; CHECK-LABEL: @mul_32bit_ptr: 58; CHECK: V_MUL_LO_I32 59; CHECK-NEXT: V_ADD_I32_e32 60; CHECK-NEXT: DS_READ_B32 61define void @mul_32bit_ptr(float addrspace(1)* %out, [3 x float] addrspace(3)* %lds, i32 %tid) { 62 %ptr = getelementptr [3 x float] addrspace(3)* %lds, i32 %tid, i32 0 63 %val = load float addrspace(3)* %ptr 64 store float %val, float addrspace(1)* %out 65 ret void 66} 67 68@g_lds = addrspace(3) global float zeroinitializer, align 4 69 70; CHECK-LABEL: @infer_ptr_alignment_global_offset: 71; CHECK: V_MOV_B32_e32 [[REG:v[0-9]+]], 0 72; CHECK: DS_READ_B32 v{{[0-9]+}}, 0, [[REG]] 73define void @infer_ptr_alignment_global_offset(float addrspace(1)* %out, i32 %tid) { 74 %val = load float addrspace(3)* @g_lds 75 store float %val, float addrspace(1)* %out 76 ret void 77} 78 79 80@ptr = addrspace(3) global i32 addrspace(3)* null 81@dst = addrspace(3) global [16384 x i32] zeroinitializer 82 83; SI-LABEL: @global_ptr: 84; SI-CHECK: DS_WRITE_B32 85define void @global_ptr() nounwind { 86 store i32 addrspace(3)* getelementptr ([16384 x i32] addrspace(3)* @dst, i32 0, i32 16), i32 addrspace(3)* addrspace(3)* @ptr 87 ret void 88} 89