]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Optimize A < B ? A : B to MIN_EXPR.
authorliuhongt <hongtao.liu@intel.com>
Tue, 19 Dec 2023 02:39:06 +0000 (10:39 +0800)
committerliuhongt <hongtao.liu@intel.com>
Thu, 11 Jan 2024 01:20:17 +0000 (09:20 +0800)
Similar for A < B ? B : A to MAX_EXPR.
There're codes in the frontend to optimize such pattern but failed to
handle testcase in the PR since it's exposed at gimple level when
folding backend builtins.

pr95906 now can be optimized to MAX_EXPR as it's commented in the
testcase.

// FIXME: this should further optimize to a MAX_EXPR
 typedef signed char v16i8 __attribute__((vector_size(16)));
 v16i8 f(v16i8 a, v16i8 b)

gcc/ChangeLog:

PR target/104401
* match.pd (VEC_COND_EXPR: A < B ? A : B -> MIN_EXPR): New patten match.

gcc/testsuite/ChangeLog:

* gcc.target/i386/pr104401.c: New test.
* gcc.dg/tree-ssa/pr95906.c: Adjust testcase.

gcc/match.pd
gcc/testsuite/gcc.dg/tree-ssa/pr95906.c
gcc/testsuite/gcc.target/i386/pr104401.c [new file with mode: 0644]

index d75babd86c259ca2dc6868bbfe4822c4edb88cbb..876a9d1c06ed3fe7b7ecb6546b695ba6eb2fbb77 100644 (file)
@@ -5684,6 +5684,27 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       (if (VECTOR_TYPE_P (type))
        (view_convert @c0)
        (convert @c0))))))))
+
+/* This is for VEC_COND_EXPR
+   Optimize A < B ? A : B to MIN (A, B)
+           A > B ? A : B to MAX (A, B).  */
+(for cmp (lt le ungt unge gt ge unlt unle)
+     minmax (min min min min max max max max)
+     MINMAX (MIN_EXPR MIN_EXPR MIN_EXPR MIN_EXPR MAX_EXPR MAX_EXPR MAX_EXPR MAX_EXPR)
+ (simplify
+  (vec_cond (cmp @0 @1) @0 @1)
+   (if (VECTOR_INTEGER_TYPE_P (type)
+       && target_supports_op_p (type, MINMAX, optab_vector))
+    (minmax @0 @1))))
+
+(for cmp (lt le ungt unge gt ge unlt unle)
+     minmax (max max max max min min min min)
+     MINMAX (MAX_EXPR MAX_EXPR MAX_EXPR MAX_EXPR MIN_EXPR MIN_EXPR MIN_EXPR MIN_EXPR)
+ (simplify
+  (vec_cond (cmp @0 @1) @1 @0)
+   (if (VECTOR_INTEGER_TYPE_P (type)
+       && target_supports_op_p (type, MINMAX, optab_vector))
+    (minmax @0 @1))))
 #endif
 
 (for cnd (cond vec_cond)
index 3d820a58e9303823e146559ad3dfa1e2d714c81e..d15670f3e9e635c37caa942952675289cbeeb350 100644 (file)
@@ -1,7 +1,6 @@
 /* { dg-do compile } */
 /* { dg-options "-O2 -fdump-tree-forwprop3-raw -w -Wno-psabi" } */
 
-// FIXME: this should further optimize to a MAX_EXPR
 typedef signed char v16i8 __attribute__((vector_size(16)));
 v16i8 f(v16i8 a, v16i8 b)
 {
@@ -10,4 +9,4 @@ v16i8 f(v16i8 a, v16i8 b)
 }
 
 /* { dg-final { scan-tree-dump-not "bit_(and|ior)_expr" "forwprop3" } } */
-/* { dg-final { scan-tree-dump-times "vec_cond_expr" 1 "forwprop3" } } */
+/* { dg-final { scan-tree-dump-times "max_expr" 1 "forwprop3" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr104401.c b/gcc/testsuite/gcc.target/i386/pr104401.c
new file mode 100644 (file)
index 0000000..8ce7ff8
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse4.1" } */
+/* { dg-final { scan-assembler-times "pminsd" 2 } } */
+/* { dg-final { scan-assembler-times "pmaxsd" 2 } } */
+
+#include <smmintrin.h>
+
+__m128i min32(__m128i value, __m128i input)
+{
+  return _mm_blendv_epi8(input, value, _mm_cmplt_epi32(value, input));
+}
+
+__m128i max32(__m128i value, __m128i input)
+{
+  return _mm_blendv_epi8(input, value, _mm_cmpgt_epi32(value, input));
+}
+
+__m128i min32_1(__m128i value, __m128i input)
+{
+  return _mm_blendv_epi8(input, value, _mm_cmpgt_epi32(input, value));
+}
+
+__m128i max32_1(__m128i value, __m128i input)
+{
+  return _mm_blendv_epi8(input, value, _mm_cmplt_epi32(input, value));
+}
+