[llvm] s390x: pattern match saturated truncation (PR #155377)
Folkert de Vries via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 26 04:15:01 PDT 2025
https://github.com/folkertdev updated https://github.com/llvm/llvm-project/pull/155377
>From 2d60ac3ae2eb54cb2a3c066f519bb84405008aef Mon Sep 17 00:00:00 2001
From: Folkert de Vries <folkert at folkertdev.nl>
Date: Tue, 26 Aug 2025 11:39:50 +0200
Subject: [PATCH 1/2] s390x: legalize smin/smax/umin/umax
---
.../Target/SystemZ/SystemZISelLowering.cpp | 3 ++
llvm/lib/Target/SystemZ/SystemZInstrVector.td | 32 +++++++++----------
2 files changed, 19 insertions(+), 16 deletions(-)
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index c73dc3021eb42..43c6e9a6d7514 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -492,6 +492,9 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
// Map SETCCs onto one of VCE, VCH or VCHL, swapping the operands
// and inverting the result as necessary.
setOperationAction(ISD::SETCC, VT, Custom);
+
+ setOperationAction({ISD::SMIN, ISD::UMIN, ISD::SMAX, ISD::UMAX}, VT,
+ Legal);
}
}
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrVector.td b/llvm/lib/Target/SystemZ/SystemZInstrVector.td
index 10de8b05cf45f..a5a121ba31711 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrVector.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrVector.td
@@ -680,19 +680,19 @@ let Predicates = [FeatureVector] in {
let isCommutable = 1 in {
// Maximum.
def VMX : BinaryVRRcGeneric<"vmx", 0xE7FF>;
- def VMXB : BinaryVRRc<"vmxb", 0xE7FF, null_frag, v128b, v128b, 0>;
- def VMXH : BinaryVRRc<"vmxh", 0xE7FF, null_frag, v128h, v128h, 1>;
- def VMXF : BinaryVRRc<"vmxf", 0xE7FF, null_frag, v128f, v128f, 2>;
- def VMXG : BinaryVRRc<"vmxg", 0xE7FF, null_frag, v128g, v128g, 3>;
+ def VMXB : BinaryVRRc<"vmxb", 0xE7FF, smax, v128b, v128b, 0>;
+ def VMXH : BinaryVRRc<"vmxh", 0xE7FF, smax, v128h, v128h, 1>;
+ def VMXF : BinaryVRRc<"vmxf", 0xE7FF, smax, v128f, v128f, 2>;
+ def VMXG : BinaryVRRc<"vmxg", 0xE7FF, smax, v128g, v128g, 3>;
let Predicates = [FeatureVectorEnhancements3] in
def VMXQ : BinaryVRRc<"vmxq", 0xE7FF, null_frag, v128q, v128q, 4>;
// Maximum logical.
def VMXL : BinaryVRRcGeneric<"vmxl", 0xE7FD>;
- def VMXLB : BinaryVRRc<"vmxlb", 0xE7FD, null_frag, v128b, v128b, 0>;
- def VMXLH : BinaryVRRc<"vmxlh", 0xE7FD, null_frag, v128h, v128h, 1>;
- def VMXLF : BinaryVRRc<"vmxlf", 0xE7FD, null_frag, v128f, v128f, 2>;
- def VMXLG : BinaryVRRc<"vmxlg", 0xE7FD, null_frag, v128g, v128g, 3>;
+ def VMXLB : BinaryVRRc<"vmxlb", 0xE7FD, umax, v128b, v128b, 0>;
+ def VMXLH : BinaryVRRc<"vmxlh", 0xE7FD, umax, v128h, v128h, 1>;
+ def VMXLF : BinaryVRRc<"vmxlf", 0xE7FD, umax, v128f, v128f, 2>;
+ def VMXLG : BinaryVRRc<"vmxlg", 0xE7FD, umax, v128g, v128g, 3>;
let Predicates = [FeatureVectorEnhancements3] in
def VMXLQ : BinaryVRRc<"vmxlq", 0xE7FD, null_frag, v128q, v128q, 4>;
}
@@ -700,19 +700,19 @@ let Predicates = [FeatureVector] in {
let isCommutable = 1 in {
// Minimum.
def VMN : BinaryVRRcGeneric<"vmn", 0xE7FE>;
- def VMNB : BinaryVRRc<"vmnb", 0xE7FE, null_frag, v128b, v128b, 0>;
- def VMNH : BinaryVRRc<"vmnh", 0xE7FE, null_frag, v128h, v128h, 1>;
- def VMNF : BinaryVRRc<"vmnf", 0xE7FE, null_frag, v128f, v128f, 2>;
- def VMNG : BinaryVRRc<"vmng", 0xE7FE, null_frag, v128g, v128g, 3>;
+ def VMNB : BinaryVRRc<"vmnb", 0xE7FE, smin, v128b, v128b, 0>;
+ def VMNH : BinaryVRRc<"vmnh", 0xE7FE, smin, v128h, v128h, 1>;
+ def VMNF : BinaryVRRc<"vmnf", 0xE7FE, smin, v128f, v128f, 2>;
+ def VMNG : BinaryVRRc<"vmng", 0xE7FE, smin, v128g, v128g, 3>;
let Predicates = [FeatureVectorEnhancements3] in
def VMNQ : BinaryVRRc<"vmnq", 0xE7FE, null_frag, v128q, v128q, 4>;
// Minimum logical.
def VMNL : BinaryVRRcGeneric<"vmnl", 0xE7FC>;
- def VMNLB : BinaryVRRc<"vmnlb", 0xE7FC, null_frag, v128b, v128b, 0>;
- def VMNLH : BinaryVRRc<"vmnlh", 0xE7FC, null_frag, v128h, v128h, 1>;
- def VMNLF : BinaryVRRc<"vmnlf", 0xE7FC, null_frag, v128f, v128f, 2>;
- def VMNLG : BinaryVRRc<"vmnlg", 0xE7FC, null_frag, v128g, v128g, 3>;
+ def VMNLB : BinaryVRRc<"vmnlb", 0xE7FC, umin, v128b, v128b, 0>;
+ def VMNLH : BinaryVRRc<"vmnlh", 0xE7FC, umin, v128h, v128h, 1>;
+ def VMNLF : BinaryVRRc<"vmnlf", 0xE7FC, umin, v128f, v128f, 2>;
+ def VMNLG : BinaryVRRc<"vmnlg", 0xE7FC, umin, v128g, v128g, 3>;
let Predicates = [FeatureVectorEnhancements3] in
def VMNLQ : BinaryVRRc<"vmnlq", 0xE7FC, null_frag, v128q, v128q, 4>;
}
>From 5fa5714358ebccbfdee8ad4f5c5b59c618eb3934 Mon Sep 17 00:00:00 2001
From: Folkert de Vries <folkert at folkertdev.nl>
Date: Tue, 26 Aug 2025 11:40:26 +0200
Subject: [PATCH 2/2] s390x: map signed saturating truncation to a packs
---
llvm/lib/Target/SystemZ/SystemZInstrVector.td | 16 ++++++++++++++++
llvm/lib/Target/SystemZ/SystemZOperators.td | 9 +++++++++
2 files changed, 25 insertions(+)
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrVector.td b/llvm/lib/Target/SystemZ/SystemZInstrVector.td
index a5a121ba31711..e3278440daf8c 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrVector.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrVector.td
@@ -415,6 +415,22 @@ let Predicates = [FeatureVector] in {
defm VPKSG : BinaryVRRbSPair<"vpksg", 0xE797, int_s390_vpksg, z_packs_cc,
v128f, v128g, 3>;
+ def : Pat<
+ (v8i16 (z_pack
+ (smin (smax (v4i32 VR128:$a), vsplat_imm_eq_s32_min), vsplat_imm_eq_s32_max),
+ (smin (smax (v4i32 VR128:$b), vsplat_imm_eq_s32_min), vsplat_imm_eq_s32_max)
+ )),
+ (VPKSF VR128:$a, VR128:$b)
+ >;
+
+ def : Pat<
+ (v8i16 (z_pack
+ (smax (smin (v4i32 VR128:$a), vsplat_imm_eq_s32_max), vsplat_imm_eq_s32_min),
+ (smax (smin (v4i32 VR128:$b), vsplat_imm_eq_s32_max), vsplat_imm_eq_s32_min)
+ )),
+ (VPKSF VR128:$a, VR128:$b)
+ >;
+
// Pack saturate logical.
def VPKLS : BinaryVRRbSPairGeneric<"vpkls", 0xE795>;
defm VPKLSH : BinaryVRRbSPair<"vpklsh", 0xE795, int_s390_vpklsh, z_packls_cc,
diff --git a/llvm/lib/Target/SystemZ/SystemZOperators.td b/llvm/lib/Target/SystemZ/SystemZOperators.td
index 39e216b993b11..ca0a068006bb5 100644
--- a/llvm/lib/Target/SystemZ/SystemZOperators.td
+++ b/llvm/lib/Target/SystemZ/SystemZOperators.td
@@ -1067,6 +1067,15 @@ def vsplat_imm_eq_1 : PatFrag<(ops), (build_vector), [{
}]>;
def z_vzext1 : PatFrag<(ops node:$x), (and node:$x, vsplat_imm_eq_1)>;
+def vsplat_imm_eq_s32_min : PatFrag<(ops), (build_vector), [{
+ APInt Imm;
+ return ISD::isConstantSplatVector(N, Imm) && Imm.getSExtValue() == -32768;
+}]>;
+def vsplat_imm_eq_s32_max : PatFrag<(ops), (build_vector), [{
+ APInt Imm;
+ return ISD::isConstantSplatVector(N, Imm) && Imm == 32767;
+}]>;
+
// Signed "integer greater than zero" on vectors.
def z_vicmph_zero : PatFrag<(ops node:$x), (z_vicmph node:$x, immAllZerosV)>;
More information about the llvm-commits
mailing list