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 PR56661


This fixes PR56661 - we were value-numbering two call results
the same even though function attributes tell us that they are
required to return a distinct value (and this property is exploited
by alias analysis).  Simply don't do that (as opposed to trying to
fix things up).

Bootstrap and regtest pending on x86_64-unknown-linux-gnu.

Richard.

2013-03-20  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/56661
	* tree-ssa-sccvn.c (visit_use): Only value-number calls if
	the result does not have to be distinct.

	* gcc.dg/torture/pr56661.c: New testcase.

Index: gcc/tree-ssa-sccvn.c
===================================================================
*** gcc/tree-ssa-sccvn.c	(revision 196808)
--- gcc/tree-ssa-sccvn.c	(working copy)
*************** visit_use (tree use)
*** 3506,3513 ****
  		     We can value number 2 calls to the same function with the
  		     same vuse and the same operands which are not subsequent
  		     the same, because there is no code in the program that can
! 		     compare the 2 values.  */
! 		  || gimple_vdef (stmt)))
  	    changed = visit_reference_op_call (lhs, stmt);
  	  else
  	    changed = defs_to_varying (stmt);
--- 3506,3518 ----
  		     We can value number 2 calls to the same function with the
  		     same vuse and the same operands which are not subsequent
  		     the same, because there is no code in the program that can
! 		     compare the 2 values...  */
! 		  || (gimple_vdef (stmt)
! 		      /* ... unless the call returns a pointer which does
! 		         not alias with anything else.  In which case the
! 			 information that the values are distinct are encoded
! 			 in the IL.  */
! 		      && !(gimple_call_return_flags (stmt) & ERF_NOALIAS))))
  	    changed = visit_reference_op_call (lhs, stmt);
  	  else
  	    changed = defs_to_varying (stmt);
Index: gcc/testsuite/gcc.dg/torture/pr56661.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr56661.c	(revision 0)
--- gcc/testsuite/gcc.dg/torture/pr56661.c	(working copy)
***************
*** 0 ****
--- 1,46 ----
+ /* { dg-do run } */
+ 
+ __attribute__((noinline, noclone)) void
+ bar (int *b)
+ {
+   b[0] = b[1] = b[2] = 1;
+ }
+ 
+ __attribute__((noinline, noclone)) int
+ baz (int x)
+ {
+   if (x != 1)
+     __builtin_abort ();
+ }
+ 
+ void
+ foo (int x)
+ {
+   if (x == 0)
+     {
+       int *b = __builtin_malloc (3 * sizeof (int));
+       while (b[0])
+ 	;
+     }
+   else if (x == 1)
+     {
+       int i, j;
+       int *b = __builtin_malloc (3 * sizeof (int));
+       for (i = 0; i < 2; i++)
+ 	{
+ 	  bar (b);
+ 	  for (j = 0; j < 3; ++j)
+ 	    baz (b[j]);
+ 	  baz (b[0]);
+ 	}
+     }
+ }
+ 
+ int
+ main ()
+ {
+   int x = 1;
+   asm volatile ("" : "+r" (x));
+   foo (x);
+   return 0;
+ }


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