On August 30, 2017 7:22:45 PM GMT+02:00, Bill Schmidt 
<wschm...@linux.vnet.ibm.com> wrote:
>Hi,
>
>https://gcc.gnu.org/PR81987 identifies an SSA verification error
>following
>SLSR.  The problem arises when SLSR places an initialization expression
>at
>a point not dominated by the definition of an SSA name it uses.  When
>there
>are multiple conditional candidates for replacement, the initialization
>expression must dominate all of these candidates and their phi
>dependencies,
>but the nearest common dominator for these may actually be above the
>stride
>definition in some cases.
>
>In such cases a single initialization point is not possible.  With
>sufficient
>analysis, it would be possible to find multiple initialization points
>that
>would satisfy availability of the stride at the cost of larger code. 
>This
>is too complex for a bug fix, though.  This patch instead refuses to
>replace
>candidates where a single legal initialization point isn't possible. 
>We
>ensure this by setting the cost for the increment associated with this
>initialization to effectively infinite.
>
>Bootstrapped and tested on powerpc64le-linux-gnu with no regressions. 
>Is
>this okay for trunk, and backport to all supported releases after a
>period
>of burn-in?

Yes. 

Thanks, 
Richard. 

>Thanks,
>Bill
>
>
>[gcc]
>
>2017-08-30  Bill Schmidt  <wschm...@linux.vnet.ibm.com>
>
>       PR tree-optimization/81987
>       * gimple-ssa-strength-reduction.c (insert_initializers): Don't
>       insert an initializer in a location not dominated by the stride
>       definition.
>
>[gcc/testsuite]
>
>2017-08-30  Bill Schmidt  <wschm...@linux.vnet.ibm.com>
>
>       PR tree-optimization/81987
>       * g++.dg/torture/pr81987.C: New file.
>
>
>Index: gcc/gimple-ssa-strength-reduction.c
>===================================================================
>--- gcc/gimple-ssa-strength-reduction.c        (revision 251369)
>+++ gcc/gimple-ssa-strength-reduction.c        (working copy)
>@@ -3340,6 +3340,23 @@ insert_initializers (slsr_cand_t c)
>        that block, the earliest one will be returned in WHERE.  */
>       bb = nearest_common_dominator_for_cands (c, incr, &where);
> 
>+      /* If the NCD is not dominated by the block containing the
>+       definition of the stride, we can't legally insert a
>+       single initializer.  Mark the increment as unprofitable
>+       so we don't make any replacements.  FIXME: Multiple
>+       initializers could be placed with more analysis.  */
>+      gimple *stride_def = SSA_NAME_DEF_STMT (c->stride);
>+      basic_block stride_bb = gimple_bb (stride_def);
>+
>+      if (stride_bb && !dominated_by_p (CDI_DOMINATORS, bb,
>stride_bb))
>+      {
>+        if (dump_file && (dump_flags & TDF_DETAILS))
>+          fprintf (dump_file,
>+                   "Initializer #%d cannot be legally placed\n", i);
>+        incr_vec[i].cost = COST_INFINITE;
>+        continue;
>+      }
>+
>       /* If the nominal stride has a different type than the recorded
>        stride type, build a cast from the nominal stride to that type.  */
>       if (!types_compatible_p (TREE_TYPE (c->stride), c->stride_type))
>Index: gcc/testsuite/g++.dg/torture/pr81987.C
>===================================================================
>--- gcc/testsuite/g++.dg/torture/pr81987.C     (nonexistent)
>+++ gcc/testsuite/g++.dg/torture/pr81987.C     (working copy)
>@@ -0,0 +1,61 @@
>+extern short var_1;
>+extern const short var_3;
>+extern unsigned long int var_9;
>+extern short var_13;
>+extern const unsigned long int var_15;
>+extern const unsigned long int var_37;
>+extern unsigned long int var_40;
>+extern long long int var_47;
>+extern short var_48;
>+extern const short var_54;
>+extern long long int var_79;
>+extern long long int var_81;
>+extern long long int var_94;
>+extern long long int var_95;
>+extern long long int var_701;
>+extern unsigned long int var_786;
>+extern short var_788;
>+extern long long int var_844;
>+
>+struct struct_1 {
>+  short member_1_2 : 15;
>+  static long long int member_1_3;
>+};
>+
>+extern struct_1 struct_obj_6;
>+extern struct_1 struct_obj_8;
>+
>+void foo() {
>+  int a = var_3 <= 602154393864UL;
>+  if (var_81 ? 0 : var_3 && var_9)
>+    ;
>+  else {
>+    var_94 = 0;
>+    if (var_3 && var_48 || var_13) {
>+      if (var_48)
>+      var_95 = 0;
>+      short b((2364461588881776511UL + var_3) * (2 ? var_13 : 0) ||
>var_1);
>+      struct_obj_8.member_1_2 = b;
>+      if (var_15) {
>+      if (var_81)
>+        if (var_47)
>+          ;
>+        else if (var_40)
>+          var_701 = 0;
>+      } else {
>+      if (var_40)
>+        var_79 = 0;
>+      if (var_54) {
>+        if (var_37)
>+          var_786 = 0;
>+        else
>+          var_788 = 0;
>+                  struct_obj_6.member_1_3 =
>+                    (2364461588881776511UL + var_3) * (2 ? var_13 : 0);
>+      }
>+      }
>+      if ((2364461588881776511UL + var_3) * (2 ? var_13 : 0))
>+      var_844 = 0;
>+    }
>+  }
>+}

Reply via email to