@@ -680,41 +680,41 @@ let Predicates = [FeatureVector] in {
680680 let isCommutable = 1 in {
681681 // Maximum.
682682 def VMX : BinaryVRRcGeneric<"vmx", 0xE7FF>;
683- def VMXB : BinaryVRRc<"vmxb", 0xE7FF, null_frag , v128b, v128b, 0>;
684- def VMXH : BinaryVRRc<"vmxh", 0xE7FF, null_frag , v128h, v128h, 1>;
685- def VMXF : BinaryVRRc<"vmxf", 0xE7FF, null_frag , v128f, v128f, 2>;
686- def VMXG : BinaryVRRc<"vmxg", 0xE7FF, null_frag , v128g, v128g, 3>;
683+ def VMXB : BinaryVRRc<"vmxb", 0xE7FF, smax , v128b, v128b, 0>;
684+ def VMXH : BinaryVRRc<"vmxh", 0xE7FF, smax , v128h, v128h, 1>;
685+ def VMXF : BinaryVRRc<"vmxf", 0xE7FF, smax , v128f, v128f, 2>;
686+ def VMXG : BinaryVRRc<"vmxg", 0xE7FF, smax , v128g, v128g, 3>;
687687 let Predicates = [FeatureVectorEnhancements3] in
688- def VMXQ : BinaryVRRc<"vmxq", 0xE7FF, null_frag , v128q, v128q, 4>;
688+ def VMXQ : BinaryVRRc<"vmxq", 0xE7FF, smax , v128q, v128q, 4>;
689689
690690 // Maximum logical.
691691 def VMXL : BinaryVRRcGeneric<"vmxl", 0xE7FD>;
692- def VMXLB : BinaryVRRc<"vmxlb", 0xE7FD, null_frag , v128b, v128b, 0>;
693- def VMXLH : BinaryVRRc<"vmxlh", 0xE7FD, null_frag , v128h, v128h, 1>;
694- def VMXLF : BinaryVRRc<"vmxlf", 0xE7FD, null_frag , v128f, v128f, 2>;
695- def VMXLG : BinaryVRRc<"vmxlg", 0xE7FD, null_frag , v128g, v128g, 3>;
692+ def VMXLB : BinaryVRRc<"vmxlb", 0xE7FD, umax , v128b, v128b, 0>;
693+ def VMXLH : BinaryVRRc<"vmxlh", 0xE7FD, umax , v128h, v128h, 1>;
694+ def VMXLF : BinaryVRRc<"vmxlf", 0xE7FD, umax , v128f, v128f, 2>;
695+ def VMXLG : BinaryVRRc<"vmxlg", 0xE7FD, umax , v128g, v128g, 3>;
696696 let Predicates = [FeatureVectorEnhancements3] in
697- def VMXLQ : BinaryVRRc<"vmxlq", 0xE7FD, null_frag , v128q, v128q, 4>;
697+ def VMXLQ : BinaryVRRc<"vmxlq", 0xE7FD, umax , v128q, v128q, 4>;
698698 }
699699
700700 let isCommutable = 1 in {
701701 // Minimum.
702702 def VMN : BinaryVRRcGeneric<"vmn", 0xE7FE>;
703- def VMNB : BinaryVRRc<"vmnb", 0xE7FE, null_frag , v128b, v128b, 0>;
704- def VMNH : BinaryVRRc<"vmnh", 0xE7FE, null_frag , v128h, v128h, 1>;
705- def VMNF : BinaryVRRc<"vmnf", 0xE7FE, null_frag , v128f, v128f, 2>;
706- def VMNG : BinaryVRRc<"vmng", 0xE7FE, null_frag , v128g, v128g, 3>;
703+ def VMNB : BinaryVRRc<"vmnb", 0xE7FE, smin , v128b, v128b, 0>;
704+ def VMNH : BinaryVRRc<"vmnh", 0xE7FE, smin , v128h, v128h, 1>;
705+ def VMNF : BinaryVRRc<"vmnf", 0xE7FE, smin , v128f, v128f, 2>;
706+ def VMNG : BinaryVRRc<"vmng", 0xE7FE, smin , v128g, v128g, 3>;
707707 let Predicates = [FeatureVectorEnhancements3] in
708- def VMNQ : BinaryVRRc<"vmnq", 0xE7FE, null_frag , v128q, v128q, 4>;
708+ def VMNQ : BinaryVRRc<"vmnq", 0xE7FE, smin , v128q, v128q, 4>;
709709
710710 // Minimum logical.
711711 def VMNL : BinaryVRRcGeneric<"vmnl", 0xE7FC>;
712- def VMNLB : BinaryVRRc<"vmnlb", 0xE7FC, null_frag , v128b, v128b, 0>;
713- def VMNLH : BinaryVRRc<"vmnlh", 0xE7FC, null_frag , v128h, v128h, 1>;
714- def VMNLF : BinaryVRRc<"vmnlf", 0xE7FC, null_frag , v128f, v128f, 2>;
715- def VMNLG : BinaryVRRc<"vmnlg", 0xE7FC, null_frag , v128g, v128g, 3>;
712+ def VMNLB : BinaryVRRc<"vmnlb", 0xE7FC, umin , v128b, v128b, 0>;
713+ def VMNLH : BinaryVRRc<"vmnlh", 0xE7FC, umin , v128h, v128h, 1>;
714+ def VMNLF : BinaryVRRc<"vmnlf", 0xE7FC, umin , v128f, v128f, 2>;
715+ def VMNLG : BinaryVRRc<"vmnlg", 0xE7FC, umin , v128g, v128g, 3>;
716716 let Predicates = [FeatureVectorEnhancements3] in
717- def VMNLQ : BinaryVRRc<"vmnlq", 0xE7FC, null_frag , v128q, v128q, 4>;
717+ def VMNLQ : BinaryVRRc<"vmnlq", 0xE7FC, umin , v128q, v128q, 4>;
718718 }
719719
720720 let isCommutable = 1 in {
@@ -1250,54 +1250,45 @@ defm : IntegerAbsoluteVectorOps<v8i16, VLCH, VLPH, 15>;
12501250defm : IntegerAbsoluteVectorOps<v4i32, VLCF, VLPF, 31>;
12511251defm : IntegerAbsoluteVectorOps<v2i64, VLCG, VLPG, 63>;
12521252
1253- // Instantiate minimum- and maximum-related patterns for TYPE. CMPH is the
1254- // signed or unsigned "set if greater than" comparison instruction and
1255- // MIN and MAX are the associated minimum and maximum instructions.
1256- multiclass IntegerMinMaxVectorOps<ValueType type, SDPatternOperator cmph,
1257- Instruction min, Instruction max> {
1258- let Predicates = [FeatureVector] in {
1259- def : Pat<(type (vselect (cmph VR128:$x, VR128:$y), VR128:$x, VR128:$y)),
1260- (max VR128:$x, VR128:$y)>;
1261- def : Pat<(type (vselect (cmph VR128:$x, VR128:$y), VR128:$y, VR128:$x)),
1262- (min VR128:$x, VR128:$y)>;
1263- def : Pat<(type (vselect (z_vnot (cmph VR128:$x, VR128:$y)),
1264- VR128:$x, VR128:$y)),
1265- (min VR128:$x, VR128:$y)>;
1266- def : Pat<(type (vselect (z_vnot (cmph VR128:$x, VR128:$y)),
1267- VR128:$y, VR128:$x)),
1268- (max VR128:$x, VR128:$y)>;
1269- }
1253+ // Instantiate packs/packu: recognize a saturating truncation and convert
1254+ // into the corresponding packs/packu instruction.
1255+ multiclass SignedSaturatingTruncate<ValueType input, ValueType output,
1256+ Instruction packs> {
1257+ def : Pat<
1258+ (output (z_pack
1259+ (smin (smax (input VR128:$a), ssat_trunc_min_vec), ssat_trunc_max_vec),
1260+ (smin (smax (input VR128:$b), ssat_trunc_min_vec), ssat_trunc_max_vec)
1261+ )),
1262+ (packs VR128:$a, VR128:$b)
1263+ >;
1264+
1265+ def : Pat<
1266+ (output (z_pack
1267+ (smax (smin (input VR128:$a), ssat_trunc_max_vec), ssat_trunc_min_vec),
1268+ (smax (smin (input VR128:$b), ssat_trunc_max_vec), ssat_trunc_min_vec)
1269+ )),
1270+ (packs VR128:$a, VR128:$b)
1271+ >;
12701272}
12711273
1272- // Signed min/max.
1273- defm : IntegerMinMaxVectorOps<v16i8, z_vicmph, VMNB, VMXB >;
1274- defm : IntegerMinMaxVectorOps<v8i16, z_vicmph, VMNH, VMXH >;
1275- defm : IntegerMinMaxVectorOps<v4i32, z_vicmph, VMNF, VMXF>;
1276- defm : IntegerMinMaxVectorOps<v2i64, z_vicmph, VMNG, VMXG>;
1277-
1278- let Predicates = [FeatureVectorEnhancements3] in {
1279- def : Pat<(i128 (or (and VR128:$x, (z_vicmph VR128:$x, VR128:$y)),
1280- (and VR128:$y, (not (z_vicmph VR128:$x, VR128:$y)))) ),
1281- (VMXQ VR128:$x, VR128:$y)>;
1282- def : Pat<(i128 (or (and VR128:$y, (z_vicmph VR128:$x, VR128:$y )),
1283- (and VR128:$x, (not (z_vicmph VR128:$x, VR128:$y))))),
1284- (VMNQ VR128:$x, VR128:$y) >;
1274+ defm : SignedSaturatingTruncate<v8i16, v16i8, VPKSH>;
1275+ defm : SignedSaturatingTruncate<v4i32, v8i16, VPKSF >;
1276+ defm : SignedSaturatingTruncate<v2i64, v4i32, VPKSG >;
1277+
1278+ multiclass UnsignedSaturatingTruncate<ValueType input, ValueType output,
1279+ Instruction packu> {
1280+ def : Pat<
1281+ (output (z_pack
1282+ (umin (input VR128:$a), usat_trunc_max_vec ),
1283+ (umin (input VR128:$b), usat_trunc_max_vec)
1284+ )),
1285+ (packu VR128:$a, VR128:$b)
1286+ >;
12851287}
12861288
1287- // Unsigned min/max.
1288- defm : IntegerMinMaxVectorOps<v16i8, z_vicmphl, VMNLB, VMXLB>;
1289- defm : IntegerMinMaxVectorOps<v8i16, z_vicmphl, VMNLH, VMXLH>;
1290- defm : IntegerMinMaxVectorOps<v4i32, z_vicmphl, VMNLF, VMXLF>;
1291- defm : IntegerMinMaxVectorOps<v2i64, z_vicmphl, VMNLG, VMXLG>;
1292-
1293- let Predicates = [FeatureVectorEnhancements3] in {
1294- def : Pat<(i128 (or (and VR128:$x, (z_vicmphl VR128:$x, VR128:$y)),
1295- (and VR128:$y, (not (z_vicmphl VR128:$x, VR128:$y))))),
1296- (VMXLQ VR128:$x, VR128:$y)>;
1297- def : Pat<(i128 (or (and VR128:$y, (z_vicmphl VR128:$x, VR128:$y)),
1298- (and VR128:$x, (not (z_vicmphl VR128:$x, VR128:$y))))),
1299- (VMNLQ VR128:$x, VR128:$y)>;
1300- }
1289+ defm : UnsignedSaturatingTruncate<v8i16, v16i8, VPKLSH>;
1290+ defm : UnsignedSaturatingTruncate<v4i32, v8i16, VPKLSF>;
1291+ defm : UnsignedSaturatingTruncate<v2i64, v4i32, VPKLSG>;
13011292
13021293// Instantiate comparison patterns to recognize VACC/VSCBI for TYPE.
13031294multiclass IntegerComputeCarryOrBorrow<ValueType type,
0 commit comments