https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96453
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> --- So the issue is that veclower gets to see - _3 = { 8, 8 }; - _4 = _3 != { 0, 0 }; _5 = VEC_COND_EXPR <_4, { -1, -1 }, { 0, 0 }>; while ISEL sees + _4 = { -1, -1 }; _5 = VEC_COND_EXPR <_4, { -1, -1 }, { 0, 0 }>; now, the issue is the target doesn't support the _4 < {0, 0} we fake but it would support _4 != { 0, 0 }. The expansion code already handles this, but only for literal constants: icode = get_vcond_icode (mode, cmp_op_mode, unsignedp); if (icode == CODE_FOR_nothing) { if (tcode == LT_EXPR && op0a == op0 && TREE_CODE (op0) == VECTOR_CST) { /* A VEC_COND_EXPR condition could be folded from EQ_EXPR/NE_EXPR into a constant when only get_vcond_eq_icode is supported. Verify < 0 and != 0 behave the same and change it to NE_EXPR. */ ... I'm not sure why the code is restrictive as it is - we always will have a vector boolean operand for the mask which means the only valid values are -1 and 0 and thus using NE_EXPR should be always valid. In fact the verification code will ICE when we cannot use NE_EXPR so it should also work for non-constant ops. diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc index b330cf4c20e..97922632afd 100644 --- a/gcc/gimple-isel.cc +++ b/gcc/gimple-isel.cc @@ -138,22 +138,11 @@ gimple_expand_vec_cond_expr (gimple_stmt_iterator *gsi, if (icode == CODE_FOR_nothing) { if (tcode == LT_EXPR - && op0a == op0 - && TREE_CODE (op0) == VECTOR_CST) + && op0a == op0) { /* A VEC_COND_EXPR condition could be folded from EQ_EXPR/NE_EXPR into a constant when only get_vcond_eq_icode is supported. - Verify < 0 and != 0 behave the same and change it to NE_EXPR. */ - unsigned HOST_WIDE_INT nelts; - if (!VECTOR_CST_NELTS (op0).is_constant (&nelts)) - { - if (VECTOR_CST_STEPPED_P (op0)) - gcc_unreachable (); - nelts = vector_cst_encoded_nelts (op0); - } - for (unsigned int i = 0; i < nelts; ++i) - if (tree_int_cst_sgn (vector_cst_elt (op0, i)) == 1) - gcc_unreachable (); + Try changing it to NE_EXPR. */ tcode = NE_EXPR; } if (tcode == EQ_EXPR || tcode == NE_EXPR) fixes the testcase.