diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc index d40338ce4a2..0f3d6bba229 100644 --- a/gcc/gimple-isel.cc +++ b/gcc/gimple-isel.cc @@ -154,6 +154,7 @@ gimple_expand_vec_cond_expr (gimple_stmt_iterator *gsi, return gimple_build_assign (lhs, tem3); } + bool can_compute_op0 = true; gcc_assert (!COMPARISON_CLASS_P (op0)); if (TREE_CODE (op0) == SSA_NAME) { @@ -184,13 +185,16 @@ gimple_expand_vec_cond_expr (gimple_stmt_iterator *gsi, tree op0_type = TREE_TYPE (op0); tree op0a_type = TREE_TYPE (op0a); + if (TREE_CODE_CLASS (tcode) == tcc_comparison) + can_compute_op0 = expand_vec_cmp_expr_p (op0a_type, op0_type, + tcode); /* Try to fold x CMP y ? -1 : 0 to x CMP y. */ - if (integer_minus_onep (op1) + if (can_compute_op0 + && integer_minus_onep (op1) && integer_zerop (op2) - && TYPE_MODE (TREE_TYPE (lhs)) == TYPE_MODE (TREE_TYPE (op0)) - && expand_vec_cmp_expr_p (op0a_type, op0_type, tcode)) + && TYPE_MODE (TREE_TYPE (lhs)) == TYPE_MODE (TREE_TYPE (op0))) { tree conv_op = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lhs), op0); gassign *new_stmt = gimple_build_assign (lhs, conv_op); @@ -198,10 +202,10 @@ gimple_expand_vec_cond_expr (gimple_stmt_iterator *gsi, return new_stmt; } - if (used_vec_cond_exprs >= 2 + if (can_compute_op0 + && used_vec_cond_exprs >= 2 && (get_vcond_mask_icode (mode, TYPE_MODE (op0_type)) - != CODE_FOR_nothing) - && expand_vec_cmp_expr_p (op0a_type, op0_type, tcode)) + != CODE_FOR_nothing)) { /* Keep the SSA name and use vcond_mask. */ tcode = TREE_CODE (op0); @@ -254,7 +258,15 @@ gimple_expand_vec_cond_expr (gimple_stmt_iterator *gsi, } } - gcc_assert (icode != CODE_FOR_nothing); + if (icode == CODE_FOR_nothing) + { + gcc_assert (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (op0)) + && can_compute_op0 + && (get_vcond_mask_icode (mode, TYPE_MODE (TREE_TYPE (op0))) + != CODE_FOR_nothing)); + return gimple_build_call_internal (IFN_VCOND_MASK, 3, op0, op1, op2); + } + tree tcode_tree = build_int_cst (integer_type_node, tcode); return gimple_build_call_internal (unsignedp ? IFN_VCONDU : IFN_VCOND, 5, op0a, op0b, op1, op2, tcode_tree); diff --git a/gcc/testsuite/gcc.dg/vect/pr98560-1.c b/gcc/testsuite/gcc.dg/vect/pr98560-1.c new file mode 100644 index 00000000000..2583fc48f8a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr98560-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O3 -fno-tree-vrp -fno-tree-fre -fno-tree-pre -fno-code-hoisting -fvect-cost-model=dynamic" } */ +/* { dg-additional-options "-msve-vector-bits=128" { target aarch64_sve } } */ + +#include + +void +f (uint16_t *restrict dst, uint32_t *restrict src1, float *restrict src2) +{ + int i = 0; + for (int j = 0; j < 4; ++j) + { + uint16_t tmp = src1[i] >> 1; + dst[i] = (uint16_t) (src2[i] < 0 && i < 4 ? tmp : 1); + i += 1; + } +}