[PATCH] Fix PR70484, RTL DSE using wrong dependence check

Richard Biener rguenther@suse.de
Fri Apr 1 09:08:00 GMT 2016


RTL DSE uses true_dependence to see whether a store may be killed by
anothe store - that's obviously broken.  The following patch makes
it use output_dependence instead (introducing a canon_ variant of that).

Bootstrap & regtest running on x86_64-unknown-linux-gnu.

Ok?

Thanks,
Richard.

2016-04-01  Richard Biener  <rguenther@suse.de>

	PR rtl-optimization/70484
	* rtl.h (canon_output_dependence): Declare.
	* alias.c (canon_output_dependence): New function.
	* dse.c (record_store): Use canon_output_dependence rather
	than canon_true_dependence.

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

Index: gcc/rtl.h
===================================================================
*** gcc/rtl.h	(revision 234663)
--- gcc/rtl.h	(working copy)
*************** extern int anti_dependence (const_rtx, c
*** 3652,3657 ****
--- 3652,3659 ----
  extern int canon_anti_dependence (const_rtx, bool,
  				  const_rtx, machine_mode, rtx);
  extern int output_dependence (const_rtx, const_rtx);
+ extern int canon_output_dependence (const_rtx, bool,
+ 				    const_rtx, machine_mode, rtx);
  extern int may_alias_p (const_rtx, const_rtx);
  extern void init_alias_target (void);
  extern void init_alias_analysis (void);
Index: gcc/alias.c
===================================================================
*** gcc/alias.c	(revision 234663)
--- gcc/alias.c	(working copy)
*************** output_dependence (const_rtx mem, const_
*** 3057,3062 ****
--- 3057,3076 ----
  			     /*mem_canonicalized=*/false,
  			     /*x_canonicalized*/false, /*writep=*/true);
  }
+ 
+ /* Likewise, but we already have a canonicalized MEM, and X_ADDR for X.
+    Also, consider X in X_MODE (which might be from an enclosing
+    STRICT_LOW_PART / ZERO_EXTRACT).
+    If MEM_CANONICALIZED is true, MEM is canonicalized.  */
+ 
+ int
+ canon_output_dependence (const_rtx mem, bool mem_canonicalized,
+ 			 const_rtx x, machine_mode x_mode, rtx x_addr)
+ {
+   return write_dependence_p (mem, x, x_mode, x_addr,
+ 			     mem_canonicalized, /*x_canonicalized=*/true,
+ 			     /*writep=*/true);
+ }
  
  
  
Index: gcc/dse.c
===================================================================
*** gcc/dse.c	(revision 234663)
--- gcc/dse.c	(working copy)
*************** record_store (rtx body, bb_info_t bb_inf
*** 1609,1618 ****
  	   the value of store_info.  If it is, set the rhs to NULL to
  	   keep it from being used to remove a load.  */
  	{
! 	  if (canon_true_dependence (s_info->mem,
! 				     GET_MODE (s_info->mem),
! 				     s_info->mem_addr,
! 				     mem, mem_addr))
  	    {
  	      s_info->rhs = NULL;
  	      s_info->const_rhs = NULL;
--- 1609,1617 ----
  	   the value of store_info.  If it is, set the rhs to NULL to
  	   keep it from being used to remove a load.  */
  	{
! 	  if (canon_output_dependence (s_info->mem, true,
! 				       mem, GET_MODE (mem),
! 				       mem_addr))
  	    {
  	      s_info->rhs = NULL;
  	      s_info->const_rhs = NULL;
Index: gcc/testsuite/gcc.dg/torture/pr70484.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr70484.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr70484.c	(working copy)
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+int __attribute__((noinline,noclone))
+f(int *pi, long *pl)
+{
+  *pi = 1;
+  *pl = 0;
+  return *(char *)pi;
+}
+
+int main()
+{
+  char a[sizeof (long)];
+  if (f ((int *)a, (long *)a) != 0)
+    abort ();
+  return 0;
+}



More information about the Gcc-patches mailing list