Commit a844293d by Richard Sandiford Committed by Richard Sandiford

Set the call nothrow flag more often

This patch sets the nothrow flag for various calls to internal functions
that are not inherently NOTHROW (and so can't be declared that way in
internal-fn.def) but that are used in contexts that can guarantee
NOTHROWness.

2017-08-29  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	* gimplify.c (gimplify_call_expr): Copy the nothrow flag to
	calls to internal functions.
	(gimplify_modify_expr): Likewise.
	* tree-call-cdce.c (use_internal_fn): Likewise.
	* tree-ssa-math-opts.c (pass_cse_reciprocals::execute): Likewise.
	(convert_to_divmod): Set the nothrow flag.
	* tree-if-conv.c (predicate_mem_writes):  Likewise.
	* tree-vect-stmts.c (vectorizable_mask_load_store): Likewise.
	(vectorizable_call): Likewise.
	(vectorizable_store): Likewise.
	(vectorizable_load): Likewise.
	* tree-vect-patterns.c (vect_recog_pow_pattern): Likewise.
	(vect_recog_mask_conversion_pattern): Likewise.

From-SVN: r251401
parent 130fcab0
2017-08-29 Richard Sandiford <richard.sandiford@linaro.org>
* gimplify.c (gimplify_call_expr): Copy the nothrow flag to
calls to internal functions.
(gimplify_modify_expr): Likewise.
* tree-call-cdce.c (use_internal_fn): Likewise.
* tree-ssa-math-opts.c (pass_cse_reciprocals::execute): Likewise.
(convert_to_divmod): Set the nothrow flag.
* tree-if-conv.c (predicate_mem_writes): Likewise.
* tree-vect-stmts.c (vectorizable_mask_load_store): Likewise.
(vectorizable_call): Likewise.
(vectorizable_store): Likewise.
(vectorizable_load): Likewise.
* tree-vect-patterns.c (vect_recog_pow_pattern): Likewise.
(vect_recog_mask_conversion_pattern): Likewise.
2017-08-29 Martin Liska <mliska@suse.cz>
PR other/39851
......
......@@ -3150,7 +3150,8 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
if (EXPR_CILK_SPAWN (*expr_p))
gimplify_cilk_detach (pre_p);
gimple *call = gimple_build_call_internal_vec (ifn, vargs);
gcall *call = gimple_build_call_internal_vec (ifn, vargs);
gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
gimplify_seq_add_stmt (pre_p, call);
return GS_ALL_DONE;
}
......@@ -5636,6 +5637,7 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
}
call_stmt = gimple_build_call_internal_vec (ifn, vargs);
gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
}
else
......
......@@ -1019,6 +1019,7 @@ use_internal_fn (gcall *call)
args.safe_push (gimple_call_arg (call, i));
gcall *new_call = gimple_build_call_internal_vec (ifn, args);
gimple_set_location (new_call, gimple_location (call));
gimple_call_set_nothrow (new_call, gimple_call_nothrow_p (call));
/* Transfer the LHS to the new call. */
tree lhs = gimple_call_lhs (call);
......
......@@ -2219,7 +2219,7 @@ predicate_mem_writes (loop_p loop)
tree lhs = gimple_assign_lhs (stmt);
tree rhs = gimple_assign_rhs1 (stmt);
tree ref, addr, ptr, mask;
gimple *new_stmt;
gcall *new_stmt;
gimple_seq stmts = NULL;
int bitsize = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (lhs)));
ref = TREE_CODE (lhs) == SSA_NAME ? rhs : lhs;
......@@ -2281,6 +2281,7 @@ predicate_mem_writes (loop_p loop)
gimple_set_vdef (new_stmt, gimple_vdef (stmt));
SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
}
gimple_call_set_nothrow (new_stmt, true);
gsi_replace (&gsi, new_stmt, true);
}
......
......@@ -690,6 +690,8 @@ pass_cse_reciprocals::execute (function *fun)
gimple_set_vdef (stmt2, gimple_vdef (call));
SSA_NAME_DEF_STMT (gimple_vdef (stmt2)) = stmt2;
}
gimple_call_set_nothrow (stmt2,
gimple_call_nothrow_p (call));
gimple_set_vuse (stmt2, gimple_vuse (call));
gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
gsi_replace (&gsi2, stmt2, true);
......@@ -4100,6 +4102,8 @@ convert_to_divmod (gassign *stmt)
tree res = make_temp_ssa_name (build_complex_type (TREE_TYPE (op1)),
call_stmt, "divmod_tmp");
gimple_call_set_lhs (call_stmt, res);
/* We rejected throwing statements above. */
gimple_call_set_nothrow (call_stmt, true);
/* Insert the call before top_stmt. */
gimple_stmt_iterator top_stmt_gsi = gsi_for_stmt (top_stmt);
......
......@@ -1085,6 +1085,7 @@ vect_recog_pow_pattern (vec<gimple *> *stmts, tree *type_in,
gcall *stmt = gimple_build_call_internal (IFN_SQRT, 1, base);
var = vect_recog_temp_ssa_var (TREE_TYPE (base), stmt);
gimple_call_set_lhs (stmt, var);
gimple_call_set_nothrow (stmt, true);
return stmt;
}
}
......@@ -3867,7 +3868,6 @@ vect_recog_mask_conversion_pattern (vec<gimple *> *stmts, tree *type_in,
stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
stmt_vec_info pattern_stmt_info;
vec_info *vinfo = stmt_vinfo->vinfo;
gimple *pattern_stmt;
/* Check for MASK_LOAD ans MASK_STORE calls requiring mask conversion. */
if (is_gimple_call (last_stmt)
......@@ -3875,6 +3875,7 @@ vect_recog_mask_conversion_pattern (vec<gimple *> *stmts, tree *type_in,
&& (gimple_call_internal_fn (last_stmt) == IFN_MASK_STORE
|| gimple_call_internal_fn (last_stmt) == IFN_MASK_LOAD))
{
gcall *pattern_stmt;
bool load = (gimple_call_internal_fn (last_stmt) == IFN_MASK_LOAD);
if (load)
......@@ -3918,6 +3919,7 @@ vect_recog_mask_conversion_pattern (vec<gimple *> *stmts, tree *type_in,
tmp,
gimple_call_arg (last_stmt, 3));
gimple_call_set_nothrow (pattern_stmt, true);
pattern_stmt_info = new_stmt_vec_info (pattern_stmt, vinfo);
set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info);
......@@ -3940,6 +3942,7 @@ vect_recog_mask_conversion_pattern (vec<gimple *> *stmts, tree *type_in,
if (!is_gimple_assign (last_stmt))
return NULL;
gimple *pattern_stmt;
lhs = gimple_assign_lhs (last_stmt);
rhs1 = gimple_assign_rhs1 (last_stmt);
rhs_code = gimple_assign_rhs_code (last_stmt);
......
......@@ -2364,9 +2364,11 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi,
misalign);
tree ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)),
misalign ? least_bit_hwi (misalign) : align);
new_stmt
gcall *call
= gimple_build_call_internal (IFN_MASK_STORE, 4, dataref_ptr,
ptr, vec_mask, vec_rhs);
gimple_call_set_nothrow (call, true);
new_stmt = call;
vect_finish_stmt_generation (stmt, new_stmt, gsi);
if (i == 0)
STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
......@@ -2414,16 +2416,17 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi,
misalign);
tree ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)),
misalign ? least_bit_hwi (misalign) : align);
new_stmt
gcall *call
= gimple_build_call_internal (IFN_MASK_LOAD, 3, dataref_ptr,
ptr, vec_mask);
gimple_call_set_lhs (new_stmt, make_ssa_name (vec_dest));
vect_finish_stmt_generation (stmt, new_stmt, gsi);
gimple_call_set_lhs (call, make_ssa_name (vec_dest));
gimple_call_set_nothrow (call, true);
vect_finish_stmt_generation (stmt, call, gsi);
if (i == 0)
STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = call;
else
STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
prev_stmt_info = vinfo_for_stmt (new_stmt);
STMT_VINFO_RELATED_STMT (prev_stmt_info) = call;
prev_stmt_info = vinfo_for_stmt (call);
}
}
......@@ -2867,8 +2870,11 @@ vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt,
if (modifier == NARROW)
{
tree half_res = make_ssa_name (vectype_in);
new_stmt = gimple_build_call_internal_vec (ifn, vargs);
gimple_call_set_lhs (new_stmt, half_res);
gcall *call
= gimple_build_call_internal_vec (ifn, vargs);
gimple_call_set_lhs (call, half_res);
gimple_call_set_nothrow (call, true);
new_stmt = call;
vect_finish_stmt_generation (stmt, new_stmt, gsi);
if ((i & 1) == 0)
{
......@@ -2881,12 +2887,15 @@ vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt,
}
else
{
gcall *call;
if (ifn != IFN_LAST)
new_stmt = gimple_build_call_internal_vec (ifn, vargs);
call = gimple_build_call_internal_vec (ifn, vargs);
else
new_stmt = gimple_build_call_vec (fndecl, vargs);
new_temp = make_ssa_name (vec_dest, new_stmt);
gimple_call_set_lhs (new_stmt, new_temp);
call = gimple_build_call_vec (fndecl, vargs);
new_temp = make_ssa_name (vec_dest, call);
gimple_call_set_lhs (call, new_temp);
gimple_call_set_nothrow (call, true);
new_stmt = call;
}
vect_finish_stmt_generation (stmt, new_stmt, gsi);
SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
......@@ -2934,8 +2943,10 @@ vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt,
else if (modifier == NARROW)
{
tree half_res = make_ssa_name (vectype_in);
new_stmt = gimple_build_call_internal_vec (ifn, vargs);
gimple_call_set_lhs (new_stmt, half_res);
gcall *call = gimple_build_call_internal_vec (ifn, vargs);
gimple_call_set_lhs (call, half_res);
gimple_call_set_nothrow (call, true);
new_stmt = call;
vect_finish_stmt_generation (stmt, new_stmt, gsi);
if ((j & 1) == 0)
{
......@@ -2948,12 +2959,15 @@ vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt,
}
else
{
gcall *call;
if (ifn != IFN_LAST)
new_stmt = gimple_build_call_internal_vec (ifn, vargs);
call = gimple_build_call_internal_vec (ifn, vargs);
else
new_stmt = gimple_build_call_vec (fndecl, vargs);
call = gimple_build_call_vec (fndecl, vargs);
new_temp = make_ssa_name (vec_dest, new_stmt);
gimple_call_set_lhs (new_stmt, new_temp);
gimple_call_set_lhs (call, new_temp);
gimple_call_set_nothrow (call, true);
new_stmt = call;
}
vect_finish_stmt_generation (stmt, new_stmt, gsi);
......@@ -2996,12 +3010,15 @@ vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt,
vargs.quick_push (vec_oprndsk[i]);
vargs.quick_push (vec_oprndsk[i + 1]);
}
gcall *call;
if (ifn != IFN_LAST)
new_stmt = gimple_build_call_internal_vec (ifn, vargs);
call = gimple_build_call_internal_vec (ifn, vargs);
else
new_stmt = gimple_build_call_vec (fndecl, vargs);
new_temp = make_ssa_name (vec_dest, new_stmt);
gimple_call_set_lhs (new_stmt, new_temp);
call = gimple_build_call_vec (fndecl, vargs);
new_temp = make_ssa_name (vec_dest, call);
gimple_call_set_lhs (call, new_temp);
gimple_call_set_nothrow (call, true);
new_stmt = call;
vect_finish_stmt_generation (stmt, new_stmt, gsi);
SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
}
......@@ -6356,8 +6373,11 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
/* Emit:
MEM_REF[...all elements...] = STORE_LANES (VEC_ARRAY). */
data_ref = create_array_ref (aggr_type, dataref_ptr, ref_type);
new_stmt = gimple_build_call_internal (IFN_STORE_LANES, 1, vec_array);
gimple_call_set_lhs (new_stmt, data_ref);
gcall *call = gimple_build_call_internal (IFN_STORE_LANES, 1,
vec_array);
gimple_call_set_lhs (call, data_ref);
gimple_call_set_nothrow (call, true);
new_stmt = call;
vect_finish_stmt_generation (stmt, new_stmt, gsi);
}
else
......@@ -7448,8 +7468,11 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
/* Emit:
VEC_ARRAY = LOAD_LANES (MEM_REF[...all elements...]). */
data_ref = create_array_ref (aggr_type, dataref_ptr, ref_type);
new_stmt = gimple_build_call_internal (IFN_LOAD_LANES, 1, data_ref);
gimple_call_set_lhs (new_stmt, vec_array);
gcall *call = gimple_build_call_internal (IFN_LOAD_LANES, 1,
data_ref);
gimple_call_set_lhs (call, vec_array);
gimple_call_set_nothrow (call, true);
new_stmt = call;
vect_finish_stmt_generation (stmt, new_stmt, gsi);
/* Extract each vector into an SSA_NAME. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment