[llvm] [AMDGPU][GISel] Fold 'min(min(x,y),z)' and 'max(max(x,y),z)' into min3 and max3 (PR #200410)
Petar Avramovic via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 6 09:28:11 PDT 2026
================
@@ -481,6 +491,75 @@ bool AMDGPURegBankCombinerImpl::combineD16Load(MachineInstr &MI) const {
return false;
}
+void AMDGPURegBankCombinerImpl::applyMinMaxToMinMax3(
+ MachineInstr &MI, MinMaxToMinMax3MatchInfo &MatchInfo) const {
+ B.buildInstr(MatchInfo.Opc, {MI.getOperand(0)},
+ {MatchInfo.Val0, MatchInfo.Val1, MatchInfo.Val2}, MI.getFlags());
+ MI.eraseFromParent();
+ return;
+}
+
+// min(min(a, b), c) == min(a, min(b, c)) == min3(a, b, c)
+// supported scalar type: S32 S16 U32 U16 F32 F16
+bool AMDGPURegBankCombinerImpl::matchMinMaxToMinMax3(
+ MachineInstr &MI, MinMaxToMinMax3MatchInfo &MatchInfo) const {
+ Register Dst = MI.getOperand(0).getReg();
+ Register Src1 = MI.getOperand(1).getReg();
+ Register Src2 = MI.getOperand(2).getReg();
+ // If the register is SGPR, don't optimize it.
+ if (!(isVgprRegBank(Dst) && isVgprRegBank(Src1) && isVgprRegBank(Src2))) {
+ return false;
+ }
+
+ LLT Ty = MRI.getType(Dst);
+ unsigned Opc = MI.getOpcode();
+ bool IsSupportedTy =
+ Ty == LLT::scalar(32) || (Ty == LLT::scalar(16) && STI.hasMin3Max3_16());
+ if (!IsSupportedTy)
+ return false;
+
+ Register R0, R1, R2;
+ if (!mi_match(MI, MRI,
+ m_CommutativeBinOp(
+ Opc, m_OneNonDBGUse(m_BinOp(Opc, m_Reg(R0), m_Reg(R1))),
+ m_Reg(R2)))) {
+ return false;
+ }
+
+ auto getAMDGPUOp = [](unsigned Opc) -> unsigned {
+ switch (Opc) {
+ case AMDGPU::G_SMAX:
+ return AMDGPU::G_AMDGPU_SMAX3;
+ case AMDGPU::G_SMIN:
+ return AMDGPU::G_AMDGPU_SMIN3;
+ case AMDGPU::G_UMAX:
+ return AMDGPU::G_AMDGPU_UMAX3;
+ case AMDGPU::G_UMIN:
+ return AMDGPU::G_AMDGPU_UMIN3;
+ case AMDGPU::G_FMAXNUM:
+ case AMDGPU::G_FMAXNUM_IEEE:
+ return AMDGPU::G_AMDGPU_FMAX3;
+ case AMDGPU::G_FMINNUM:
+ case AMDGPU::G_FMINNUM_IEEE:
+ return AMDGPU::G_AMDGPU_FMIN3;
+ case AMDGPU::G_FMAXIMUM:
+ case AMDGPU::G_FMAXIMUMNUM:
+ return AMDGPU::G_AMDGPU_FMAXIMUM3;
+ case AMDGPU::G_FMINIMUM:
+ case AMDGPU::G_FMINIMUMNUM:
+ return AMDGPU::G_AMDGPU_FMINIMUM3;
+ default:
+ return 0;
+ }
+ };
+ unsigned AMDGPUOpc = getAMDGPUOp(Opc);
+ if (!AMDGPUOpc)
----------------
petar-avramovic wrote:
think it is better to write switch and avoid getAMDGPUOp, somethign line this
```
switch (Opc) {
case AMDGPU::G_SMAX:
AMDGPUOpc = AMDGPU::G_AMDGPU_SMAX3;
break;
...
default:
return false;
```
https://github.com/llvm/llvm-project/pull/200410
More information about the llvm-commits
mailing list