On Tue, Aug 11, 2026 at 1:13 PM H.J. Lu <[email protected]> wrote:
>
> "(type) minmax ((wide_type) a, (wide_type) b) to minmax (a, b)" is limited
> to the single use of the result. It doesn't support:
>
> typedef int v2si __attribute__((vector_size (8)));
> typedef long long v2di __attribute__((vector_size (16)));
>
> v2si
> func (v2si a, v2si b, v2di *p)
> {
>   v2di x = __builtin_convertvector (a, v2di);
>   v2di y = __builtin_convertvector (b, v2di);
>   v2di z = x < y ? x : y;
>   *p = z;
>   return __builtin_convertvector (z, v2si);
> }
>
> Change it to
>
> minmax ((wide_type) a, (wide_type) b) -> (wide_type) minmax (a, b)
>
> instead and add "(type) ((wide_type) a) -> a" for integer types.  Now
> we generate
>
> pminsd %xmm1, %xmm0
> pmovsxdq %xmm0, %xmm1
> movaps %xmm1, (%rdi)
>
> instead of
>
> pmovsxdq %xmm0, %xmm2
> pmovsxdq %xmm1, %xmm1
> movdqa %xmm2, %xmm0
> movdqa %xmm2, %xmm3
> pcmpgtq %xmm1, %xmm0
> pblendvb %xmm0, %xmm1, %xmm3
> movdqa %xmm3, %xmm0
> movaps %xmm3, (%rdi)
> shufps $232, %xmm3, %xmm0
>
> gcc/

  (simplify
-  (convert (minmax:c@4 (convert@2 @0) (convert@3 @1)))
+  (minmax:c (convert@2 @0) (convert@3 @1))

no need for :c on minmax

   (if (ANY_INTEGRAL_TYPE_P (type)
-       && ANY_INTEGRAL_TYPE_P (TREE_TYPE (@2))
-       && types_match (type, TREE_TYPE (@0))
-       && types_match (type, TREE_TYPE (@1))
-       && types_match (TREE_TYPE (@2), TREE_TYPE (@3))
-       && element_precision (TREE_TYPE (@2)) > element_precision (type)
-       && TYPE_UNSIGNED (TREE_TYPE (@2)) == TYPE_UNSIGNED (type)
+       && ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+       && types_match (type, TREE_TYPE (@2))
+       && types_match (type, TREE_TYPE (@3))

the last two are redundant

+       && types_match (TREE_TYPE (@0), TREE_TYPE (@1))
+       && element_precision (TREE_TYPE (@0)) < element_precision (type)
+       && TYPE_UNSIGNED (TREE_TYPE (@0)) == TYPE_UNSIGNED (type)

+/* (type) ((wide_type) a) -> a.  */
+(simplify
+ (convert (convert@1 @0))
+  (if (ANY_INTEGRAL_TYPE_P (type)
+       && ANY_INTEGRAL_TYPE_P (TREE_TYPE (@1))
+       && types_match (type, TREE_TYPE (@0))
+       && element_precision (type) < element_precision (TREE_TYPE (@1)))
+   @0))

two-level conversions are already handled elsewhere, no need to add a
new pattern.

Richard.


> PR middle-end/126784
> * match.pd ((type) minmax ((wide_type) a, (wide_type) b)): Changed
> to ...
> (minmax ((wide_type) a, (wide_type) b)): This.
> ((type) ((wide_type) a) -> a) New.
>
> gcc/testsuite/
>
> PR middle-end/126784
> * g++.dg/tree-ssa/vec-narrow-1.C: Use -msse4 and require int128
> for x86.
> * g++.dg/tree-ssa/vec-narrow-minmax-2.C: Likewise.
> * g++.target/i386/pr126784-1.C: New test.
> * g++.target/i386/pr126784-2.C: Likewise.
> * gcc.target/i386/pr126784-1.c: Likewise.
> * gcc.target/i386/pr126784-2.c: Likewise.
> * gcc.target/i386/pr126788-1.c: Likewise.
>
> --
> H.J.

Reply via email to