return gimple_build_assign (lhs, tem3);
}
+ bool can_compute_op0 = true;
gcc_assert (!COMPARISON_CLASS_P (op0));
if (TREE_CODE (op0) == SSA_NAME)
{
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);
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);
}
}
- 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);
--- /dev/null
+/* { 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 <stdint.h>
+
+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;
+ }
+}