sibcall.c (uses_addressof): Add INMEM argument...
authorJakub Jelinek <jakub@redhat.com>
Fri, 7 Jul 2000 19:55:29 +0000 (21:55 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 7 Jul 2000 19:55:29 +0000 (21:55 +0200)
* sibcall.c (uses_addressof): Add INMEM argument, check for
current_function_internal_arg_pointer outside of MEM rtxs in addition
to ADDRESSOFs.
(sequence_uses_addressof): Update caller.

* gcc.c-torture/execute/20000706-1.c: New test.
* gcc.c-torture/execute/20000706-2.c: New test.
* gcc.c-torture/execute/20000706-3.c: New test.
* gcc.c-torture/execute/20000706-4.c: New test.
* gcc.c-torture/execute/20000706-5.c: New test.

From-SVN: r34906

gcc/ChangeLog
gcc/sibcall.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20000706-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/20000706-2.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/20000706-3.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/20000706-4.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/20000706-5.c [new file with mode: 0644]

index b197ef5c561299efc785e96b1f499c8334827ca5..41df73bce62a7ab7490a4597ca4ac760ac984a18 100644 (file)
@@ -1,3 +1,10 @@
+2000-07-07  Jakub Jelinek  <jakub@redhat.com>
+
+       * sibcall.c (uses_addressof): Add INMEM argument, check for
+       current_function_internal_arg_pointer outside of MEM rtxs in addition
+       to ADDRESSOFs.
+       (sequence_uses_addressof): Update caller.
+
 2000-07-07  Zack Weinberg  <zack@wolery.cumb.org>
 
        * tradcpp.c (initialize_builtins): Honor NO_BUILTIN_SIZE_TYPE
index 8387bf5d79b5292dc34f6506872806bf41843ee1..120b6410db21018b7a7d415d172597b66be10fe3 100644 (file)
@@ -37,7 +37,7 @@ static rtx skip_copy_to_return_value  PARAMS ((rtx, rtx, rtx));
 static rtx skip_use_of_return_value    PARAMS ((rtx, enum rtx_code));
 static rtx skip_stack_adjustment       PARAMS ((rtx));
 static rtx skip_jump_insn              PARAMS ((rtx));
-static int uses_addressof              PARAMS ((rtx));
+static int uses_addressof              PARAMS ((rtx, int));
 static int sequence_uses_addressof     PARAMS ((rtx));
 static void purge_reg_equiv_notes      PARAMS ((void));
 
@@ -235,12 +235,18 @@ skip_jump_insn (orig_insn)
   return orig_insn;
 }
 
-/* Scan the rtx X for an ADDRESSOF expressions.  Return nonzero if an ADDRESSOF
-   expresion is found, else return zero.  */
+/* Scan the rtx X for ADDRESSOF expressions or
+   current_function_internal_arg_pointer registers.
+   INMEM argument should be 1 if we're looking at inner part of some
+   MEM expression, otherwise 0.
+   Return nonzero if an ADDRESSOF expresion is found or if
+   current_function_internal_arg_pointer is found outside of some MEM
+   expression, else return zero.  */
 
 static int
-uses_addressof (x)
+uses_addressof (x, inmem)
      rtx x;
+     int inmem;
 {
   RTX_CODE code;
   int i, j;
@@ -254,19 +260,25 @@ uses_addressof (x)
   if (code == ADDRESSOF)
     return 1;
 
+  if (x == current_function_internal_arg_pointer && ! inmem)
+    return 1;
+
+  if (code == MEM)
+    return uses_addressof (XEXP (x, 0), 1);
+
   /* Scan all subexpressions. */
   fmt = GET_RTX_FORMAT (code);
   for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
     {
       if (*fmt == 'e')
        {
-         if (uses_addressof (XEXP (x, i)))
+         if (uses_addressof (XEXP (x, i), inmem))
            return 1;
        }
       else if (*fmt == 'E')
        {
          for (j = 0; j < XVECLEN (x, i); j++)
-           if (uses_addressof (XVECEXP (x, i, j)))
+           if (uses_addressof (XVECEXP (x, i, j), inmem))
              return 1;
        }
     }
@@ -274,8 +286,10 @@ uses_addressof (x)
 }
 
 /* Scan the sequence of insns in SEQ to see if any have an ADDRESSOF
-   rtl expression.  If an ADDRESSOF expression is found, return nonzero,
-   else return zero.
+   rtl expression or current_function_internal_arg_pointer occurences
+   not enclosed within a MEM.  If an ADDRESSOF expression or
+   current_function_internal_arg_pointer is found, return nonzero, otherwise
+   return zero.
 
    This function handles CALL_PLACEHOLDERs which contain multiple sequences
    of insns.  */
@@ -304,8 +318,8 @@ sequence_uses_addressof (seq)
                && sequence_uses_addressof (XEXP (PATTERN (insn), 2)))
              return 1;
          }
-       else if (uses_addressof (PATTERN (insn))
-                || (REG_NOTES (insn) && uses_addressof (REG_NOTES (insn))))
+       else if (uses_addressof (PATTERN (insn), 0)
+                || (REG_NOTES (insn) && uses_addressof (REG_NOTES (insn), 0)))
          return 1;
       }
   return 0;
index 4133757779301bac275ce19afcead59d55115ca0..e50a96c720a785ef23004b031ee362b6093910a6 100644 (file)
@@ -1,3 +1,11 @@
+2000-07-07  Jakub Jelinek  <jakub@redhat.com>
+
+       * gcc.c-torture/execute/20000706-1.c: New test.
+       * gcc.c-torture/execute/20000706-2.c: New test.
+       * gcc.c-torture/execute/20000706-3.c: New test.
+       * gcc.c-torture/execute/20000706-4.c: New test.
+       * gcc.c-torture/execute/20000706-5.c: New test.
+
 2000-07-06  Nathan Sidwell  <nathan@codesourcery.com>
 
        * g++.old-deja/g++.pt/instantiate7.C: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20000706-1.c b/gcc/testsuite/gcc.c-torture/execute/20000706-1.c
new file mode 100644 (file)
index 0000000..e8eb285
--- /dev/null
@@ -0,0 +1,31 @@
+extern void abort(void);
+extern void exit(int);
+
+struct baz {
+  int a, b, c, d, e;
+};
+
+void bar(struct baz *x, int f, int g, int h, int i, int j)
+{
+  if (x->a != 1 || x->b != 2 || x->c != 3 || x->d != 4 || x->e != 5 ||
+      f != 6 || g != 7 || h != 8 || i != 9 || j != 10)
+    abort();
+}
+
+void foo(struct baz x, char **y)
+{
+  bar(&x,6,7,8,9,10);
+}
+
+int main()
+{
+  struct baz x;
+
+  x.a = 1;
+  x.b = 2;
+  x.c = 3;
+  x.d = 4;
+  x.e = 5;
+  foo(x,(char **)0);
+  exit(0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20000706-2.c b/gcc/testsuite/gcc.c-torture/execute/20000706-2.c
new file mode 100644 (file)
index 0000000..faf2137
--- /dev/null
@@ -0,0 +1,31 @@
+extern void abort(void);
+extern void exit(int);
+
+struct baz {
+  int a, b, c, d, e;
+};
+
+void bar(struct baz *x, int f, int g, int h, int i, int j)
+{
+  if (x->a != 1 || x->b != 2 || x->c != 3 || x->d != 4 || x->e != 5 ||
+      f != 6 || g != 7 || h != 8 || i != 9 || j != 10)
+    abort();
+}
+
+void foo(char *z, struct baz x, char *y)
+{
+  bar(&x,6,7,8,9,10);
+}
+
+int main()
+{
+  struct baz x;
+
+  x.a = 1;
+  x.b = 2;
+  x.c = 3;
+  x.d = 4;
+  x.e = 5;
+  foo((char *)0,x,(char *)0);
+  exit(0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20000706-3.c b/gcc/testsuite/gcc.c-torture/execute/20000706-3.c
new file mode 100644 (file)
index 0000000..b5758d9
--- /dev/null
@@ -0,0 +1,27 @@
+extern void abort(void);
+extern void exit(int);
+
+int c;
+
+void baz(int *p)
+{
+  c = *p;
+}
+
+void bar(int b)
+{
+  if (c != 1 || b != 2)
+    abort();
+}
+
+void foo(int a, int b)
+{
+  baz(&a);
+  bar(b);
+}
+
+int main()
+{
+  foo(1, 2);
+  exit(0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20000706-4.c b/gcc/testsuite/gcc.c-torture/execute/20000706-4.c
new file mode 100644 (file)
index 0000000..01cc879
--- /dev/null
@@ -0,0 +1,22 @@
+extern void abort(void);
+extern void exit(int);
+
+int *c;
+
+void bar(int b)
+{
+  if (*c != 1 || b != 2)
+    abort();
+}
+
+void foo(int a, int b)
+{
+  c = &a;
+  bar(b);
+}
+
+int main()
+{
+  foo(1, 2);
+  exit(0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20000706-5.c b/gcc/testsuite/gcc.c-torture/execute/20000706-5.c
new file mode 100644 (file)
index 0000000..18756f2
--- /dev/null
@@ -0,0 +1,28 @@
+extern void abort(void);
+extern void exit(int);
+
+struct baz { int a, b, c; };
+
+struct baz *c;
+
+void bar(int b)
+{
+  if (c->a != 1 || c->b != 2 || c->c != 3 || b != 4)
+    abort();
+}
+
+void foo(struct baz a, int b)
+{
+  c = &a;
+  bar(b);
+}
+
+int main()
+{
+  struct baz a;
+  a.a = 1;
+  a.b = 2;
+  a.c = 3;
+  foo(a, 4);
+  exit(0);
+}