https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85863

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code
             Status|UNCONFIRMED                 |ASSIGNED
   Last reconfirmed|                            |2018-05-22
                 CC|                            |jakub at gcc dot gnu.org
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot 
gnu.org
   Target Milestone|---                         |9.0
     Ever confirmed|0                           |1

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
gamess works fine here (x86_64).  The test that triggers is

      if (maybe_ne (TYPE_VECTOR_SUBPARTS (type),
                    TYPE_VECTOR_SUBPARTS (op0_type)))
        {
          error ("invalid vector comparison resulting type");
          debug_generic_expr (type);
          return true;

that means the IL is bogus and the issue likely latent.  Reduced testcase:

      SUBROUTINE SOBOOK(MHSO,HSOMAX)
      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
      COMPLEX*16 HSOT,HSO1(2)
      PARAMETER (ZERO=0.0D+00,TWO=2.0D+00)
      DIMENSION SOL1(3,2),SOL2(3)
      SQRT2=SQRT(TWO)
      DO IH=1,MHSO
        IF(MS.EQ.0) THEN
          HSO1(IH) =  DCMPLX(ZERO,-SOL1(3,IH))
          HSOT =  DCMPLX(ZERO,-SOL2(3))
        ELSE
          HSO1(IH) =  DCMPLX(-SOL1(2,IH),SOL1(1,IH))/SQRT2
          HSOT =  DCMPLX(-SOL2(2),SOL2(1))/SQRT2
        ENDIF
      ENDDO
      HSOT=HSOT+HSO1(1)
      HSOMAX=MAX(HSOMAX,ABS(HSOT))
      RETURN
      END

The bogus comparison is built here:

0x0000000001378d87 in vectorizable_condition (stmt=
    <gimple_assign 0x7ffff69aa4e0>, gsi=0x7fffffffcf30, 
    vec_stmt=0x7fffffffcbf0, reduc_def=<tree 0x0>, reduc_index=0, 
    slp_node=0x2928520, cost_vec=0x0) at /tmp/trunk/gcc/tree-vect-stmts.c:9000
9000                                          vec_cond_lhs, vec_cond_rhs);
Value returned is $7 = (tree_node *) 0x7ffff69cc870
(gdb) l
8995              else
8996                {
8997                  vec_cond_rhs = vec_oprnds1[i];
8998                  if (bitop1 == NOP_EXPR)
8999                    vec_compare = build2 (cond_code, vec_cmp_type,
9000                                          vec_cond_lhs, vec_cond_rhs);
9001                  else
9002                    {
9003                      new_temp = make_ssa_name (vec_cmp_type);
9004                      if (bitop1 == BIT_NOT_EXPR)

so we face a conversion that isn't NOP.  Which looks somewhat weird.
The stmt we try to vectorize is

_ifc__74 = ms_36(D) == 0 ? _ifc__75 : _ifc__76;

where _ifc__75 is DFmode and the comparison is a SImode comparison.

Nothing in vectorizable_condition seems to verify we need no
widening/shortening
of the comparison result...  I guess pattern recognition usually deals with
this but doesn't in this case.  Ah, and it is that we run into
the following vect_is_simple_cond code:

  /* Invariant comparison.  */
  if (! *comp_vectype)
    {
      tree scalar_type = TREE_TYPE (lhs);
      /* If we can widen the comparison to match vectype do so.  */
      if (INTEGRAL_TYPE_P (scalar_type)
          && tree_int_cst_lt (TYPE_SIZE (scalar_type),
                              TYPE_SIZE (TREE_TYPE (vectype))))
        scalar_type = build_nonstandard_integer_type
          (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (vectype))),
           TYPE_UNSIGNED (scalar_type));
      *comp_vectype = get_vectype_for_scalar_type (scalar_type);

which widens the vector type.  But nothing in code-generation deals
with this in the SLP case since only vect_get_vec_def_for_operand
gets the extra invariant vector type argument but vect_get_slp_defs
knows nothing about such requirement.

Jakub ventured last in this area of the code but obviously a patch like
the following would help to reflect that reality.  I'm testing that patch.

Index: gcc/tree-vect-stmts.c
===================================================================
--- gcc/tree-vect-stmts.c       (revision 260499)
+++ gcc/tree-vect-stmts.c       (working copy)
@@ -8661,7 +8661,7 @@ vect_is_simple_cond (tree cond, vec_info

   *comp_vectype = vectype1 ? vectype1 : vectype2;
   /* Invariant comparison.  */
-  if (! *comp_vectype)
+  if (! *comp_vectype && vectype)
     {
       tree scalar_type = TREE_TYPE (lhs);
       /* If we can widen the comparison to match vectype do so.  */
@@ -8773,7 +8773,7 @@ vectorizable_condition (gimple *stmt, gi
   else_clause = gimple_assign_rhs3 (stmt);

   if (!vect_is_simple_cond (cond_expr, stmt_info->vinfo,
-                           &comp_vectype, &dts[0], vectype)
+                           &comp_vectype, &dts[0], slp_node ? NULL : vectype)
       || !comp_vectype)
     return false;

Reply via email to