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

Dark Steve via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 1 04:22:58 PDT 2026


https://github.com/PrasoonMishra updated https://github.com/llvm/llvm-project/pull/227401

>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 1/2] 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)

>From 5c66a54753f00d9c5aa3c2b2ffa9255bcf508b16 Mon Sep 17 00:00:00 2001
From: Dark Steve Jobs <Prasoon.Mishra at amd.com>
Date: Thu, 1 Oct 2026 14:46:51 +0530
Subject: [PATCH 2/2] Removed opt+llc test, copied the instcombine test from
 the patch to precommit.

---
 .../CodeGen/AMDGPU/fold-oob-buffer-access.ll  |  789 ------------
 .../InstCombine/AMDGPU/fold-oob-raw-buffer.ll | 1073 +++++++++++++++++
 2 files changed, 1073 insertions(+), 789 deletions(-)
 delete mode 100644 llvm/test/CodeGen/AMDGPU/fold-oob-buffer-access.ll
 create mode 100644 llvm/test/Transforms/InstCombine/AMDGPU/fold-oob-raw-buffer.ll

diff --git a/llvm/test/CodeGen/AMDGPU/fold-oob-buffer-access.ll b/llvm/test/CodeGen/AMDGPU/fold-oob-buffer-access.ll
deleted file mode 100644
index 37e9dffc47a79..0000000000000
--- a/llvm/test/CodeGen/AMDGPU/fold-oob-buffer-access.ll
+++ /dev/null
@@ -1,789 +0,0 @@
-; 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)
diff --git a/llvm/test/Transforms/InstCombine/AMDGPU/fold-oob-raw-buffer.ll b/llvm/test/Transforms/InstCombine/AMDGPU/fold-oob-raw-buffer.ll
new file mode 100644
index 0000000000000..fd7050d4854fb
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/AMDGPU/fold-oob-raw-buffer.ll
@@ -0,0 +1,1073 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -passes=instcombine -S < %s | FileCheck -check-prefix=GFX9 %s
+; RUN: opt -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1030 -passes=instcombine -S < %s | FileCheck -check-prefix=GFX10 %s
+; RUN: opt -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -passes=instcombine -S < %s | FileCheck -check-prefix=GFX11 %s
+; RUN: opt -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1200 -passes=instcombine -S < %s | FileCheck -check-prefix=GFX12 %s
+; RUN: opt -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1250 -passes=instcombine -S < %s | FileCheck -check-prefix=GFX1250 %s
+; RUN: opt -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1310 -passes=instcombine -S < %s | FileCheck -check-prefix=GFX13 %s
+
+;; --- gfx9 model ---
+
+; Zero stride: SOffset is subtracted from NumRecords before comparing.
+define i32 @gfx9_stride_zero_soffset_subtracted_fold(ptr %p) {
+; GFX9-LABEL: define i32 @gfx9_stride_zero_soffset_subtracted_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0:[0-9]+]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 8, i32 8, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @gfx9_stride_zero_soffset_subtracted_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0:[0-9]+]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 8, i32 8, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @gfx9_stride_zero_soffset_subtracted_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0:[0-9]+]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 8, i32 8, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @gfx9_stride_zero_soffset_subtracted_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0:[0-9]+]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 8, i32 8, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @gfx9_stride_zero_soffset_subtracted_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0:[0-9]+]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 8, i32 8, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @gfx9_stride_zero_soffset_subtracted_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0:[0-9]+]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 8, i32 8, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 16, i32 0)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 8, i32 8, i32 0)
+  ret i32 %v
+}
+
+; Nonzero stride: the bound is NumRecords directly, SOffset is ignored.
+define i32 @gfx9_stride_nonzero_soffset_ignored_fold(ptr %p) {
+; GFX9-LABEL: define i32 @gfx9_stride_nonzero_soffset_ignored_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 4, i64 16, i32 0)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 16, i32 100, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @gfx9_stride_nonzero_soffset_ignored_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 4, i64 16, i32 0)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 16, i32 100, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @gfx9_stride_nonzero_soffset_ignored_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 4, i64 16, i32 0)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 16, i32 100, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @gfx9_stride_nonzero_soffset_ignored_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 4, i64 16, i32 0)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 16, i32 100, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @gfx9_stride_nonzero_soffset_ignored_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 4, i64 16, i32 0)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 16, i32 100, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @gfx9_stride_nonzero_soffset_ignored_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 4, i64 16, i32 0)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 16, i32 100, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 4, i64 16, i32 0)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 16, i32 100, i32 0)
+  ret i32 %v
+}
+
+; add_tid_enable disqualifies the fold even though the access is OOB.
+define i32 @gfx9_addtid_no_fold(ptr %p) {
+; GFX9-LABEL: define i32 @gfx9_addtid_no_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 8388608)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @gfx9_addtid_no_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 8388608)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @gfx9_addtid_no_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 8388608)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @gfx9_addtid_no_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 8388608)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @gfx9_addtid_no_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 8388608)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @gfx9_addtid_no_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 8388608)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 16, i32 8388608)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 32, i32 0, i32 0)
+  ret i32 %v
+}
+
+; The swizzle_enable bit disqualifies the fold.
+define i32 @gfx9_swizzle_no_fold(ptr %p) {
+; GFX9-LABEL: define i32 @gfx9_swizzle_no_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 -32768, i64 16, i32 0)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @gfx9_swizzle_no_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 -32768, i64 16, i32 0)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @gfx9_swizzle_no_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 -32768, i64 16, i32 0)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @gfx9_swizzle_no_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 -32768, i64 16, i32 0)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @gfx9_swizzle_no_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 -32768, i64 16, i32 0)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @gfx9_swizzle_no_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 -32768, i64 16, i32 0)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 -32768, i64 16, i32 0)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 32, i32 0, i32 0)
+  ret i32 %v
+}
+
+; A volatile access is never folded.
+define i32 @gfx9_volatile_no_fold(ptr %p) {
+; GFX9-LABEL: define i32 @gfx9_volatile_no_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 -2147483648)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @gfx9_volatile_no_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 -2147483648)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @gfx9_volatile_no_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 -2147483648)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @gfx9_volatile_no_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 -2147483648)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @gfx9_volatile_no_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 -2147483648)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @gfx9_volatile_no_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 -2147483648)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 16, i32 0)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 32, i32 0, i32 -2147483648)
+  ret i32 %v
+}
+
+; Offset landing exactly on the boundary is already out of bounds.
+define i32 @gfx9_boundary_offset_equals_bound_fold(ptr %p) {
+; GFX9-LABEL: define i32 @gfx9_boundary_offset_equals_bound_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 64, i32 0)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 64, i32 0, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @gfx9_boundary_offset_equals_bound_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 64, i32 0)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 64, i32 0, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @gfx9_boundary_offset_equals_bound_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 64, i32 0)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 64, i32 0, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @gfx9_boundary_offset_equals_bound_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 64, i32 0)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 64, i32 0, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @gfx9_boundary_offset_equals_bound_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 64, i32 0)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 64, i32 0, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @gfx9_boundary_offset_equals_bound_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 64, i32 0)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 64, i32 0, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 64, i32 0)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 64, i32 0, i32 0)
+  ret i32 %v
+}
+
+; One byte inside the boundary must not fold.
+define i32 @gfx9_boundary_offset_below_bound_no_fold(ptr %p) {
+; GFX9-LABEL: define i32 @gfx9_boundary_offset_below_bound_no_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 64, i32 0)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 63, i32 0, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @gfx9_boundary_offset_below_bound_no_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 64, i32 0)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 63, i32 0, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @gfx9_boundary_offset_below_bound_no_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 64, i32 0)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 63, i32 0, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @gfx9_boundary_offset_below_bound_no_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 64, i32 0)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 63, i32 0, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @gfx9_boundary_offset_below_bound_no_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 64, i32 0)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 63, i32 0, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @gfx9_boundary_offset_below_bound_no_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 64, i32 0)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 63, i32 0, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 64, i32 0)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 63, i32 0, i32 0)
+  ret i32 %v
+}
+
+;; --- gfx10/gfx11/gfx12 model ---
+
+; The fold requires OOB_SELECT=3.
+define i32 @gfx10_oobselect3_fold(ptr %p) {
+; GFX9-LABEL: define i32 @gfx10_oobselect3_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @gfx10_oobselect3_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @gfx10_oobselect3_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @gfx10_oobselect3_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @gfx10_oobselect3_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @gfx10_oobselect3_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 16, i32 805306368)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 32, i32 0, i32 0)
+  ret i32 %v
+}
+
+; Any other OOB_SELECT value disqualifies the fold
+define i32 @gfx10_oobselect0_no_fold(ptr %p) {
+; GFX9-LABEL: define i32 @gfx10_oobselect0_no_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @gfx10_oobselect0_no_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @gfx10_oobselect0_no_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @gfx10_oobselect0_no_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @gfx10_oobselect0_no_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @gfx10_oobselect0_no_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 16, i32 0)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 32, i32 0, i32 0)
+  ret i32 %v
+}
+
+; add_tid_enable disqualifies the fold.
+define i32 @gfx10_addtid_no_fold(ptr %p) {
+; GFX9-LABEL: define i32 @gfx10_addtid_no_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 813694976)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @gfx10_addtid_no_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 813694976)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @gfx10_addtid_no_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 813694976)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @gfx10_addtid_no_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 813694976)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @gfx10_addtid_no_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 813694976)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @gfx10_addtid_no_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 813694976)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 16, i32 813694976)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 32, i32 0, i32 0)
+  ret i32 %v
+}
+
+; swizzle_enable=0 on gfx11/gfx12 with out of bound access.
+define i32 @gfx12_swizzle_disabled_fold(ptr %p) {
+; GFX9-LABEL: define i32 @gfx12_swizzle_disabled_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @gfx12_swizzle_disabled_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @gfx12_swizzle_disabled_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @gfx12_swizzle_disabled_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @gfx12_swizzle_disabled_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @gfx12_swizzle_disabled_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 16, i32 805306368)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 32, i32 0, i32 0)
+  ret i32 %v
+}
+
+;; --- gfx1250/gfx13 model ---
+
+; type != 0 (not a real buffer) disqualifies the fold.
+define i32 @gfx1250_nonbuffer_type_no_fold(ptr %p) {
+; GFX9-LABEL: define i32 @gfx1250_nonbuffer_type_no_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 4)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @gfx1250_nonbuffer_type_no_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 4)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @gfx1250_nonbuffer_type_no_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 4)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @gfx1250_nonbuffer_type_no_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 4)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @gfx1250_nonbuffer_type_no_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 4)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @gfx1250_nonbuffer_type_no_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 4)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 16, i32 4)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 32, i32 0, i32 0)
+  ret i32 %v
+}
+
+; A nonzero stride_scale is a conservative bail out.
+; distinct from swizzle_enable, and its actual multiplier is not applied.
+define i32 @gfx1250_stride_scaled_no_fold(ptr %p) {
+; GFX9-LABEL: define i32 @gfx1250_stride_scaled_no_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 16384, i64 1000000, i32 0)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 2000000000, i32 0, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @gfx1250_stride_scaled_no_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 16384, i64 1000000, i32 0)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 2000000000, i32 0, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @gfx1250_stride_scaled_no_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 16384, i64 1000000, i32 0)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 2000000000, i32 0, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @gfx1250_stride_scaled_no_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 16384, i64 1000000, i32 0)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 2000000000, i32 0, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @gfx1250_stride_scaled_no_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 16384, i64 1000000, i32 0)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 2000000000, i32 0, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @gfx1250_stride_scaled_no_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 16384, i64 1000000, i32 0)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 2000000000, i32 0, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 16384, i64 1000000, i32 0)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 2000000000, i32 0, i32 0)
+  ret i32 %v
+}
+
+; NumRecords == 0 means "unbound resource" on this model, the fold must not fire.
+define i32 @gfx1250_numrecords_zero_no_fold(ptr %p) {
+; GFX9-LABEL: define i32 @gfx1250_numrecords_zero_no_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 0, i32 0)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 100, i32 0, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @gfx1250_numrecords_zero_no_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 0, i32 0)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 100, i32 0, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @gfx1250_numrecords_zero_no_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 0, i32 0)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 100, i32 0, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @gfx1250_numrecords_zero_no_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 0, i32 0)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 100, i32 0, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @gfx1250_numrecords_zero_no_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 0, i32 0)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 100, i32 0, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @gfx1250_numrecords_zero_no_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 0, i32 0)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 100, i32 0, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 0, i32 0)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 100, i32 0, i32 0)
+  ret i32 %v
+}
+
+; NumRecords == all-ones means OOB checking is explicitly disabled on this
+; model, so the fold must not fire.
+define i32 @gfx1250_numrecords_allones_no_fold(ptr %p) {
+; GFX9-LABEL: define i32 @gfx1250_numrecords_allones_no_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 35184372088831, i32 0)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 -1, i32 0, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @gfx1250_numrecords_allones_no_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 35184372088831, i32 0)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 -1, i32 0, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @gfx1250_numrecords_allones_no_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 35184372088831, i32 0)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 -1, i32 0, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @gfx1250_numrecords_allones_no_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 35184372088831, i32 0)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 -1, i32 0, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @gfx1250_numrecords_allones_no_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 35184372088831, i32 0)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 -1, i32 0, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @gfx1250_numrecords_allones_no_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 35184372088831, i32 0)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 -1, i32 0, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 35184372088831, i32 0)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 -1, i32 0, i32 0)
+  ret i32 %v
+}
+
+; OOB_SELECT=0 folds via the plain NumRecords check.
+define i32 @gfx1250_oobselect0_fold(ptr %p) {
+; GFX9-LABEL: define i32 @gfx1250_oobselect0_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @gfx1250_oobselect0_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @gfx1250_oobselect0_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @gfx1250_oobselect0_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @gfx1250_oobselect0_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @gfx1250_oobselect0_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 16, i32 0)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 32, i32 0, i32 0)
+  ret i32 %v
+}
+
+; OOB_SELECT=1 with stride=0 makes every access OOB
+define i32 @gfx1250_oobselect1_stride0_always_oob(ptr %p) {
+; GFX9-LABEL: define i32 @gfx1250_oobselect1_stride0_always_oob(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 1000000, i32 2)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 0, i32 0, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @gfx1250_oobselect1_stride0_always_oob(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 1000000, i32 2)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 0, i32 0, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @gfx1250_oobselect1_stride0_always_oob(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 1000000, i32 2)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 0, i32 0, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @gfx1250_oobselect1_stride0_always_oob(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 1000000, i32 2)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 0, i32 0, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @gfx1250_oobselect1_stride0_always_oob(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 1000000, i32 2)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 0, i32 0, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @gfx1250_oobselect1_stride0_always_oob(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 1000000, i32 2)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 0, i32 0, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 1000000, i32 2)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 0, i32 0, i32 0)
+  ret i32 %v
+}
+
+; SOffset is added directly into the address used for the bound check, so
+; it alone can push an access out of bounds.
+define i32 @gfx1250_soffset_alone_sufficient_fold(ptr %p) {
+; GFX9-LABEL: define i32 @gfx1250_soffset_alone_sufficient_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 0, i32 32, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @gfx1250_soffset_alone_sufficient_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 0, i32 32, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @gfx1250_soffset_alone_sufficient_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 0, i32 32, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @gfx1250_soffset_alone_sufficient_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 0, i32 32, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @gfx1250_soffset_alone_sufficient_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 0, i32 32, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @gfx1250_soffset_alone_sufficient_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 0)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 0, i32 32, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 16, i32 0)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 0, i32 32, i32 0)
+  ret i32 %v
+}
+
+;; --- computeKnownBits-based folding (model-independent; gfx10 used here) ---
+
+; The offset is not a literal constant but it's bound can be computed.
+define i32 @known_bits_offset_provable_fold(ptr %p, i32 %x) {
+; GFX9-LABEL: define i32 @known_bits_offset_provable_fold(
+; GFX9-SAME: ptr [[P:%.*]], i32 [[X:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX9-NEXT:    [[OFF:%.*]] = or i32 [[X]], 2048
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 [[OFF]], i32 0, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @known_bits_offset_provable_fold(
+; GFX10-SAME: ptr [[P:%.*]], i32 [[X:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX10-NEXT:    [[OFF:%.*]] = or i32 [[X]], 2048
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 [[OFF]], i32 0, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @known_bits_offset_provable_fold(
+; GFX11-SAME: ptr [[P:%.*]], i32 [[X:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX11-NEXT:    [[OFF:%.*]] = or i32 [[X]], 2048
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 [[OFF]], i32 0, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @known_bits_offset_provable_fold(
+; GFX12-SAME: ptr [[P:%.*]], i32 [[X:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX12-NEXT:    [[OFF:%.*]] = or i32 [[X]], 2048
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 [[OFF]], i32 0, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @known_bits_offset_provable_fold(
+; GFX1250-SAME: ptr [[P:%.*]], i32 [[X:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX1250-NEXT:    [[OFF:%.*]] = or i32 [[X]], 2048
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 [[OFF]], i32 0, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @known_bits_offset_provable_fold(
+; GFX13-SAME: ptr [[P:%.*]], i32 [[X:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX13-NEXT:    [[OFF:%.*]] = or i32 [[X]], 2048
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 [[OFF]], i32 0, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 16, i32 805306368)
+  %off = or i32 %x, 2048
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 %off, i32 0, i32 0)
+  ret i32 %v
+}
+
+; The offset having no provable bound at all, so the fold must decline.
+define i32 @known_bits_offset_unprovable_no_fold(ptr %p, i32 %x) {
+; GFX9-LABEL: define i32 @known_bits_offset_unprovable_no_fold(
+; GFX9-SAME: ptr [[P:%.*]], i32 [[X:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 [[X]], i32 0, i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @known_bits_offset_unprovable_no_fold(
+; GFX10-SAME: ptr [[P:%.*]], i32 [[X:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 [[X]], i32 0, i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @known_bits_offset_unprovable_no_fold(
+; GFX11-SAME: ptr [[P:%.*]], i32 [[X:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 [[X]], i32 0, i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @known_bits_offset_unprovable_no_fold(
+; GFX12-SAME: ptr [[P:%.*]], i32 [[X:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 [[X]], i32 0, i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @known_bits_offset_unprovable_no_fold(
+; GFX1250-SAME: ptr [[P:%.*]], i32 [[X:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 [[X]], i32 0, i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @known_bits_offset_unprovable_no_fold(
+; GFX13-SAME: ptr [[P:%.*]], i32 [[X:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 [[X]], i32 0, i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 16, i32 805306368)
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 %x, i32 0, i32 0)
+  ret i32 %v
+}
+
+; Neither offset nor soffset alone is sufficient, and the fold declines.
+define i32 @known_bits_neither_sufficient_no_fold(ptr %p, i32 %x, i32 %y) {
+; GFX9-LABEL: define i32 @known_bits_neither_sufficient_no_fold(
+; GFX9-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX9-NEXT:    [[SOFF:%.*]] = or i32 [[Y]], 4
+; GFX9-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 [[X]], i32 [[SOFF]], i32 0)
+; GFX9-NEXT:    ret i32 [[V]]
+;
+; GFX10-LABEL: define i32 @known_bits_neither_sufficient_no_fold(
+; GFX10-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX10-NEXT:    [[SOFF:%.*]] = or i32 [[Y]], 4
+; GFX10-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 [[X]], i32 [[SOFF]], i32 0)
+; GFX10-NEXT:    ret i32 [[V]]
+;
+; GFX11-LABEL: define i32 @known_bits_neither_sufficient_no_fold(
+; GFX11-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX11-NEXT:    [[SOFF:%.*]] = or i32 [[Y]], 4
+; GFX11-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 [[X]], i32 [[SOFF]], i32 0)
+; GFX11-NEXT:    ret i32 [[V]]
+;
+; GFX12-LABEL: define i32 @known_bits_neither_sufficient_no_fold(
+; GFX12-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX12-NEXT:    [[SOFF:%.*]] = or i32 [[Y]], 4
+; GFX12-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 [[X]], i32 [[SOFF]], i32 0)
+; GFX12-NEXT:    ret i32 [[V]]
+;
+; GFX1250-LABEL: define i32 @known_bits_neither_sufficient_no_fold(
+; GFX1250-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX1250-NEXT:    [[SOFF:%.*]] = or i32 [[Y]], 4
+; GFX1250-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 [[X]], i32 [[SOFF]], i32 0)
+; GFX1250-NEXT:    ret i32 [[V]]
+;
+; GFX13-LABEL: define i32 @known_bits_neither_sufficient_no_fold(
+; GFX13-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX13-NEXT:    [[SOFF:%.*]] = or i32 [[Y]], 4
+; GFX13-NEXT:    [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) [[RSRC]], i32 [[X]], i32 [[SOFF]], i32 0)
+; GFX13-NEXT:    ret i32 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 16, i32 805306368)
+  %soff = or i32 %y, 4
+  %v = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) %rsrc, i32 %x, i32 %soff, i32 0)
+  ret i32 %v
+}
+
+;; --- the fold does not depend on payload width ---
+
+; A wide vector load is replaced with a vector of zeros, not a scalar.
+define <4 x i32> @wide_vector_load_fold(ptr %p) {
+; GFX9-LABEL: define <4 x i32> @wide_vector_load_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX9-NEXT:    [[V:%.*]] = call <4 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v4i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX9-NEXT:    ret <4 x i32> [[V]]
+;
+; GFX10-LABEL: define <4 x i32> @wide_vector_load_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX10-NEXT:    [[V:%.*]] = call <4 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v4i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX10-NEXT:    ret <4 x i32> [[V]]
+;
+; GFX11-LABEL: define <4 x i32> @wide_vector_load_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX11-NEXT:    [[V:%.*]] = call <4 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v4i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX11-NEXT:    ret <4 x i32> [[V]]
+;
+; GFX12-LABEL: define <4 x i32> @wide_vector_load_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX12-NEXT:    [[V:%.*]] = call <4 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v4i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX12-NEXT:    ret <4 x i32> [[V]]
+;
+; GFX1250-LABEL: define <4 x i32> @wide_vector_load_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX1250-NEXT:    [[V:%.*]] = call <4 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v4i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX1250-NEXT:    ret <4 x i32> [[V]]
+;
+; GFX13-LABEL: define <4 x i32> @wide_vector_load_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX13-NEXT:    [[V:%.*]] = call <4 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v4i32(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX13-NEXT:    ret <4 x i32> [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 16, i32 805306368)
+  %v = call <4 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v4i32(ptr addrspace(8) %rsrc, i32 32, i32 0, i32 0)
+  ret <4 x i32> %v
+}
+
+; A wide scalar load folds the same way as a plain i32 one.
+define i64 @wide_i64_load_fold(ptr %p) {
+; GFX9-LABEL: define i64 @wide_i64_load_fold(
+; GFX9-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX9-NEXT:    [[V:%.*]] = call i64 @llvm.amdgcn.raw.ptr.buffer.load.i64(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX9-NEXT:    ret i64 [[V]]
+;
+; GFX10-LABEL: define i64 @wide_i64_load_fold(
+; GFX10-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX10-NEXT:    [[V:%.*]] = call i64 @llvm.amdgcn.raw.ptr.buffer.load.i64(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX10-NEXT:    ret i64 [[V]]
+;
+; GFX11-LABEL: define i64 @wide_i64_load_fold(
+; GFX11-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX11-NEXT:    [[V:%.*]] = call i64 @llvm.amdgcn.raw.ptr.buffer.load.i64(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX11-NEXT:    ret i64 [[V]]
+;
+; GFX12-LABEL: define i64 @wide_i64_load_fold(
+; GFX12-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX12-NEXT:    [[V:%.*]] = call i64 @llvm.amdgcn.raw.ptr.buffer.load.i64(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX12-NEXT:    ret i64 [[V]]
+;
+; GFX1250-LABEL: define i64 @wide_i64_load_fold(
+; GFX1250-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX1250-NEXT:    [[V:%.*]] = call i64 @llvm.amdgcn.raw.ptr.buffer.load.i64(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX1250-NEXT:    ret i64 [[V]]
+;
+; GFX13-LABEL: define i64 @wide_i64_load_fold(
+; GFX13-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX13-NEXT:    [[V:%.*]] = call i64 @llvm.amdgcn.raw.ptr.buffer.load.i64(ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX13-NEXT:    ret i64 [[V]]
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 16, i32 805306368)
+  %v = call i64 @llvm.amdgcn.raw.ptr.buffer.load.i64(ptr addrspace(8) %rsrc, i32 32, i32 0, i32 0)
+  ret i64 %v
+}
+
+; A wide store is erased outright, same as a narrow one.
+define void @wide_vector_store_erased(ptr %p, <4 x i32> %val) {
+; GFX9-LABEL: define void @wide_vector_store_erased(
+; GFX9-SAME: ptr [[P:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR0]] {
+; GFX9-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX9-NEXT:    call void @llvm.amdgcn.raw.ptr.buffer.store.v4i32(<4 x i32> [[VAL]], ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX9-NEXT:    ret void
+;
+; GFX10-LABEL: define void @wide_vector_store_erased(
+; GFX10-SAME: ptr [[P:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR0]] {
+; GFX10-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX10-NEXT:    call void @llvm.amdgcn.raw.ptr.buffer.store.v4i32(<4 x i32> [[VAL]], ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX10-NEXT:    ret void
+;
+; GFX11-LABEL: define void @wide_vector_store_erased(
+; GFX11-SAME: ptr [[P:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR0]] {
+; GFX11-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX11-NEXT:    call void @llvm.amdgcn.raw.ptr.buffer.store.v4i32(<4 x i32> [[VAL]], ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX11-NEXT:    ret void
+;
+; GFX12-LABEL: define void @wide_vector_store_erased(
+; GFX12-SAME: ptr [[P:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR0]] {
+; GFX12-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX12-NEXT:    call void @llvm.amdgcn.raw.ptr.buffer.store.v4i32(<4 x i32> [[VAL]], ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX12-NEXT:    ret void
+;
+; GFX1250-LABEL: define void @wide_vector_store_erased(
+; GFX1250-SAME: ptr [[P:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR0]] {
+; GFX1250-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX1250-NEXT:    call void @llvm.amdgcn.raw.ptr.buffer.store.v4i32(<4 x i32> [[VAL]], ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX1250-NEXT:    ret void
+;
+; GFX13-LABEL: define void @wide_vector_store_erased(
+; GFX13-SAME: ptr [[P:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR0]] {
+; GFX13-NEXT:    [[RSRC:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr [[P]], i16 0, i64 16, i32 805306368)
+; GFX13-NEXT:    call void @llvm.amdgcn.raw.ptr.buffer.store.v4i32(<4 x i32> [[VAL]], ptr addrspace(8) [[RSRC]], i32 32, i32 0, i32 0)
+; GFX13-NEXT:    ret void
+;
+  %rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 16, i32 805306368)
+  call void @llvm.amdgcn.raw.ptr.buffer.store.v4i32(<4 x i32> %val, ptr addrspace(8) %rsrc, i32 32, i32 0, i32 0)
+  ret void
+}
+
+declare i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8), i32, i32, i32 immarg)
+declare i64 @llvm.amdgcn.raw.ptr.buffer.load.i64(ptr addrspace(8), i32, i32, i32 immarg)
+declare <4 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v4i32(ptr addrspace(8), i32, i32, i32 immarg)
+declare void @llvm.amdgcn.raw.ptr.buffer.store.i32(i32, ptr addrspace(8), i32, i32, i32 immarg)
+declare void @llvm.amdgcn.raw.ptr.buffer.store.v4i32(<4 x i32>, ptr addrspace(8), i32, i32, i32 immarg)
+declare ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr, i16, i64, i32)



More information about the llvm-commits mailing list