[PATCH] Fix PR34334, make sure to add virtual operands for the fallback SMT itself

Richard Guenther rguenther@suse.de
Tue Dec 4 14:42:00 GMT 2007


This fixes PR34334 where the thing happens that I thought would.  We
right after may_alias compute virtual operands for the stmt

*dest_19 = 0B

where dest_19 is pt_anything (that is, has no NMT associated).  So we
use dests SMT which happens to be SMT.32 which aliases SMT.33.  Which
causes us in add_virtual_operand to add a virtual operand for SMT.33
only:

# SMT.33_40 = VDEF <SMT.33_55> { SMT.33 }
*dest_19 = 0B

(which is the bug - we certainly have to VDEF SMT.32 here as well, which
is the main SMT for dest).

Now where things break is the point PRE inserts a fake load 

# VUSE <SMT.33_40> { SMT.32 SMT.33 }
storetmp.46_60 = *dest_19

(note the difference in VUSEs and loaded syms - the other part of the
patch fixes that), but as we re-run may_alias after PRE, the operand
scanner somehow ends up with flow-sensitive information for dest_19
and adds SMT.32 in addition to SMT.33 (but we don't end up renaming
the added bare SMT.32).

So, to make the machinery somewhat more robust (even if there are
parts of the problem unfixed, such as dest_19 even though it is stored
to, does not get an NMT (it is because it points to 'nothing'), or PRE not 
renaming the added virtual symbol)
the following patch makes sure that in case we end up falling back to
using a variables SMT for setting up virtual operands, we do so
correctly and make sure to add a virtual operand for exactly this
SMT as well.

This also happens to fix PR34222 (the problem has come up before and
gone away again as it is sensitive to UID differences and whatnot).

Bootstrap and regtest on x86_64-unknown-linux-gnu in progress, I'll
apply this to mainline later.

Thanks,
Richard.

2007-12-04  Richard Guenther  <rguenther@suse.de>

	PR middle-end/34334
	PR middle-end/34222
	* tree-ssa-operands.c (get_addr_dereference_operands): If we
	fall back to using the SMTs aliases, make sure to add virtual
	operands for the SMT itself.
	(create_ssa_artificial_load_stmt): Fix typo.  Make sure to also
	clear the loaded and stored symbols bitmaps.

	* gcc.c-torture/compile/pr34334.c: New testcase.
	* g++.dg/torture/pr34222.C: New testcase.


Index: tree-ssa-operands.c
===================================================================
*** tree-ssa-operands.c	(revision 130600)
--- tree-ssa-operands.c	(working copy)
*************** get_addr_dereference_operands (tree stmt
*** 1665,1672 ****
  	     to make sure to not prune virtual operands based on offset
  	     and size.  */
  	  if (v_ann->symbol_mem_tag)
! 	    add_virtual_operand (v_ann->symbol_mem_tag, s_ann, flags,
! 				 full_ref, 0, -1, false);
  
  	  /* Aliasing information is missing; mark statement as
  	     volatile so we won't optimize it out too actively.  */
--- 1665,1679 ----
  	     to make sure to not prune virtual operands based on offset
  	     and size.  */
  	  if (v_ann->symbol_mem_tag)
! 	    {
! 	      add_virtual_operand (v_ann->symbol_mem_tag, s_ann, flags,
! 				   full_ref, 0, -1, false);
! 	      /* Make sure we add the SMT itself.  */
! 	      if (flags & opf_def)
! 		append_vdef (v_ann->symbol_mem_tag);
! 	      else
! 		append_vuse (v_ann->symbol_mem_tag);
! 	    }
  
  	  /* Aliasing information is missing; mark statement as
  	     volatile so we won't optimize it out too actively.  */
*************** create_ssa_artificial_load_stmt (tree ne
*** 2657,2663 ****
      if (TREE_CODE (op) != SSA_NAME)
        var_ann (op)->in_vuse_list = false;
     
!   for (i = 0; VEC_iterate (tree, build_vuses, i, op); i++)
      if (TREE_CODE (op) != SSA_NAME)
        var_ann (op)->in_vdef_list = false;
  
--- 2664,2670 ----
      if (TREE_CODE (op) != SSA_NAME)
        var_ann (op)->in_vuse_list = false;
     
!   for (i = 0; VEC_iterate (tree, build_vdefs, i, op); i++)
      if (TREE_CODE (op) != SSA_NAME)
        var_ann (op)->in_vdef_list = false;
  
*************** create_ssa_artificial_load_stmt (tree ne
*** 2665,2670 ****
--- 2672,2681 ----
    VEC_truncate (tree, build_vdefs, 0);
    VEC_truncate (tree, build_vuses, 0);
  
+   /* Clear the loads and stores bitmaps.  */
+   bitmap_clear (build_loads);
+   bitmap_clear (build_stores);
+ 
    /* For each VDEF on the original statement, we want to create a
       VUSE of the VDEF result operand on the new statement.  */
    FOR_EACH_SSA_TREE_OPERAND (op, old_stmt, iter, SSA_OP_VDEF)
Index: testsuite/gcc.c-torture/compile/pr34334.c
===================================================================
*** testsuite/gcc.c-torture/compile/pr34334.c	(revision 0)
--- testsuite/gcc.c-torture/compile/pr34334.c	(revision 0)
***************
*** 0 ****
--- 1,140 ----
+ typedef unsigned int size_t;
+ __extension__ typedef long long int __quad_t;
+ __extension__ typedef unsigned int __mode_t;
+ __extension__ typedef __quad_t __off64_t;
+ typedef __mode_t mode_t;
+ typedef __off64_t off_t;
+ struct timeval   {};
+ typedef struct   {} fd_set;
+ typedef union {} __pthread_slist_t;
+ typedef union {
+     struct __pthread_mutex_s   { __extension__ union { };   } __data;
+ };
+ extern int stat64 (__const char *__restrict __file,      struct stat64 *__restrict __buf) __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));
+ extern int fstatat64 (int __fd, __const char *__restrict __file,         struct stat64 *__restrict __buf, int __flag)      __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (2, 3)));
+ enum __socket_type { SOCK_STREAM = 1, };
+ enum { SI_ASYNCNL = -60, };
+ enum { CLD_EXITED = 1, };
+ typedef struct sigaltstack   { } stack_t;
+ enum __rlimit_resource { __RLIMIT_SIGPENDING = 11, };
+ struct rlimit   { };
+ enum __priority_which { PRIO_PROCESS = 0, };
+ typedef union   { } __WAIT_STATUS __attribute__ ((__transparent_union__));
+ union wait   {
+     struct       {       } __wait_stopped;
+ };
+ typedef enum {  P_ALL, } idtype_t;
+ struct utsname   { };
+ enum   { IPPROTO_IP = 0,   };
+ enum   { IPPORT_ECHO = 7,   };
+ struct in_addr   { };
+ struct in6_addr   {
+     union       {       } in6_u;
+ };
+ typedef long int wchar_t;
+ typedef unsigned char guint8;
+ typedef signed int gint32;
+ typedef unsigned int guint32;
+ typedef signed int gssize;
+ typedef unsigned int gsize;
+ struct _GStaticMutex {
+     union {   } static_mutex;
+ };
+ union _GSystemThread { };
+ typedef int GPid;
+ typedef char gchar;
+ typedef int gint;
+ typedef gint gboolean;
+ typedef unsigned short gushort;
+ typedef unsigned long gulong;
+ typedef unsigned int guint;
+ typedef void* gpointer;
+ typedef const void *gconstpointer;
+ typedef gboolean (*GEqualFunc) (gconstpointer a, gconstpointer b);
+ typedef void (*GFunc) (gpointer data,   gpointer user_data);
+ typedef void (*GHFunc) (gpointer key,   gpointer user_data);
+ struct _GTimeVal { };
+ typedef struct _GByteArray GByteArray;
+ guint8* g_byte_array_free (GByteArray *array,      guint index_);
+ typedef guint32 GQuark;
+ typedef struct _GError GError;
+ GError* g_error_new (GQuark domain,   const gchar *message);
+ gboolean g_error_matches (const GError *error,   gint code);
+ typedef __builtin_va_list __gnuc_va_list;
+ typedef __gnuc_va_list va_list;
+ typedef enum { G_USER_DIRECTORY_DESKTOP, } GUserDirectory;
+ typedef enum { G_THREAD_PRIORITY_URGENT } GThreadPriority;
+ struct _GThread { };
+ typedef struct _GCond GCond;
+ struct _GThreadFunctions {
+     void (*cond_wait) (GCond *cond,  GError **error);
+     gboolean (*thread_equal) (gpointer thread1,        gpointer thread2);
+ };
+ typedef struct _GAsyncQueue GAsyncQueue;
+ void g_async_queue_sort (GAsyncQueue *queue,           guint *save);
+ struct tm { };
+ typedef struct __locale_struct { } *__locale_t;
+ extern int getaddrinfo (__const char *__restrict __name, struct addrinfo **__restrict __pai);
+ typedef struct _IO_FILE FILE;
+ __strsep_1c (char **__s, char __reject) { }
+ __strsep_2c (char **__s, char __reject1, char __reject2) { }
+ typedef struct stack_st  { } STACK;
+ typedef struct asn1_string_st ASN1_BIT_STRING;
+ typedef struct bn_mont_ctx_st BN_MONT_CTX;
+ typedef struct evp_cipher_st EVP_CIPHER;
+ typedef struct EDIPartyName_st {
+     union { } d;
+ } GENERAL_NAME;
+ typedef struct DIST_POINT_NAME_st {
+     union { } name;
+ } DIST_POINT_NAME;
+ typedef struct SXNET_st { } NOTICEREF;
+ typedef struct GENERAL_SUBTREE_st { } X509_PURPOSE;
+ int X509V3_add_value(const char *name, const char *value, STACK **extlist);
+ int X509_PURPOSE_add(int id, int trust, int flags, char *name, char *sname, void *arg);
+ extern char *dcgettext (__const char *__domainname, __const char *__msgid, int __category) __attribute__ ((__nothrow__)) __attribute__ ((__format_arg__ (2)));
+ enum { __LC_CTYPE = 0, };
+ struct lconv { };
+ typedef enum gftp_logging_level_tag { gftp_logging_send, } gftp_logging_level;
+ struct gftp_file_tag {
+     char *file,        *destfile;
+     unsigned int selected : 1,
+                 is_fd : 1;
+     gint32 ipv4_network_address, ipv4_netmask;
+ } gftp_proxy_hosts;
+ typedef enum { gftp_option_type_text = 0, } gftp_option_type_enum;
+ typedef struct gftp_config_list_vars_tag { } gftp_config_list_vars;
+ typedef struct gftp_config_vars_tag { } gftp_config_vars;
+ typedef struct gftp_option_type_tag {
+     int (*read_function) (char *str, gftp_config_vars * cv, int line);
+     int (*write_function) (gftp_config_vars * cv, char *buf, size_t buflen, int to_config_file);
+ } gftp_option_type_var;
+ typedef struct gftp_request_tag gftp_request;
+ typedef void (*gftp_logging_func) ( gftp_logging_level level, const char *string, ... );
+ typedef struct gftp_transfer_tag {
+     gftp_request * fromreq, * toreq;
+     unsigned int cancel : 1,
+                 skip_file : 1;
+     long numfiles,  resumed_bytes;
+ } gftp_transfer;
+ typedef struct gftp_log_tag {
+     unsigned int shown : 1,
+ 	use_threads : 1;
+ } supported_gftp_protocols;
+ void
+ gftp_config_parse_args (char *str, int numargs, int lineno, char **first, ...)
+ {
+     char *curpos, *endpos, *pos, **dest, tempchar;
+     va_list argp;
+     dest = first;
+     while (numargs > 0)
+     {
+         if (numargs > 1)
+ 	{  
+ 	    dest = __builtin_va_arg(argp,char **); 
+ 	    *dest = ((void *)0);
+ 	} 
+ 	numargs--; 
+ 	**dest = '\0'; 
+     }
+ }
Index: testsuite/g++.dg/torture/pr34222.C
===================================================================
*** testsuite/g++.dg/torture/pr34222.C	(revision 0)
--- testsuite/g++.dg/torture/pr34222.C	(revision 0)
***************
*** 0 ****
--- 1,65 ----
+ /* { dg-do compile } */
+ 
+ namespace std __attribute__ ((__visibility__ ("default"))) {
+     template<class _CharT>     struct char_traits;
+   }
+ typedef long int ptrdiff_t;
+ namespace std __attribute__ ((__visibility__ ("default"))) {
+     typedef ptrdiff_t streamsize;
+     template<typename _CharT, typename _Traits = char_traits<_CharT> >     class basic_ifstream;
+     typedef basic_ifstream<char> ifstream;
+     class ios_base   {
+     };
+   }
+ template<class T> class Vector4 {
+    public:
+       inline Vector4();
+       inline Vector4(T, T, T, T);
+       T x, y, z, w;
+   };
+ template<class T> class Matrix4 {
+    public:
+       Matrix4(const Vector4<T>&, const Vector4<T>&,             const Vector4<T>&, const Vector4<T>&);
+       Matrix4(const Matrix4<T>& m);
+       Vector4<T> r[4];
+   };
+ typedef Vector4<float> Vec4f;
+ typedef Matrix4<float> Mat4f;
+ template<class T> Vector4<T>::Vector4() : x(0), y(0), z(0), w(0) {
+   }
+ template<class T> Vector4<T>::Vector4(T _x, T _y, T _z, T _w) :     x(_x), y(_y), z(_z), w(_w) {
+   }
+ template<class T> Matrix4<T>::Matrix4(const Vector4<T>& v0,                                       const Vector4<T>& v1,                                       const Vector4<T>& v2,                                       const Vector4<T>& v3) {
+   }
+ namespace std __attribute__ ((__visibility__ ("default"))) {
+     template<typename _CharT, typename _Traits>     class basic_ios : public ios_base     {
+       };
+     template<typename _CharT, typename _Traits>     class basic_istream : virtual public basic_ios<_CharT, _Traits>     {
+       public:
+         typedef _CharT char_type;
+         typedef basic_istream<_CharT, _Traits> __istream_type;
+         __istream_type&       read(char_type* __s, streamsize __n);
+       };
+     template<typename _CharT, typename _Traits>     class basic_ifstream : public basic_istream<_CharT, _Traits>     {
+       };
+   }
+ using namespace std;
+ static float readFloat(ifstream& in) {
+       float f;
+       in.read((char*) &f, sizeof(float));
+   }
+ Mat4f readMeshMatrix(ifstream& in, int nBytes) {
+       float m00 = readFloat(in);
+       float m01 = readFloat(in);
+       float m02 = readFloat(in);
+       float m10 = readFloat(in);
+       float m11 = readFloat(in);
+       float m12 = readFloat(in);
+       float m20 = readFloat(in);
+       float m21 = readFloat(in);
+       float m22 = readFloat(in);
+       float m30 = readFloat(in);
+       float m31 = readFloat(in);
+       float m32 = readFloat(in);
+       return Mat4f(Vec4f(m00, m01, m02, 0),                  Vec4f(m10, m11, m12, 0),                  Vec4f(m20, m21, m22, 0),                  Vec4f(m30, m31, m32, 1));
+   }



More information about the Gcc-patches mailing list