@@ -313,26 +313,51 @@ expand_vec_cmp_expr_p (tree value_type, tree mask_type)
return (icode != CODE_FOR_nothing);
}
-/* Return TRUE iff, appropriate vector insns are available
- for vector cond expr with vector type VALUE_TYPE and a comparison
+/* Return TRUE iff appropriate vector insns are available
+ for VCOND_MASK pattern with vector type VALUE_TYPE and a comparison
with operand vector types in CMP_OP_TYPE. */
bool
-expand_vec_cond_expr_p (tree value_type, tree cmp_op_type)
+expand_vcond_mask_p (tree value_type, tree cmp_op_type)
{
- machine_mode value_mode = TYPE_MODE (value_type);
- machine_mode cmp_op_mode = TYPE_MODE (cmp_op_type);
if (VECTOR_BOOLEAN_TYPE_P (cmp_op_type)
&& get_vcond_mask_icode (TYPE_MODE (value_type),
TYPE_MODE (cmp_op_type)) != CODE_FOR_nothing)
return true;
- if (GET_MODE_SIZE (value_mode) != GET_MODE_SIZE (cmp_op_mode)
- || GET_MODE_NUNITS (value_mode) != GET_MODE_NUNITS (cmp_op_mode)
- || get_vcond_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type),
- TYPE_UNSIGNED (cmp_op_type)) == CODE_FOR_nothing)
- return false;
- return true;
+ return false;
+}
+
+/* Return TRUE iff appropriate vector insns are available
+ for VCOND pattern with vector type VALUE_TYPE and a comparison
+ with operand vector types in CMP_OP_TYPE. */
+
+bool
+expand_vcond_p (tree value_type, tree cmp_op_type)
+{
+ machine_mode value_mode = TYPE_MODE (value_type);
+ machine_mode cmp_op_mode = TYPE_MODE (cmp_op_type);
+ if (GET_MODE_SIZE (value_mode) == GET_MODE_SIZE (cmp_op_mode)
+ && GET_MODE_NUNITS (value_mode) == GET_MODE_NUNITS (cmp_op_mode)
+ && get_vcond_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type),
+ TYPE_UNSIGNED (cmp_op_type)) != CODE_FOR_nothing)
+ return true;
+
+ return false;
+}
+
+/* Return TRUE iff appropriate vector insns are available
+ for vector cond expr with vector type VALUE_TYPE and a comparison
+ with operand vector types in CMP_OP_TYPE. */
+
+bool
+expand_vec_cond_expr_p (tree value_type, tree cmp_op_type)
+{
+ if (expand_vcond_mask_p (value_type, cmp_op_type)
+ || expand_vcond_p (value_type, cmp_op_type))
+ return true;
+
+ return false;
}
/* Use the current target and options to initialize
@@ -39,6 +39,8 @@ optab optab_for_tree_code (enum tree_code, const_tree, enum optab_subtype);
bool supportable_convert_operation (enum tree_code, tree, tree, tree *,
enum tree_code *);
bool expand_vec_cmp_expr_p (tree, tree);
+bool expand_vcond_mask_p (tree, tree);
+bool expand_vcond_p (tree, tree);
bool expand_vec_cond_expr_p (tree, tree);
void init_tree_optimization_optabs (tree);
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "ssa.h"
#include "expmed.h"
+#include "optabs-tree.h"
#include "optabs-query.h"
#include "gimple-pretty-print.h"
#include "fold-const.h"
@@ -585,7 +586,10 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
{
enum tree_code def_code;
tree name = cond;
- gimple *def_stmt = get_prop_source_stmt (name, true, NULL);
+ bool single_use_only = (code != VEC_COND_EXPR
+ || !expand_vcond_p (gimple_expr_type (stmt),
+ TREE_TYPE (cond)));
+ gimple *def_stmt = get_prop_source_stmt (name, single_use_only, NULL);
if (!def_stmt || !can_propagate_from (def_stmt))
return 0;