This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR60930
- From: Bill Schmidt <wschmidt at linux dot vnet dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: rguenther at suse dot de
- Date: Thu, 24 Apr 2014 11:20:46 -0500
- Subject: [PATCH] Fix PR60930
- Authentication-results: sourceware.org; auth=none
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 <wschmidt@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 <wschmidt@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;
+}