Hi!

As the following testcase shows, the exception for the aarch64
vec_pack_trunc_di is not sufficient on x86, the halfvectype
"vectors" have SImode but the x86 vec_pack_trunc_si meant for
the bool bitmasks combines 2x SImode into DImode, while in the
testcase the halfvectype is 1x SImode "vector" with SImode and
result is 2x HImode "vector" with SImode.

The patch also verifies the result mode.  The other option is
to throw away the aarch64 exception.  And yet another option
would be to use different optabs for vector bools with integral modes.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/10.2?

2020-06-18  Jakub Jelinek  <ja...@redhat.com>

        PR target/95713
        * tree-ssa-forwprop.c: Include insn-config.h and recog.h.
        (simplify_vector_constructor): For integral TYPE_MODE of
        non-VECTOR_BOOLEAN_P vector same as element mode, verify also
        that lhs mode matches the output operand mode of the expander.

        * gcc.dg/pr95713.c: New test.

--- gcc/tree-ssa-forwprop.c.jj  2020-06-08 11:05:04.196939262 +0200
+++ gcc/tree-ssa-forwprop.c     2020-06-17 11:18:10.816155772 +0200
@@ -51,6 +51,8 @@ along with GCC; see the file COPYING3.
 #include "internal-fn.h"
 #include "cgraph.h"
 #include "tree-ssa.h"
+#include "insn-config.h"
+#include "recog.h"
 
 /* This pass propagates the RHS of assignment statements into use
    sites of the LHS of the assignment.  It's basically a specialized
@@ -2391,7 +2393,8 @@ simplify_vector_constructor (gimple_stmt
          /* Only few targets implement direct conversion patterns so try
             some simple special cases via VEC_[UN]PACK[_FLOAT]_LO_EXPR.  */
          optab optab;
-         tree halfvectype, dblvectype;
+         enum insn_code icode;
+         tree halfvectype, dblvectype, lhs;
          if (CONVERT_EXPR_CODE_P (conv_code)
              && (2 * TYPE_PRECISION (TREE_TYPE (TREE_TYPE (orig[0])))
                  == TYPE_PRECISION (TREE_TYPE (type)))
@@ -2446,18 +2449,21 @@ simplify_vector_constructor (gimple_stmt
                   && (halfvectype
                         = build_vector_type (TREE_TYPE (TREE_TYPE (orig[0])),
                                              nelts / 2))
+                  && (optab = optab_for_tree_code (VEC_PACK_TRUNC_EXPR,
+                                                   halfvectype,
+                                                   optab_default))
+                  && ((icode = optab_handler (optab, TYPE_MODE (halfvectype)))
+                      != CODE_FOR_nothing)
                   /* Only use it for vector modes or for vector booleans
                      represented as scalar bitmasks, or allow halfvectype
                      be the element mode.  See PR95528.  */
                   && (VECTOR_MODE_P (TYPE_MODE (halfvectype))
                       || VECTOR_BOOLEAN_TYPE_P (halfvectype)
                       || (TYPE_MODE (halfvectype)
-                          == TYPE_MODE (TREE_TYPE (halfvectype))))
-                  && (optab = optab_for_tree_code (VEC_PACK_TRUNC_EXPR,
-                                                   halfvectype,
-                                                   optab_default))
-                  && (optab_handler (optab, TYPE_MODE (halfvectype))
-                      != CODE_FOR_nothing))
+                          == TYPE_MODE (TREE_TYPE (halfvectype))
+                          && (lhs == gimple_assign_lhs (stmt))
+                          && (insn_data[icode].operand[0].mode
+                              == TYPE_MODE (TREE_TYPE (lhs))))))
            {
              gimple_seq stmts = NULL;
              tree low = gimple_build (&stmts, BIT_FIELD_REF, halfvectype,
--- gcc/testsuite/gcc.dg/pr95713.c.jj   2020-06-17 11:20:12.288381166 +0200
+++ gcc/testsuite/gcc.dg/pr95713.c      2020-06-17 11:19:56.057618283 +0200
@@ -0,0 +1,15 @@
+/* PR target/95713 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wno-psabi -w" } */
+/* { dg-additional-options "-mavx512bw" { target i?86-*-* x86_64-*-* } } */
+
+typedef int v2si __attribute__((vector_size (8)));
+typedef short int v2hi __attribute__((vector_size (4)));
+void foo (v2hi);
+
+void
+bar (v2si x)
+{
+  v2hi a = (v2hi) { (short) x[0], (short) x[1] };
+  foo (4 > a);
+}

        Jakub

Reply via email to