OSDN Git Service

2007-07-06 Josh Conner <jconner@apple.com>
authorjconner <jconner@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 6 Jul 2007 16:57:19 +0000 (16:57 +0000)
committerjconner <jconner@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 6 Jul 2007 16:57:19 +0000 (16:57 +0000)
PR middle-end/32602
PR middle-end/32603
* calls.c (store_one_arg): Handle arguments which are partially
on the stack when detecting argument overlap.

2007-07-06  Josh Conner  <jconner@apple.com>

PR middle-end/32602
* gcc.dg/sibcall-8.c: New test.

2007-07-06  Josh Conner  <jconner@apple.com>

PR middle-end/32603
* gcc.target/arm/sibcall-1.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@126422 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/calls.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/sibcall-8.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/sibcall-1.c [new file with mode: 0644]

index 2c5edb5..36b080b 100644 (file)
@@ -1,3 +1,10 @@
+2007-07-06  Josh Conner  <jconner@apple.com>
+
+       PR middle-end/32602
+       PR middle-end/32603
+       * calls.c (store_one_arg): Handle arguments which are partially
+       on the stack when detecting argument overlap.
+
 2007-07-06  Bernd Schmidt  <bernd.schmidt@analog.com>
 
        * reload1.c (choose_reload_regs): Set reload_spill_index for regs
index aa63755..e6741c8 100644 (file)
@@ -4326,6 +4326,7 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags,
 
              /* expand_call should ensure this.  */
              gcc_assert (!arg->locate.offset.var
+                         && arg->locate.size.var == 0
                          && GET_CODE (size_rtx) == CONST_INT);
 
              if (arg->locate.offset.constant > i)
@@ -4335,7 +4336,21 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags,
                }
              else if (arg->locate.offset.constant < i)
                {
-                 if (i < arg->locate.offset.constant + INTVAL (size_rtx))
+                 /* Use arg->locate.size.constant instead of size_rtx
+                    because we only care about the part of the argument
+                    on the stack.  */
+                 if (i < (arg->locate.offset.constant
+                          + arg->locate.size.constant))
+                   sibcall_failure = 1;
+               }
+             else
+               {
+                 /* Even though they appear to be at the same location,
+                    if part of the outgoing argument is in registers,
+                    they aren't really at the same location.  Check for
+                    this by making sure that the incoming size is the
+                    same as the outgoing size.  */
+                 if (arg->locate.size.constant != INTVAL (size_rtx))
                    sibcall_failure = 1;
                }
            }
index e5486e9..2e0437d 100644 (file)
@@ -1,3 +1,13 @@
+2007-07-06  Josh Conner  <jconner@apple.com>
+
+       PR middle-end/32602
+       * gcc.dg/sibcall-8.c: New test.
+
+2007-07-06  Josh Conner  <jconner@apple.com>
+
+       PR middle-end/32603
+       * gcc.target/arm/sibcall-1.c: New test.
+
 2007-07-06  H.J. Lu  <hongjiu.lu@intel.com>
 
        * gcc.dg/dfp/convert-dfp-round-thread.c: New test.
diff --git a/gcc/testsuite/gcc.dg/sibcall-8.c b/gcc/testsuite/gcc.dg/sibcall-8.c
new file mode 100644 (file)
index 0000000..767040f
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -foptimize-sibling-calls" } */
+
+typedef struct {
+  int data[4];
+} arr16_t;
+
+int result = 0;
+
+void func2(int i, int j, arr16_t arr)
+{
+  result = (arr.data[0] != 1
+           || arr.data[1] != 2
+           || arr.data[2] != 3
+           || arr.data[3] != 4);
+}
+
+void func1(int i, int j, int k, arr16_t a)
+{
+  func2(i, j, a);
+}
+
+int main(int argc, const char *argv[])
+{
+  arr16_t arr = {{1, 2, 3, 4}};
+    
+  func1(0, 0, 0, arr);
+  return result;
+}
+
diff --git a/gcc/testsuite/gcc.target/arm/sibcall-1.c b/gcc/testsuite/gcc.target/arm/sibcall-1.c
new file mode 100644 (file)
index 0000000..77c94fd
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do compile { target { arm32 } } } */
+/* { dg-options "-O2" } */
+
+#define noinline __attribute__((noinline))
+
+typedef struct {
+  int data[4];
+} arr16_t;
+
+int result = 0;
+
+void noinline func2 (int i, int j, arr16_t arr)
+{
+  result = (arr.data[0] != 1
+           || arr.data[1] != 2
+           || arr.data[2] != 3
+           || arr.data[3] != 4);
+}
+
+void func1 (int i, int j, int k, int l, int m, int n, arr16_t a)
+{
+  func2(i, j, a);
+}
+
+int main(int argc, const char *argv[])
+{
+  arr16_t arr = {{1, 2, 3, 4}};
+    
+  func1(0, 0, 0, 0, 0, 0, arr);
+  return result;
+}
+
+/* { dg-final { scan-assembler "\tb\tfunc2\n" } } */
+