This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR60930


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;
+}



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]