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;