Hi, 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 interpretation. 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. Thanks, Bill 2018-05-25 Bill Schmidt <wschm...@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);