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> 2017-08-29 Martin Liska <mliska@suse.cz>
PR other/39851 PR other/39851
......
...@@ -3150,7 +3150,8 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value) ...@@ -3150,7 +3150,8 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
if (EXPR_CILK_SPAWN (*expr_p)) if (EXPR_CILK_SPAWN (*expr_p))
gimplify_cilk_detach (pre_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); gimplify_seq_add_stmt (pre_p, call);
return GS_ALL_DONE; return GS_ALL_DONE;
} }
...@@ -5636,6 +5637,7 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, ...@@ -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)); vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
} }
call_stmt = gimple_build_call_internal_vec (ifn, vargs); 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)); gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
} }
else else
......
...@@ -1019,6 +1019,7 @@ use_internal_fn (gcall *call) ...@@ -1019,6 +1019,7 @@ use_internal_fn (gcall *call)
args.safe_push (gimple_call_arg (call, i)); args.safe_push (gimple_call_arg (call, i));
gcall *new_call = gimple_build_call_internal_vec (ifn, args); gcall *new_call = gimple_build_call_internal_vec (ifn, args);
gimple_set_location (new_call, gimple_location (call)); 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. */ /* Transfer the LHS to the new call. */
tree lhs = gimple_call_lhs (call); tree lhs = gimple_call_lhs (call);
......
...@@ -2219,7 +2219,7 @@ predicate_mem_writes (loop_p loop) ...@@ -2219,7 +2219,7 @@ predicate_mem_writes (loop_p loop)
tree lhs = gimple_assign_lhs (stmt); tree lhs = gimple_assign_lhs (stmt);
tree rhs = gimple_assign_rhs1 (stmt); tree rhs = gimple_assign_rhs1 (stmt);
tree ref, addr, ptr, mask; tree ref, addr, ptr, mask;
gimple *new_stmt; gcall *new_stmt;
gimple_seq stmts = NULL; gimple_seq stmts = NULL;
int bitsize = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (lhs))); int bitsize = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (lhs)));
ref = TREE_CODE (lhs) == SSA_NAME ? rhs : lhs; ref = TREE_CODE (lhs) == SSA_NAME ? rhs : lhs;
...@@ -2281,6 +2281,7 @@ predicate_mem_writes (loop_p loop) ...@@ -2281,6 +2281,7 @@ predicate_mem_writes (loop_p loop)
gimple_set_vdef (new_stmt, gimple_vdef (stmt)); gimple_set_vdef (new_stmt, gimple_vdef (stmt));
SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt; SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
} }
gimple_call_set_nothrow (new_stmt, true);
gsi_replace (&gsi, new_stmt, true); gsi_replace (&gsi, new_stmt, true);
} }
......
...@@ -690,6 +690,8 @@ pass_cse_reciprocals::execute (function *fun) ...@@ -690,6 +690,8 @@ pass_cse_reciprocals::execute (function *fun)
gimple_set_vdef (stmt2, gimple_vdef (call)); gimple_set_vdef (stmt2, gimple_vdef (call));
SSA_NAME_DEF_STMT (gimple_vdef (stmt2)) = stmt2; 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_set_vuse (stmt2, gimple_vuse (call));
gimple_stmt_iterator gsi2 = gsi_for_stmt (call); gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
gsi_replace (&gsi2, stmt2, true); gsi_replace (&gsi2, stmt2, true);
...@@ -4100,6 +4102,8 @@ convert_to_divmod (gassign *stmt) ...@@ -4100,6 +4102,8 @@ convert_to_divmod (gassign *stmt)
tree res = make_temp_ssa_name (build_complex_type (TREE_TYPE (op1)), tree res = make_temp_ssa_name (build_complex_type (TREE_TYPE (op1)),
call_stmt, "divmod_tmp"); call_stmt, "divmod_tmp");
gimple_call_set_lhs (call_stmt, res); 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. */ /* Insert the call before top_stmt. */
gimple_stmt_iterator top_stmt_gsi = gsi_for_stmt (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, ...@@ -1085,6 +1085,7 @@ vect_recog_pow_pattern (vec<gimple *> *stmts, tree *type_in,
gcall *stmt = gimple_build_call_internal (IFN_SQRT, 1, base); gcall *stmt = gimple_build_call_internal (IFN_SQRT, 1, base);
var = vect_recog_temp_ssa_var (TREE_TYPE (base), stmt); var = vect_recog_temp_ssa_var (TREE_TYPE (base), stmt);
gimple_call_set_lhs (stmt, var); gimple_call_set_lhs (stmt, var);
gimple_call_set_nothrow (stmt, true);
return stmt; return stmt;
} }
} }
...@@ -3867,7 +3868,6 @@ vect_recog_mask_conversion_pattern (vec<gimple *> *stmts, tree *type_in, ...@@ -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 stmt_vinfo = vinfo_for_stmt (last_stmt);
stmt_vec_info pattern_stmt_info; stmt_vec_info pattern_stmt_info;
vec_info *vinfo = stmt_vinfo->vinfo; vec_info *vinfo = stmt_vinfo->vinfo;
gimple *pattern_stmt;
/* Check for MASK_LOAD ans MASK_STORE calls requiring mask conversion. */ /* Check for MASK_LOAD ans MASK_STORE calls requiring mask conversion. */
if (is_gimple_call (last_stmt) if (is_gimple_call (last_stmt)
...@@ -3875,6 +3875,7 @@ vect_recog_mask_conversion_pattern (vec<gimple *> *stmts, tree *type_in, ...@@ -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_STORE
|| gimple_call_internal_fn (last_stmt) == IFN_MASK_LOAD)) || gimple_call_internal_fn (last_stmt) == IFN_MASK_LOAD))
{ {
gcall *pattern_stmt;
bool load = (gimple_call_internal_fn (last_stmt) == IFN_MASK_LOAD); bool load = (gimple_call_internal_fn (last_stmt) == IFN_MASK_LOAD);
if (load) if (load)
...@@ -3918,6 +3919,7 @@ vect_recog_mask_conversion_pattern (vec<gimple *> *stmts, tree *type_in, ...@@ -3918,6 +3919,7 @@ vect_recog_mask_conversion_pattern (vec<gimple *> *stmts, tree *type_in,
tmp, tmp,
gimple_call_arg (last_stmt, 3)); gimple_call_arg (last_stmt, 3));
gimple_call_set_nothrow (pattern_stmt, true);
pattern_stmt_info = new_stmt_vec_info (pattern_stmt, vinfo); pattern_stmt_info = new_stmt_vec_info (pattern_stmt, vinfo);
set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info); set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info);
...@@ -3940,6 +3942,7 @@ vect_recog_mask_conversion_pattern (vec<gimple *> *stmts, tree *type_in, ...@@ -3940,6 +3942,7 @@ vect_recog_mask_conversion_pattern (vec<gimple *> *stmts, tree *type_in,
if (!is_gimple_assign (last_stmt)) if (!is_gimple_assign (last_stmt))
return NULL; return NULL;
gimple *pattern_stmt;
lhs = gimple_assign_lhs (last_stmt); lhs = gimple_assign_lhs (last_stmt);
rhs1 = gimple_assign_rhs1 (last_stmt); rhs1 = gimple_assign_rhs1 (last_stmt);
rhs_code = gimple_assign_rhs_code (last_stmt); rhs_code = gimple_assign_rhs_code (last_stmt);
......
...@@ -2364,9 +2364,11 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi, ...@@ -2364,9 +2364,11 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi,
misalign); misalign);
tree ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), tree ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)),
misalign ? least_bit_hwi (misalign) : align); misalign ? least_bit_hwi (misalign) : align);
new_stmt gcall *call
= gimple_build_call_internal (IFN_MASK_STORE, 4, dataref_ptr, = gimple_build_call_internal (IFN_MASK_STORE, 4, dataref_ptr,
ptr, vec_mask, vec_rhs); ptr, vec_mask, vec_rhs);
gimple_call_set_nothrow (call, true);
new_stmt = call;
vect_finish_stmt_generation (stmt, new_stmt, gsi); vect_finish_stmt_generation (stmt, new_stmt, gsi);
if (i == 0) if (i == 0)
STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt; STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
...@@ -2414,16 +2416,17 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi, ...@@ -2414,16 +2416,17 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi,
misalign); misalign);
tree ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), tree ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)),
misalign ? least_bit_hwi (misalign) : align); misalign ? least_bit_hwi (misalign) : align);
new_stmt gcall *call
= gimple_build_call_internal (IFN_MASK_LOAD, 3, dataref_ptr, = gimple_build_call_internal (IFN_MASK_LOAD, 3, dataref_ptr,
ptr, vec_mask); ptr, vec_mask);
gimple_call_set_lhs (new_stmt, make_ssa_name (vec_dest)); gimple_call_set_lhs (call, make_ssa_name (vec_dest));
vect_finish_stmt_generation (stmt, new_stmt, gsi); gimple_call_set_nothrow (call, true);
vect_finish_stmt_generation (stmt, call, gsi);
if (i == 0) if (i == 0)
STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt; STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = call;
else else
STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt; STMT_VINFO_RELATED_STMT (prev_stmt_info) = call;
prev_stmt_info = vinfo_for_stmt (new_stmt); prev_stmt_info = vinfo_for_stmt (call);
} }
} }
...@@ -2867,8 +2870,11 @@ vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt, ...@@ -2867,8 +2870,11 @@ vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt,
if (modifier == NARROW) if (modifier == NARROW)
{ {
tree half_res = make_ssa_name (vectype_in); tree half_res = make_ssa_name (vectype_in);
new_stmt = gimple_build_call_internal_vec (ifn, vargs); gcall *call
gimple_call_set_lhs (new_stmt, half_res); = 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); vect_finish_stmt_generation (stmt, new_stmt, gsi);
if ((i & 1) == 0) if ((i & 1) == 0)
{ {
...@@ -2881,12 +2887,15 @@ vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt, ...@@ -2881,12 +2887,15 @@ vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt,
} }
else else
{ {
gcall *call;
if (ifn != IFN_LAST) if (ifn != IFN_LAST)
new_stmt = gimple_build_call_internal_vec (ifn, vargs); call = gimple_build_call_internal_vec (ifn, vargs);
else 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); new_temp = make_ssa_name (vec_dest, call);
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); vect_finish_stmt_generation (stmt, new_stmt, gsi);
SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); 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, ...@@ -2934,8 +2943,10 @@ vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt,
else if (modifier == NARROW) else if (modifier == NARROW)
{ {
tree half_res = make_ssa_name (vectype_in); tree half_res = make_ssa_name (vectype_in);
new_stmt = gimple_build_call_internal_vec (ifn, vargs); gcall *call = gimple_build_call_internal_vec (ifn, vargs);
gimple_call_set_lhs (new_stmt, half_res); gimple_call_set_lhs (call, half_res);
gimple_call_set_nothrow (call, true);
new_stmt = call;
vect_finish_stmt_generation (stmt, new_stmt, gsi); vect_finish_stmt_generation (stmt, new_stmt, gsi);
if ((j & 1) == 0) if ((j & 1) == 0)
{ {
...@@ -2948,12 +2959,15 @@ vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt, ...@@ -2948,12 +2959,15 @@ vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt,
} }
else else
{ {
gcall *call;
if (ifn != IFN_LAST) if (ifn != IFN_LAST)
new_stmt = gimple_build_call_internal_vec (ifn, vargs); call = gimple_build_call_internal_vec (ifn, vargs);
else 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); 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); vect_finish_stmt_generation (stmt, new_stmt, gsi);
...@@ -2996,12 +3010,15 @@ vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt, ...@@ -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]);
vargs.quick_push (vec_oprndsk[i + 1]); vargs.quick_push (vec_oprndsk[i + 1]);
} }
gcall *call;
if (ifn != IFN_LAST) if (ifn != IFN_LAST)
new_stmt = gimple_build_call_internal_vec (ifn, vargs); call = gimple_build_call_internal_vec (ifn, vargs);
else 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); new_temp = make_ssa_name (vec_dest, call);
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); vect_finish_stmt_generation (stmt, new_stmt, gsi);
SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); 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, ...@@ -6356,8 +6373,11 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
/* Emit: /* Emit:
MEM_REF[...all elements...] = STORE_LANES (VEC_ARRAY). */ MEM_REF[...all elements...] = STORE_LANES (VEC_ARRAY). */
data_ref = create_array_ref (aggr_type, dataref_ptr, ref_type); data_ref = create_array_ref (aggr_type, dataref_ptr, ref_type);
new_stmt = gimple_build_call_internal (IFN_STORE_LANES, 1, vec_array); gcall *call = gimple_build_call_internal (IFN_STORE_LANES, 1,
gimple_call_set_lhs (new_stmt, data_ref); 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); vect_finish_stmt_generation (stmt, new_stmt, gsi);
} }
else else
...@@ -7448,8 +7468,11 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, ...@@ -7448,8 +7468,11 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
/* Emit: /* Emit:
VEC_ARRAY = LOAD_LANES (MEM_REF[...all elements...]). */ VEC_ARRAY = LOAD_LANES (MEM_REF[...all elements...]). */
data_ref = create_array_ref (aggr_type, dataref_ptr, ref_type); data_ref = create_array_ref (aggr_type, dataref_ptr, ref_type);
new_stmt = gimple_build_call_internal (IFN_LOAD_LANES, 1, data_ref); gcall *call = gimple_build_call_internal (IFN_LOAD_LANES, 1,
gimple_call_set_lhs (new_stmt, vec_array); 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); vect_finish_stmt_generation (stmt, new_stmt, gsi);
/* Extract each vector into an SSA_NAME. */ /* 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