diff --git a/gcc/match.pd b/gcc/match.pd
index d75babd86c259ca2dc6868bbfe4822c4edb88cbb..876a9d1c06ed3fe7b7ecb6546b695ba6eb2fbb77 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -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)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr95906.c b/gcc/testsuite/gcc.dg/tree-ssa/pr95906.c
index 3d820a58e9303823e146559ad3dfa1e2d714c81e..d15670f3e9e635c37caa942952675289cbeeb350 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr95906.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr95906.c
@@ -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
index 0000000000000000000000000000000000000000..8ce7ff88d9ef0816564070be8aeec900dbaa9c02
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr104401.c
@@ -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));
+}
+