[llvm] [AMDGPU] Fuse dword load + sign/zero-extension into subword load (PR #219019)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 26 14:55:14 PDT 2026
https://github.com/LU-JOHN updated https://github.com/llvm/llvm-project/pull/219019
>From 1d77b7a6d78aefcf783fdd7c621477ae40217917 Mon Sep 17 00:00:00 2001
From: John Lu <John.Lu at amd.com>
Date: Wed, 26 Aug 2026 10:19:39 -0500
Subject: [PATCH 1/2] Commit current results for new testcases
Signed-off-by: John Lu <John.Lu at amd.com>
---
.../CodeGen/AMDGPU/scalar-subword-loads.ll | 264 +++++++++
.../AMDGPU/si-load-opt-scalar-subword.mir | 561 ++++++++++++++++++
2 files changed, 825 insertions(+)
create mode 100644 llvm/test/CodeGen/AMDGPU/scalar-subword-loads.ll
create mode 100644 llvm/test/CodeGen/AMDGPU/si-load-opt-scalar-subword.mir
diff --git a/llvm/test/CodeGen/AMDGPU/scalar-subword-loads.ll b/llvm/test/CodeGen/AMDGPU/scalar-subword-loads.ll
new file mode 100644
index 0000000000000..e39d12963633b
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/scalar-subword-loads.ll
@@ -0,0 +1,264 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; Test all scalar subword load optimization variants
+; RUN: llc -mtriple=amdgcn -mcpu=gfx1250 < %s | FileCheck %s
+
+declare i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32>, i32, i32 immarg)
+
+;===----------------------------------------------------------------------===;
+; S_LOAD variants (address space 4)
+;===----------------------------------------------------------------------===;
+
+define amdgpu_kernel void @s_load_u8(ptr addrspace(1) %out) {
+; CHECK-LABEL: s_load_u8:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_mov_b64 s[64:65], 0
+; CHECK-NEXT: v_nop
+; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
+; CHECK-NEXT: s_mov_b64 s[0:1], 16
+; CHECK-NEXT: s_load_b32 s6, s[0:1], 0x0 nv
+; CHECK-NEXT: s_load_b64 s[2:3], s[4:5], 0x24 nv
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: s_and_b32 s0, s6, 0xff
+; CHECK-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
+; CHECK-NEXT: v_dual_mov_b32 v0, 0 :: v_dual_mov_b32 v1, s0
+; CHECK-NEXT: global_store_b32 v0, v1, s[2:3]
+; CHECK-NEXT: s_endpgm
+ %ptr = inttoptr i64 16 to ptr addrspace(4)
+ %val = load i32, ptr addrspace(4) %ptr, align 4
+ %masked = and i32 %val, 255
+ store i32 %masked, ptr addrspace(1) %out
+ ret void
+}
+
+define amdgpu_kernel void @s_load_u16(ptr addrspace(1) %out) {
+; CHECK-LABEL: s_load_u16:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_mov_b64 s[64:65], 0
+; CHECK-NEXT: v_nop
+; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
+; CHECK-NEXT: s_mov_b64 s[0:1], 16
+; CHECK-NEXT: s_load_b32 s6, s[0:1], 0x0 nv
+; CHECK-NEXT: s_load_b64 s[2:3], s[4:5], 0x24 nv
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: s_and_b32 s0, s6, 0xffff
+; CHECK-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
+; CHECK-NEXT: v_dual_mov_b32 v0, 0 :: v_dual_mov_b32 v1, s0
+; CHECK-NEXT: global_store_b32 v0, v1, s[2:3]
+; CHECK-NEXT: s_endpgm
+ %ptr = inttoptr i64 16 to ptr addrspace(4)
+ %val = load i32, ptr addrspace(4) %ptr, align 4
+ %masked = and i32 %val, 65535
+ store i32 %masked, ptr addrspace(1) %out
+ ret void
+}
+
+define amdgpu_kernel void @s_load_i8(ptr addrspace(1) %out) {
+; CHECK-LABEL: s_load_i8:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_mov_b64 s[64:65], 0
+; CHECK-NEXT: v_nop
+; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
+; CHECK-NEXT: s_mov_b64 s[0:1], 16
+; CHECK-NEXT: s_load_i8 s6, s[0:1], 0x0 nv
+; CHECK-NEXT: s_load_b64 s[2:3], s[4:5], 0x24 nv
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: v_dual_mov_b32 v0, 0 :: v_dual_mov_b32 v1, s6
+; CHECK-NEXT: global_store_b32 v0, v1, s[2:3]
+; CHECK-NEXT: s_endpgm
+ %ptr = inttoptr i64 16 to ptr addrspace(4)
+ %val8 = load i8, ptr addrspace(4) %ptr, align 1
+ %ext = sext i8 %val8 to i32
+ store i32 %ext, ptr addrspace(1) %out
+ ret void
+}
+
+define amdgpu_kernel void @s_load_i16(ptr addrspace(1) %out) {
+; CHECK-LABEL: s_load_i16:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_mov_b64 s[64:65], 0
+; CHECK-NEXT: v_nop
+; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
+; CHECK-NEXT: s_mov_b64 s[0:1], 16
+; CHECK-NEXT: s_load_i16 s6, s[0:1], 0x0 nv
+; CHECK-NEXT: s_load_b64 s[2:3], s[4:5], 0x24 nv
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: v_dual_mov_b32 v0, 0 :: v_dual_mov_b32 v1, s6
+; CHECK-NEXT: global_store_b32 v0, v1, s[2:3]
+; CHECK-NEXT: s_endpgm
+ %ptr = inttoptr i64 16 to ptr addrspace(4)
+ %val16 = load i16, ptr addrspace(4) %ptr, align 2
+ %ext = sext i16 %val16 to i32
+ store i32 %ext, ptr addrspace(1) %out
+ ret void
+}
+
+;===----------------------------------------------------------------------===;
+; S_BUFFER_LOAD variants with immediate offsets
+;===----------------------------------------------------------------------===;
+
+define amdgpu_cs i32 @s_buffer_load_u8_imm(<4 x i32> inreg %buf) {
+; CHECK-LABEL: s_buffer_load_u8_imm:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_mov_b64 s[64:65], 0
+; CHECK-NEXT: v_nop
+; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
+; CHECK-NEXT: s_buffer_load_b32 s0, s[0:3], 0x10 nv
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: s_and_b32 s0, s0, 0xff
+; CHECK-NEXT: ; return to shader part epilog
+ %val = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %buf, i32 16, i32 0)
+ %masked = and i32 %val, 255
+ ret i32 %masked
+}
+
+define amdgpu_cs i32 @s_buffer_load_u16_imm(<4 x i32> inreg %buf) {
+; CHECK-LABEL: s_buffer_load_u16_imm:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_mov_b64 s[64:65], 0
+; CHECK-NEXT: v_nop
+; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
+; CHECK-NEXT: s_buffer_load_b32 s0, s[0:3], 0x10 nv
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: s_and_b32 s0, s0, 0xffff
+; CHECK-NEXT: ; return to shader part epilog
+ %val = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %buf, i32 16, i32 0)
+ %masked = and i32 %val, 65535
+ ret i32 %masked
+}
+
+define amdgpu_cs i32 @s_buffer_load_i8_imm(<4 x i32> inreg %buf) {
+; CHECK-LABEL: s_buffer_load_i8_imm:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_mov_b64 s[64:65], 0
+; CHECK-NEXT: v_nop
+; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
+; CHECK-NEXT: s_buffer_load_b32 s0, s[0:3], 0x10 nv
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: s_sext_i32_i8 s0, s0
+; CHECK-NEXT: ; return to shader part epilog
+ %val = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %buf, i32 16, i32 0)
+ %trunc = trunc i32 %val to i8
+ %ext = sext i8 %trunc to i32
+ ret i32 %ext
+}
+
+define amdgpu_cs i32 @s_buffer_load_i16_imm(<4 x i32> inreg %buf) {
+; CHECK-LABEL: s_buffer_load_i16_imm:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_mov_b64 s[64:65], 0
+; CHECK-NEXT: v_nop
+; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
+; CHECK-NEXT: s_buffer_load_b32 s0, s[0:3], 0x10 nv
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: s_sext_i32_i16 s0, s0
+; CHECK-NEXT: ; return to shader part epilog
+ %val = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %buf, i32 16, i32 0)
+ %trunc = trunc i32 %val to i16
+ %ext = sext i16 %trunc to i32
+ ret i32 %ext
+}
+
+;===----------------------------------------------------------------------===;
+; S_BUFFER_LOAD variants with SGPR offsets (SGPR_IMM mode)
+;===----------------------------------------------------------------------===;
+
+define amdgpu_cs i32 @s_buffer_load_u8_sgpr(<4 x i32> inreg %buf, i32 inreg %offset) {
+; CHECK-LABEL: s_buffer_load_u8_sgpr:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_mov_b64 s[64:65], 0
+; CHECK-NEXT: v_nop
+; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
+; CHECK-NEXT: s_buffer_load_b32 s0, s[0:3], s4 offset:0x0 nv
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: s_and_b32 s0, s0, 0xff
+; CHECK-NEXT: ; return to shader part epilog
+ %val = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %buf, i32 %offset, i32 0)
+ %masked = and i32 %val, 255
+ ret i32 %masked
+}
+
+define amdgpu_cs i32 @s_buffer_load_u16_sgpr(<4 x i32> inreg %buf, i32 inreg %offset) {
+; CHECK-LABEL: s_buffer_load_u16_sgpr:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_mov_b64 s[64:65], 0
+; CHECK-NEXT: v_nop
+; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
+; CHECK-NEXT: s_buffer_load_b32 s0, s[0:3], s4 offset:0x0 nv
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: s_and_b32 s0, s0, 0xffff
+; CHECK-NEXT: ; return to shader part epilog
+ %val = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %buf, i32 %offset, i32 0)
+ %masked = and i32 %val, 65535
+ ret i32 %masked
+}
+
+define amdgpu_cs i32 @s_buffer_load_i8_sgpr(<4 x i32> inreg %buf, i32 inreg %offset) {
+; CHECK-LABEL: s_buffer_load_i8_sgpr:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_mov_b64 s[64:65], 0
+; CHECK-NEXT: v_nop
+; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
+; CHECK-NEXT: s_buffer_load_b32 s0, s[0:3], s4 offset:0x0 nv
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: s_sext_i32_i8 s0, s0
+; CHECK-NEXT: ; return to shader part epilog
+ %val = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %buf, i32 %offset, i32 0)
+ %trunc = trunc i32 %val to i8
+ %ext = sext i8 %trunc to i32
+ ret i32 %ext
+}
+
+define amdgpu_cs i32 @s_buffer_load_i16_sgpr(<4 x i32> inreg %buf, i32 inreg %offset) {
+; CHECK-LABEL: s_buffer_load_i16_sgpr:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_mov_b64 s[64:65], 0
+; CHECK-NEXT: v_nop
+; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
+; CHECK-NEXT: s_buffer_load_b32 s0, s[0:3], s4 offset:0x0 nv
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: s_sext_i32_i16 s0, s0
+; CHECK-NEXT: ; return to shader part epilog
+ %val = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %buf, i32 %offset, i32 0)
+ %trunc = trunc i32 %val to i16
+ %ext = sext i16 %trunc to i32
+ ret i32 %ext
+}
+
+;===----------------------------------------------------------------------===;
+; Negative tests
+;===----------------------------------------------------------------------===;
+
+define amdgpu_kernel void @no_opt_wrong_mask(ptr addrspace(1) %out) {
+; CHECK-LABEL: no_opt_wrong_mask:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_mov_b64 s[64:65], 0
+; CHECK-NEXT: v_nop
+; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
+; CHECK-NEXT: s_mov_b64 s[0:1], 16
+; CHECK-NEXT: s_load_b32 s6, s[0:1], 0x0 nv
+; CHECK-NEXT: s_load_b64 s[2:3], s[4:5], 0x24 nv
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: s_and_b32 s0, s6, 0x7f
+; CHECK-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
+; CHECK-NEXT: v_dual_mov_b32 v0, 0 :: v_dual_mov_b32 v1, s0
+; CHECK-NEXT: global_store_b32 v0, v1, s[2:3]
+; CHECK-NEXT: s_endpgm
+ %ptr = inttoptr i64 16 to ptr addrspace(4)
+ %val = load i32, ptr addrspace(4) %ptr, align 4
+ %masked = and i32 %val, 127
+ store i32 %masked, ptr addrspace(1) %out
+ ret void
+}
diff --git a/llvm/test/CodeGen/AMDGPU/si-load-opt-scalar-subword.mir b/llvm/test/CodeGen/AMDGPU/si-load-opt-scalar-subword.mir
new file mode 100644
index 0000000000000..c65dc6cb32764
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/si-load-opt-scalar-subword.mir
@@ -0,0 +1,561 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -mtriple=amdgcn -mcpu=gfx1250 -run-pass=si-load-store-opt %s -o - | FileCheck %s
+
+# Test scalar subword load optimization at MIR level
+# Tests all combinations of: {u8, u16, i8, i16} × {IMM, SGPR, SGPR_IMM} addressing modes
+# for both S_LOAD and S_BUFFER_LOAD variants
+
+---
+name: s_load_u8_imm
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1
+ ; CHECK-LABEL: name: s_load_u8_imm
+ ; CHECK: liveins: $sgpr0, $sgpr1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1
+ ; CHECK-NEXT: [[S_LOAD_DWORD_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_LOAD_DWORD_IMM]], 255, implicit-def $scc
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %2:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
+ %3:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM %2, 16, 0 :: (load (s32))
+ %4:sreg_32 = S_AND_B32 %3, 255, implicit-def $scc
+ S_ENDPGM 0, implicit %4
+...
+
+---
+name: s_load_u16_imm
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1
+ ; CHECK-LABEL: name: s_load_u16_imm
+ ; CHECK: liveins: $sgpr0, $sgpr1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1
+ ; CHECK-NEXT: [[S_LOAD_DWORD_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_LOAD_DWORD_IMM]], 65535, implicit-def $scc
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %2:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
+ %3:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM %2, 16, 0 :: (load (s32))
+ %4:sreg_32 = S_AND_B32 %3, 65535, implicit-def $scc
+ S_ENDPGM 0, implicit %4
+...
+
+---
+name: s_load_i8_imm
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1
+ ; CHECK-LABEL: name: s_load_i8_imm
+ ; CHECK: liveins: $sgpr0, $sgpr1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1
+ ; CHECK-NEXT: [[S_LOAD_DWORD_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_SEXT_I32_I8_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I8 [[S_LOAD_DWORD_IMM]]
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I8_]]
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %2:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
+ %3:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM %2, 16, 0 :: (load (s32))
+ %4:sreg_32 = S_SEXT_I32_I8 %3
+ S_ENDPGM 0, implicit %4
+...
+
+---
+name: s_load_i16_imm
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1
+ ; CHECK-LABEL: name: s_load_i16_imm
+ ; CHECK: liveins: $sgpr0, $sgpr1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1
+ ; CHECK-NEXT: [[S_LOAD_DWORD_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_SEXT_I32_I16_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I16 [[S_LOAD_DWORD_IMM]]
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I16_]]
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %2:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
+ %3:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM %2, 16, 0 :: (load (s32))
+ %4:sreg_32 = S_SEXT_I32_I16 %3
+ S_ENDPGM 0, implicit %4
+...
+
+---
+name: s_load_u8_sgpr
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1, $sgpr2
+ ; CHECK-LABEL: name: s_load_u8_sgpr
+ ; CHECK: liveins: $sgpr0, $sgpr1, $sgpr2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr2
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1
+ ; CHECK-NEXT: [[S_LOAD_DWORD_SGPR:%[0-9]+]]:sreg_32_xm0_xexec = S_LOAD_DWORD_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_LOAD_DWORD_SGPR]], 255, implicit-def $scc
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ %2:sgpr_32 = COPY $sgpr2
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %3:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
+ %4:sreg_32_xm0_xexec = S_LOAD_DWORD_SGPR %3, %2, 0 :: (load (s32))
+ %5:sreg_32 = S_AND_B32 %4, 255, implicit-def $scc
+ S_ENDPGM 0, implicit %5
+...
+
+---
+name: s_load_u16_sgpr
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1, $sgpr2
+ ; CHECK-LABEL: name: s_load_u16_sgpr
+ ; CHECK: liveins: $sgpr0, $sgpr1, $sgpr2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr2
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1
+ ; CHECK-NEXT: [[S_LOAD_DWORD_SGPR:%[0-9]+]]:sreg_32_xm0_xexec = S_LOAD_DWORD_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_LOAD_DWORD_SGPR]], 65535, implicit-def $scc
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ %2:sgpr_32 = COPY $sgpr2
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %3:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
+ %4:sreg_32_xm0_xexec = S_LOAD_DWORD_SGPR %3, %2, 0 :: (load (s32))
+ %5:sreg_32 = S_AND_B32 %4, 65535, implicit-def $scc
+ S_ENDPGM 0, implicit %5
+...
+
+---
+name: s_load_i8_sgpr
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1, $sgpr2
+ ; CHECK-LABEL: name: s_load_i8_sgpr
+ ; CHECK: liveins: $sgpr0, $sgpr1, $sgpr2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr2
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1
+ ; CHECK-NEXT: [[S_LOAD_DWORD_SGPR:%[0-9]+]]:sreg_32_xm0_xexec = S_LOAD_DWORD_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_SEXT_I32_I8_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I8 [[S_LOAD_DWORD_SGPR]]
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I8_]]
+ %2:sgpr_32 = COPY $sgpr2
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %3:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
+ %4:sreg_32_xm0_xexec = S_LOAD_DWORD_SGPR %3, %2, 0 :: (load (s32))
+ %5:sreg_32 = S_SEXT_I32_I8 %4
+ S_ENDPGM 0, implicit %5
+...
+
+---
+name: s_load_i16_sgpr
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1, $sgpr2
+ ; CHECK-LABEL: name: s_load_i16_sgpr
+ ; CHECK: liveins: $sgpr0, $sgpr1, $sgpr2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr2
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1
+ ; CHECK-NEXT: [[S_LOAD_DWORD_SGPR:%[0-9]+]]:sreg_32_xm0_xexec = S_LOAD_DWORD_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_SEXT_I32_I16_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I16 [[S_LOAD_DWORD_SGPR]]
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I16_]]
+ %2:sgpr_32 = COPY $sgpr2
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %3:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
+ %4:sreg_32_xm0_xexec = S_LOAD_DWORD_SGPR %3, %2, 0 :: (load (s32))
+ %5:sreg_32 = S_SEXT_I32_I16 %4
+ S_ENDPGM 0, implicit %5
+...
+
+---
+name: s_buffer_load_u8_imm
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3
+ ; CHECK-LABEL: name: s_buffer_load_u8_imm
+ ; CHECK: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr3
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr2
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY1]], %subreg.sub2, [[COPY]], %subreg.sub3
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_BUFFER_LOAD_DWORD_IMM]], 255, implicit-def $scc
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ %3:sgpr_32 = COPY $sgpr3
+ %2:sgpr_32 = COPY $sgpr2
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %4:sgpr_128 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1, %2, %subreg.sub2, %3, %subreg.sub3
+ %5:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_IMM %4, 16, 0 :: (load (s32))
+ %6:sreg_32 = S_AND_B32 %5, 255, implicit-def $scc
+ S_ENDPGM 0, implicit %6
+...
+
+---
+name: s_buffer_load_u16_imm
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3
+ ; CHECK-LABEL: name: s_buffer_load_u16_imm
+ ; CHECK: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr3
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr2
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY1]], %subreg.sub2, [[COPY]], %subreg.sub3
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_BUFFER_LOAD_DWORD_IMM]], 65535, implicit-def $scc
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ %3:sgpr_32 = COPY $sgpr3
+ %2:sgpr_32 = COPY $sgpr2
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %4:sgpr_128 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1, %2, %subreg.sub2, %3, %subreg.sub3
+ %5:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_IMM %4, 16, 0 :: (load (s32))
+ %6:sreg_32 = S_AND_B32 %5, 65535, implicit-def $scc
+ S_ENDPGM 0, implicit %6
+...
+
+---
+name: s_buffer_load_i8_imm
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3
+ ; CHECK-LABEL: name: s_buffer_load_i8_imm
+ ; CHECK: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr3
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr2
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY1]], %subreg.sub2, [[COPY]], %subreg.sub3
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_SEXT_I32_I8_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I8 [[S_BUFFER_LOAD_DWORD_IMM]]
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I8_]]
+ %3:sgpr_32 = COPY $sgpr3
+ %2:sgpr_32 = COPY $sgpr2
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %4:sgpr_128 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1, %2, %subreg.sub2, %3, %subreg.sub3
+ %5:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_IMM %4, 16, 0 :: (load (s32))
+ %6:sreg_32 = S_SEXT_I32_I8 %5
+ S_ENDPGM 0, implicit %6
+...
+
+---
+name: s_buffer_load_i16_imm
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3
+ ; CHECK-LABEL: name: s_buffer_load_i16_imm
+ ; CHECK: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr3
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr2
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY1]], %subreg.sub2, [[COPY]], %subreg.sub3
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_SEXT_I32_I16_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I16 [[S_BUFFER_LOAD_DWORD_IMM]]
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I16_]]
+ %3:sgpr_32 = COPY $sgpr3
+ %2:sgpr_32 = COPY $sgpr2
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %4:sgpr_128 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1, %2, %subreg.sub2, %3, %subreg.sub3
+ %5:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_IMM %4, 16, 0 :: (load (s32))
+ %6:sreg_32 = S_SEXT_I32_I16 %5
+ S_ENDPGM 0, implicit %6
+...
+
+---
+name: s_buffer_load_u8_sgpr
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4
+ ; CHECK-LABEL: name: s_buffer_load_u8_sgpr
+ ; CHECK: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr3
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr2
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_SGPR:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_BUFFER_LOAD_DWORD_SGPR]], 255, implicit-def $scc
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ %4:sgpr_32 = COPY $sgpr4
+ %3:sgpr_32 = COPY $sgpr3
+ %2:sgpr_32 = COPY $sgpr2
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %5:sgpr_128 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1, %2, %subreg.sub2, %3, %subreg.sub3
+ %6:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR %5, %4, 0 :: (load (s32))
+ %7:sreg_32 = S_AND_B32 %6, 255, implicit-def $scc
+ S_ENDPGM 0, implicit %7
+...
+
+---
+name: s_buffer_load_u16_sgpr
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4
+ ; CHECK-LABEL: name: s_buffer_load_u16_sgpr
+ ; CHECK: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr3
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr2
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_SGPR:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_BUFFER_LOAD_DWORD_SGPR]], 65535, implicit-def $scc
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ %4:sgpr_32 = COPY $sgpr4
+ %3:sgpr_32 = COPY $sgpr3
+ %2:sgpr_32 = COPY $sgpr2
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %5:sgpr_128 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1, %2, %subreg.sub2, %3, %subreg.sub3
+ %6:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR %5, %4, 0 :: (load (s32))
+ %7:sreg_32 = S_AND_B32 %6, 65535, implicit-def $scc
+ S_ENDPGM 0, implicit %7
+...
+
+---
+name: s_buffer_load_i8_sgpr
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4
+ ; CHECK-LABEL: name: s_buffer_load_i8_sgpr
+ ; CHECK: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr3
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr2
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_SGPR:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_SEXT_I32_I8_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I8 [[S_BUFFER_LOAD_DWORD_SGPR]]
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I8_]]
+ %4:sgpr_32 = COPY $sgpr4
+ %3:sgpr_32 = COPY $sgpr3
+ %2:sgpr_32 = COPY $sgpr2
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %5:sgpr_128 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1, %2, %subreg.sub2, %3, %subreg.sub3
+ %6:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR %5, %4, 0 :: (load (s32))
+ %7:sreg_32 = S_SEXT_I32_I8 %6
+ S_ENDPGM 0, implicit %7
+...
+
+---
+name: s_buffer_load_i16_sgpr
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4
+ ; CHECK-LABEL: name: s_buffer_load_i16_sgpr
+ ; CHECK: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr3
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr2
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_SGPR:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_SEXT_I32_I16_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I16 [[S_BUFFER_LOAD_DWORD_SGPR]]
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I16_]]
+ %4:sgpr_32 = COPY $sgpr4
+ %3:sgpr_32 = COPY $sgpr3
+ %2:sgpr_32 = COPY $sgpr2
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %5:sgpr_128 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1, %2, %subreg.sub2, %3, %subreg.sub3
+ %6:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR %5, %4, 0 :: (load (s32))
+ %7:sreg_32 = S_SEXT_I32_I16 %6
+ S_ENDPGM 0, implicit %7
+...
+
+---
+name: s_buffer_load_u8_sgpr_imm
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4
+ ; CHECK-LABEL: name: s_buffer_load_u8_sgpr_imm
+ ; CHECK: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr3
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr2
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_SGPR_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR_IMM [[REG_SEQUENCE]], [[COPY]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_BUFFER_LOAD_DWORD_SGPR_IMM]], 255, implicit-def $scc
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ %4:sgpr_32 = COPY $sgpr4
+ %3:sgpr_32 = COPY $sgpr3
+ %2:sgpr_32 = COPY $sgpr2
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %5:sgpr_128 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1, %2, %subreg.sub2, %3, %subreg.sub3
+ %6:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR_IMM %5, %4, 16, 0 :: (load (s32))
+ %7:sreg_32 = S_AND_B32 %6, 255, implicit-def $scc
+ S_ENDPGM 0, implicit %7
+...
+
+---
+name: s_buffer_load_u16_sgpr_imm
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4
+ ; CHECK-LABEL: name: s_buffer_load_u16_sgpr_imm
+ ; CHECK: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr3
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr2
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_SGPR_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR_IMM [[REG_SEQUENCE]], [[COPY]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_BUFFER_LOAD_DWORD_SGPR_IMM]], 65535, implicit-def $scc
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ %4:sgpr_32 = COPY $sgpr4
+ %3:sgpr_32 = COPY $sgpr3
+ %2:sgpr_32 = COPY $sgpr2
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %5:sgpr_128 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1, %2, %subreg.sub2, %3, %subreg.sub3
+ %6:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR_IMM %5, %4, 16, 0 :: (load (s32))
+ %7:sreg_32 = S_AND_B32 %6, 65535, implicit-def $scc
+ S_ENDPGM 0, implicit %7
+...
+
+---
+name: s_buffer_load_i8_sgpr_imm
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4
+ ; CHECK-LABEL: name: s_buffer_load_i8_sgpr_imm
+ ; CHECK: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr3
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr2
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_SGPR_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR_IMM [[REG_SEQUENCE]], [[COPY]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_SEXT_I32_I8_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I8 [[S_BUFFER_LOAD_DWORD_SGPR_IMM]]
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I8_]]
+ %4:sgpr_32 = COPY $sgpr4
+ %3:sgpr_32 = COPY $sgpr3
+ %2:sgpr_32 = COPY $sgpr2
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %5:sgpr_128 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1, %2, %subreg.sub2, %3, %subreg.sub3
+ %6:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR_IMM %5, %4, 16, 0 :: (load (s32))
+ %7:sreg_32 = S_SEXT_I32_I8 %6
+ S_ENDPGM 0, implicit %7
+...
+
+---
+name: s_buffer_load_i16_sgpr_imm
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4
+ ; CHECK-LABEL: name: s_buffer_load_i16_sgpr_imm
+ ; CHECK: liveins: $sgpr0, $sgpr1, $sgpr2, $sgpr3, $sgpr4
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr4
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr3
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr2
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_SGPR_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR_IMM [[REG_SEQUENCE]], [[COPY]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_SEXT_I32_I16_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I16 [[S_BUFFER_LOAD_DWORD_SGPR_IMM]]
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I16_]]
+ %4:sgpr_32 = COPY $sgpr4
+ %3:sgpr_32 = COPY $sgpr3
+ %2:sgpr_32 = COPY $sgpr2
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %5:sgpr_128 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1, %2, %subreg.sub2, %3, %subreg.sub3
+ %6:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR_IMM %5, %4, 16, 0 :: (load (s32))
+ %7:sreg_32 = S_SEXT_I32_I16 %6
+ S_ENDPGM 0, implicit %7
+...
+
+---
+name: no_opt_wrong_mask
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0, $sgpr1
+ ; CHECK-LABEL: name: no_opt_wrong_mask
+ ; CHECK: liveins: $sgpr0, $sgpr1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr1
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1
+ ; CHECK-NEXT: [[S_LOAD_DWORD_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_LOAD_DWORD_IMM]], 127, implicit-def $scc
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ %1:sgpr_32 = COPY $sgpr1
+ %0:sgpr_32 = COPY $sgpr0
+ %2:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
+ %3:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM %2, 16, 0 :: (load (s32))
+ %4:sreg_32 = S_AND_B32 %3, 127, implicit-def $scc
+ S_ENDPGM 0, implicit %4
+...
>From c33f902e92d64975b4ad89b0c199dcca206cd722 Mon Sep 17 00:00:00 2001
From: John Lu <John.Lu at amd.com>
Date: Wed, 26 Aug 2026 14:42:56 -0500
Subject: [PATCH 2/2] Convert dword load + extension into subword load
Signed-off-by: John Lu <John.Lu at amd.com>
---
.../Target/AMDGPU/SILoadStoreOptimizer.cpp | 142 +++++++++++++++++-
.../atomic_optimizations_global_pointer.ll | 32 ++--
llvm/test/CodeGen/AMDGPU/max.ll | 26 ++--
llvm/test/CodeGen/AMDGPU/min.ll | 26 ++--
.../AMDGPU/reassoc-mul-add-1-to-mad.ll | 92 ++++++------
.../CodeGen/AMDGPU/scalar-subword-loads.ll | 38 ++---
.../AMDGPU/si-load-opt-scalar-subword.mir | 106 ++++++-------
7 files changed, 278 insertions(+), 184 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/SILoadStoreOptimizer.cpp b/llvm/lib/Target/AMDGPU/SILoadStoreOptimizer.cpp
index 555bb002a2521..18d0f622f5fb1 100644
--- a/llvm/lib/Target/AMDGPU/SILoadStoreOptimizer.cpp
+++ b/llvm/lib/Target/AMDGPU/SILoadStoreOptimizer.cpp
@@ -6,7 +6,14 @@
//
//===----------------------------------------------------------------------===//
//
-// This pass tries to fuse DS instructions with close by immediate offsets.
+// This pass tries to:
+// 1. fuse DS instructions with close by immediate offsets.
+// 2. fuse dword load + sign/zero extension into a subword load.
+// Optimization #1 (fusion) must be done before optimization #2 (subword loads).
+// The additional sign/zero-extension functionality in subword loads prevents
+// them from being fused with adjacent DS instructions.
+//
+// Optimization #1, fuse DS instructions
// This will fuse operations such as
// ds_read_b32 v0, v2 offset:16
// ds_read_b32 v1, v2 offset:32
@@ -55,6 +62,17 @@
// offsets, but are close enough to fit in the 8 bits, we can add to the base
// pointer and use the new reduced offsets.
//
+// Optimization #2, fuse dword load + extension into subword load
+// This will transform patterns like:
+// s_load_dword s0, ...
+// s_and_b32 s1, s0, 0xff
+// into:
+// s_load_u8 s1, ...
+//
+// The optimization recognizes dword loads followed by either zero-extension
+// (via AND with 0xff or 0xffff) or sign-extension (via S_SEXT_I32_I8/I16)
+// and replaces both instructions with a single subword load instruction.
+// This is only available on GFX12+ via the hasScalarSubwordLoads() feature.
//===----------------------------------------------------------------------===//
#include "SILoadStoreOptimizer.h"
@@ -313,6 +331,8 @@ class SILoadStoreOptimizer {
bool &OptimizeListAgain);
bool optimizeBlock(std::list<std::list<CombineInfo> > &MergeableInsts);
+ bool optimizeDwordLoadExtension(MachineBasicBlock &MBB);
+
public:
SILoadStoreOptimizer(AliasAnalysis *AA) : AA(AA) {}
bool run(MachineFunction &MF);
@@ -2861,6 +2881,123 @@ bool SILoadStoreOptimizerLegacy::runOnMachineFunction(MachineFunction &MF) {
.run(MF);
}
+enum SubwordExtensionType {
+ EXT_U8 = 0,
+ EXT_U16 = 1,
+ EXT_I8 = 2,
+ EXT_I16 = 3,
+ EXT_NONE = -1
+};
+
+// Determine the extension type based on the use instruction.
+// Returns EXT_NONE if the use pattern doesn't match a subword load.
+static SubwordExtensionType getExtensionType(const MachineInstr *UseInst) {
+ switch (UseInst->getOpcode()) {
+ case AMDGPU::S_AND_B32: {
+ // Check if it's masking with 0xff or 0xffff
+ const MachineOperand &MaskOp = UseInst->getOperand(2);
+ if (!MaskOp.isImm())
+ return EXT_NONE;
+
+ int64_t Mask = MaskOp.getImm();
+ if (Mask == 0xff)
+ return EXT_U8;
+ if (Mask == 0xffff)
+ return EXT_U16;
+ return EXT_NONE;
+ }
+ case AMDGPU::S_SEXT_I32_I8:
+ return EXT_I8;
+ case AMDGPU::S_SEXT_I32_I16:
+ return EXT_I16;
+ }
+ return EXT_NONE;
+}
+
+// Optimize a dword load + mask/extend by fusing the two instructions
+// into a subword load instruction.
+//
+// Patterns:
+// s_load_dword + s_and_b32 ... 0xff -> s_load_u8
+// s_load_dword + s_and_b32 ... 0xffff -> s_load_u16
+// s_load_dword + s_sext_i32_i8 -> s_load_i8
+// s_load_dword + s_sext_i32_i16 -> s_load_i16
+//
+// Same patterns for s_buffer_load_dword -> s_buffer_load_u8/i8/u16/i16
+bool SILoadStoreOptimizer::optimizeDwordLoadExtension(MachineBasicBlock &MBB) {
+ if (!STM->hasScalarSubwordLoads())
+ return false;
+
+ // Opcode tables for subword loads indexed by SubwordExtensionType
+ static const unsigned S_LOAD_IMM_TABLE[] = {
+ AMDGPU::S_LOAD_U8_IMM, AMDGPU::S_LOAD_U16_IMM,
+ AMDGPU::S_LOAD_I8_IMM, AMDGPU::S_LOAD_I16_IMM
+ };
+ static const unsigned S_LOAD_SGPR_TABLE[] = {
+ AMDGPU::S_LOAD_U8_SGPR, AMDGPU::S_LOAD_U16_SGPR,
+ AMDGPU::S_LOAD_I8_SGPR, AMDGPU::S_LOAD_I16_SGPR
+ };
+ static const unsigned S_BUFFER_LOAD_IMM_TABLE[] = {
+ AMDGPU::S_BUFFER_LOAD_U8_IMM, AMDGPU::S_BUFFER_LOAD_U16_IMM,
+ AMDGPU::S_BUFFER_LOAD_I8_IMM, AMDGPU::S_BUFFER_LOAD_I16_IMM
+ };
+ static const unsigned S_BUFFER_LOAD_SGPR_TABLE[] = {
+ AMDGPU::S_BUFFER_LOAD_U8_SGPR, AMDGPU::S_BUFFER_LOAD_U16_SGPR,
+ AMDGPU::S_BUFFER_LOAD_I8_SGPR, AMDGPU::S_BUFFER_LOAD_I16_SGPR
+ };
+ static const unsigned S_BUFFER_LOAD_SGPR_IMM_TABLE[] = {
+ AMDGPU::S_BUFFER_LOAD_U8_SGPR_IMM, AMDGPU::S_BUFFER_LOAD_U16_SGPR_IMM,
+ AMDGPU::S_BUFFER_LOAD_I8_SGPR_IMM, AMDGPU::S_BUFFER_LOAD_I16_SGPR_IMM
+ };
+
+ // Map from dword load opcode to subword load opcode table
+ static const DenseMap<unsigned, const unsigned *> DwordLoadToSubwordOpcodes =
+ {{AMDGPU::S_LOAD_DWORD_IMM, S_LOAD_IMM_TABLE},
+ {AMDGPU::S_LOAD_DWORD_SGPR, S_LOAD_SGPR_TABLE},
+ {AMDGPU::S_BUFFER_LOAD_DWORD_IMM, S_BUFFER_LOAD_IMM_TABLE},
+ {AMDGPU::S_BUFFER_LOAD_DWORD_SGPR, S_BUFFER_LOAD_SGPR_TABLE},
+ {AMDGPU::S_BUFFER_LOAD_DWORD_SGPR_IMM, S_BUFFER_LOAD_SGPR_IMM_TABLE}};
+
+ bool Modified = false;
+
+ for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E;
+ ++I) {
+ MachineInstr &MI = *I;
+
+ // Find the subword load opcodes for this dword load opcode
+ auto It = DwordLoadToSubwordOpcodes.find(MI.getOpcode());
+ if (It == DwordLoadToSubwordOpcodes.end())
+ continue;
+ const unsigned *SubwordOpcodes =
+ It->second; // Array indexed by SubwordExtensionType
+
+ Register LoadReg = MI.getOperand(0).getReg();
+ MachineInstr *UseInst = MRI->getOneNonDBGUser(LoadReg);
+ if (!UseInst)
+ continue;
+
+ SubwordExtensionType ExtType = getExtensionType(UseInst);
+ if (ExtType == EXT_NONE)
+ continue;
+
+ assert(UseInst->getOperand(1).isReg() &&
+ UseInst->getOperand(1).getReg() == LoadReg &&
+ "Extension source operand should be the load result");
+
+ unsigned NewOpcode = SubwordOpcodes[ExtType];
+ Register UseDestReg = UseInst->getOperand(0).getReg();
+
+ MI.setDesc(TII->get(NewOpcode));
+ MI.getOperand(0).setReg(UseDestReg);
+
+ UseInst->eraseFromParent();
+
+ Modified = true;
+ }
+
+ return Modified;
+}
+
bool SILoadStoreOptimizer::run(MachineFunction &MF) {
this->MF = &MF;
STM = &MF.getSubtarget<GCNSubtarget>();
@@ -2901,6 +3038,9 @@ bool SILoadStoreOptimizer::run(MachineFunction &MF) {
} while (OptimizeAgain);
}
+ // Optimize subword loads after fusion has been completed
+ Modified |= optimizeDwordLoadExtension(MBB);
+
Visited.clear();
AnchorList.clear();
}
diff --git a/llvm/test/CodeGen/AMDGPU/atomic_optimizations_global_pointer.ll b/llvm/test/CodeGen/AMDGPU/atomic_optimizations_global_pointer.ll
index 3e3b5ac65eabc..29c5fbc9b5626 100644
--- a/llvm/test/CodeGen/AMDGPU/atomic_optimizations_global_pointer.ll
+++ b/llvm/test/CodeGen/AMDGPU/atomic_optimizations_global_pointer.ll
@@ -11639,7 +11639,7 @@ define amdgpu_kernel void @uniform_xchg_i8(ptr addrspace(1) %result, ptr addrspa
; GFX1264: ; %bb.0:
; GFX1264-NEXT: s_clause 0x1
; GFX1264-NEXT: s_load_b128 s[0:3], s[4:5], 0x24
-; GFX1264-NEXT: s_load_b32 s6, s[4:5], 0x34
+; GFX1264-NEXT: s_load_u8 s6, s[4:5], 0x34
; GFX1264-NEXT: s_mov_b64 s[8:9], 0
; GFX1264-NEXT: s_wait_kmcnt 0x0
; GFX1264-NEXT: s_and_b32 s4, s2, -4
@@ -11647,7 +11647,7 @@ define amdgpu_kernel void @uniform_xchg_i8(ptr addrspace(1) %result, ptr addrspa
; GFX1264-NEXT: s_and_b32 s2, s2, 3
; GFX1264-NEXT: s_load_b32 s5, s[4:5], 0x0
; GFX1264-NEXT: s_lshl_b32 s2, s2, 3
-; GFX1264-NEXT: s_and_b32 s6, s6, 0xff
+; GFX1264-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX1264-NEXT: s_lshl_b32 s7, 0xff, s2
; GFX1264-NEXT: s_lshl_b32 s11, s6, s2
; GFX1264-NEXT: s_not_b32 s10, s7
@@ -11682,7 +11682,7 @@ define amdgpu_kernel void @uniform_xchg_i8(ptr addrspace(1) %result, ptr addrspa
; GFX1232: ; %bb.0:
; GFX1232-NEXT: s_clause 0x1
; GFX1232-NEXT: s_load_b128 s[0:3], s[4:5], 0x24
-; GFX1232-NEXT: s_load_b32 s6, s[4:5], 0x34
+; GFX1232-NEXT: s_load_u8 s6, s[4:5], 0x34
; GFX1232-NEXT: s_mov_b32 s9, 0
; GFX1232-NEXT: s_wait_kmcnt 0x0
; GFX1232-NEXT: s_and_b32 s4, s2, -4
@@ -11690,7 +11690,7 @@ define amdgpu_kernel void @uniform_xchg_i8(ptr addrspace(1) %result, ptr addrspa
; GFX1232-NEXT: s_and_b32 s2, s2, 3
; GFX1232-NEXT: s_load_b32 s5, s[4:5], 0x0
; GFX1232-NEXT: s_lshl_b32 s2, s2, 3
-; GFX1232-NEXT: s_and_b32 s6, s6, 0xff
+; GFX1232-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX1232-NEXT: s_lshl_b32 s7, 0xff, s2
; GFX1232-NEXT: s_lshl_b32 s10, s6, s2
; GFX1232-NEXT: s_not_b32 s8, s7
@@ -11724,14 +11724,14 @@ define amdgpu_kernel void @uniform_xchg_i8(ptr addrspace(1) %result, ptr addrspa
; GFX1364: ; %bb.0:
; GFX1364-NEXT: s_clause 0x1
; GFX1364-NEXT: s_load_b128 s[0:3], s[4:5], 0x24 nv
-; GFX1364-NEXT: s_load_b32 s6, s[4:5], 0x34 nv
+; GFX1364-NEXT: s_load_u8 s6, s[4:5], 0x34 nv
; GFX1364-NEXT: s_mov_b32 s7, 0x31016000
; GFX1364-NEXT: s_wait_kmcnt 0x0
; GFX1364-NEXT: s_and_b64 s[4:5], s[2:3], -4
; GFX1364-NEXT: s_and_b32 s2, s2, 3
; GFX1364-NEXT: s_load_b32 s3, s[4:5], 0x0
; GFX1364-NEXT: s_lshl_b32 s8, s2, 3
-; GFX1364-NEXT: s_and_b32 s6, s6, 0xff
+; GFX1364-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX1364-NEXT: s_lshl_b32 s2, 0xff, s8
; GFX1364-NEXT: s_lshl_b32 s10, s6, s8
; GFX1364-NEXT: s_not_b32 s9, s2
@@ -11765,14 +11765,14 @@ define amdgpu_kernel void @uniform_xchg_i8(ptr addrspace(1) %result, ptr addrspa
; GFX1332: ; %bb.0:
; GFX1332-NEXT: s_clause 0x1
; GFX1332-NEXT: s_load_b128 s[0:3], s[4:5], 0x24 nv
-; GFX1332-NEXT: s_load_b32 s6, s[4:5], 0x34 nv
+; GFX1332-NEXT: s_load_u8 s6, s[4:5], 0x34 nv
; GFX1332-NEXT: s_mov_b32 s9, 0
; GFX1332-NEXT: s_wait_kmcnt 0x0
; GFX1332-NEXT: s_and_b64 s[4:5], s[2:3], -4
; GFX1332-NEXT: s_and_b32 s2, s2, 3
; GFX1332-NEXT: s_load_b32 s7, s[4:5], 0x0
; GFX1332-NEXT: s_lshl_b32 s2, s2, 3
-; GFX1332-NEXT: s_and_b32 s6, s6, 0xff
+; GFX1332-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX1332-NEXT: s_lshl_b32 s3, 0xff, s2
; GFX1332-NEXT: s_lshl_b32 s8, s6, s2
; GFX1332-NEXT: s_not_b32 s3, s3
@@ -14074,7 +14074,7 @@ define amdgpu_kernel void @uniform_xchg_i16(ptr addrspace(1) %result, ptr addrsp
; GFX1264: ; %bb.0:
; GFX1264-NEXT: s_clause 0x1
; GFX1264-NEXT: s_load_b128 s[0:3], s[4:5], 0x24
-; GFX1264-NEXT: s_load_b32 s6, s[4:5], 0x34
+; GFX1264-NEXT: s_load_u16 s6, s[4:5], 0x34
; GFX1264-NEXT: s_mov_b64 s[8:9], 0
; GFX1264-NEXT: s_wait_kmcnt 0x0
; GFX1264-NEXT: s_and_b32 s4, s2, -4
@@ -14082,7 +14082,7 @@ define amdgpu_kernel void @uniform_xchg_i16(ptr addrspace(1) %result, ptr addrsp
; GFX1264-NEXT: s_and_b32 s2, s2, 3
; GFX1264-NEXT: s_load_b32 s5, s[4:5], 0x0
; GFX1264-NEXT: s_lshl_b32 s2, s2, 3
-; GFX1264-NEXT: s_and_b32 s6, s6, 0xffff
+; GFX1264-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX1264-NEXT: s_lshl_b32 s7, 0xffff, s2
; GFX1264-NEXT: s_lshl_b32 s11, s6, s2
; GFX1264-NEXT: s_not_b32 s10, s7
@@ -14117,7 +14117,7 @@ define amdgpu_kernel void @uniform_xchg_i16(ptr addrspace(1) %result, ptr addrsp
; GFX1232: ; %bb.0:
; GFX1232-NEXT: s_clause 0x1
; GFX1232-NEXT: s_load_b128 s[0:3], s[4:5], 0x24
-; GFX1232-NEXT: s_load_b32 s6, s[4:5], 0x34
+; GFX1232-NEXT: s_load_u16 s6, s[4:5], 0x34
; GFX1232-NEXT: s_mov_b32 s9, 0
; GFX1232-NEXT: s_wait_kmcnt 0x0
; GFX1232-NEXT: s_and_b32 s4, s2, -4
@@ -14125,7 +14125,7 @@ define amdgpu_kernel void @uniform_xchg_i16(ptr addrspace(1) %result, ptr addrsp
; GFX1232-NEXT: s_and_b32 s2, s2, 3
; GFX1232-NEXT: s_load_b32 s5, s[4:5], 0x0
; GFX1232-NEXT: s_lshl_b32 s2, s2, 3
-; GFX1232-NEXT: s_and_b32 s6, s6, 0xffff
+; GFX1232-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX1232-NEXT: s_lshl_b32 s7, 0xffff, s2
; GFX1232-NEXT: s_lshl_b32 s10, s6, s2
; GFX1232-NEXT: s_not_b32 s8, s7
@@ -14159,14 +14159,14 @@ define amdgpu_kernel void @uniform_xchg_i16(ptr addrspace(1) %result, ptr addrsp
; GFX1364: ; %bb.0:
; GFX1364-NEXT: s_clause 0x1
; GFX1364-NEXT: s_load_b128 s[0:3], s[4:5], 0x24 nv
-; GFX1364-NEXT: s_load_b32 s6, s[4:5], 0x34 nv
+; GFX1364-NEXT: s_load_u16 s6, s[4:5], 0x34 nv
; GFX1364-NEXT: s_mov_b32 s7, 0x31016000
; GFX1364-NEXT: s_wait_kmcnt 0x0
; GFX1364-NEXT: s_and_b64 s[4:5], s[2:3], -4
; GFX1364-NEXT: s_and_b32 s2, s2, 3
; GFX1364-NEXT: s_load_b32 s3, s[4:5], 0x0
; GFX1364-NEXT: s_lshl_b32 s8, s2, 3
-; GFX1364-NEXT: s_and_b32 s6, s6, 0xffff
+; GFX1364-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX1364-NEXT: s_lshl_b32 s2, 0xffff, s8
; GFX1364-NEXT: s_lshl_b32 s10, s6, s8
; GFX1364-NEXT: s_not_b32 s9, s2
@@ -14200,14 +14200,14 @@ define amdgpu_kernel void @uniform_xchg_i16(ptr addrspace(1) %result, ptr addrsp
; GFX1332: ; %bb.0:
; GFX1332-NEXT: s_clause 0x1
; GFX1332-NEXT: s_load_b128 s[0:3], s[4:5], 0x24 nv
-; GFX1332-NEXT: s_load_b32 s6, s[4:5], 0x34 nv
+; GFX1332-NEXT: s_load_u16 s6, s[4:5], 0x34 nv
; GFX1332-NEXT: s_mov_b32 s9, 0
; GFX1332-NEXT: s_wait_kmcnt 0x0
; GFX1332-NEXT: s_and_b64 s[4:5], s[2:3], -4
; GFX1332-NEXT: s_and_b32 s2, s2, 3
; GFX1332-NEXT: s_load_b32 s7, s[4:5], 0x0
; GFX1332-NEXT: s_lshl_b32 s2, s2, 3
-; GFX1332-NEXT: s_and_b32 s6, s6, 0xffff
+; GFX1332-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX1332-NEXT: s_lshl_b32 s3, 0xffff, s2
; GFX1332-NEXT: s_lshl_b32 s8, s6, s2
; GFX1332-NEXT: s_not_b32 s3, s3
diff --git a/llvm/test/CodeGen/AMDGPU/max.ll b/llvm/test/CodeGen/AMDGPU/max.ll
index 01be3f8ea2323..be1aadb95bc49 100644
--- a/llvm/test/CodeGen/AMDGPU/max.ll
+++ b/llvm/test/CodeGen/AMDGPU/max.ll
@@ -982,15 +982,13 @@ define amdgpu_kernel void @simplify_demanded_bits_test_umax_ugt_i16(ptr addrspac
; GFX1250-NEXT: v_nop
; GFX1250-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
; GFX1250-NEXT: s_clause 0x2
-; GFX1250-NEXT: s_load_b32 s2, s[4:5], 0x4c nv
-; GFX1250-NEXT: s_load_b32 s3, s[4:5], 0x70 nv
+; GFX1250-NEXT: s_load_u16 s2, s[4:5], 0x4c nv
+; GFX1250-NEXT: s_load_u16 s3, s[4:5], 0x70 nv
; GFX1250-NEXT: s_load_b64 s[0:1], s[4:5], 0x24 nv
; GFX1250-NEXT: v_mov_b32_e32 v0, 0
; GFX1250-NEXT: s_wait_kmcnt 0x0
-; GFX1250-NEXT: s_and_b32 s2, s2, 0xffff
-; GFX1250-NEXT: s_and_b32 s3, s3, 0xffff
-; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
; GFX1250-NEXT: s_max_u32 s2, s2, s3
+; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX1250-NEXT: v_mov_b32_e32 v1, s2
; GFX1250-NEXT: global_store_b32 v0, v1, s[0:1]
; GFX1250-NEXT: s_endpgm
@@ -1049,15 +1047,13 @@ define amdgpu_kernel void @simplify_demanded_bits_test_max_slt_i16(ptr addrspace
; GFX1250-NEXT: v_nop
; GFX1250-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
; GFX1250-NEXT: s_clause 0x2
-; GFX1250-NEXT: s_load_b32 s2, s[4:5], 0x4c nv
-; GFX1250-NEXT: s_load_b32 s3, s[4:5], 0x70 nv
+; GFX1250-NEXT: s_load_i16 s2, s[4:5], 0x4c nv
+; GFX1250-NEXT: s_load_i16 s3, s[4:5], 0x70 nv
; GFX1250-NEXT: s_load_b64 s[0:1], s[4:5], 0x24 nv
; GFX1250-NEXT: v_mov_b32_e32 v0, 0
; GFX1250-NEXT: s_wait_kmcnt 0x0
-; GFX1250-NEXT: s_sext_i32_i16 s2, s2
-; GFX1250-NEXT: s_sext_i32_i16 s3, s3
-; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
; GFX1250-NEXT: s_max_i32 s2, s2, s3
+; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX1250-NEXT: v_mov_b32_e32 v1, s2
; GFX1250-NEXT: global_store_b32 v0, v1, s[0:1]
; GFX1250-NEXT: s_endpgm
@@ -1115,15 +1111,13 @@ define amdgpu_kernel void @s_test_imax_sge_i16(ptr addrspace(1) %out, [8 x i32],
; GFX1250-NEXT: v_nop
; GFX1250-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
; GFX1250-NEXT: s_clause 0x2
-; GFX1250-NEXT: s_load_b32 s2, s[4:5], 0x70 nv
-; GFX1250-NEXT: s_load_b32 s3, s[4:5], 0x4c nv
+; GFX1250-NEXT: s_load_i16 s2, s[4:5], 0x4c nv
+; GFX1250-NEXT: s_load_i16 s3, s[4:5], 0x70 nv
; GFX1250-NEXT: s_load_b64 s[0:1], s[4:5], 0x24 nv
; GFX1250-NEXT: v_mov_b32_e32 v0, 0
; GFX1250-NEXT: s_wait_kmcnt 0x0
-; GFX1250-NEXT: s_sext_i32_i16 s2, s2
-; GFX1250-NEXT: s_sext_i32_i16 s3, s3
-; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
-; GFX1250-NEXT: s_max_i32 s2, s3, s2
+; GFX1250-NEXT: s_max_i32 s2, s2, s3
+; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX1250-NEXT: v_mov_b32_e32 v1, s2
; GFX1250-NEXT: global_store_b16 v0, v1, s[0:1]
; GFX1250-NEXT: s_endpgm
diff --git a/llvm/test/CodeGen/AMDGPU/min.ll b/llvm/test/CodeGen/AMDGPU/min.ll
index f7cb1914749a7..69a394e7cdf03 100644
--- a/llvm/test/CodeGen/AMDGPU/min.ll
+++ b/llvm/test/CodeGen/AMDGPU/min.ll
@@ -595,15 +595,13 @@ define amdgpu_kernel void @s_test_imin_sle_i8(ptr addrspace(1) %out, [8 x i32],
; GFX1250-NEXT: v_nop
; GFX1250-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
; GFX1250-NEXT: s_clause 0x2
-; GFX1250-NEXT: s_load_b32 s2, s[4:5], 0x4c nv
-; GFX1250-NEXT: s_load_b32 s3, s[4:5], 0x28 nv
+; GFX1250-NEXT: s_load_i8 s2, s[4:5], 0x28 nv
+; GFX1250-NEXT: s_load_i8 s3, s[4:5], 0x4c nv
; GFX1250-NEXT: s_load_b64 s[0:1], s[4:5], 0x0 nv
; GFX1250-NEXT: v_mov_b32_e32 v0, 0
; GFX1250-NEXT: s_wait_kmcnt 0x0
-; GFX1250-NEXT: s_sext_i32_i8 s2, s2
-; GFX1250-NEXT: s_sext_i32_i8 s3, s3
-; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
-; GFX1250-NEXT: s_min_i32 s2, s3, s2
+; GFX1250-NEXT: s_min_i32 s2, s2, s3
+; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX1250-NEXT: v_mov_b32_e32 v1, s2
; GFX1250-NEXT: global_store_b8 v0, v1, s[0:1]
; GFX1250-NEXT: s_endpgm
@@ -4081,15 +4079,13 @@ define amdgpu_kernel void @simplify_demanded_bits_test_umin_ult_i16(ptr addrspac
; GFX1250-NEXT: v_nop
; GFX1250-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
; GFX1250-NEXT: s_clause 0x2
-; GFX1250-NEXT: s_load_b32 s2, s[4:5], 0x28 nv
-; GFX1250-NEXT: s_load_b32 s3, s[4:5], 0x4c nv
+; GFX1250-NEXT: s_load_u16 s2, s[4:5], 0x28 nv
+; GFX1250-NEXT: s_load_u16 s3, s[4:5], 0x4c nv
; GFX1250-NEXT: s_load_b64 s[0:1], s[4:5], 0x0 nv
; GFX1250-NEXT: v_mov_b32_e32 v0, 0
; GFX1250-NEXT: s_wait_kmcnt 0x0
-; GFX1250-NEXT: s_and_b32 s2, s2, 0xffff
-; GFX1250-NEXT: s_and_b32 s3, s3, 0xffff
-; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
; GFX1250-NEXT: s_min_u32 s2, s2, s3
+; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX1250-NEXT: v_mov_b32_e32 v1, s2
; GFX1250-NEXT: global_store_b32 v0, v1, s[0:1]
; GFX1250-NEXT: s_endpgm
@@ -4214,15 +4210,13 @@ define amdgpu_kernel void @simplify_demanded_bits_test_min_slt_i16(ptr addrspace
; GFX1250-NEXT: v_nop
; GFX1250-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
; GFX1250-NEXT: s_clause 0x2
-; GFX1250-NEXT: s_load_b32 s2, s[4:5], 0x28 nv
-; GFX1250-NEXT: s_load_b32 s3, s[4:5], 0x4c nv
+; GFX1250-NEXT: s_load_i16 s2, s[4:5], 0x28 nv
+; GFX1250-NEXT: s_load_i16 s3, s[4:5], 0x4c nv
; GFX1250-NEXT: s_load_b64 s[0:1], s[4:5], 0x0 nv
; GFX1250-NEXT: v_mov_b32_e32 v0, 0
; GFX1250-NEXT: s_wait_kmcnt 0x0
-; GFX1250-NEXT: s_sext_i32_i16 s2, s2
-; GFX1250-NEXT: s_sext_i32_i16 s3, s3
-; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
; GFX1250-NEXT: s_min_i32 s2, s2, s3
+; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX1250-NEXT: v_mov_b32_e32 v1, s2
; GFX1250-NEXT: global_store_b32 v0, v1, s[0:1]
; GFX1250-NEXT: s_endpgm
diff --git a/llvm/test/CodeGen/AMDGPU/reassoc-mul-add-1-to-mad.ll b/llvm/test/CodeGen/AMDGPU/reassoc-mul-add-1-to-mad.ll
index f9c85fa324fe1..3aa4d9bf8707a 100644
--- a/llvm/test/CodeGen/AMDGPU/reassoc-mul-add-1-to-mad.ll
+++ b/llvm/test/CodeGen/AMDGPU/reassoc-mul-add-1-to-mad.ll
@@ -5293,47 +5293,47 @@ define amdgpu_kernel void @compute_mad(ptr addrspace(4) %i18, ptr addrspace(4) %
; GFX1250-NEXT: s_mov_b64 s[64:65], 0
; GFX1250-NEXT: v_nop
; GFX1250-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
-; GFX1250-NEXT: s_load_b96 s[0:2], s[4:5], 0x10 nv
+; GFX1250-NEXT: s_load_b96 s[8:10], s[4:5], 0x10 nv
; GFX1250-NEXT: v_and_b32_e32 v0, 0x3ff, v0
-; GFX1250-NEXT: s_wait_xcnt 0x0
-; GFX1250-NEXT: s_load_b128 s[4:7], s[4:5], 0x0 nv
; GFX1250-NEXT: s_wait_kmcnt 0x0
-; GFX1250-NEXT: s_add_co_i32 s2, s2, 1
-; GFX1250-NEXT: s_load_b32 s6, s[6:7], 0x4 nv
-; GFX1250-NEXT: v_mul_lo_u32 v1, s2, v0
-; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_3) | instid1(VALU_DEP_1)
-; GFX1250-NEXT: v_dual_add_nc_u32 v2, s2, v1 :: v_dual_add_nc_u32 v1, 1, v1
-; GFX1250-NEXT: s_bfe_u32 s2, ttmp6, 0x4000c
-; GFX1250-NEXT: s_wait_xcnt 0x0
-; GFX1250-NEXT: s_add_co_i32 s7, s2, 1
-; GFX1250-NEXT: v_mul_lo_u32 v2, v2, v0
-; GFX1250-NEXT: s_load_b64 s[2:3], s[4:5], 0x0 nv
+; GFX1250-NEXT: s_add_co_i32 s0, s10, 1
+; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; GFX1250-NEXT: v_mul_lo_u32 v1, s0, v0
+; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX1250-NEXT: v_dual_add_nc_u32 v2, s0, v1 :: v_dual_add_nc_u32 v1, 1, v1
+; GFX1250-NEXT: s_load_b128 s[0:3], s[4:5], 0x0 nv
; GFX1250-NEXT: s_wait_xcnt 0x0
; GFX1250-NEXT: s_and_b32 s4, ttmp6, 15
-; GFX1250-NEXT: s_mul_i32 s5, ttmp9, s7
-; GFX1250-NEXT: s_getreg_b32 s7, hwreg(HW_REG_IB_STS2, 6, 4)
-; GFX1250-NEXT: s_add_co_i32 s4, s4, s5
-; GFX1250-NEXT: s_wait_kmcnt 0x0
-; GFX1250-NEXT: s_and_b32 s5, s6, 0xffff
-; GFX1250-NEXT: s_cmp_eq_u32 s7, 0
+; GFX1250-NEXT: s_getreg_b32 s5, hwreg(HW_REG_IB_STS2, 6, 4)
+; GFX1250-NEXT: v_mul_lo_u32 v2, v2, v0
+; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX1250-NEXT: v_mul_lo_u32 v3, v2, v1
-; GFX1250-NEXT: s_cselect_b32 s4, ttmp9, s4
-; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX1250-NEXT: v_mad_u32 v0, s4, s5, v0
; GFX1250-NEXT: v_add_nc_u32_e32 v1, v3, v1
-; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
+; GFX1250-NEXT: s_wait_kmcnt 0x0
+; GFX1250-NEXT: s_load_u16 s2, s[2:3], 0x4 nv
+; GFX1250-NEXT: s_wait_xcnt 0x0
+; GFX1250-NEXT: s_bfe_u32 s3, ttmp6, 0x4000c
+; GFX1250-NEXT: s_load_b64 s[0:1], s[0:1], 0x0 nv
+; GFX1250-NEXT: s_add_co_i32 s3, s3, 1
; GFX1250-NEXT: v_mul_lo_u32 v1, v1, v2
; GFX1250-NEXT: v_add_nc_u32_e32 v2, 1, v3
+; GFX1250-NEXT: s_mul_i32 s3, ttmp9, s3
+; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_2) | instid1(VALU_DEP_2)
+; GFX1250-NEXT: s_add_co_i32 s4, s4, s3
+; GFX1250-NEXT: s_cmp_eq_u32 s5, 0
+; GFX1250-NEXT: s_cselect_b32 s3, ttmp9, s4
; GFX1250-NEXT: v_mul_lo_u32 v3, v1, v2
-; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX1250-NEXT: s_wait_kmcnt 0x0
+; GFX1250-NEXT: v_mad_u32 v0, s3, s2, v0
+; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX1250-NEXT: v_add_nc_u32_e32 v2, v3, v2
; GFX1250-NEXT: v_mul_lo_u32 v2, v2, v1
; GFX1250-NEXT: v_mov_b32_e32 v1, 0
; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_3)
-; GFX1250-NEXT: v_add_nc_u64_e32 v[0:1], s[2:3], v[0:1]
+; GFX1250-NEXT: v_add_nc_u64_e32 v[0:1], s[0:1], v[0:1]
; GFX1250-NEXT: v_mad_u32 v3, v2, v3, v2
; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX1250-NEXT: v_lshl_add_u64 v[0:1], v[0:1], 2, s[0:1]
+; GFX1250-NEXT: v_lshl_add_u64 v[0:1], v[0:1], 2, s[8:9]
; GFX1250-NEXT: v_mad_u32 v2, v3, v2, v3
; GFX1250-NEXT: global_store_b32 v[0:1], v2, off
; GFX1250-NEXT: s_endpgm
@@ -5343,46 +5343,44 @@ define amdgpu_kernel void @compute_mad(ptr addrspace(4) %i18, ptr addrspace(4) %
; GFX13-NEXT: s_load_b96 s[0:2], s[4:5], 0x10 nv
; GFX13-NEXT: v_and_b32_e32 v0, 0x3ff, v0
; GFX13-NEXT: s_load_b128 s[4:7], s[4:5], 0x0 nv
-; GFX13-NEXT: s_bfe_u32 s8, ttmp6, 0x4000c
-; GFX13-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
-; GFX13-NEXT: s_add_co_i32 s8, s8, 1
; GFX13-NEXT: s_wait_kmcnt 0x0
; GFX13-NEXT: s_add_co_i32 s2, s2, 1
-; GFX13-NEXT: s_load_b32 s6, s[6:7], 0x4 nv
+; GFX13-NEXT: s_load_u16 s6, s[6:7], 0x4 nv
; GFX13-NEXT: v_mul_lo_u32 v1, s2, v0
-; GFX13-NEXT: s_and_b32 s7, ttmp6, 15
-; GFX13-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_3) | instid1(VALU_DEP_1)
+; GFX13-NEXT: s_bfe_u32 s7, ttmp6, 0x4000c
+; GFX13-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX13-NEXT: s_add_co_i32 s7, s7, 1
; GFX13-NEXT: v_dual_add_nc_u32 v2, s2, v1 :: v_dual_add_nc_u32 v1, 1, v1
; GFX13-NEXT: s_load_b64 s[2:3], s[4:5], 0x0 nv
-; GFX13-NEXT: s_mul_i32 s4, ttmp9, s8
-; GFX13-NEXT: s_getreg_b32 s5, hwreg(HW_REG_IB_STS2, 6, 4)
+; GFX13-NEXT: s_and_b32 s4, ttmp6, 15
+; GFX13-NEXT: s_mul_i32 s5, ttmp9, s7
+; GFX13-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_4) | instid1(VALU_DEP_1)
; GFX13-NEXT: v_mul_lo_u32 v2, v2, v0
-; GFX13-NEXT: s_add_co_i32 s7, s7, s4
-; GFX13-NEXT: s_wait_kmcnt 0x0
-; GFX13-NEXT: s_and_b32 s4, s6, 0xffff
-; GFX13-NEXT: s_cmp_eq_u32 s5, 0
-; GFX13-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
+; GFX13-NEXT: s_getreg_b32 s7, hwreg(HW_REG_IB_STS2, 6, 4)
+; GFX13-NEXT: s_add_co_i32 s4, s4, s5
+; GFX13-NEXT: s_cmp_eq_u32 s7, 0
+; GFX13-NEXT: s_cselect_b32 s4, ttmp9, s4
; GFX13-NEXT: v_mul_lo_u32 v3, v2, v1
-; GFX13-NEXT: s_cselect_b32 s5, ttmp9, s7
+; GFX13-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX13-NEXT: v_add_nc_u32_e32 v1, v3, v1
-; GFX13-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
; GFX13-NEXT: v_mul_lo_u32 v2, v1, v2
; GFX13-NEXT: v_add_nc_u32_e32 v1, 1, v3
+; GFX13-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX13-NEXT: v_mul_lo_u32 v4, v2, v1
-; GFX13-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
; GFX13-NEXT: v_add_nc_u32_e32 v3, v4, v1
-; GFX13-NEXT: v_mad_co_u64_u32 v[0:1], null, s5, s4, v[0:1]
+; GFX13-NEXT: s_wait_kmcnt 0x0
+; GFX13-NEXT: v_mad_co_u64_u32 v[0:1], null, s4, s6, v[0:1]
+; GFX13-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
; GFX13-NEXT: v_mul_lo_u32 v1, v3, v2
-; GFX13-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX13-NEXT: v_add_co_u32 v2, s2, s2, v0
+; GFX13-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
; GFX13-NEXT: v_add_co_ci_u32_e64 v3, null, s3, 0, s2
-; GFX13-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
; GFX13-NEXT: v_mad_co_u64_u32 v[4:5], null, v1, v4, v[1:2]
-; GFX13-NEXT: v_lshlrev_b64_e32 v[2:3], 2, v[2:3]
; GFX13-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX13-NEXT: v_lshlrev_b64_e32 v[2:3], 2, v[2:3]
; GFX13-NEXT: v_mad_co_u64_u32 v[0:1], null, v4, v1, v[4:5]
+; GFX13-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX13-NEXT: v_add_co_u32 v1, vcc_lo, s0, v2
-; GFX13-NEXT: s_delay_alu instid0(VALU_DEP_1)
; GFX13-NEXT: v_add_co_ci_u32_e64 v2, null, s1, v3, vcc_lo
; GFX13-NEXT: global_store_b32 v[1:2], v0, off
; GFX13-NEXT: s_endpgm
diff --git a/llvm/test/CodeGen/AMDGPU/scalar-subword-loads.ll b/llvm/test/CodeGen/AMDGPU/scalar-subword-loads.ll
index e39d12963633b..7421ce6bfd450 100644
--- a/llvm/test/CodeGen/AMDGPU/scalar-subword-loads.ll
+++ b/llvm/test/CodeGen/AMDGPU/scalar-subword-loads.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
; Test all scalar subword load optimization variants
-; RUN: llc -mtriple=amdgcn -mcpu=gfx1250 < %s | FileCheck %s
+; RUN: llc -mtriple=amdgpu12.50 < %s | FileCheck %s
declare i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32>, i32, i32 immarg)
@@ -16,12 +16,10 @@ define amdgpu_kernel void @s_load_u8(ptr addrspace(1) %out) {
; CHECK-NEXT: v_nop
; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
; CHECK-NEXT: s_mov_b64 s[0:1], 16
-; CHECK-NEXT: s_load_b32 s6, s[0:1], 0x0 nv
+; CHECK-NEXT: s_load_u8 s6, s[0:1], 0x0 nv
; CHECK-NEXT: s_load_b64 s[2:3], s[4:5], 0x24 nv
; CHECK-NEXT: s_wait_kmcnt 0x0
-; CHECK-NEXT: s_and_b32 s0, s6, 0xff
-; CHECK-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
-; CHECK-NEXT: v_dual_mov_b32 v0, 0 :: v_dual_mov_b32 v1, s0
+; CHECK-NEXT: v_dual_mov_b32 v0, 0 :: v_dual_mov_b32 v1, s6
; CHECK-NEXT: global_store_b32 v0, v1, s[2:3]
; CHECK-NEXT: s_endpgm
%ptr = inttoptr i64 16 to ptr addrspace(4)
@@ -39,12 +37,10 @@ define amdgpu_kernel void @s_load_u16(ptr addrspace(1) %out) {
; CHECK-NEXT: v_nop
; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
; CHECK-NEXT: s_mov_b64 s[0:1], 16
-; CHECK-NEXT: s_load_b32 s6, s[0:1], 0x0 nv
+; CHECK-NEXT: s_load_u16 s6, s[0:1], 0x0 nv
; CHECK-NEXT: s_load_b64 s[2:3], s[4:5], 0x24 nv
; CHECK-NEXT: s_wait_kmcnt 0x0
-; CHECK-NEXT: s_and_b32 s0, s6, 0xffff
-; CHECK-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
-; CHECK-NEXT: v_dual_mov_b32 v0, 0 :: v_dual_mov_b32 v1, s0
+; CHECK-NEXT: v_dual_mov_b32 v0, 0 :: v_dual_mov_b32 v1, s6
; CHECK-NEXT: global_store_b32 v0, v1, s[2:3]
; CHECK-NEXT: s_endpgm
%ptr = inttoptr i64 16 to ptr addrspace(4)
@@ -107,9 +103,8 @@ define amdgpu_cs i32 @s_buffer_load_u8_imm(<4 x i32> inreg %buf) {
; CHECK-NEXT: s_mov_b64 s[64:65], 0
; CHECK-NEXT: v_nop
; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
-; CHECK-NEXT: s_buffer_load_b32 s0, s[0:3], 0x10 nv
+; CHECK-NEXT: s_buffer_load_u8 s0, s[0:3], 0x10 nv
; CHECK-NEXT: s_wait_kmcnt 0x0
-; CHECK-NEXT: s_and_b32 s0, s0, 0xff
; CHECK-NEXT: ; return to shader part epilog
%val = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %buf, i32 16, i32 0)
%masked = and i32 %val, 255
@@ -123,9 +118,8 @@ define amdgpu_cs i32 @s_buffer_load_u16_imm(<4 x i32> inreg %buf) {
; CHECK-NEXT: s_mov_b64 s[64:65], 0
; CHECK-NEXT: v_nop
; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
-; CHECK-NEXT: s_buffer_load_b32 s0, s[0:3], 0x10 nv
+; CHECK-NEXT: s_buffer_load_u16 s0, s[0:3], 0x10 nv
; CHECK-NEXT: s_wait_kmcnt 0x0
-; CHECK-NEXT: s_and_b32 s0, s0, 0xffff
; CHECK-NEXT: ; return to shader part epilog
%val = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %buf, i32 16, i32 0)
%masked = and i32 %val, 65535
@@ -139,9 +133,8 @@ define amdgpu_cs i32 @s_buffer_load_i8_imm(<4 x i32> inreg %buf) {
; CHECK-NEXT: s_mov_b64 s[64:65], 0
; CHECK-NEXT: v_nop
; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
-; CHECK-NEXT: s_buffer_load_b32 s0, s[0:3], 0x10 nv
+; CHECK-NEXT: s_buffer_load_i8 s0, s[0:3], 0x10 nv
; CHECK-NEXT: s_wait_kmcnt 0x0
-; CHECK-NEXT: s_sext_i32_i8 s0, s0
; CHECK-NEXT: ; return to shader part epilog
%val = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %buf, i32 16, i32 0)
%trunc = trunc i32 %val to i8
@@ -156,9 +149,8 @@ define amdgpu_cs i32 @s_buffer_load_i16_imm(<4 x i32> inreg %buf) {
; CHECK-NEXT: s_mov_b64 s[64:65], 0
; CHECK-NEXT: v_nop
; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
-; CHECK-NEXT: s_buffer_load_b32 s0, s[0:3], 0x10 nv
+; CHECK-NEXT: s_buffer_load_i16 s0, s[0:3], 0x10 nv
; CHECK-NEXT: s_wait_kmcnt 0x0
-; CHECK-NEXT: s_sext_i32_i16 s0, s0
; CHECK-NEXT: ; return to shader part epilog
%val = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %buf, i32 16, i32 0)
%trunc = trunc i32 %val to i16
@@ -177,9 +169,8 @@ define amdgpu_cs i32 @s_buffer_load_u8_sgpr(<4 x i32> inreg %buf, i32 inreg %off
; CHECK-NEXT: s_mov_b64 s[64:65], 0
; CHECK-NEXT: v_nop
; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
-; CHECK-NEXT: s_buffer_load_b32 s0, s[0:3], s4 offset:0x0 nv
+; CHECK-NEXT: s_buffer_load_u8 s0, s[0:3], s4 offset:0x0 nv
; CHECK-NEXT: s_wait_kmcnt 0x0
-; CHECK-NEXT: s_and_b32 s0, s0, 0xff
; CHECK-NEXT: ; return to shader part epilog
%val = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %buf, i32 %offset, i32 0)
%masked = and i32 %val, 255
@@ -193,9 +184,8 @@ define amdgpu_cs i32 @s_buffer_load_u16_sgpr(<4 x i32> inreg %buf, i32 inreg %of
; CHECK-NEXT: s_mov_b64 s[64:65], 0
; CHECK-NEXT: v_nop
; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
-; CHECK-NEXT: s_buffer_load_b32 s0, s[0:3], s4 offset:0x0 nv
+; CHECK-NEXT: s_buffer_load_u16 s0, s[0:3], s4 offset:0x0 nv
; CHECK-NEXT: s_wait_kmcnt 0x0
-; CHECK-NEXT: s_and_b32 s0, s0, 0xffff
; CHECK-NEXT: ; return to shader part epilog
%val = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %buf, i32 %offset, i32 0)
%masked = and i32 %val, 65535
@@ -209,9 +199,8 @@ define amdgpu_cs i32 @s_buffer_load_i8_sgpr(<4 x i32> inreg %buf, i32 inreg %off
; CHECK-NEXT: s_mov_b64 s[64:65], 0
; CHECK-NEXT: v_nop
; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
-; CHECK-NEXT: s_buffer_load_b32 s0, s[0:3], s4 offset:0x0 nv
+; CHECK-NEXT: s_buffer_load_i8 s0, s[0:3], s4 offset:0x0 nv
; CHECK-NEXT: s_wait_kmcnt 0x0
-; CHECK-NEXT: s_sext_i32_i8 s0, s0
; CHECK-NEXT: ; return to shader part epilog
%val = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %buf, i32 %offset, i32 0)
%trunc = trunc i32 %val to i8
@@ -226,9 +215,8 @@ define amdgpu_cs i32 @s_buffer_load_i16_sgpr(<4 x i32> inreg %buf, i32 inreg %of
; CHECK-NEXT: s_mov_b64 s[64:65], 0
; CHECK-NEXT: v_nop
; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
-; CHECK-NEXT: s_buffer_load_b32 s0, s[0:3], s4 offset:0x0 nv
+; CHECK-NEXT: s_buffer_load_i16 s0, s[0:3], s4 offset:0x0 nv
; CHECK-NEXT: s_wait_kmcnt 0x0
-; CHECK-NEXT: s_sext_i32_i16 s0, s0
; CHECK-NEXT: ; return to shader part epilog
%val = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %buf, i32 %offset, i32 0)
%trunc = trunc i32 %val to i16
diff --git a/llvm/test/CodeGen/AMDGPU/si-load-opt-scalar-subword.mir b/llvm/test/CodeGen/AMDGPU/si-load-opt-scalar-subword.mir
index c65dc6cb32764..913849fb2f7f5 100644
--- a/llvm/test/CodeGen/AMDGPU/si-load-opt-scalar-subword.mir
+++ b/llvm/test/CodeGen/AMDGPU/si-load-opt-scalar-subword.mir
@@ -1,9 +1,9 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
-# RUN: llc -mtriple=amdgcn -mcpu=gfx1250 -run-pass=si-load-store-opt %s -o - | FileCheck %s
+# RUN: llc -mtriple=amdgpu12.50 -run-pass=si-load-store-opt %s -o - | FileCheck %s
# Test scalar subword load optimization at MIR level
-# Tests all combinations of: {u8, u16, i8, i16} × {IMM, SGPR, SGPR_IMM} addressing modes
-# for both S_LOAD and S_BUFFER_LOAD variants
+# Tests all combinations of: {S_LOAD: IMM, SGPR } x {u8, u16, i8, i16}
+# Tests all combinations of: {S_BUFFER_LOAD: IMM, SGPR, SGPR_IMM} x {u8, u16, i8, i16}
---
name: s_load_u8_imm
@@ -17,9 +17,8 @@ body: |
; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1
- ; CHECK-NEXT: [[S_LOAD_DWORD_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
- ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_LOAD_DWORD_IMM]], 255, implicit-def $scc
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ ; CHECK-NEXT: [[S_LOAD_U8_IMM:%[0-9]+]]:sreg_32 = S_LOAD_U8_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_LOAD_U8_IMM]]
%1:sgpr_32 = COPY $sgpr1
%0:sgpr_32 = COPY $sgpr0
%2:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
@@ -40,9 +39,8 @@ body: |
; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1
- ; CHECK-NEXT: [[S_LOAD_DWORD_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
- ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_LOAD_DWORD_IMM]], 65535, implicit-def $scc
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ ; CHECK-NEXT: [[S_LOAD_U16_IMM:%[0-9]+]]:sreg_32 = S_LOAD_U16_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_LOAD_U16_IMM]]
%1:sgpr_32 = COPY $sgpr1
%0:sgpr_32 = COPY $sgpr0
%2:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
@@ -63,9 +61,8 @@ body: |
; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1
- ; CHECK-NEXT: [[S_LOAD_DWORD_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
- ; CHECK-NEXT: [[S_SEXT_I32_I8_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I8 [[S_LOAD_DWORD_IMM]]
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I8_]]
+ ; CHECK-NEXT: [[S_LOAD_I8_IMM:%[0-9]+]]:sreg_32 = S_LOAD_I8_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_LOAD_I8_IMM]]
%1:sgpr_32 = COPY $sgpr1
%0:sgpr_32 = COPY $sgpr0
%2:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
@@ -86,9 +83,8 @@ body: |
; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY1]], %subreg.sub0, [[COPY]], %subreg.sub1
- ; CHECK-NEXT: [[S_LOAD_DWORD_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
- ; CHECK-NEXT: [[S_SEXT_I32_I16_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I16 [[S_LOAD_DWORD_IMM]]
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I16_]]
+ ; CHECK-NEXT: [[S_LOAD_I16_IMM:%[0-9]+]]:sreg_32 = S_LOAD_I16_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_LOAD_I16_IMM]]
%1:sgpr_32 = COPY $sgpr1
%0:sgpr_32 = COPY $sgpr0
%2:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
@@ -110,9 +106,8 @@ body: |
; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1
- ; CHECK-NEXT: [[S_LOAD_DWORD_SGPR:%[0-9]+]]:sreg_32_xm0_xexec = S_LOAD_DWORD_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
- ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_LOAD_DWORD_SGPR]], 255, implicit-def $scc
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ ; CHECK-NEXT: [[S_LOAD_U8_SGPR:%[0-9]+]]:sreg_32 = S_LOAD_U8_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_LOAD_U8_SGPR]]
%2:sgpr_32 = COPY $sgpr2
%1:sgpr_32 = COPY $sgpr1
%0:sgpr_32 = COPY $sgpr0
@@ -135,9 +130,8 @@ body: |
; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1
- ; CHECK-NEXT: [[S_LOAD_DWORD_SGPR:%[0-9]+]]:sreg_32_xm0_xexec = S_LOAD_DWORD_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
- ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_LOAD_DWORD_SGPR]], 65535, implicit-def $scc
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ ; CHECK-NEXT: [[S_LOAD_U16_SGPR:%[0-9]+]]:sreg_32 = S_LOAD_U16_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_LOAD_U16_SGPR]]
%2:sgpr_32 = COPY $sgpr2
%1:sgpr_32 = COPY $sgpr1
%0:sgpr_32 = COPY $sgpr0
@@ -160,9 +154,8 @@ body: |
; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1
- ; CHECK-NEXT: [[S_LOAD_DWORD_SGPR:%[0-9]+]]:sreg_32_xm0_xexec = S_LOAD_DWORD_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
- ; CHECK-NEXT: [[S_SEXT_I32_I8_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I8 [[S_LOAD_DWORD_SGPR]]
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I8_]]
+ ; CHECK-NEXT: [[S_LOAD_I8_SGPR:%[0-9]+]]:sreg_32 = S_LOAD_I8_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_LOAD_I8_SGPR]]
%2:sgpr_32 = COPY $sgpr2
%1:sgpr_32 = COPY $sgpr1
%0:sgpr_32 = COPY $sgpr0
@@ -185,9 +178,8 @@ body: |
; CHECK-NEXT: [[COPY1:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY2]], %subreg.sub0, [[COPY1]], %subreg.sub1
- ; CHECK-NEXT: [[S_LOAD_DWORD_SGPR:%[0-9]+]]:sreg_32_xm0_xexec = S_LOAD_DWORD_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
- ; CHECK-NEXT: [[S_SEXT_I32_I16_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I16 [[S_LOAD_DWORD_SGPR]]
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I16_]]
+ ; CHECK-NEXT: [[S_LOAD_I16_SGPR:%[0-9]+]]:sreg_32 = S_LOAD_I16_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_LOAD_I16_SGPR]]
%2:sgpr_32 = COPY $sgpr2
%1:sgpr_32 = COPY $sgpr1
%0:sgpr_32 = COPY $sgpr0
@@ -211,9 +203,8 @@ body: |
; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY1]], %subreg.sub2, [[COPY]], %subreg.sub3
- ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
- ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_BUFFER_LOAD_DWORD_IMM]], 255, implicit-def $scc
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_U8_IMM:%[0-9]+]]:sreg_32 = S_BUFFER_LOAD_U8_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_BUFFER_LOAD_U8_IMM]]
%3:sgpr_32 = COPY $sgpr3
%2:sgpr_32 = COPY $sgpr2
%1:sgpr_32 = COPY $sgpr1
@@ -238,9 +229,8 @@ body: |
; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY1]], %subreg.sub2, [[COPY]], %subreg.sub3
- ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
- ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_BUFFER_LOAD_DWORD_IMM]], 65535, implicit-def $scc
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_U16_IMM:%[0-9]+]]:sreg_32 = S_BUFFER_LOAD_U16_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_BUFFER_LOAD_U16_IMM]]
%3:sgpr_32 = COPY $sgpr3
%2:sgpr_32 = COPY $sgpr2
%1:sgpr_32 = COPY $sgpr1
@@ -265,9 +255,8 @@ body: |
; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY1]], %subreg.sub2, [[COPY]], %subreg.sub3
- ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
- ; CHECK-NEXT: [[S_SEXT_I32_I8_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I8 [[S_BUFFER_LOAD_DWORD_IMM]]
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I8_]]
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_I8_IMM:%[0-9]+]]:sreg_32 = S_BUFFER_LOAD_I8_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_BUFFER_LOAD_I8_IMM]]
%3:sgpr_32 = COPY $sgpr3
%2:sgpr_32 = COPY $sgpr2
%1:sgpr_32 = COPY $sgpr1
@@ -292,9 +281,8 @@ body: |
; CHECK-NEXT: [[COPY2:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY3]], %subreg.sub0, [[COPY2]], %subreg.sub1, [[COPY1]], %subreg.sub2, [[COPY]], %subreg.sub3
- ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
- ; CHECK-NEXT: [[S_SEXT_I32_I16_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I16 [[S_BUFFER_LOAD_DWORD_IMM]]
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I16_]]
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_I16_IMM:%[0-9]+]]:sreg_32 = S_BUFFER_LOAD_I16_IMM [[REG_SEQUENCE]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_BUFFER_LOAD_I16_IMM]]
%3:sgpr_32 = COPY $sgpr3
%2:sgpr_32 = COPY $sgpr2
%1:sgpr_32 = COPY $sgpr1
@@ -320,9 +308,8 @@ body: |
; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3
- ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_SGPR:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
- ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_BUFFER_LOAD_DWORD_SGPR]], 255, implicit-def $scc
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_U8_SGPR:%[0-9]+]]:sreg_32 = S_BUFFER_LOAD_U8_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_BUFFER_LOAD_U8_SGPR]]
%4:sgpr_32 = COPY $sgpr4
%3:sgpr_32 = COPY $sgpr3
%2:sgpr_32 = COPY $sgpr2
@@ -349,9 +336,8 @@ body: |
; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3
- ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_SGPR:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
- ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_BUFFER_LOAD_DWORD_SGPR]], 65535, implicit-def $scc
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_U16_SGPR:%[0-9]+]]:sreg_32 = S_BUFFER_LOAD_U16_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_BUFFER_LOAD_U16_SGPR]]
%4:sgpr_32 = COPY $sgpr4
%3:sgpr_32 = COPY $sgpr3
%2:sgpr_32 = COPY $sgpr2
@@ -378,9 +364,8 @@ body: |
; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3
- ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_SGPR:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
- ; CHECK-NEXT: [[S_SEXT_I32_I8_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I8 [[S_BUFFER_LOAD_DWORD_SGPR]]
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I8_]]
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_I8_SGPR:%[0-9]+]]:sreg_32 = S_BUFFER_LOAD_I8_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_BUFFER_LOAD_I8_SGPR]]
%4:sgpr_32 = COPY $sgpr4
%3:sgpr_32 = COPY $sgpr3
%2:sgpr_32 = COPY $sgpr2
@@ -407,9 +392,8 @@ body: |
; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3
- ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_SGPR:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
- ; CHECK-NEXT: [[S_SEXT_I32_I16_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I16 [[S_BUFFER_LOAD_DWORD_SGPR]]
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I16_]]
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_I16_SGPR:%[0-9]+]]:sreg_32 = S_BUFFER_LOAD_I16_SGPR [[REG_SEQUENCE]], [[COPY]], 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_BUFFER_LOAD_I16_SGPR]]
%4:sgpr_32 = COPY $sgpr4
%3:sgpr_32 = COPY $sgpr3
%2:sgpr_32 = COPY $sgpr2
@@ -436,9 +420,8 @@ body: |
; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3
- ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_SGPR_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR_IMM [[REG_SEQUENCE]], [[COPY]], 16, 0 :: (load (s32))
- ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_BUFFER_LOAD_DWORD_SGPR_IMM]], 255, implicit-def $scc
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_U8_SGPR_IMM:%[0-9]+]]:sreg_32 = S_BUFFER_LOAD_U8_SGPR_IMM [[REG_SEQUENCE]], [[COPY]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_BUFFER_LOAD_U8_SGPR_IMM]]
%4:sgpr_32 = COPY $sgpr4
%3:sgpr_32 = COPY $sgpr3
%2:sgpr_32 = COPY $sgpr2
@@ -465,9 +448,8 @@ body: |
; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3
- ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_SGPR_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR_IMM [[REG_SEQUENCE]], [[COPY]], 16, 0 :: (load (s32))
- ; CHECK-NEXT: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_BUFFER_LOAD_DWORD_SGPR_IMM]], 65535, implicit-def $scc
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_AND_B32_]]
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_U16_SGPR_IMM:%[0-9]+]]:sreg_32 = S_BUFFER_LOAD_U16_SGPR_IMM [[REG_SEQUENCE]], [[COPY]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_BUFFER_LOAD_U16_SGPR_IMM]]
%4:sgpr_32 = COPY $sgpr4
%3:sgpr_32 = COPY $sgpr3
%2:sgpr_32 = COPY $sgpr2
@@ -494,9 +476,8 @@ body: |
; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3
- ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_SGPR_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR_IMM [[REG_SEQUENCE]], [[COPY]], 16, 0 :: (load (s32))
- ; CHECK-NEXT: [[S_SEXT_I32_I8_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I8 [[S_BUFFER_LOAD_DWORD_SGPR_IMM]]
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I8_]]
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_I8_SGPR_IMM:%[0-9]+]]:sreg_32 = S_BUFFER_LOAD_I8_SGPR_IMM [[REG_SEQUENCE]], [[COPY]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_BUFFER_LOAD_I8_SGPR_IMM]]
%4:sgpr_32 = COPY $sgpr4
%3:sgpr_32 = COPY $sgpr3
%2:sgpr_32 = COPY $sgpr2
@@ -523,9 +504,8 @@ body: |
; CHECK-NEXT: [[COPY3:%[0-9]+]]:sgpr_32 = COPY $sgpr1
; CHECK-NEXT: [[COPY4:%[0-9]+]]:sgpr_32 = COPY $sgpr0
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sgpr_128 = REG_SEQUENCE [[COPY4]], %subreg.sub0, [[COPY3]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY1]], %subreg.sub3
- ; CHECK-NEXT: [[S_BUFFER_LOAD_DWORD_SGPR_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_BUFFER_LOAD_DWORD_SGPR_IMM [[REG_SEQUENCE]], [[COPY]], 16, 0 :: (load (s32))
- ; CHECK-NEXT: [[S_SEXT_I32_I16_:%[0-9]+]]:sreg_32 = S_SEXT_I32_I16 [[S_BUFFER_LOAD_DWORD_SGPR_IMM]]
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_SEXT_I32_I16_]]
+ ; CHECK-NEXT: [[S_BUFFER_LOAD_I16_SGPR_IMM:%[0-9]+]]:sreg_32 = S_BUFFER_LOAD_I16_SGPR_IMM [[REG_SEQUENCE]], [[COPY]], 16, 0 :: (load (s32))
+ ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_BUFFER_LOAD_I16_SGPR_IMM]]
%4:sgpr_32 = COPY $sgpr4
%3:sgpr_32 = COPY $sgpr3
%2:sgpr_32 = COPY $sgpr2
More information about the llvm-commits
mailing list