Index: gcc/df-problems.c
===================================================================
--- gcc/df-problems.c	(revision 189440)
+++ gcc/df-problems.c	(working copy)
@@ -4068,6 +4068,19 @@ can_move_insns_across (rtx from, rtx to,
 
   for (insn = across_to; ; insn = next)
     {
+      if (CALL_P (insn))
+	{
+	  if (RTL_CONST_OR_PURE_CALL_P (insn))
+	    /* Pure functions can read from memory.  Const functions can
+	       read from arguments that the ABI has forced onto the stack.
+	       Neither sort of read can be volatile.  */
+	    memrefs_in_across |= MEMREF_NORMAL;
+	  else
+	    {
+	      memrefs_in_across |= MEMREF_VOLATILE;
+	      mem_sets_in_across |= MEMREF_VOLATILE;
+	    }
+	}
       if (NONDEBUG_INSN_P (insn))
 	{
 	  memrefs_in_across |= for_each_rtx (&PATTERN (insn), find_memory,

--- /dev/null	Tue Oct 29 15:57:07 2002
+++ gcc/testsuite/gcc.dg/torture/pr53908.c	Thu Jul 12 19:22:59 2012
@@ -0,0 +1,288 @@
+/* { dg-do run } */
+/* SEGV at comment below.  */
+typedef unsigned int size_t;
+typedef enum har {
+  he_fatal = (-199),
+  he_not_initialized,
+  he_bad_input,
+  he_memory_too_small,
+  he_bad_action,
+  he_duplicate,
+  he_bad_nonce,
+  he_stale_nonce,
+  he_bad_credentials,
+  he_bad_user,
+  he_no_such_user,
+  he_bad_passwd,
+  he_unknown_auth_scheme,
+  he_not_found,
+  he_failed_digest_file_check,
+  he_failed_digest_file_save,
+  he_process_not_privileged,
+  he_other,
+  he_end_of_range,
+  ha_no_error = 0,
+  ha_no_value = 1
+} har;
+typedef enum realm_type
+{
+  axis_realm = 0,
+  ws_realm
+} realm_type;
+
+__attribute__((__noclone__, __noinline__))
+har has_www_auth(char *, size_t, realm_type, har);
+
+__attribute__((__noclone__, __noinline__))
+har has_auth_user(const char *, const char *, realm_type, char *, size_t);
+
+__attribute__((__noclone__, __noinline__))
+char *ha_get_string_value(void);
+
+typedef struct
+{
+  unsigned int track_id;
+  char* user;
+  char* realm;
+  char* authent;
+  int internal_realm;
+} request;
+enum user_response {
+  file_not_found_user_response = -3,
+  access_denied_user_response = -2,
+  no_user_response = -1,
+  ok_user_response = 0
+};
+struct realm_group {
+  char *name;
+  int id;
+  struct realm_group *next;
+};
+struct realm {
+  char *name;
+  char *space;
+  struct realm_group *groups;
+  struct realm *next;
+};
+struct user_info {
+  char *name;
+  int no_groups;
+  int groups[128];
+  struct user_info *next;
+};
+static struct user_info *find_user(const char *user_name);
+static int is_member_of_groups(const struct user_info *user_item,
+                                const struct realm_group *groups);
+int authent_author(request *req);
+struct realm *realms = ((void *)0);
+struct user_info *users = ((void *)0);
+static struct user_info*
+find_user(const char *user_name)
+{
+  struct user_info *user_item;
+  user_item = users;
+  while (user_item != ((void *)0)) {
+    /* SEGV due to NULL access here on user_name.  See also comment below.  */
+    if ((__builtin_strcmp(user_item->name, user_name) == 0))
+      break;
+    user_item = user_item->next;
+  }
+  return user_item;
+}
+static int
+is_member_of_groups(const struct user_info *user_item,
+                    const struct realm_group *groups)
+{
+  const struct realm_group *group_item;
+  int i;
+  group_item = groups;
+  while (group_item != ((void *)0)) {
+    for (i = 0; i < user_item->no_groups; i++)
+      if (user_item->groups[i] == group_item->id)
+	return 0;
+    group_item = group_item->next;
+  }
+  return -1;
+}
+char *foo (void) __attribute__((__noclone__, __noinline__));
+char* g_strdup (const char *str) __attribute__((__malloc__, __noclone__, __noinline__));
+int g_strcmp0 (const char *str1, const char *str2);
+static int
+is_basic(char **user)
+{
+  char *passwd_ptr;
+  char *authent = foo();
+  passwd_ptr = __builtin_strchr(authent, ':');
+  if (passwd_ptr != ((void *)0)) {
+    *user = g_strdup(authent);
+    return 0;
+  }
+  return -1;
+}
+static int
+is_digest(char **user)
+{
+  int ret_val = -1;
+  char *authent;
+  authent = ha_get_string_value();
+  if (authent) {
+    *user = g_strdup(authent);
+    ret_val = 0;
+  }
+  return ret_val;
+}
+__attribute__((__noclone__, __noinline__))
+void g_free (void * mem);
+static enum user_response
+get_user_info_from_header(const realm_type type,
+                          char **user_name,
+                          struct user_info **user_item)
+{
+  int ret_val = no_user_response;
+  if ((type == ws_realm)) {
+    if (is_basic(user_name) == 0)
+      ret_val = access_denied_user_response;
+    if (is_digest(user_name) == 0)
+      ret_val = ok_user_response;
+  } else {
+    if (is_basic(user_name) < 0 &&
+	/* Load of *user_name here, but not after the is_digest call.  */
+	is_digest(user_name) < 0)
+      ;
+    else if ((*user_item = find_user(*user_name)) != ((void *)0))
+      ret_val = ok_user_response;
+    else
+      ret_val = access_denied_user_response;
+    if (ret_val != ok_user_response)
+      g_free(*user_name);
+  }
+  return ret_val;
+}
+static enum user_response
+authenticate_user(request *req,
+                  char **user_name,
+                  struct user_info **user_item)
+{
+  char *authent = ((void *)0);
+  har resp = ha_no_value;
+  enum user_response user_resp;
+  int ret_val = no_user_response;
+  if (req->authent && __builtin_strlen(req->authent)) {
+    authent = req->authent;
+    user_resp = get_user_info_from_header(req->internal_realm,
+                                          user_name,
+                                          user_item);
+    if (user_resp == ok_user_response) {
+      resp = has_auth_user(authent, 0, req->internal_realm, "", 1);
+      if (resp == ha_no_error)
+	ret_val = ok_user_response;
+      else if (resp != he_stale_nonce)
+	ret_val = access_denied_user_response;
+    } else if (user_resp == access_denied_user_response)
+      ret_val = access_denied_user_response;
+  }
+  if (resp != he_memory_too_small && resp != ha_no_error)
+    resp = has_www_auth("", 1, req->internal_realm, resp);
+  return ret_val;
+}
+
+int __attribute__ ((__noinline__, __noclone__))
+authent_author(request *req)
+{
+  struct realm *realm;
+  char *user_name = ((void *)0);
+  struct user_info *user_item = ((void *)0);
+  int res = 0;
+  asm ("");
+  realm = realms;
+  if (__builtin_strcmp("Wsd", realm->name) == 0) {
+    req->internal_realm = ws_realm;
+    is_digest(&user_name);
+  }
+  if (authenticate_user(req, &user_name, &user_item) < 0) {
+    if (user_name != ((void *)0))
+      req->user = user_name;
+    res = -2;
+    goto authent_author_return;
+  }
+  if (is_member_of_groups(user_item, realm->groups) < 0)
+    res = -1;
+authent_author_return:
+  return res;
+}
+
+int good0, good1, good2;
+
+__attribute__ ((__noinline__, __noclone__))
+char *foo(void)
+{
+  asm ("");
+  good0++;
+  return "";
+}
+
+__attribute__ ((__noinline__, __noclone__))
+char *ha_get_string_value(void)
+{
+  asm ("");
+  good1++;
+  return "f";
+}
+
+__attribute__ ((__noinline__, __noclone__))
+har has_auth_user(const char *a, const char *b, realm_type c, char *d, size_t e)
+{
+  asm ("");
+  if (*a != 'z' || a[1] != 0 || b != 0 || c != axis_realm || *d != 0
+      || e != 1)
+    __builtin_abort ();
+  return ha_no_error;
+}
+
+__attribute__ ((__noinline__, __noclone__))
+har has_www_auth(char *a, size_t b, realm_type c, har d)
+{
+  (void)(*a+b+c+d);
+  asm ("");
+  __builtin_abort ();
+}
+
+
+char *strdupped_user = "me";
+__attribute__((__malloc__, __noclone__, __noinline__))
+char* g_strdup (const char *str)
+{
+  asm ("");
+  if (*str != 'f')
+    __builtin_abort ();
+  good2++;
+  return strdupped_user;
+}
+
+__attribute__((__noclone__, __noinline__))
+void g_free (void * mem)
+{
+  (void)mem;
+  asm ("");
+  __builtin_abort ();
+}
+
+struct user_info me = { .name = "me", .no_groups = 1, .groups = {42}, .next = 0};
+struct user_info you = { .name = "you", .next = &me};
+struct realm_group xgroups = { .name = "*", .id = 42, .next = 0};
+
+int main(void)
+{
+  char *orig_user = "?";
+  struct realm r = { .name = "x", .space = "space?", .groups = &xgroups, .next = 0};
+  request req = { .user = orig_user, .realm = "!", .authent = "z",
+		  .internal_realm = axis_realm};
+  realms = &r;
+  users = &you;
+  if (authent_author (&req) != 0 || good0 != 1 || good1 != 1 || good2 != 1
+      || req.user != orig_user
+      || req.internal_realm != axis_realm)
+    __builtin_abort ();
+  __builtin_exit (0);
+}
+
