new file mode 100644
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+
+static inline const unsigned short *
+min(unsigned short *d, const unsigned short *e)
+{
+ return *e < *d ? e : d;
+}
+
+unsigned short __attribute__((noipa))
+test(unsigned short arr, unsigned short val)
+{
+ unsigned short tem = 1;
+ unsigned short tem2 = *min(&arr, &tem);
+ return tem2 / (arr ? arr : val);
+}
+
+int
+main()
+{
+ if (test (2, 2) != 0)
+ __builtin_abort();
+ return 0;
+}
@@ -323,6 +323,7 @@ static unsigned int next_expression_id;
static vec<pre_expr> expressions;
static hash_table<pre_expr_d> *expression_to_id;
static vec<unsigned> name_to_id;
+static obstack pre_expr_obstack;
/* Allocate an expression id for EXPR. */
@@ -433,7 +434,7 @@ get_or_alloc_expr_for_name (tree name)
/* Given an NARY, get or create a pre_expr to represent it. */
static pre_expr
-get_or_alloc_expr_for_nary (vn_nary_op_t nary,
+get_or_alloc_expr_for_nary (vn_nary_op_t nary, unsigned value_id,
location_t loc = UNKNOWN_LOCATION)
{
struct pre_expr_d expr;
@@ -442,6 +443,7 @@ get_or_alloc_expr_for_nary (vn_nary_op_t nary,
expr.kind = NARY;
expr.id = 0;
+ nary->hashcode = vn_nary_op_compute_hash (nary);
PRE_EXPR_NARY (&expr) = nary;
result_id = lookup_expression_id (&expr);
if (result_id != 0)
@@ -450,8 +452,10 @@ get_or_alloc_expr_for_nary (vn_nary_op_t nary,
result = pre_expr_pool.allocate ();
result->kind = NARY;
result->loc = loc;
- result->value_id = nary->value_id;
- PRE_EXPR_NARY (result) = nary;
+ result->value_id = value_id ? value_id : get_next_value_id ();
+ PRE_EXPR_NARY (result)
+ = alloc_vn_nary_op_noinit (nary->length, &pre_expr_obstack);
+ memcpy (PRE_EXPR_NARY (result), nary, sizeof_vn_nary_op (nary->length));
alloc_expression_id (result);
return result;
}
@@ -1517,15 +1521,10 @@ phi_translate_1 (bitmap_set_t dest,
return get_or_alloc_expr_for_constant (result);
if (!nary || nary->predicated_values)
- {
- new_val_id = get_next_value_id ();
- nary = vn_nary_op_insert_pieces (newnary->length,
- newnary->opcode,
- newnary->type,
- &newnary->op[0],
- result, new_val_id);
- }
- expr = get_or_alloc_expr_for_nary (nary, expr_loc);
+ new_val_id = 0; // allocate new
+ else
+ new_val_id = nary->value_id;
+ expr = get_or_alloc_expr_for_nary (newnary, new_val_id, expr_loc);
add_to_value (get_expr_value_id (expr), expr);
}
return expr;
@@ -2789,6 +2788,7 @@ find_or_generate_expression (basic_block block, tree op, gimple_seq *stmts)
/* Defer. */
return NULL_TREE;
}
+ gcc_assert (!value_id_constant_p (lookfor));
/* It must be a complex expression, so generate it recursively. Note
that this is only necessary to handle gcc.dg/tree-ssa/ssa-pre28.c
@@ -3993,8 +3993,14 @@ compute_avail (function *fun)
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
{
pre_expr e = get_or_alloc_expr_for_name (op);
+ unsigned value_id = get_expr_value_id (e);
+ if (value_id_constant_p (value_id))
+ {
+ get_or_alloc_expr_for_constant (VN_INFO (op)->valnum);
+ continue;
+ }
- add_to_value (get_expr_value_id (e), e);
+ add_to_value (value_id, e);
bitmap_insert_into_set (TMP_GEN (block), e);
bitmap_value_insert_into_set (AVAIL_OUT (block), e);
}
@@ -4073,6 +4079,13 @@ compute_avail (function *fun)
if (!nary || nary->predicated_values)
continue;
+ unsigned value_id = nary->value_id;
+ /* Record the un-valueized expression for EXP_GEN. */
+ nary = XALLOCAVAR (struct vn_nary_op_s,
+ sizeof_vn_nary_op
+ (vn_nary_length_from_stmt (stmt)));
+ init_vn_nary_op_from_stmt (nary, as_a <gassign *> (stmt));
+
/* If the NARY traps and there was a preceding
point in the block that might not return avoid
adding the nary to EXP_GEN. */
@@ -4081,7 +4094,7 @@ compute_avail (function *fun)
continue;
result = get_or_alloc_expr_for_nary
- (nary, gimple_location (stmt));
+ (nary, value_id, gimple_location (stmt));
break;
}
@@ -4275,6 +4288,7 @@ init_pre (void)
constant_value_expressions.create (get_max_constant_value_id () + 1);
constant_value_expressions.quick_grow_cleared (get_max_constant_value_id () + 1);
name_to_id.create (0);
+ gcc_obstack_init (&pre_expr_obstack);
inserted_exprs = BITMAP_ALLOC (NULL);
@@ -4312,6 +4326,7 @@ fini_pre ()
delete expression_to_id;
expression_to_id = NULL;
name_to_id.release ();
+ obstack_free (&pre_expr_obstack, NULL);
basic_block bb;
FOR_ALL_BB_FN (bb, cfun)
@@ -426,11 +426,8 @@ typedef hash_table<vn_ssa_aux_hasher>::iterator vn_ssa_aux_iterator_type;
static struct obstack vn_ssa_aux_obstack;
static vn_nary_op_t vn_nary_op_insert_stmt (gimple *, tree);
-static unsigned int vn_nary_length_from_stmt (gimple *);
-static vn_nary_op_t alloc_vn_nary_op_noinit (unsigned int, obstack *);
static vn_nary_op_t vn_nary_op_insert_into (vn_nary_op_t,
vn_nary_op_table_type *);
-static void init_vn_nary_op_from_stmt (vn_nary_op_t, gassign *);
static void init_vn_nary_op_from_pieces (vn_nary_op_t, unsigned int,
enum tree_code, tree, tree *);
static tree vn_lookup_simplify_result (gimple_match_op *);
@@ -609,8 +606,9 @@ vn_get_stmt_kind (gimple *stmt)
/* VOP-less references can go through unary case. */
if ((code == REALPART_EXPR
|| code == IMAGPART_EXPR
- || code == VIEW_CONVERT_EXPR
- || code == BIT_FIELD_REF)
+ || ((code == VIEW_CONVERT_EXPR
+ || code == BIT_FIELD_REF)
+ && is_gimple_reg_type (TREE_TYPE (rhs1))))
&& (TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME
|| is_gimple_min_invariant (TREE_OPERAND (rhs1, 0))))
return VN_NARY;
@@ -626,7 +624,8 @@ vn_get_stmt_kind (gimple *stmt)
if (code == ADDR_EXPR)
return (is_gimple_min_invariant (rhs1)
? VN_CONSTANT : VN_REFERENCE);
- else if (code == CONSTRUCTOR)
+ else if (code == CONSTRUCTOR
+ && is_gimple_reg_type (TREE_TYPE (rhs1)))
return VN_NARY;
return VN_NONE;
}
@@ -3854,7 +3853,7 @@ vn_reference_insert_pieces (tree vuse, alias_set_type set,
/* Compute and return the hash value for nary operation VBO1. */
-static hashval_t
+hashval_t
vn_nary_op_compute_hash (const vn_nary_op_t vno1)
{
inchash::hash hstate;
@@ -3927,7 +3926,7 @@ init_vn_nary_op_from_pieces (vn_nary_op_t vno, unsigned int length,
/* Return the number of operands for a vn_nary ops structure from STMT. */
-static unsigned int
+unsigned int
vn_nary_length_from_stmt (gimple *stmt)
{
switch (gimple_assign_rhs_code (stmt))
@@ -3950,7 +3949,7 @@ vn_nary_length_from_stmt (gimple *stmt)
/* Initialize VNO from STMT. */
-static void
+void
init_vn_nary_op_from_stmt (vn_nary_op_t vno, gassign *stmt)
{
unsigned i;
@@ -4047,7 +4046,7 @@ vn_nary_op_lookup_stmt (gimple *stmt, vn_nary_op_t *vnresult)
/* Allocate a vn_nary_op_t with LENGTH operands on STACK. */
-static vn_nary_op_t
+vn_nary_op_t
alloc_vn_nary_op_noinit (unsigned int length, struct obstack *stack)
{
return (vn_nary_op_t) obstack_alloc (stack, sizeof_vn_nary_op (length));
@@ -249,6 +249,10 @@ bool has_VN_INFO (tree);
extern vn_ssa_aux_t VN_INFO (tree);
tree vn_get_expr_for (tree);
void scc_vn_restore_ssa_info (void);
+vn_nary_op_t alloc_vn_nary_op_noinit (unsigned int, struct obstack *);
+unsigned int vn_nary_length_from_stmt (gimple *);
+void init_vn_nary_op_from_stmt (vn_nary_op_t, gassign *);
+hashval_t vn_nary_op_compute_hash (const vn_nary_op_t);
tree vn_nary_op_lookup_stmt (gimple *, vn_nary_op_t *);
tree vn_nary_op_lookup_pieces (unsigned int, enum tree_code,
tree, tree *, vn_nary_op_t *);