]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/55019 (Incorrectly use live argument register to save high register...
authorTerry Guo <terry.guo@arm.com>
Tue, 23 Oct 2012 03:49:17 +0000 (03:49 +0000)
committerXuepeng Guo <xguo@gcc.gnu.org>
Tue, 23 Oct 2012 03:49:17 +0000 (03:49 +0000)
gcc/
PR target/55019
* config/arm/arm.c (thumb1_expand_prologue): Don't push high regs with
live argument regs.

gcc/testsuite/
PR target/55019
* gcc.dg/pr55019.c: New.

From-SVN: r192703

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr55019.c [new file with mode: 0644]

index 9ec0467ab9b3523505899157f393285c4ab6ad04..236464f4dc1dc438c66e88bb377811b26934288d 100644 (file)
@@ -1,3 +1,9 @@
+2012-10-23  Terry Guo  <terry.guo@arm.com>
+
+       PR target/55019
+       * config/arm/arm.c (thumb1_expand_prologue): Don't push high regs with
+       live argument regs.
+
 2012-10-23  Hans-Peter Nilsson  <hp@bitrange.com>
 
        PR middle-end/55030
index 1a822fb446137f0d20d54ab0dab3d90d0935ba81..e9b94631cf93f0fda2a246bfbe77b6cd51b5e98f 100644 (file)
@@ -22753,12 +22753,18 @@ thumb1_expand_prologue (void)
     {
       unsigned pushable_regs;
       unsigned next_hi_reg;
+      unsigned arg_regs_num = TARGET_AAPCS_BASED ? crtl->args.info.aapcs_ncrn
+                                                : crtl->args.info.nregs;
+      unsigned arg_regs_mask = (1 << arg_regs_num) - 1;
 
       for (next_hi_reg = 12; next_hi_reg > LAST_LO_REGNUM; next_hi_reg--)
        if (live_regs_mask & (1 << next_hi_reg))
          break;
 
-      pushable_regs = l_mask & 0xff;
+      /* Here we need to mask out registers used for passing arguments
+        even if they can be pushed.  This is to avoid using them to stash the high
+        registers.  Such kind of stash may clobber the use of arguments.  */
+      pushable_regs = l_mask & (~arg_regs_mask) & 0xff;
 
       if (pushable_regs == 0)
        pushable_regs = 1 << thumb_find_work_register (live_regs_mask);
index 243d74e352d61af2c0d0e2562a3f62bf7354a1fc..16e6dd6b4277ad72986229a53e9aa32a68cb52cc 100644 (file)
@@ -1,3 +1,8 @@
+2012-10-23  Terry Guo  <terry.guo@arm.com>
+
+       PR target/55019
+       * gcc.dg/pr55019.c: New.
+
 2012-10-22  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
        PR tree-optimization/55008
diff --git a/gcc/testsuite/gcc.dg/pr55019.c b/gcc/testsuite/gcc.dg/pr55019.c
new file mode 100644 (file)
index 0000000..1548fb2
--- /dev/null
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-options "-O1 -funroll-loops" } */
+/* { dg-add-options ieee } */
+
+extern void exit (int);
+extern void abort (void);
+
+void
+compare (double a, double b)
+{
+  do
+    {
+      double s1 = __builtin_copysign ((double) 1.0, a);
+      double s2 = __builtin_copysign ((double) 1.0, b);
+
+      if (s1 != s2)
+        abort ();
+
+      if ((__builtin_isnan (a) != 0) != (__builtin_isnan (b) != 0))
+        abort ();
+
+      if ((a != b) != (__builtin_isnan (a) != 0))
+        abort ();
+    } while (0);
+}
+
+int
+main ()
+{
+  double a = 0.0;
+  double b = 0.0;
+  _Complex double cr = __builtin_complex (a, b);
+  static _Complex double cs = __builtin_complex (0.0, 0.0);
+
+  compare (__real__ cr, 0.0);
+  compare (__imag__ cr, 0.0);
+  compare (__real__ cs, 0.0);
+  compare (__imag__ cs, 0.0);
+
+  exit (0);
+}