]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
For Ian Bolton <ian.bolton@arm.com>
authorIan Bolton <ian.bolton@arm.com>
Thu, 19 Aug 2010 08:27:59 +0000 (08:27 +0000)
committerRamana Radhakrishnan <ramana@gcc.gnu.org>
Thu, 19 Aug 2010 08:27:59 +0000 (08:27 +0000)
2010-08-19  Ian Bolton  <ian.bolton@arm.com>

PR target/45070
* gcc.c-torture/execute/pr45070.c: New.
* config/arm/arm.c (arm_output_epilogue): Ensure that return
 value of size 1-3 is handled correctly.

From-SVN: r163367

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr45070.c [new file with mode: 0644]

index 4711095729facacf993587c23b81fa5c7a954592..ff0e2c0bdf3027a4b8493ff2481ec9d943fda1b1 100644 (file)
@@ -1,3 +1,9 @@
+2010-08-19  Ian Bolton  <ian.bolton@arm.com>
+
+       PR target/45070
+       * config/arm/arm.c (arm_output_epilogue): Ensure that return
+        value of size 1-3 is handled correctly.
+
 2010-08-19  Ian Bolton  <ian.bolton@arm.com>
 
        * tree-switch-conversion.c (gen_inbound_check): Ensure that the
index f6148a7309d59eb4f0cfa3c0e03aa514ddc63de7..5ed16a8a76e83fc90b263c11f1fa0c0d5c4e9417 100644 (file)
@@ -14467,7 +14467,8 @@ arm_output_epilogue (rtx sibling)
                  && !crtl->tail_call_emit)
                {
                  unsigned long mask;
-                 mask = (1 << (arm_size_return_regs() / 4)) - 1;
+                  /* Preserve return values, of any size.  */
+                 mask = (1 << ((arm_size_return_regs() + 3) / 4)) - 1;
                  mask ^= 0xf;
                  mask &= ~saved_regs_mask;
                  reg = 0;
index afd8b999f6cac73b3f1c0f4e93bff80e5c7a7016..f4d145a159115a0a85c731aca303973093ff0f79 100644 (file)
@@ -1,3 +1,8 @@
+2010-08-19  Ian Bolton  <ian.bolton@arm.com>
+
+       PR target/45070
+       * gcc.c-torture/execute/pr45070.c: New.
+
 2010-08-19  Ian Bolton  <ian.bolton@arm.com>
 
        * g++.dg/pr44328.C: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr45070.c b/gcc/testsuite/gcc.c-torture/execute/pr45070.c
new file mode 100644 (file)
index 0000000..95ff77a
--- /dev/null
@@ -0,0 +1,52 @@
+/* PR45070 */
+extern void abort(void);
+
+struct packed_ushort {
+    unsigned short ucs;
+} __attribute__((packed));
+
+struct source {
+    int pos, length;
+    int flag;
+};
+
+static void __attribute__((noinline)) fetch(struct source *p)
+{
+    p->length = 128;
+}
+    
+static struct packed_ushort __attribute__((noinline)) next(struct source *p)
+{
+    struct packed_ushort rv;
+
+    if (p->pos >= p->length) {
+       if (p->flag) {
+           p->flag = 0;
+           fetch(p);
+           return next(p);
+       }
+       p->flag = 1;
+       rv.ucs = 0xffff;
+       return rv;
+    }
+    rv.ucs = 0;
+    return rv;
+}
+
+int main(void)
+{
+    struct source s;
+    int i;
+
+    s.pos = 0;
+    s.length = 0;
+    s.flag = 0;
+
+    for (i = 0; i < 16; i++) {
+       struct packed_ushort rv = next(&s);
+       if ((i == 0 && rv.ucs != 0xffff)
+           || (i > 0 && rv.ucs != 0))
+           abort();
+    }
+    return 0;
+}