Set the call nothrow flag more often
authorRichard Sandiford <richard.sandiford@linaro.org>
Tue, 29 Aug 2017 07:47:05 +0000 (07:47 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 29 Aug 2017 07:47:05 +0000 (07:47 +0000)
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

gcc/ChangeLog
gcc/gimplify.c
gcc/tree-call-cdce.c
gcc/tree-if-conv.c
gcc/tree-ssa-math-opts.c
gcc/tree-vect-patterns.c
gcc/tree-vect-stmts.c

index 6c853d9932132136ca546b0325fe7bdaa7e685cf..f8f6491dea13d55f9341ec28db98f414779a858e 100644 (file)
@@ -1,3 +1,19 @@
+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
index e52d7dcddaff646ecfd2512f192ddadabc86ea78..8b29a7179c51ffb96b97c8f847e74e9408e4d5f3 100644 (file)
@@ -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
index 862d1a6421d4f3c7e98a3243ffa3f688a96670ce..1578350c0c63eb4f09618411f792f27167d54da7 100644 (file)
@@ -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);
index d78731f16783a659aaca57b89d361b603151fede..dd686c1730530998bf22c80923dbf3ddfafec15c 100644 (file)
@@ -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);
          }
index 073c9dc19acc7e38c5311783697296f2bf16d274..df0bcd6d459119243a69fc652e761f90d574ca78 100644 (file)
@@ -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);
index 877711a4f800bd26518cfce6aa1f061993e97e4c..cfdb72c6499fdcd2ffb954fe553fc1d7dd4e987b 100644 (file)
@@ -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);
index 0629c12a4bef8d1feca353220750d45fb8eddafb..013fb1fc1660a1d2646b5b54a33f8e6a6e4e9bef 100644 (file)
@@ -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.  */