[committed] Additional fix related to PR85712

Message ID b7d656af-cfc9-944c-3a0c-00e39b35e43f@linux.ibm.com
State New
Headers show
  • [committed] Additional fix related to PR85712
Related show

Commit Message

Bill Schmidt May 25, 2018, 7:11 p.m.

While backporting https://gcc.gnu.org/ml/gcc-patches/2018-05/msg01183.html to
older release branches, I ran across a corner case that can cause an ICE.
When replace_mult_candidate replaces a candidate with a copy, it does so
in situ.  Later we may attempt to replace it again under a different
interpretation in replace_one_candidate.  This violates the assumption that
a candidate being replaced there has two operands in its RHS, causing us
to segfault when we examine the missing second operand.

Most of the time we don't see this problem, because candidates are usually
replaced completely with a new statement, leaving the old candidate orphaned
with a basic block of 0.  This allows us to detect the candidate was already
replaced, and we don't ever call replace_one_candidate for the second

This patch fixes the problem by taking an early exit from replace_one_candidate
when the second operand is missing; this can only happen if the candidate has
already been replaced by a copy.

Bootstrapped and tested on powerpc64le-linux-gnu with no regressions.  I've
tested this in conjunction with the other patch for PR85712 on GCC 6, 7, and
8, also with no regressions.  On GCC 6, this fixes the problem that occurs
there on one test case.  Committed to trunk; will backport next week if all
remains well.


2018-05-25  Bill Schmidt  <wschmidt@linux.ibm.com>

	PR tree-optimization/85712
	* gimple-ssa-strength-reduction.c (replace_one_candidate): Skip if
	this candidate has already been replaced in-situ by a copy.


Index: gcc/gimple-ssa-strength-reduction.c
--- gcc/gimple-ssa-strength-reduction.c	(revision 260676)
+++ gcc/gimple-ssa-strength-reduction.c	(working copy)
@@ -3662,6 +3662,11 @@  replace_one_candidate (slsr_cand_t c, unsigned i,
   orig_rhs2 = gimple_assign_rhs2 (c->cand_stmt);
   cand_incr = cand_increment (c);
+  /* If orig_rhs2 is NULL, we have already replaced this in situ with
+     a copy statement under another interpretation.  */
+  if (!orig_rhs2)
+    return;
   if (dump_file && (dump_flags & TDF_DETAILS))
       fputs ("Replacing: ", dump_file);