From a844293de1d30da8ddba7384fc22ae59e857709f Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 29 Aug 2017 07:47:05 +0000 Subject: [PATCH] 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 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 --- gcc/ChangeLog | 16 +++++++++ gcc/gimplify.c | 4 ++- gcc/tree-call-cdce.c | 1 + gcc/tree-if-conv.c | 3 +- gcc/tree-ssa-math-opts.c | 4 +++ gcc/tree-vect-patterns.c | 5 ++- gcc/tree-vect-stmts.c | 75 ++++++++++++++++++++++++++-------------- 7 files changed, 79 insertions(+), 29 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6c853d99321..f8f6491dea1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2017-08-29 Richard Sandiford + + * 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 PR other/39851 diff --git a/gcc/gimplify.c b/gcc/gimplify.c index e52d7dcddaf..8b29a7179c5 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -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 diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c index 862d1a6421d..1578350c0c6 100644 --- a/gcc/tree-call-cdce.c +++ b/gcc/tree-call-cdce.c @@ -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); diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index d78731f1678..dd686c17305 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -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); } diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index 073c9dc19ac..df0bcd6d459 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -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); diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 877711a4f80..cfdb72c6499 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -1085,6 +1085,7 @@ vect_recog_pow_pattern (vec *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 *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 *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 *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 *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); diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 0629c12a4be..013fb1fc166 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -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. */ -- 2.30.2