Hi, PR60930 exposes an SLSR problem with a fold. When multiplying two constants to create a new stride, the result must fit in the stride type for the computation or the fold is invalid.
Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no regressions. The same patch applies equally to 4.8, 4.9, and trunk. Is this ok for trunk (and for 4.8/4.9 after a suitable burn-in period)? Thanks, Bill [gcc] 2014-04-24 Bill Schmidt <wschm...@linux.vnet.ibm.com> PR tree-optimization/60930 * gimple-ssa-strength-reduction.c (create_mul_imm_cand): Reject creating a multiply candidate by folding two constant multiplicands when the result overflows. [gcc/testsuite] 2014-04-24 Bill Schmidt <wschm...@linux.vnet.ibm.com> PR tree-optimization/60930 * gcc.dg/torture/pr60930.c: New test. Index: gcc/gimple-ssa-strength-reduction.c =================================================================== --- gcc/gimple-ssa-strength-reduction.c (revision 209714) +++ gcc/gimple-ssa-strength-reduction.c (working copy) @@ -1114,15 +1114,18 @@ create_mul_imm_cand (gimple gs, tree base_in, tree X = Y * c ============================ X = (B + i') * (S * c) */ - base = base_cand->base_expr; - index = base_cand->index; temp = tree_to_double_int (base_cand->stride) * tree_to_double_int (stride_in); - stride = double_int_to_tree (TREE_TYPE (stride_in), temp); - ctype = base_cand->cand_type; - if (has_single_use (base_in)) - savings = (base_cand->dead_savings - + stmt_cost (base_cand->cand_stmt, speed)); + if (double_int_fits_to_tree_p (TREE_TYPE (stride_in), temp)) + { + base = base_cand->base_expr; + index = base_cand->index; + stride = double_int_to_tree (TREE_TYPE (stride_in), temp); + ctype = base_cand->cand_type; + if (has_single_use (base_in)) + savings = (base_cand->dead_savings + + stmt_cost (base_cand->cand_stmt, speed)); + } } else if (base_cand->kind == CAND_ADD && integer_onep (base_cand->stride)) { Index: gcc/testsuite/gcc.dg/torture/pr60930.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr60930.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr60930.c (working copy) @@ -0,0 +1,20 @@ +/* { dg-do run } */ + +int x = 1; + +__attribute__((noinline, noclone)) void +foo (unsigned long long t) +{ + asm volatile ("" : : "r" (&t)); + if (t == 1) + __builtin_abort (); +} + +int +main () +{ + unsigned long long t = 0xffffffffffffffffULL * (0xffffffffUL * x); + if (t != 0xffffffff00000001ULL) + foo (t);; + return 0; +}