[llvm-branch-commits] [llvm] [AMDGPU] Fold sreg32 operand across Lo16 subcopy (PR #217999)
Guo Chen via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Sep 9 10:51:40 PDT 2026
https://github.com/broxigarchen updated https://github.com/llvm/llvm-project/pull/217999
>From 7a34294990feee3d7a40baeeb705ebf41e1f43dd Mon Sep 17 00:00:00 2001
From: guochen2 <guochen2 at amd.com>
Date: Mon, 10 Aug 2026 13:47:41 -0400
Subject: [PATCH] fold sgpr32 via vgpr16
---
llvm/lib/Target/AMDGPU/SIFoldOperands.cpp | 57 ++++++++
llvm/test/CodeGen/AMDGPU/GlobalISel/fshl.ll | 84 ++++--------
.../GlobalISel/fshr-new-regbank-select.ll | 4 +-
llvm/test/CodeGen/AMDGPU/GlobalISel/fshr.ll | 15 +-
.../inst-select-amdgcn.class.s16.mir | 3 +-
.../CodeGen/AMDGPU/llvm.amdgcn.alignbyte.ll | 4 +-
llvm/test/CodeGen/AMDGPU/true16-fold.mir | 128 ++++++++++++++++--
7 files changed, 207 insertions(+), 88 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp
index e5490b390db08..31038d2116f30 100644
--- a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp
+++ b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp
@@ -935,6 +935,24 @@ bool SIFoldOperandsImpl::tryAddToFoldList(
}
}
+ // Special case for valu16 using sreg32
+ // %1:vgpr32 = copy %0:sreg32/sregxx:sub_x
+ // VALU16 %1.lo16:vgpr16 ...
+ // =>
+ // VALU16 %0:sreg32/sregxx:sub_x...
+ // Hack to allow 32-bit SGPRs to be folded into True16 instructions
+ // Remove this if 16-bit SGPRs (i.e. SGPR_LO16) are added to the
+ // VS_16RegClass
+ if (OpToFold.isReg() && OpToFold.DefSubReg == AMDGPU::lo16 &&
+ TRI->isSGPRReg(*MRI, OpToFold.getReg())) {
+ FoldableDef NewOpToFold(*OpToFold.OpToFold, OpToFold.DefRC,
+ AMDGPU::NoSubRegister);
+ if (NewOpToFold.isOperandLegal(*TII, *MI, OpNo)) {
+ appendFoldCandidate(FoldList, MI, OpNo, NewOpToFold);
+ return true;
+ }
+ }
+
// Operand is not legal, so try to commute the instruction to
// see if this makes it possible to fold.
unsigned CommuteOpNo = TargetInstrInfo::CommuteAnyOperandIndex;
@@ -1538,6 +1556,45 @@ bool SIFoldOperandsImpl::foldOperand(
return true;
}
+ // Look through Lo16 Copy
+ // OpToFold: %0
+ // %1:vgpr32 = copy %0:sreg32/sregxx:sub_x
+ // %2:vgpr16 = copy %1.lo16:vgpr32 (UseMI)
+ // VALU16 %2:vgpr16 ...
+ // =>
+ // VALU16 %0:sreg32/sregxx:sub_x...
+ // Hack to allow 32-bit SGPRs to be folded into True16 instructions
+ // Remove this if 16-bit SGPRs (i.e. SGPR_LO16) are added to the
+ // VS_16RegClass
+ if (UseMI->isCopy() && OpToFold.isReg() &&
+ UseMI->getOperand(0).getReg().isVirtual() &&
+ TRI->isSGPRReg(*MRI, OpToFold.getReg()) &&
+ TII->getOpSize(*UseMI, 0) == 2 &&
+ UseMI->getOperand(1).getSubReg() == AMDGPU::lo16 &&
+ OpToFold.DefMI->implicit_operands().empty()) {
+
+ // Append Users of the UseMI instead
+ SmallVector<MachineOperand *, 4> UsesToProcess(llvm::make_pointer_range(
+ MRI->use_nodbg_operands(UseMI->getOperand(0).getReg())));
+ for (auto *U : UsesToProcess) {
+ MachineInstr *NextMI = U->getParent();
+
+ const MCInstrDesc &UseDesc = NextMI->getDesc();
+ if (UseDesc.isVariadic() || U->isImplicit() ||
+ UseDesc.operands()[NextMI->getOperandNo(U)].RegClass == -1)
+ continue;
+
+ FoldableDef NextOpToFold(*OpToFold.OpToFold, OpToFold.DefRC,
+ U->getSubReg());
+ LLVM_DEBUG(dbgs() << "Folding " << *NextOpToFold.OpToFold
+ << "\n through" << *UseMI << " into " << *NextMI);
+
+ Changed |= tryAddToFoldList(FoldList, NextMI, NextMI->getOperandNo(U),
+ NextOpToFold);
+ }
+ return Changed;
+ }
+
unsigned UseOpc = UseMI->getOpcode();
if (UseOpc == AMDGPU::V_READFIRSTLANE_B32 ||
(UseOpc == AMDGPU::V_READLANE_B32 &&
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/fshl.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/fshl.ll
index 571877ecaea9a..7d92ff45a7d59 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/fshl.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/fshl.ll
@@ -3008,28 +3008,16 @@ define amdgpu_ps i32 @s_fshl_i32(i32 inreg %lhs, i32 inreg %rhs, i32 inreg %amt)
; GFX10-NEXT: v_readfirstlane_b32 s0, v0
; GFX10-NEXT: ; return to shader part epilog
;
-; GFX11-TRUE16-LABEL: s_fshl_i32:
-; GFX11-TRUE16: ; %bb.0:
-; GFX11-TRUE16-NEXT: s_not_b32 s2, s2
-; GFX11-TRUE16-NEXT: v_alignbit_b32 v0, s0, s1, 1
-; GFX11-TRUE16-NEXT: v_mov_b32_e32 v1, s2
-; GFX11-TRUE16-NEXT: s_lshr_b32 s0, s0, 1
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
-; GFX11-TRUE16-NEXT: v_alignbit_b32 v0, s0, v0, v1.l
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
-; GFX11-TRUE16-NEXT: v_readfirstlane_b32 s0, v0
-; GFX11-TRUE16-NEXT: ; return to shader part epilog
-;
-; GFX11-FAKE16-LABEL: s_fshl_i32:
-; GFX11-FAKE16: ; %bb.0:
-; GFX11-FAKE16-NEXT: v_alignbit_b32 v0, s0, s1, 1
-; GFX11-FAKE16-NEXT: s_lshr_b32 s0, s0, 1
-; GFX11-FAKE16-NEXT: s_not_b32 s1, s2
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
-; GFX11-FAKE16-NEXT: v_alignbit_b32 v0, s0, v0, s1
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_readfirstlane_b32 s0, v0
-; GFX11-FAKE16-NEXT: ; return to shader part epilog
+; GFX11-LABEL: s_fshl_i32:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: v_alignbit_b32 v0, s0, s1, 1
+; GFX11-NEXT: s_lshr_b32 s0, s0, 1
+; GFX11-NEXT: s_not_b32 s1, s2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_alignbit_b32 v0, s0, v0, s1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT: v_readfirstlane_b32 s0, v0
+; GFX11-NEXT: ; return to shader part epilog
%result = call i32 @llvm.fshl.i32(i32 %lhs, i32 %rhs, i32 %amt)
ret i32 %result
}
@@ -3269,24 +3257,14 @@ define amdgpu_ps float @v_fshl_i32_svs(i32 inreg %lhs, i32 %rhs, i32 inreg %amt)
; GFX10-NEXT: v_alignbit_b32 v0, s0, v0, s1
; GFX10-NEXT: ; return to shader part epilog
;
-; GFX11-TRUE16-LABEL: v_fshl_i32_svs:
-; GFX11-TRUE16: ; %bb.0:
-; GFX11-TRUE16-NEXT: s_not_b32 s1, s1
-; GFX11-TRUE16-NEXT: v_alignbit_b32 v0, s0, v0, 1
-; GFX11-TRUE16-NEXT: v_mov_b32_e32 v1, s1
-; GFX11-TRUE16-NEXT: s_lshr_b32 s0, s0, 1
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
-; GFX11-TRUE16-NEXT: v_alignbit_b32 v0, s0, v0, v1.l
-; GFX11-TRUE16-NEXT: ; return to shader part epilog
-;
-; GFX11-FAKE16-LABEL: v_fshl_i32_svs:
-; GFX11-FAKE16: ; %bb.0:
-; GFX11-FAKE16-NEXT: v_alignbit_b32 v0, s0, v0, 1
-; GFX11-FAKE16-NEXT: s_lshr_b32 s0, s0, 1
-; GFX11-FAKE16-NEXT: s_not_b32 s1, s1
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
-; GFX11-FAKE16-NEXT: v_alignbit_b32 v0, s0, v0, s1
-; GFX11-FAKE16-NEXT: ; return to shader part epilog
+; GFX11-LABEL: v_fshl_i32_svs:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: v_alignbit_b32 v0, s0, v0, 1
+; GFX11-NEXT: s_lshr_b32 s0, s0, 1
+; GFX11-NEXT: s_not_b32 s1, s1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_alignbit_b32 v0, s0, v0, s1
+; GFX11-NEXT: ; return to shader part epilog
%result = call i32 @llvm.fshl.i32(i32 %lhs, i32 %rhs, i32 %amt)
%cast.result = bitcast i32 %result to float
ret float %cast.result
@@ -3331,24 +3309,14 @@ define amdgpu_ps float @v_fshl_i32_vss(i32 inreg %lhs, i32 inreg %rhs, i32 inreg
; GFX10-NEXT: v_alignbit_b32 v0, s0, v0, s1
; GFX10-NEXT: ; return to shader part epilog
;
-; GFX11-TRUE16-LABEL: v_fshl_i32_vss:
-; GFX11-TRUE16: ; %bb.0:
-; GFX11-TRUE16-NEXT: s_not_b32 s2, s2
-; GFX11-TRUE16-NEXT: v_alignbit_b32 v0, s0, s1, 1
-; GFX11-TRUE16-NEXT: v_mov_b32_e32 v1, s2
-; GFX11-TRUE16-NEXT: s_lshr_b32 s0, s0, 1
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
-; GFX11-TRUE16-NEXT: v_alignbit_b32 v0, s0, v0, v1.l
-; GFX11-TRUE16-NEXT: ; return to shader part epilog
-;
-; GFX11-FAKE16-LABEL: v_fshl_i32_vss:
-; GFX11-FAKE16: ; %bb.0:
-; GFX11-FAKE16-NEXT: v_alignbit_b32 v0, s0, s1, 1
-; GFX11-FAKE16-NEXT: s_lshr_b32 s0, s0, 1
-; GFX11-FAKE16-NEXT: s_not_b32 s1, s2
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
-; GFX11-FAKE16-NEXT: v_alignbit_b32 v0, s0, v0, s1
-; GFX11-FAKE16-NEXT: ; return to shader part epilog
+; GFX11-LABEL: v_fshl_i32_vss:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: v_alignbit_b32 v0, s0, s1, 1
+; GFX11-NEXT: s_lshr_b32 s0, s0, 1
+; GFX11-NEXT: s_not_b32 s1, s2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_alignbit_b32 v0, s0, v0, s1
+; GFX11-NEXT: ; return to shader part epilog
%result = call i32 @llvm.fshl.i32(i32 %lhs, i32 %rhs, i32 %amt)
%cast.result = bitcast i32 %result to float
ret float %cast.result
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/fshr-new-regbank-select.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/fshr-new-regbank-select.ll
index 3e006544637a5..eaa417eb8ffa9 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/fshr-new-regbank-select.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/fshr-new-regbank-select.ll
@@ -6,7 +6,7 @@ define amdgpu_ps void @uniform_fshr_i32(i32 inreg %lhs, i32 inreg %rhs, i32 inre
; CHECK: ; %bb.0:
; CHECK-NEXT: v_mov_b32_e32 v2, s2
; CHECK-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
-; CHECK-NEXT: v_alignbit_b32 v2, s0, s1, v2
+; CHECK-NEXT: v_alignbit_b32 v2, s0, s1, v2.l
; CHECK-NEXT: v_readfirstlane_b32 s0, v2
; CHECK-NEXT: s_add_co_i32 s0, s0, s0
; CHECK-NEXT: s_wait_alu depctr_sa_sdst(0)
@@ -24,7 +24,7 @@ declare i32 @llvm.amdgcn.readfirstlane.i32(i32)
define amdgpu_ps void @divergent_fshr_i32(i32 %lhs, i32 %rhs, i32 %amt, ptr %resptr) {
; CHECK-LABEL: divergent_fshr_i32:
; CHECK: ; %bb.0:
-; CHECK-NEXT: v_alignbit_b32 v0, v0, v1, v2
+; CHECK-NEXT: v_alignbit_b32 v0, v0, v1, v2.l
; CHECK-NEXT: flat_store_b32 v[3:4], v0
; CHECK-NEXT: s_endpgm
%result = call i32 @llvm.fshr.i32(i32 %lhs, i32 %rhs, i32 %amt)
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/fshr.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/fshr.ll
index 878bda7c7ec22..351a7f7c6705d 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/fshr.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/fshr.ll
@@ -3240,17 +3240,10 @@ define amdgpu_ps float @v_fshr_i32_svs(i32 inreg %lhs, i32 %rhs, i32 inreg %amt)
; GFX10-NEXT: v_alignbit_b32 v0, s0, v0, s1
; GFX10-NEXT: ; return to shader part epilog
;
-; GFX11-TRUE16-LABEL: v_fshr_i32_svs:
-; GFX11-TRUE16: ; %bb.0:
-; GFX11-TRUE16-NEXT: v_mov_b32_e32 v1, s1
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
-; GFX11-TRUE16-NEXT: v_alignbit_b32 v0, s0, v0, v1.l
-; GFX11-TRUE16-NEXT: ; return to shader part epilog
-;
-; GFX11-FAKE16-LABEL: v_fshr_i32_svs:
-; GFX11-FAKE16: ; %bb.0:
-; GFX11-FAKE16-NEXT: v_alignbit_b32 v0, s0, v0, s1
-; GFX11-FAKE16-NEXT: ; return to shader part epilog
+; GFX11-LABEL: v_fshr_i32_svs:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: v_alignbit_b32 v0, s0, v0, s1
+; GFX11-NEXT: ; return to shader part epilog
%result = call i32 @llvm.fshr.i32(i32 %lhs, i32 %rhs, i32 %amt)
%cast.result = bitcast i32 %result to float
ret float %cast.result
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/inst-select-amdgcn.class.s16.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/inst-select-amdgcn.class.s16.mir
index b0587821eb116..df9d756bdd0bc 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/inst-select-amdgcn.class.s16.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/inst-select-amdgcn.class.s16.mir
@@ -136,8 +136,7 @@ body: |
; GFX11-FOLD-TRUE16-NEXT: {{ $}}
; GFX11-FOLD-TRUE16-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
; GFX11-FOLD-TRUE16-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr0
- ; GFX11-FOLD-TRUE16-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY [[COPY1]]
- ; GFX11-FOLD-TRUE16-NEXT: [[V_CMP_CLASS_F16_t16_e64_:%[0-9]+]]:sreg_32_xm0_xexec = V_CMP_CLASS_F16_t16_e64 0, [[COPY]].lo16, 0, [[COPY2]].lo16, 0, implicit $exec
+ ; GFX11-FOLD-TRUE16-NEXT: [[V_CMP_CLASS_F16_t16_e64_:%[0-9]+]]:sreg_32_xm0_xexec = V_CMP_CLASS_F16_t16_e64 0, [[COPY]].lo16, 0, [[COPY1]], 0, implicit $exec
; GFX11-FOLD-TRUE16-NEXT: S_ENDPGM 0, implicit [[V_CMP_CLASS_F16_t16_e64_]]
;
; GFX11-FOLD-FAKE16-LABEL: name: class_f16_vcc_vs
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.alignbyte.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.alignbyte.ll
index 361a1e88e5271..feb957eecc78c 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.alignbyte.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.alignbyte.ll
@@ -293,9 +293,7 @@ define amdgpu_kernel void @v_alignbyte_b32_2(ptr addrspace(1) %out, ptr addrspac
; GFX11-TRUE16-GISEL-NEXT: s_waitcnt vmcnt(0)
; GFX11-TRUE16-GISEL-NEXT: s_load_b32 s2, s[4:5], 0x3c
; GFX11-TRUE16-GISEL-NEXT: s_waitcnt lgkmcnt(0)
-; GFX11-TRUE16-GISEL-NEXT: v_mov_b32_e32 v2, s2
-; GFX11-TRUE16-GISEL-NEXT: s_delay_alu instid0(VALU_DEP_1)
-; GFX11-TRUE16-GISEL-NEXT: v_alignbyte_b32 v0, v1, v0, v2.l
+; GFX11-TRUE16-GISEL-NEXT: v_alignbyte_b32 v0, v1, v0, s2
; GFX11-TRUE16-GISEL-NEXT: v_mov_b32_e32 v1, 0
; GFX11-TRUE16-GISEL-NEXT: global_store_b32 v1, v0, s[0:1]
; GFX11-TRUE16-GISEL-NEXT: s_endpgm
diff --git a/llvm/test/CodeGen/AMDGPU/true16-fold.mir b/llvm/test/CodeGen/AMDGPU/true16-fold.mir
index 5dfabb938f1f9..b99b83efab516 100644
--- a/llvm/test/CodeGen/AMDGPU/true16-fold.mir
+++ b/llvm/test/CodeGen/AMDGPU/true16-fold.mir
@@ -267,19 +267,123 @@ body: |
...
---
-name: sgpr_hi16_copy_not_folded
+name: fold_sreg32_to_lo16_1
tracksRegLiveness: true
+registers:
body: |
bb.0:
- ; CHECK-LABEL: name: sgpr_hi16_copy_not_folded
- ; CHECK: [[DEF:%[0-9]+]]:sreg_32 = IMPLICIT_DEF
- ; CHECK-NEXT: [[DEF1:%[0-9]+]]:sreg_32 = IMPLICIT_DEF
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY [[DEF]].hi16
- ; CHECK-NEXT: [[S_PACK_LL_B32_B16_:%[0-9]+]]:sreg_32 = S_PACK_LL_B32_B16 [[DEF1]], killed [[COPY]], implicit-def dead $scc
- ; CHECK-NEXT: S_ENDPGM 0, implicit [[S_PACK_LL_B32_B16_]]
- %0:sreg_32 = IMPLICIT_DEF
- %1:sreg_32 = IMPLICIT_DEF
- %2:sreg_32 = COPY %0.hi16
- %3:sreg_32 = S_PACK_LL_B32_B16 %1, killed %2, implicit-def dead $scc
- S_ENDPGM 0, implicit %3
+ liveins: $sgpr0
+ ; CHECK-LABEL: name: fold_sreg32_to_lo16_1
+ ; CHECK: liveins: $sgpr0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[V_MAX_F16_t16_e64_:%[0-9]+]]:vgpr_16 = nofpexcept V_MAX_F16_t16_e64 0, [[COPY]], 0, [[COPY]], -1, 0, 0, implicit $mode, implicit $exec
+ ; CHECK-NEXT: S_ENDPGM 0
+ %0:sreg_32 = COPY $sgpr0
+ %1:vgpr_32 = COPY %0:sreg_32
+ %2:vgpr_16 = nofpexcept V_MAX_F16_t16_e64 0, %1.lo16, 0, %1.lo16, -1, 0, 0, implicit $mode, implicit $exec
+ S_ENDPGM 0
+...
+
+---
+name: fold_sreg32_to_lo16_2
+tracksRegLiveness: true
+registers:
+body: |
+ bb.0:
+ liveins: $sgpr0
+ ; CHECK-LABEL: name: fold_sreg32_to_lo16_2
+ ; CHECK: liveins: $sgpr0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:sreg_64 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[V_MAX_F16_t16_e64_:%[0-9]+]]:vgpr_16 = nofpexcept V_MAX_F16_t16_e64 0, [[DEF]].sub1, 0, [[DEF]].sub1, -1, 0, 0, implicit $mode, implicit $exec
+ ; CHECK-NEXT: S_ENDPGM 0
+ %0:sreg_64 = IMPLICIT_DEF
+ %1:vgpr_32 = COPY %0.sub1:sreg_64
+ %2:vgpr_16 = nofpexcept V_MAX_F16_t16_e64 0, %1.lo16, 0, %1.lo16, -1, 0, 0, implicit $mode, implicit $exec
+ S_ENDPGM 0
+...
+
+# Should not fold
+---
+name: fold_sreg32_to_hi16
+tracksRegLiveness: true
+registers:
+body: |
+ bb.0:
+ liveins: $sgpr0
+ ; CHECK-LABEL: name: fold_sreg32_to_hi16
+ ; CHECK: liveins: $sgpr0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY [[COPY]]
+ ; CHECK-NEXT: [[V_MAX_F16_t16_e64_:%[0-9]+]]:vgpr_16 = nofpexcept V_MAX_F16_t16_e64 0, [[COPY1]].hi16, 0, [[COPY1]].hi16, -1, 0, 0, implicit $mode, implicit $exec
+ ; CHECK-NEXT: S_ENDPGM 0
+ %0:sreg_32 = COPY $sgpr0
+ %1:vgpr_32 = COPY %0:sreg_32
+ %2:vgpr_16 = nofpexcept V_MAX_F16_t16_e64 0, %1.hi16, 0, %1.hi16, -1, 0, 0, implicit $mode, implicit $exec
+ S_ENDPGM 0
+...
+
+
+---
+name: fold_sreg32_cross_lo16_copy_1
+tracksRegLiveness: true
+registers:
+body: |
+ bb.0:
+ liveins: $sgpr0
+ ; CHECK-LABEL: name: fold_sreg32_cross_lo16_copy_1
+ ; CHECK: liveins: $sgpr0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[V_MAX_F16_t16_e64_:%[0-9]+]]:vgpr_16 = nofpexcept V_MAX_F16_t16_e64 0, [[COPY]], 0, [[COPY]], -1, 0, 0, implicit $mode, implicit $exec
+ ; CHECK-NEXT: S_ENDPGM 0
+ %0:sreg_32 = COPY $sgpr0
+ %1:vgpr_32 = COPY %0:sreg_32
+ %2:vgpr_16 = COPY %1.lo16:vgpr_32
+ %3:vgpr_16 = nofpexcept V_MAX_F16_t16_e64 0, %2, 0, %2, -1, 0, 0, implicit $mode, implicit $exec
+ S_ENDPGM 0
+...
+
+---
+name: fold_sreg32_cross_lo16_copy_2
+tracksRegLiveness: true
+registers:
+body: |
+ bb.0:
+ liveins: $sgpr0
+ ; CHECK-LABEL: name: fold_sreg32_cross_lo16_copy_2
+ ; CHECK: liveins: $sgpr0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:sreg_64 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[V_MAX_F16_t16_e64_:%[0-9]+]]:vgpr_16 = nofpexcept V_MAX_F16_t16_e64 0, [[DEF]].sub1, 0, [[DEF]].sub1, -1, 0, 0, implicit $mode, implicit $exec
+ ; CHECK-NEXT: S_ENDPGM 0
+ %0:sreg_64 = IMPLICIT_DEF
+ %1:vgpr_32 = COPY %0.sub1:sreg_64
+ %2:vgpr_16 = COPY %1.lo16:vgpr_32
+ %3:vgpr_16 = nofpexcept V_MAX_F16_t16_e64 0, %2, 0, %2, -1, 0, 0, implicit $mode, implicit $exec
+ S_ENDPGM 0
+...
+
+# Should not fold
+---
+name: fold_sreg32_cross_hi16
+tracksRegLiveness: true
+registers:
+body: |
+ bb.0:
+ liveins: $sgpr0
+ ; CHECK-LABEL: name: fold_sreg32_cross_hi16
+ ; CHECK: liveins: $sgpr0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY [[COPY]]
+ ; CHECK-NEXT: [[V_MAX_F16_t16_e64_:%[0-9]+]]:vgpr_16 = nofpexcept V_MAX_F16_t16_e64 0, [[COPY1]].hi16, 0, [[COPY1]].hi16, -1, 0, 0, implicit $mode, implicit $exec
+ ; CHECK-NEXT: S_ENDPGM 0
+ %0:sreg_32 = COPY $sgpr0
+ %1:vgpr_32 = COPY %0:sreg_32
+ %2:vgpr_16 = COPY %1.hi16:vgpr_32
+ %3:vgpr_16 = nofpexcept V_MAX_F16_t16_e64 0, %2, 0, %2, -1, 0, 0, implicit $mode, implicit $exec
+ S_ENDPGM 0
...
More information about the llvm-branch-commits
mailing list