[llvm] [AMDGPU][NFC] Pre-commit tests for out-of-bounds raw buffer fold (PR #227385)

Dark Steve via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 29 09:58:09 PDT 2026


https://github.com/PrasoonMishra created https://github.com/llvm/llvm-project/pull/227385

The tests document the current behavior for out-of-bounds raw buffer accesses.  Cases that are provably OOB at compile time (for example, an `INT_MIN` offset with a small `NumRecords`) are currently preserved as `buffer_load`/`buffer_store` instructions across all supported generations because no compile-time fold exists yet.


>From 7d2fddf3078dfcc1c4c7dfbbbf2176ca5e6d995b Mon Sep 17 00:00:00 2001
From: Dark Steve Jobs <Prasoon.Mishra at amd.com>
Date: Tue, 22 Sep 2026 20:38:31 +0530
Subject: [PATCH] Pre-commit to show the changes later on.

---
 .../CodeGen/AMDGPU/fold-oob-buffer-access.ll  | 789 ++++++++++++++++++
 1 file changed, 789 insertions(+)
 create mode 100644 llvm/test/CodeGen/AMDGPU/fold-oob-buffer-access.ll

diff --git a/llvm/test/CodeGen/AMDGPU/fold-oob-buffer-access.ll b/llvm/test/CodeGen/AMDGPU/fold-oob-buffer-access.ll
new file mode 100644
index 0000000000000..37e9dffc47a79
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/fold-oob-buffer-access.ll
@@ -0,0 +1,789 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -mtriple=amdgpu9.4-amd-amdhsa -O2 -S < %s | llc -mtriple=amdgpu9.4-amd-amdhsa | FileCheck -check-prefix=GFX9 %s
+; RUN: opt -mtriple=amdgpu10.1-amd-amdhsa -O2 -S < %s | llc -mtriple=amdgpu10.1-amd-amdhsa | FileCheck -check-prefix=GFX10 %s
+; RUN: opt -mtriple=amdgpu11-amd-amdhsa -O2 -S < %s | llc -mtriple=amdgpu11-amd-amdhsa | FileCheck -check-prefix=GFX11 %s
+; RUN: opt -mtriple=amdgpu12-amd-amdhsa -O2 -S < %s | llc -mtriple=amdgpu12-amd-amdhsa | FileCheck -check-prefix=GFX12 %s
+; RUN: opt -mtriple=amdgpu13-amd-amdhsa -O2 -S < %s | llc -mtriple=amdgpu13-amd-amdhsa | FileCheck -check-prefix=GFX13 %s
+
+; OOB raw buffer store but without OOB_SELECT = 3
+define void @oob_store_flags0(i32 %val) {
+; GFX9-LABEL: oob_store_flags0:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    s_mov_b32 s0, 0
+; GFX9-NEXT:    s_movk_i32 s2, 0x200
+; GFX9-NEXT:    s_mov_b32 s1, s0
+; GFX9-NEXT:    s_mov_b32 s3, s0
+; GFX9-NEXT:    v_bfrev_b32_e32 v1, 1
+; GFX9-NEXT:    buffer_store_dword v0, v1, s[0:3], 0 offen
+; GFX9-NEXT:    s_waitcnt vmcnt(0)
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: oob_store_flags0:
+; GFX10:       ; %bb.0:
+; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT:    v_bfrev_b32_e32 v1, 1
+; GFX10-NEXT:    s_mov_b32 s4, 0
+; GFX10-NEXT:    s_movk_i32 s6, 0x200
+; GFX10-NEXT:    s_mov_b32 s5, s4
+; GFX10-NEXT:    s_mov_b32 s7, s4
+; GFX10-NEXT:    buffer_store_dword v0, v1, s[4:7], 0 offen
+; GFX10-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: oob_store_flags0:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_bfrev_b32_e32 v1, 1
+; GFX11-NEXT:    s_mov_b32 s0, 0
+; GFX11-NEXT:    s_movk_i32 s2, 0x200
+; GFX11-NEXT:    s_mov_b32 s1, s0
+; GFX11-NEXT:    s_mov_b32 s3, s0
+; GFX11-NEXT:    buffer_store_b32 v0, v1, s[0:3], 0 offen
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX12-LABEL: oob_store_flags0:
+; GFX12:       ; %bb.0:
+; GFX12-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT:    s_wait_expcnt 0x0
+; GFX12-NEXT:    s_wait_samplecnt 0x0
+; GFX12-NEXT:    s_wait_bvhcnt 0x0
+; GFX12-NEXT:    s_wait_kmcnt 0x0
+; GFX12-NEXT:    v_bfrev_b32_e32 v1, 1
+; GFX12-NEXT:    s_mov_b32 s0, 0
+; GFX12-NEXT:    s_movk_i32 s2, 0x200
+; GFX12-NEXT:    s_wait_alu depctr_sa_sdst(0)
+; GFX12-NEXT:    s_mov_b32 s1, s0
+; GFX12-NEXT:    s_mov_b32 s3, s0
+; GFX12-NEXT:    buffer_store_b32 v0, v1, s[0:3], null offen
+; GFX12-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX13-LABEL: oob_store_flags0:
+; GFX13:       ; %bb.0:
+; GFX13-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX13-NEXT:    s_wait_expcnt 0x0
+; GFX13-NEXT:    s_wait_samplecnt 0x0
+; GFX13-NEXT:    s_wait_bvhcnt 0x0
+; GFX13-NEXT:    s_wait_kmcnt 0x0
+; GFX13-NEXT:    v_bfrev_b32_e32 v1, 1
+; GFX13-NEXT:    s_mov_b32 s0, 0
+; GFX13-NEXT:    s_mov_b32 s2, 4
+; GFX13-NEXT:    s_mov_b32 s1, s0
+; GFX13-NEXT:    s_mov_b32 s3, s0
+; GFX13-NEXT:    buffer_store_b32 v0, v1, s[0:3], null offen
+; GFX13-NEXT:    s_set_pc_i64 s[30:31]
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc(ptr null, i16 0, i32 512, i32 0)
+  call void @llvm.amdgcn.raw.ptr.buffer.store.i32(i32 %val, ptr addrspace(8) %rsrc, i32 -2147483648, i32 0, i32 0)
+  ret void
+}
+
+; OOB raw buffer store with OOB_SELECT = 3
+define void @oob_store_oobsel3(i32 %val) {
+; GFX9-LABEL: oob_store_oobsel3:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    s_mov_b32 s0, 0
+; GFX9-NEXT:    s_brev_b32 s3, 12
+; GFX9-NEXT:    s_movk_i32 s2, 0x200
+; GFX9-NEXT:    s_mov_b32 s1, s0
+; GFX9-NEXT:    v_bfrev_b32_e32 v1, 1
+; GFX9-NEXT:    buffer_store_dword v0, v1, s[0:3], 0 offen
+; GFX9-NEXT:    s_waitcnt vmcnt(0)
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: oob_store_oobsel3:
+; GFX10:       ; %bb.0:
+; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT:    v_bfrev_b32_e32 v1, 1
+; GFX10-NEXT:    s_mov_b32 s4, 0
+; GFX10-NEXT:    s_brev_b32 s7, 12
+; GFX10-NEXT:    s_movk_i32 s6, 0x200
+; GFX10-NEXT:    s_mov_b32 s5, s4
+; GFX10-NEXT:    buffer_store_dword v0, v1, s[4:7], 0 offen
+; GFX10-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: oob_store_oobsel3:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_bfrev_b32_e32 v1, 1
+; GFX11-NEXT:    s_mov_b32 s0, 0
+; GFX11-NEXT:    s_brev_b32 s3, 12
+; GFX11-NEXT:    s_movk_i32 s2, 0x200
+; GFX11-NEXT:    s_mov_b32 s1, s0
+; GFX11-NEXT:    buffer_store_b32 v0, v1, s[0:3], 0 offen
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX12-LABEL: oob_store_oobsel3:
+; GFX12:       ; %bb.0:
+; GFX12-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT:    s_wait_expcnt 0x0
+; GFX12-NEXT:    s_wait_samplecnt 0x0
+; GFX12-NEXT:    s_wait_bvhcnt 0x0
+; GFX12-NEXT:    s_wait_kmcnt 0x0
+; GFX12-NEXT:    v_bfrev_b32_e32 v1, 1
+; GFX12-NEXT:    s_mov_b32 s0, 0
+; GFX12-NEXT:    s_brev_b32 s3, 12
+; GFX12-NEXT:    s_movk_i32 s2, 0x200
+; GFX12-NEXT:    s_wait_alu depctr_sa_sdst(0)
+; GFX12-NEXT:    s_mov_b32 s1, s0
+; GFX12-NEXT:    buffer_store_b32 v0, v1, s[0:3], null offen
+; GFX12-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX13-LABEL: oob_store_oobsel3:
+; GFX13:       ; %bb.0:
+; GFX13-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX13-NEXT:    s_wait_expcnt 0x0
+; GFX13-NEXT:    s_wait_samplecnt 0x0
+; GFX13-NEXT:    s_wait_bvhcnt 0x0
+; GFX13-NEXT:    s_wait_kmcnt 0x0
+; GFX13-NEXT:    v_bfrev_b32_e32 v1, 1
+; GFX13-NEXT:    s_mov_b32 s0, 0
+; GFX13-NEXT:    s_mov_b32 s2, 4
+; GFX13-NEXT:    s_mov_b32 s1, s0
+; GFX13-NEXT:    s_mov_b32 s3, s0
+; GFX13-NEXT:    buffer_store_b32 v0, v1, s[0:3], null offen
+; GFX13-NEXT:    s_set_pc_i64 s[30:31]
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc(ptr null, i16 0, i32 512, i32 805306368)
+  call void @llvm.amdgcn.raw.ptr.buffer.store.i32(i32 %val, ptr addrspace(8) %rsrc, i32 -2147483648, i32 0, i32 0)
+  ret void
+}
+
+; OOB raw buffer load but without OOB_SELECT = 3
+define i32 @oob_load_flags0() {
+; GFX9-LABEL: oob_load_flags0:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    s_mov_b32 s0, 0
+; GFX9-NEXT:    s_movk_i32 s2, 0x200
+; GFX9-NEXT:    s_mov_b32 s1, s0
+; GFX9-NEXT:    s_mov_b32 s3, s0
+; GFX9-NEXT:    v_bfrev_b32_e32 v0, 1
+; GFX9-NEXT:    buffer_load_dword v0, v0, s[0:3], 0 offen
+; GFX9-NEXT:    s_waitcnt vmcnt(0)
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: oob_load_flags0:
+; GFX10:       ; %bb.0:
+; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT:    v_bfrev_b32_e32 v0, 1
+; GFX10-NEXT:    s_mov_b32 s4, 0
+; GFX10-NEXT:    s_movk_i32 s6, 0x200
+; GFX10-NEXT:    s_mov_b32 s5, s4
+; GFX10-NEXT:    s_mov_b32 s7, s4
+; GFX10-NEXT:    buffer_load_dword v0, v0, s[4:7], 0 offen
+; GFX10-NEXT:    s_waitcnt vmcnt(0)
+; GFX10-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: oob_load_flags0:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_bfrev_b32_e32 v0, 1
+; GFX11-NEXT:    s_mov_b32 s0, 0
+; GFX11-NEXT:    s_movk_i32 s2, 0x200
+; GFX11-NEXT:    s_mov_b32 s1, s0
+; GFX11-NEXT:    s_mov_b32 s3, s0
+; GFX11-NEXT:    buffer_load_b32 v0, v0, s[0:3], 0 offen
+; GFX11-NEXT:    s_waitcnt vmcnt(0)
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX12-LABEL: oob_load_flags0:
+; GFX12:       ; %bb.0:
+; GFX12-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT:    s_wait_expcnt 0x0
+; GFX12-NEXT:    s_wait_samplecnt 0x0
+; GFX12-NEXT:    s_wait_bvhcnt 0x0
+; GFX12-NEXT:    s_wait_kmcnt 0x0
+; GFX12-NEXT:    v_bfrev_b32_e32 v0, 1
+; GFX12-NEXT:    s_mov_b32 s0, 0
+; GFX12-NEXT:    s_movk_i32 s2, 0x200
+; GFX12-NEXT:    s_wait_alu depctr_sa_sdst(0)
+; GFX12-NEXT:    s_mov_b32 s1, s0
+; GFX12-NEXT:    s_mov_b32 s3, s0
+; GFX12-NEXT:    buffer_load_b32 v0, v0, s[0:3], null offen
+; GFX12-NEXT:    s_wait_loadcnt 0x0
+; GFX12-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX13-LABEL: oob_load_flags0:
+; GFX13:       ; %bb.0:
+; GFX13-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX13-NEXT:    s_wait_expcnt 0x0
+; GFX13-NEXT:    s_wait_samplecnt 0x0
+; GFX13-NEXT:    s_wait_bvhcnt 0x0
+; GFX13-NEXT:    s_wait_kmcnt 0x0
+; GFX13-NEXT:    v_bfrev_b32_e32 v0, 1
+; GFX13-NEXT:    s_mov_b32 s0, 0
+; GFX13-NEXT:    s_mov_b32 s2, 4
+; GFX13-NEXT:    s_mov_b32 s1, s0
+; GFX13-NEXT:    s_mov_b32 s3, s0
+; GFX13-NEXT:    buffer_load_b32 v0, v0, s[0:3], null offen
+; GFX13-NEXT:    s_wait_loadcnt 0x0
+; GFX13-NEXT:    s_set_pc_i64 s[30:31]
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc(ptr null, i16 0, i32 512, i32 0)
+  %val = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 -2147483648, i32 0, i32 0)
+  ret i32 %val
+}
+
+; OOB raw buffer load with OOB_SELECT = 3
+define i32 @oob_load_oobsel3() {
+; GFX9-LABEL: oob_load_oobsel3:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    s_mov_b32 s0, 0
+; GFX9-NEXT:    s_brev_b32 s3, 12
+; GFX9-NEXT:    s_movk_i32 s2, 0x200
+; GFX9-NEXT:    s_mov_b32 s1, s0
+; GFX9-NEXT:    v_bfrev_b32_e32 v0, 1
+; GFX9-NEXT:    buffer_load_dword v0, v0, s[0:3], 0 offen
+; GFX9-NEXT:    s_waitcnt vmcnt(0)
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: oob_load_oobsel3:
+; GFX10:       ; %bb.0:
+; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT:    v_bfrev_b32_e32 v0, 1
+; GFX10-NEXT:    s_mov_b32 s4, 0
+; GFX10-NEXT:    s_brev_b32 s7, 12
+; GFX10-NEXT:    s_movk_i32 s6, 0x200
+; GFX10-NEXT:    s_mov_b32 s5, s4
+; GFX10-NEXT:    buffer_load_dword v0, v0, s[4:7], 0 offen
+; GFX10-NEXT:    s_waitcnt vmcnt(0)
+; GFX10-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: oob_load_oobsel3:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_bfrev_b32_e32 v0, 1
+; GFX11-NEXT:    s_mov_b32 s0, 0
+; GFX11-NEXT:    s_brev_b32 s3, 12
+; GFX11-NEXT:    s_movk_i32 s2, 0x200
+; GFX11-NEXT:    s_mov_b32 s1, s0
+; GFX11-NEXT:    buffer_load_b32 v0, v0, s[0:3], 0 offen
+; GFX11-NEXT:    s_waitcnt vmcnt(0)
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX12-LABEL: oob_load_oobsel3:
+; GFX12:       ; %bb.0:
+; GFX12-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT:    s_wait_expcnt 0x0
+; GFX12-NEXT:    s_wait_samplecnt 0x0
+; GFX12-NEXT:    s_wait_bvhcnt 0x0
+; GFX12-NEXT:    s_wait_kmcnt 0x0
+; GFX12-NEXT:    v_bfrev_b32_e32 v0, 1
+; GFX12-NEXT:    s_mov_b32 s0, 0
+; GFX12-NEXT:    s_brev_b32 s3, 12
+; GFX12-NEXT:    s_movk_i32 s2, 0x200
+; GFX12-NEXT:    s_wait_alu depctr_sa_sdst(0)
+; GFX12-NEXT:    s_mov_b32 s1, s0
+; GFX12-NEXT:    buffer_load_b32 v0, v0, s[0:3], null offen
+; GFX12-NEXT:    s_wait_loadcnt 0x0
+; GFX12-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX13-LABEL: oob_load_oobsel3:
+; GFX13:       ; %bb.0:
+; GFX13-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX13-NEXT:    s_wait_expcnt 0x0
+; GFX13-NEXT:    s_wait_samplecnt 0x0
+; GFX13-NEXT:    s_wait_bvhcnt 0x0
+; GFX13-NEXT:    s_wait_kmcnt 0x0
+; GFX13-NEXT:    v_bfrev_b32_e32 v0, 1
+; GFX13-NEXT:    s_mov_b32 s0, 0
+; GFX13-NEXT:    s_mov_b32 s2, 4
+; GFX13-NEXT:    s_mov_b32 s1, s0
+; GFX13-NEXT:    s_mov_b32 s3, s0
+; GFX13-NEXT:    buffer_load_b32 v0, v0, s[0:3], null offen
+; GFX13-NEXT:    s_wait_loadcnt 0x0
+; GFX13-NEXT:    s_set_pc_i64 s[30:31]
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc(ptr null, i16 0, i32 512, i32 805306368)
+  %val = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 -2147483648, i32 0, i32 0)
+  ret i32 %val
+}
+
+; OOB raw buffer store feeding a dead FMA+exp chain.
+define void @oob_store_with_dead_chain(float %x) {
+; GFX9-LABEL: oob_store_with_dead_chain:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_fma_f32 v1, v0, 0.5, 1.0
+; GFX9-NEXT:    v_fmac_f32_e32 v0, 0.5, v1
+; GFX9-NEXT:    s_mov_b32 s0, 0x3fb8aa3b
+; GFX9-NEXT:    v_mul_f32_e32 v2, 0x3fb8aa3b, v0
+; GFX9-NEXT:    v_fma_f32 v3, v0, s0, -v2
+; GFX9-NEXT:    v_rndne_f32_e32 v4, v2
+; GFX9-NEXT:    v_fmamk_f32 v3, v0, 0x32a5705f, v3
+; GFX9-NEXT:    v_sub_f32_e32 v2, v2, v4
+; GFX9-NEXT:    v_add_f32_e32 v2, v2, v3
+; GFX9-NEXT:    v_exp_f32_e32 v2, v2
+; GFX9-NEXT:    v_cvt_i32_f32_e32 v3, v4
+; GFX9-NEXT:    s_mov_b32 s4, 0xc2ce8ed0
+; GFX9-NEXT:    v_cmp_ngt_f32_e32 vcc, s4, v0
+; GFX9-NEXT:    s_mov_b32 s4, 0x42b17218
+; GFX9-NEXT:    v_ldexp_f32 v2, v2, v3
+; GFX9-NEXT:    v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT:    v_mov_b32_e32 v3, 0x7f800000
+; GFX9-NEXT:    v_cmp_nlt_f32_e32 vcc, s4, v0
+; GFX9-NEXT:    s_mov_b32 s0, 0
+; GFX9-NEXT:    s_brev_b32 s3, 12
+; GFX9-NEXT:    v_cndmask_b32_e32 v0, v3, v2, vcc
+; GFX9-NEXT:    s_movk_i32 s2, 0x200
+; GFX9-NEXT:    s_mov_b32 s1, s0
+; GFX9-NEXT:    v_fmac_f32_e32 v1, 0.5, v0
+; GFX9-NEXT:    v_bfrev_b32_e32 v0, 1
+; GFX9-NEXT:    buffer_store_dword v1, v0, s[0:3], 0 offen
+; GFX9-NEXT:    s_waitcnt vmcnt(0)
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: oob_store_with_dead_chain:
+; GFX10:       ; %bb.0:
+; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT:    v_fma_f32 v1, v0, 0.5, 1.0
+; GFX10-NEXT:    s_mov_b32 s4, 0
+; GFX10-NEXT:    s_brev_b32 s7, 12
+; GFX10-NEXT:    s_movk_i32 s6, 0x200
+; GFX10-NEXT:    s_mov_b32 s5, s4
+; GFX10-NEXT:    v_fmac_f32_e32 v0, 0.5, v1
+; GFX10-NEXT:    v_mul_f32_e32 v2, 0x3fb8aa3b, v0
+; GFX10-NEXT:    v_cmp_ngt_f32_e32 vcc_lo, 0xc2ce8ed0, v0
+; GFX10-NEXT:    v_fma_f32 v3, 0x3fb8aa3b, v0, -v2
+; GFX10-NEXT:    v_rndne_f32_e32 v4, v2
+; GFX10-NEXT:    v_fmamk_f32 v3, v0, 0x32a5705f, v3
+; GFX10-NEXT:    v_sub_f32_e32 v2, v2, v4
+; GFX10-NEXT:    v_add_f32_e32 v2, v2, v3
+; GFX10-NEXT:    v_cvt_i32_f32_e32 v3, v4
+; GFX10-NEXT:    v_exp_f32_e32 v2, v2
+; GFX10-NEXT:    v_ldexp_f32 v2, v2, v3
+; GFX10-NEXT:    v_cndmask_b32_e32 v2, 0, v2, vcc_lo
+; GFX10-NEXT:    v_cmp_nlt_f32_e32 vcc_lo, 0x42b17218, v0
+; GFX10-NEXT:    v_cndmask_b32_e32 v0, 0x7f800000, v2, vcc_lo
+; GFX10-NEXT:    v_fmac_f32_e32 v1, 0.5, v0
+; GFX10-NEXT:    v_bfrev_b32_e32 v0, 1
+; GFX10-NEXT:    buffer_store_dword v1, v0, s[4:7], 0 offen
+; GFX10-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: oob_store_with_dead_chain:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_fma_f32 v1, v0, 0.5, 1.0
+; GFX11-NEXT:    s_mov_b32 s0, 0
+; GFX11-NEXT:    s_brev_b32 s3, 12
+; GFX11-NEXT:    s_movk_i32 s2, 0x200
+; GFX11-NEXT:    s_mov_b32 s1, s0
+; GFX11-NEXT:    v_fmac_f32_e32 v0, 0.5, v1
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT:    v_mul_f32_e32 v2, 0x3fb8aa3b, v0
+; GFX11-NEXT:    v_cmp_ngt_f32_e32 vcc_lo, 0xc2ce8ed0, v0
+; GFX11-NEXT:    v_fma_f32 v3, 0x3fb8aa3b, v0, -v2
+; GFX11-NEXT:    v_rndne_f32_e32 v4, v2
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-NEXT:    v_fmamk_f32 v3, v0, 0x32a5705f, v3
+; GFX11-NEXT:    v_sub_f32_e32 v2, v2, v4
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT:    v_add_f32_e32 v2, v2, v3
+; GFX11-NEXT:    v_cvt_i32_f32_e32 v3, v4
+; GFX11-NEXT:    v_exp_f32_e32 v2, v2
+; GFX11-NEXT:    s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT:    v_ldexp_f32 v2, v2, v3
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT:    v_cndmask_b32_e32 v2, 0, v2, vcc_lo
+; GFX11-NEXT:    v_cmp_nlt_f32_e32 vcc_lo, 0x42b17218, v0
+; GFX11-NEXT:    v_cndmask_b32_e32 v0, 0x7f800000, v2, vcc_lo
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT:    v_fmac_f32_e32 v1, 0.5, v0
+; GFX11-NEXT:    v_bfrev_b32_e32 v0, 1
+; GFX11-NEXT:    buffer_store_b32 v1, v0, s[0:3], 0 offen
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX12-LABEL: oob_store_with_dead_chain:
+; GFX12:       ; %bb.0:
+; GFX12-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT:    s_wait_expcnt 0x0
+; GFX12-NEXT:    s_wait_samplecnt 0x0
+; GFX12-NEXT:    s_wait_bvhcnt 0x0
+; GFX12-NEXT:    s_wait_kmcnt 0x0
+; GFX12-NEXT:    v_fma_f32 v1, v0, 0.5, 1.0
+; GFX12-NEXT:    s_mov_b32 s0, 0
+; GFX12-NEXT:    s_brev_b32 s3, 12
+; GFX12-NEXT:    s_movk_i32 s2, 0x200
+; GFX12-NEXT:    s_wait_alu depctr_sa_sdst(0)
+; GFX12-NEXT:    s_mov_b32 s1, s0
+; GFX12-NEXT:    v_fmac_f32_e32 v0, 0.5, v1
+; GFX12-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX12-NEXT:    v_mul_f32_e32 v2, 0x3fb8aa3b, v0
+; GFX12-NEXT:    v_cmp_ngt_f32_e32 vcc_lo, 0xc2ce8ed0, v0
+; GFX12-NEXT:    v_fma_f32 v3, 0x3fb8aa3b, v0, -v2
+; GFX12-NEXT:    v_rndne_f32_e32 v4, v2
+; GFX12-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX12-NEXT:    v_dual_fmamk_f32 v3, v0, 0x32a5705f, v3 :: v_dual_sub_f32 v2, v2, v4
+; GFX12-NEXT:    v_add_f32_e32 v2, v2, v3
+; GFX12-NEXT:    v_cvt_i32_f32_e32 v3, v4
+; GFX12-NEXT:    s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(TRANS32_DEP_1)
+; GFX12-NEXT:    v_exp_f32_e32 v2, v2
+; GFX12-NEXT:    v_ldexp_f32 v2, v2, v3
+; GFX12-NEXT:    s_wait_alu depctr_va_vcc(0)
+; GFX12-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_2)
+; GFX12-NEXT:    v_cndmask_b32_e32 v2, 0, v2, vcc_lo
+; GFX12-NEXT:    v_cmp_nlt_f32_e32 vcc_lo, 0x42b17218, v0
+; GFX12-NEXT:    s_wait_alu depctr_va_vcc(0)
+; GFX12-NEXT:    v_cndmask_b32_e32 v0, 0x7f800000, v2, vcc_lo
+; GFX12-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; GFX12-NEXT:    v_fmac_f32_e32 v1, 0.5, v0
+; GFX12-NEXT:    v_bfrev_b32_e32 v0, 1
+; GFX12-NEXT:    buffer_store_b32 v1, v0, s[0:3], null offen
+; GFX12-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX13-LABEL: oob_store_with_dead_chain:
+; GFX13:       ; %bb.0:
+; GFX13-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX13-NEXT:    s_wait_expcnt 0x0
+; GFX13-NEXT:    s_wait_samplecnt 0x0
+; GFX13-NEXT:    s_wait_bvhcnt 0x0
+; GFX13-NEXT:    s_wait_kmcnt 0x0
+; GFX13-NEXT:    v_fma_f32 v1, v0, 0.5, 1.0
+; GFX13-NEXT:    s_mov_b32 s0, 0
+; GFX13-NEXT:    s_mov_b32 s2, 4
+; GFX13-NEXT:    s_mov_b32 s1, s0
+; GFX13-NEXT:    s_mov_b32 s3, s0
+; GFX13-NEXT:    v_fmac_f32_e32 v0, 0.5, v1
+; GFX13-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX13-NEXT:    v_mul_f32_e32 v2, 0x3fb8aa3b, v0
+; GFX13-NEXT:    v_fma_f32 v3, 0x3fb8aa3b, v0, -v2
+; GFX13-NEXT:    v_rndne_f32_e32 v4, v2
+; GFX13-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX13-NEXT:    v_dual_sub_f32 v2, v2, v4 :: v_dual_fmamk_f32 v3, v0, 0x32a5705f, v3
+; GFX13-NEXT:    v_cmp_ngt_f32_e32 vcc_lo, 0xc2ce8ed0, v0
+; GFX13-NEXT:    v_add_f32_e32 v2, v2, v3
+; GFX13-NEXT:    v_cvt_i32_f32_e32 v3, v4
+; GFX13-NEXT:    s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(TRANS32_DEP_1)
+; GFX13-NEXT:    v_exp_f32_e32 v2, v2
+; GFX13-NEXT:    v_ldexp_f32 v2, v2, v3
+; GFX13-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX13-NEXT:    v_cndmask_b32_e32 v2, 0, v2, vcc_lo
+; GFX13-NEXT:    v_cmp_nlt_f32_e32 vcc_lo, 0x42b17218, v0
+; GFX13-NEXT:    v_cndmask_b32_e32 v0, 0x7f800000, v2, vcc_lo
+; GFX13-NEXT:    s_delay_alu instid0(VALU_DEP_1)
+; GFX13-NEXT:    v_fmac_f32_e32 v1, 0.5, v0
+; GFX13-NEXT:    v_bfrev_b32_e32 v0, 1
+; GFX13-NEXT:    buffer_store_b32 v1, v0, s[0:3], null offen
+; GFX13-NEXT:    s_set_pc_i64 s[30:31]
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc(ptr null, i16 0, i32 512, i32 805306368)
+  %fma1 = call float @llvm.fma.f32(float %x, float 0.5, float 1.0)
+  %fma2 = call float @llvm.fma.f32(float %fma1, float 0.5, float %x)
+  %exp = call float @llvm.exp.f32(float %fma2)
+  %result = call float @llvm.fma.f32(float %exp, float 0.5, float %fma1)
+  %result.i32 = bitcast float %result to i32
+  call void @llvm.amdgcn.raw.ptr.buffer.store.i32(i32 %result.i32, ptr addrspace(8) %rsrc, i32 -2147483648, i32 0, i32 0)
+  ret void
+}
+
+; OOB raw buffer load whose result feeds a chain that is NOT dead.
+define float @oob_load_with_dead_consumer(float %x) {
+; GFX9-LABEL: oob_load_with_dead_consumer:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    s_mov_b32 s0, 0
+; GFX9-NEXT:    s_brev_b32 s3, 12
+; GFX9-NEXT:    s_movk_i32 s2, 0x200
+; GFX9-NEXT:    s_mov_b32 s1, s0
+; GFX9-NEXT:    v_bfrev_b32_e32 v1, 1
+; GFX9-NEXT:    buffer_load_dword v1, v1, s[0:3], 0 offen
+; GFX9-NEXT:    s_waitcnt vmcnt(0)
+; GFX9-NEXT:    v_fmac_f32_e32 v0, 0.5, v1
+; GFX9-NEXT:    v_fmac_f32_e32 v1, 0.5, v0
+; GFX9-NEXT:    v_mov_b32_e32 v0, v1
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: oob_load_with_dead_consumer:
+; GFX10:       ; %bb.0:
+; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT:    v_bfrev_b32_e32 v1, 1
+; GFX10-NEXT:    s_mov_b32 s4, 0
+; GFX10-NEXT:    s_brev_b32 s7, 12
+; GFX10-NEXT:    s_movk_i32 s6, 0x200
+; GFX10-NEXT:    s_mov_b32 s5, s4
+; GFX10-NEXT:    buffer_load_dword v1, v1, s[4:7], 0 offen
+; GFX10-NEXT:    s_waitcnt vmcnt(0)
+; GFX10-NEXT:    v_fmac_f32_e32 v0, 0.5, v1
+; GFX10-NEXT:    v_fmac_f32_e32 v1, 0.5, v0
+; GFX10-NEXT:    v_mov_b32_e32 v0, v1
+; GFX10-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: oob_load_with_dead_consumer:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_bfrev_b32_e32 v1, 1
+; GFX11-NEXT:    s_mov_b32 s0, 0
+; GFX11-NEXT:    s_brev_b32 s3, 12
+; GFX11-NEXT:    s_movk_i32 s2, 0x200
+; GFX11-NEXT:    s_mov_b32 s1, s0
+; GFX11-NEXT:    buffer_load_b32 v1, v1, s[0:3], 0 offen
+; GFX11-NEXT:    s_waitcnt vmcnt(0)
+; GFX11-NEXT:    v_fmac_f32_e32 v0, 0.5, v1
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT:    v_fmac_f32_e32 v1, 0.5, v0
+; GFX11-NEXT:    v_mov_b32_e32 v0, v1
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX12-LABEL: oob_load_with_dead_consumer:
+; GFX12:       ; %bb.0:
+; GFX12-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT:    s_wait_expcnt 0x0
+; GFX12-NEXT:    s_wait_samplecnt 0x0
+; GFX12-NEXT:    s_wait_bvhcnt 0x0
+; GFX12-NEXT:    s_wait_kmcnt 0x0
+; GFX12-NEXT:    v_bfrev_b32_e32 v1, 1
+; GFX12-NEXT:    s_mov_b32 s0, 0
+; GFX12-NEXT:    s_brev_b32 s3, 12
+; GFX12-NEXT:    s_movk_i32 s2, 0x200
+; GFX12-NEXT:    s_wait_alu depctr_sa_sdst(0)
+; GFX12-NEXT:    s_mov_b32 s1, s0
+; GFX12-NEXT:    buffer_load_b32 v1, v1, s[0:3], null offen
+; GFX12-NEXT:    s_wait_loadcnt 0x0
+; GFX12-NEXT:    v_fmac_f32_e32 v0, 0.5, v1
+; GFX12-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX12-NEXT:    v_fmac_f32_e32 v1, 0.5, v0
+; GFX12-NEXT:    v_mov_b32_e32 v0, v1
+; GFX12-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX13-LABEL: oob_load_with_dead_consumer:
+; GFX13:       ; %bb.0:
+; GFX13-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX13-NEXT:    s_wait_expcnt 0x0
+; GFX13-NEXT:    s_wait_samplecnt 0x0
+; GFX13-NEXT:    s_wait_bvhcnt 0x0
+; GFX13-NEXT:    s_wait_kmcnt 0x0
+; GFX13-NEXT:    v_bfrev_b32_e32 v1, 1
+; GFX13-NEXT:    s_mov_b32 s0, 0
+; GFX13-NEXT:    s_mov_b32 s2, 4
+; GFX13-NEXT:    s_mov_b32 s1, s0
+; GFX13-NEXT:    s_mov_b32 s3, s0
+; GFX13-NEXT:    buffer_load_b32 v1, v1, s[0:3], null offen
+; GFX13-NEXT:    s_wait_loadcnt 0x0
+; GFX13-NEXT:    v_fmac_f32_e32 v0, 0.5, v1
+; GFX13-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX13-NEXT:    v_fmac_f32_e32 v1, 0.5, v0
+; GFX13-NEXT:    v_mov_b32_e32 v0, v1
+; GFX13-NEXT:    s_set_pc_i64 s[30:31]
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc(ptr null, i16 0, i32 512, i32 805306368)
+  %loaded = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 -2147483648, i32 0, i32 0)
+  %loaded.f = bitcast i32 %loaded to float
+  %fma1 = call float @llvm.fma.f32(float %loaded.f, float 0.5, float %x)
+  %fma2 = call float @llvm.fma.f32(float %fma1, float 0.5, float %loaded.f)
+  ret float %fma2
+}
+
+; OOB raw buffer load where offset is NOT a literal constant.
+define i32 @oob_load_known_bits(i32 %off_bits) {
+; GFX9-LABEL: oob_load_known_bits:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    s_mov_b32 s0, 0
+; GFX9-NEXT:    s_brev_b32 s3, 12
+; GFX9-NEXT:    s_movk_i32 s2, 0x200
+; GFX9-NEXT:    s_mov_b32 s1, s0
+; GFX9-NEXT:    v_or_b32_e32 v0, 0x8000000, v0
+; GFX9-NEXT:    buffer_load_dword v0, v0, s[0:3], 0 offen
+; GFX9-NEXT:    s_waitcnt vmcnt(0)
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: oob_load_known_bits:
+; GFX10:       ; %bb.0:
+; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT:    v_or_b32_e32 v0, 0x8000000, v0
+; GFX10-NEXT:    s_mov_b32 s4, 0
+; GFX10-NEXT:    s_brev_b32 s7, 12
+; GFX10-NEXT:    s_movk_i32 s6, 0x200
+; GFX10-NEXT:    s_mov_b32 s5, s4
+; GFX10-NEXT:    buffer_load_dword v0, v0, s[4:7], 0 offen
+; GFX10-NEXT:    s_waitcnt vmcnt(0)
+; GFX10-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: oob_load_known_bits:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_or_b32_e32 v0, 0x8000000, v0
+; GFX11-NEXT:    s_mov_b32 s0, 0
+; GFX11-NEXT:    s_brev_b32 s3, 12
+; GFX11-NEXT:    s_movk_i32 s2, 0x200
+; GFX11-NEXT:    s_mov_b32 s1, s0
+; GFX11-NEXT:    buffer_load_b32 v0, v0, s[0:3], 0 offen
+; GFX11-NEXT:    s_waitcnt vmcnt(0)
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX12-LABEL: oob_load_known_bits:
+; GFX12:       ; %bb.0:
+; GFX12-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT:    s_wait_expcnt 0x0
+; GFX12-NEXT:    s_wait_samplecnt 0x0
+; GFX12-NEXT:    s_wait_bvhcnt 0x0
+; GFX12-NEXT:    s_wait_kmcnt 0x0
+; GFX12-NEXT:    v_or_b32_e32 v0, 0x8000000, v0
+; GFX12-NEXT:    s_mov_b32 s0, 0
+; GFX12-NEXT:    s_brev_b32 s3, 12
+; GFX12-NEXT:    s_movk_i32 s2, 0x200
+; GFX12-NEXT:    s_wait_alu depctr_sa_sdst(0)
+; GFX12-NEXT:    s_mov_b32 s1, s0
+; GFX12-NEXT:    buffer_load_b32 v0, v0, s[0:3], null offen
+; GFX12-NEXT:    s_wait_loadcnt 0x0
+; GFX12-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX13-LABEL: oob_load_known_bits:
+; GFX13:       ; %bb.0:
+; GFX13-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX13-NEXT:    s_wait_expcnt 0x0
+; GFX13-NEXT:    s_wait_samplecnt 0x0
+; GFX13-NEXT:    s_wait_bvhcnt 0x0
+; GFX13-NEXT:    s_wait_kmcnt 0x0
+; GFX13-NEXT:    v_or_b32_e32 v0, 0x8000000, v0
+; GFX13-NEXT:    s_mov_b32 s0, 0
+; GFX13-NEXT:    s_mov_b32 s2, 4
+; GFX13-NEXT:    s_mov_b32 s1, s0
+; GFX13-NEXT:    s_mov_b32 s3, s0
+; GFX13-NEXT:    buffer_load_b32 v0, v0, s[0:3], null offen
+; GFX13-NEXT:    s_wait_loadcnt 0x0
+; GFX13-NEXT:    s_set_pc_i64 s[30:31]
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc(ptr null, i16 0, i32 512, i32 805306368)
+  %off = or i32 %off_bits, 134217728
+  %val = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 %off, i32 0, i32 0)
+  ret i32 %val
+}
+
+; Negative test: offset is unknown with no provable bound at all.
+; Must NOT fold.
+define i32 @unknown_offset_no_fold(i32 %off) {
+; GFX9-LABEL: unknown_offset_no_fold:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    s_mov_b32 s0, 0
+; GFX9-NEXT:    s_brev_b32 s3, 12
+; GFX9-NEXT:    s_movk_i32 s2, 0x200
+; GFX9-NEXT:    s_mov_b32 s1, s0
+; GFX9-NEXT:    buffer_load_dword v0, v0, s[0:3], 0 offen
+; GFX9-NEXT:    s_waitcnt vmcnt(0)
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: unknown_offset_no_fold:
+; GFX10:       ; %bb.0:
+; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT:    s_mov_b32 s4, 0
+; GFX10-NEXT:    s_brev_b32 s7, 12
+; GFX10-NEXT:    s_movk_i32 s6, 0x200
+; GFX10-NEXT:    s_mov_b32 s5, s4
+; GFX10-NEXT:    buffer_load_dword v0, v0, s[4:7], 0 offen
+; GFX10-NEXT:    s_waitcnt vmcnt(0)
+; GFX10-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: unknown_offset_no_fold:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    s_mov_b32 s0, 0
+; GFX11-NEXT:    s_brev_b32 s3, 12
+; GFX11-NEXT:    s_movk_i32 s2, 0x200
+; GFX11-NEXT:    s_mov_b32 s1, s0
+; GFX11-NEXT:    buffer_load_b32 v0, v0, s[0:3], 0 offen
+; GFX11-NEXT:    s_waitcnt vmcnt(0)
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX12-LABEL: unknown_offset_no_fold:
+; GFX12:       ; %bb.0:
+; GFX12-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT:    s_wait_expcnt 0x0
+; GFX12-NEXT:    s_wait_samplecnt 0x0
+; GFX12-NEXT:    s_wait_bvhcnt 0x0
+; GFX12-NEXT:    s_wait_kmcnt 0x0
+; GFX12-NEXT:    s_mov_b32 s0, 0
+; GFX12-NEXT:    s_brev_b32 s3, 12
+; GFX12-NEXT:    s_movk_i32 s2, 0x200
+; GFX12-NEXT:    s_wait_alu depctr_sa_sdst(0)
+; GFX12-NEXT:    s_mov_b32 s1, s0
+; GFX12-NEXT:    buffer_load_b32 v0, v0, s[0:3], null offen
+; GFX12-NEXT:    s_wait_loadcnt 0x0
+; GFX12-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX13-LABEL: unknown_offset_no_fold:
+; GFX13:       ; %bb.0:
+; GFX13-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX13-NEXT:    s_wait_expcnt 0x0
+; GFX13-NEXT:    s_wait_samplecnt 0x0
+; GFX13-NEXT:    s_wait_bvhcnt 0x0
+; GFX13-NEXT:    s_wait_kmcnt 0x0
+; GFX13-NEXT:    s_mov_b32 s0, 0
+; GFX13-NEXT:    s_mov_b32 s2, 4
+; GFX13-NEXT:    s_mov_b32 s1, s0
+; GFX13-NEXT:    s_mov_b32 s3, s0
+; GFX13-NEXT:    buffer_load_b32 v0, v0, s[0:3], null offen
+; GFX13-NEXT:    s_wait_loadcnt 0x0
+; GFX13-NEXT:    s_set_pc_i64 s[30:31]
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc(ptr null, i16 0, i32 512, i32 805306368)
+  %val = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 %off, i32 0, i32 0)
+  ret i32 %val
+}
+
+; Negative test: the fold doesn't fire on a genuinely in-bounds access
+define void @in_bounds_no_fold(i32 %val) {
+; GFX9-LABEL: in_bounds_no_fold:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    s_mov_b32 s0, 0
+; GFX9-NEXT:    s_brev_b32 s3, 12
+; GFX9-NEXT:    s_movk_i32 s2, 0x200
+; GFX9-NEXT:    s_mov_b32 s1, s0
+; GFX9-NEXT:    buffer_store_dword v0, off, s[0:3], 0
+; GFX9-NEXT:    s_waitcnt vmcnt(0)
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: in_bounds_no_fold:
+; GFX10:       ; %bb.0:
+; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT:    s_mov_b32 s4, 0
+; GFX10-NEXT:    s_brev_b32 s7, 12
+; GFX10-NEXT:    s_movk_i32 s6, 0x200
+; GFX10-NEXT:    s_mov_b32 s5, s4
+; GFX10-NEXT:    buffer_store_dword v0, off, s[4:7], 0
+; GFX10-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: in_bounds_no_fold:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    s_mov_b32 s0, 0
+; GFX11-NEXT:    s_brev_b32 s3, 12
+; GFX11-NEXT:    s_movk_i32 s2, 0x200
+; GFX11-NEXT:    s_mov_b32 s1, s0
+; GFX11-NEXT:    buffer_store_b32 v0, off, s[0:3], 0
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX12-LABEL: in_bounds_no_fold:
+; GFX12:       ; %bb.0:
+; GFX12-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT:    s_wait_expcnt 0x0
+; GFX12-NEXT:    s_wait_samplecnt 0x0
+; GFX12-NEXT:    s_wait_bvhcnt 0x0
+; GFX12-NEXT:    s_wait_kmcnt 0x0
+; GFX12-NEXT:    s_mov_b32 s0, 0
+; GFX12-NEXT:    s_brev_b32 s3, 12
+; GFX12-NEXT:    s_movk_i32 s2, 0x200
+; GFX12-NEXT:    s_wait_alu depctr_sa_sdst(0)
+; GFX12-NEXT:    s_mov_b32 s1, s0
+; GFX12-NEXT:    buffer_store_b32 v0, off, s[0:3], null
+; GFX12-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX13-LABEL: in_bounds_no_fold:
+; GFX13:       ; %bb.0:
+; GFX13-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX13-NEXT:    s_wait_expcnt 0x0
+; GFX13-NEXT:    s_wait_samplecnt 0x0
+; GFX13-NEXT:    s_wait_bvhcnt 0x0
+; GFX13-NEXT:    s_wait_kmcnt 0x0
+; GFX13-NEXT:    s_mov_b32 s0, 0
+; GFX13-NEXT:    s_mov_b32 s2, 4
+; GFX13-NEXT:    s_mov_b32 s1, s0
+; GFX13-NEXT:    s_mov_b32 s3, s0
+; GFX13-NEXT:    buffer_store_b32 v0, off, s[0:3], null
+; GFX13-NEXT:    s_set_pc_i64 s[30:31]
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc(ptr null, i16 0, i32 512, i32 805306368)
+  call void @llvm.amdgcn.raw.ptr.buffer.store.i32(i32 %val, ptr addrspace(8) %rsrc, i32 0, i32 0, i32 0)
+  ret void
+}
+
+declare void @llvm.amdgcn.raw.ptr.buffer.store.i32(i32, ptr addrspace(8), i32, i32, i32 immarg)
+declare i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8), i32, i32, i32 immarg)
+declare ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc(ptr, i16, i32, i32)
+declare float @llvm.fma.f32(float, float, float)
+declare float @llvm.exp.f32(float)



More information about the llvm-commits mailing list