
Attempting to pass a `ptr addrspace(7)` to functions that take `ptr` arguments produces undesirable `addrspacecast(addrspacecast(p8 x to p7) to p0) => addrspacecast(p8 x to p0)` folds. This results in illegal GEP operations on buffer resources, which can't be GEP'd. (However, note that, while unimplemneted, addressspacecast from ptr addrspace(7) to ptr is legal - it's just an effective address computation) To resolve this problem, and thus prevent illegal `getelementptr T, ptr addrspace(8) %x, ...` s from being produces, this commit extends amdgcn.make.buffer.rsrc to also be variadic in its result type, auto-upgrading old manglings. The logic for handling a make.buffer.rsrc in instruction selection remains untouched and expects the output type to be a ptr addrspace(8), as does the Clang lowering for its builtin (the pointer-to-pointer version might want a different name in clang). LowerBufferFatPointers has been updated to lower amdgcn.make.buffer.rsrc.p7.p* to amdgcn.make.buffer.rsrc.p8.p* . This'll also make exposing buffer fat pointers in Clang easier, since you don't have to cast between a `__amdgcn_rsrc_t` and a pointer.
215 lines
9.7 KiB
LLVM
215 lines
9.7 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
|
|
; RUN: llc < %s -mtriple=amdgcn -mcpu=gfx900 -verify-machineinstrs | FileCheck %s --check-prefixes=SDAG
|
|
; RUN: llc < %s -global-isel -mtriple=amdgcn -mcpu=gfx900 -verify-machineinstrs | FileCheck %s --check-prefixes=GISEL
|
|
|
|
define amdgpu_kernel void @buffers_dont_alias(ptr addrspace(8) noalias %a, ptr addrspace(8) noalias %b) {
|
|
; SDAG-LABEL: buffers_dont_alias:
|
|
; SDAG: ; %bb.0:
|
|
; SDAG-NEXT: s_load_dwordx8 s[8:15], s[4:5], 0x24
|
|
; SDAG-NEXT: s_waitcnt lgkmcnt(0)
|
|
; SDAG-NEXT: buffer_load_dwordx4 v[0:3], off, s[8:11], 0
|
|
; SDAG-NEXT: s_waitcnt vmcnt(0)
|
|
; SDAG-NEXT: v_mul_f32_e32 v0, v0, v0
|
|
; SDAG-NEXT: v_mul_f32_e32 v1, v1, v1
|
|
; SDAG-NEXT: v_mul_f32_e32 v2, v2, v2
|
|
; SDAG-NEXT: v_mul_f32_e32 v3, v3, v3
|
|
; SDAG-NEXT: buffer_store_dwordx4 v[0:3], off, s[12:15], 0
|
|
; SDAG-NEXT: s_endpgm
|
|
;
|
|
; GISEL-LABEL: buffers_dont_alias:
|
|
; GISEL: ; %bb.0:
|
|
; GISEL-NEXT: s_load_dwordx8 s[8:15], s[4:5], 0x24
|
|
; GISEL-NEXT: s_waitcnt lgkmcnt(0)
|
|
; GISEL-NEXT: buffer_load_dwordx4 v[0:3], off, s[8:11], 0
|
|
; GISEL-NEXT: s_waitcnt vmcnt(0)
|
|
; GISEL-NEXT: v_mul_f32_e32 v0, v0, v0
|
|
; GISEL-NEXT: v_mul_f32_e32 v1, v1, v1
|
|
; GISEL-NEXT: v_mul_f32_e32 v2, v2, v2
|
|
; GISEL-NEXT: v_mul_f32_e32 v3, v3, v3
|
|
; GISEL-NEXT: buffer_store_dwordx4 v[0:3], off, s[12:15], 0
|
|
; GISEL-NEXT: s_endpgm
|
|
%l0 = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) %a, i32 0, i32 0, i32 0)
|
|
%s0 = fmul float %l0, %l0
|
|
call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float %s0, ptr addrspace(8) %b, i32 0, i32 0, i32 0)
|
|
|
|
%l1 = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) %a, i32 4, i32 0, i32 0)
|
|
%s1 = fmul float %l1, %l1
|
|
call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float %s1, ptr addrspace(8) %b, i32 4, i32 0, i32 0)
|
|
|
|
%l2 = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) %a, i32 8, i32 0, i32 0)
|
|
%s2 = fmul float %l2, %l2
|
|
call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float %s2, ptr addrspace(8) %b, i32 8, i32 0, i32 0)
|
|
|
|
%l3 = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) %a, i32 12, i32 0, i32 0)
|
|
%s3 = fmul float %l3, %l3
|
|
call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float %s3, ptr addrspace(8) %b, i32 12, i32 0, i32 0)
|
|
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @buffers_from_flat_dont_alias(ptr noalias %a.flat, ptr noalias %b.flat) {
|
|
; SDAG-LABEL: buffers_from_flat_dont_alias:
|
|
; SDAG: ; %bb.0:
|
|
; SDAG-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24
|
|
; SDAG-NEXT: s_mov_b32 s7, 0
|
|
; SDAG-NEXT: s_mov_b32 s6, 16
|
|
; SDAG-NEXT: s_waitcnt lgkmcnt(0)
|
|
; SDAG-NEXT: s_and_b32 s5, s1, 0xffff
|
|
; SDAG-NEXT: s_mov_b32 s4, s0
|
|
; SDAG-NEXT: buffer_load_dwordx4 v[0:3], off, s[4:7], 0
|
|
; SDAG-NEXT: s_and_b32 s5, s3, 0xffff
|
|
; SDAG-NEXT: s_mov_b32 s4, s2
|
|
; SDAG-NEXT: s_waitcnt vmcnt(0)
|
|
; SDAG-NEXT: v_mul_f32_e32 v0, v0, v0
|
|
; SDAG-NEXT: v_mul_f32_e32 v1, v1, v1
|
|
; SDAG-NEXT: v_mul_f32_e32 v2, v2, v2
|
|
; SDAG-NEXT: v_mul_f32_e32 v3, v3, v3
|
|
; SDAG-NEXT: buffer_store_dwordx4 v[0:3], off, s[4:7], 0
|
|
; SDAG-NEXT: s_endpgm
|
|
;
|
|
; GISEL-LABEL: buffers_from_flat_dont_alias:
|
|
; GISEL: ; %bb.0:
|
|
; GISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24
|
|
; GISEL-NEXT: s_mov_b32 s7, 0
|
|
; GISEL-NEXT: s_mov_b32 s6, 16
|
|
; GISEL-NEXT: s_waitcnt lgkmcnt(0)
|
|
; GISEL-NEXT: s_and_b32 s5, s1, 0xffff
|
|
; GISEL-NEXT: s_mov_b32 s4, s0
|
|
; GISEL-NEXT: buffer_load_dwordx4 v[0:3], off, s[4:7], 0
|
|
; GISEL-NEXT: s_and_b32 s5, s3, 0xffff
|
|
; GISEL-NEXT: s_mov_b32 s4, s2
|
|
; GISEL-NEXT: s_waitcnt vmcnt(0)
|
|
; GISEL-NEXT: v_mul_f32_e32 v0, v0, v0
|
|
; GISEL-NEXT: v_mul_f32_e32 v1, v1, v1
|
|
; GISEL-NEXT: v_mul_f32_e32 v2, v2, v2
|
|
; GISEL-NEXT: v_mul_f32_e32 v3, v3, v3
|
|
; GISEL-NEXT: buffer_store_dwordx4 v[0:3], off, s[4:7], 0
|
|
; GISEL-NEXT: s_endpgm
|
|
%a = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0(ptr %a.flat, i16 0, i32 16, i32 0)
|
|
%b = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0(ptr %b.flat, i16 0, i32 16, i32 0)
|
|
|
|
%l0 = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) %a, i32 0, i32 0, i32 0)
|
|
%s0 = fmul float %l0, %l0
|
|
call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float %s0, ptr addrspace(8) %b, i32 0, i32 0, i32 0)
|
|
|
|
%l1 = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) %a, i32 4, i32 0, i32 0)
|
|
%s1 = fmul float %l1, %l1
|
|
call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float %s1, ptr addrspace(8) %b, i32 4, i32 0, i32 0)
|
|
|
|
%l2 = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) %a, i32 8, i32 0, i32 0)
|
|
%s2 = fmul float %l2, %l2
|
|
call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float %s2, ptr addrspace(8) %b, i32 8, i32 0, i32 0)
|
|
|
|
%l3 = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) %a, i32 12, i32 0, i32 0)
|
|
%s3 = fmul float %l3, %l3
|
|
call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float %s3, ptr addrspace(8) %b, i32 12, i32 0, i32 0)
|
|
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @buffers_might_alias(ptr addrspace(8) %a, ptr addrspace(8) %b) {
|
|
; SDAG-LABEL: buffers_might_alias:
|
|
; SDAG: ; %bb.0:
|
|
; SDAG-NEXT: s_load_dwordx8 s[8:15], s[4:5], 0x24
|
|
; SDAG-NEXT: s_waitcnt lgkmcnt(0)
|
|
; SDAG-NEXT: buffer_load_dword v0, off, s[8:11], 0
|
|
; SDAG-NEXT: s_waitcnt vmcnt(0)
|
|
; SDAG-NEXT: v_mul_f32_e32 v0, v0, v0
|
|
; SDAG-NEXT: buffer_store_dword v0, off, s[12:15], 0
|
|
; SDAG-NEXT: buffer_load_dword v0, off, s[8:11], 0 offset:4
|
|
; SDAG-NEXT: s_waitcnt vmcnt(0)
|
|
; SDAG-NEXT: v_mul_f32_e32 v0, v0, v0
|
|
; SDAG-NEXT: buffer_store_dword v0, off, s[12:15], 0 offset:4
|
|
; SDAG-NEXT: buffer_load_dword v0, off, s[8:11], 0 offset:8
|
|
; SDAG-NEXT: s_waitcnt vmcnt(0)
|
|
; SDAG-NEXT: v_mul_f32_e32 v0, v0, v0
|
|
; SDAG-NEXT: buffer_store_dword v0, off, s[12:15], 0 offset:8
|
|
; SDAG-NEXT: buffer_load_dword v0, off, s[8:11], 0 offset:12
|
|
; SDAG-NEXT: s_waitcnt vmcnt(0)
|
|
; SDAG-NEXT: v_mul_f32_e32 v0, v0, v0
|
|
; SDAG-NEXT: buffer_store_dword v0, off, s[12:15], 0 offset:12
|
|
; SDAG-NEXT: s_endpgm
|
|
;
|
|
; GISEL-LABEL: buffers_might_alias:
|
|
; GISEL: ; %bb.0:
|
|
; GISEL-NEXT: s_load_dwordx8 s[8:15], s[4:5], 0x24
|
|
; GISEL-NEXT: s_waitcnt lgkmcnt(0)
|
|
; GISEL-NEXT: buffer_load_dword v0, off, s[8:11], 0
|
|
; GISEL-NEXT: s_waitcnt vmcnt(0)
|
|
; GISEL-NEXT: v_mul_f32_e32 v0, v0, v0
|
|
; GISEL-NEXT: buffer_store_dword v0, off, s[12:15], 0
|
|
; GISEL-NEXT: buffer_load_dword v0, off, s[8:11], 0 offset:4
|
|
; GISEL-NEXT: s_waitcnt vmcnt(0)
|
|
; GISEL-NEXT: v_mul_f32_e32 v0, v0, v0
|
|
; GISEL-NEXT: buffer_store_dword v0, off, s[12:15], 0 offset:4
|
|
; GISEL-NEXT: buffer_load_dword v0, off, s[8:11], 0 offset:8
|
|
; GISEL-NEXT: s_waitcnt vmcnt(0)
|
|
; GISEL-NEXT: v_mul_f32_e32 v0, v0, v0
|
|
; GISEL-NEXT: buffer_store_dword v0, off, s[12:15], 0 offset:8
|
|
; GISEL-NEXT: buffer_load_dword v0, off, s[8:11], 0 offset:12
|
|
; GISEL-NEXT: s_waitcnt vmcnt(0)
|
|
; GISEL-NEXT: v_mul_f32_e32 v0, v0, v0
|
|
; GISEL-NEXT: buffer_store_dword v0, off, s[12:15], 0 offset:12
|
|
; GISEL-NEXT: s_endpgm
|
|
%l0 = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) %a, i32 0, i32 0, i32 0)
|
|
%s0 = fmul float %l0, %l0
|
|
call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float %s0, ptr addrspace(8) %b, i32 0, i32 0, i32 0)
|
|
|
|
%l1 = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) %a, i32 4, i32 0, i32 0)
|
|
%s1 = fmul float %l1, %l1
|
|
call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float %s1, ptr addrspace(8) %b, i32 4, i32 0, i32 0)
|
|
|
|
%l2 = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) %a, i32 8, i32 0, i32 0)
|
|
%s2 = fmul float %l2, %l2
|
|
call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float %s2, ptr addrspace(8) %b, i32 8, i32 0, i32 0)
|
|
|
|
%l3 = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) %a, i32 12, i32 0, i32 0)
|
|
%s3 = fmul float %l3, %l3
|
|
call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float %s3, ptr addrspace(8) %b, i32 12, i32 0, i32 0)
|
|
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @independent_offsets(ptr addrspace(8) %a) {
|
|
; SDAG-LABEL: independent_offsets:
|
|
; SDAG: ; %bb.0:
|
|
; SDAG-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24
|
|
; SDAG-NEXT: v_lshlrev_b32_e32 v0, 2, v0
|
|
; SDAG-NEXT: v_mov_b32_e32 v2, 1.0
|
|
; SDAG-NEXT: s_waitcnt lgkmcnt(0)
|
|
; SDAG-NEXT: buffer_load_dword v1, v0, s[0:3], 0 offen offset:4
|
|
; SDAG-NEXT: s_nop 0
|
|
; SDAG-NEXT: buffer_store_dword v2, v0, s[0:3], 0 offen
|
|
; SDAG-NEXT: s_waitcnt vmcnt(1)
|
|
; SDAG-NEXT: buffer_store_dword v1, v0, s[0:3], 0 offen offset:8
|
|
; SDAG-NEXT: s_endpgm
|
|
;
|
|
; GISEL-LABEL: independent_offsets:
|
|
; GISEL: ; %bb.0:
|
|
; GISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24
|
|
; GISEL-NEXT: v_lshlrev_b32_e32 v0, 2, v0
|
|
; GISEL-NEXT: v_mov_b32_e32 v2, 1.0
|
|
; GISEL-NEXT: s_waitcnt lgkmcnt(0)
|
|
; GISEL-NEXT: buffer_load_dword v1, v0, s[0:3], 0 offen offset:4
|
|
; GISEL-NEXT: s_nop 0
|
|
; GISEL-NEXT: buffer_store_dword v2, v0, s[0:3], 0 offen
|
|
; GISEL-NEXT: s_waitcnt vmcnt(1)
|
|
; GISEL-NEXT: buffer_store_dword v1, v0, s[0:3], 0 offen offset:8
|
|
; GISEL-NEXT: s_endpgm
|
|
%lane = call i32 @llvm.amdgcn.workitem.id.x()
|
|
%idx = shl i32 %lane, 2
|
|
call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float 1.0, ptr addrspace(8) %a, i32 %idx, i32 0, i32 0)
|
|
%idx.1 = add i32 %idx, 4
|
|
%idx.2 = add i32 %idx, 8
|
|
%val = call float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8) %a, i32 %idx.1, i32 0, i32 0)
|
|
call void @llvm.amdgcn.raw.ptr.buffer.store.f32(float %val, ptr addrspace(8) %a, i32 %idx.2, i32 0, i32 0)
|
|
|
|
ret void
|
|
}
|
|
|
|
declare i32 @llvm.amdgcn.workitem.id.x()
|
|
|
|
declare float @llvm.amdgcn.raw.ptr.buffer.load.f32(ptr addrspace(8), i32, i32, i32)
|
|
declare void @llvm.amdgcn.raw.ptr.buffer.store.f32(float, ptr addrspace(8), i32, i32, i32 immarg)
|
|
declare ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0(ptr readnone nocapture, i16, i32, i32)
|