diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 11f793d..555acd7 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -22410,12 +22410,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);
diff --git a/gcc/testsuite/gcc.target/arm/pr55019.c b/gcc/testsuite/gcc.target/arm/pr55019.c
new file mode 100644
index 0000000..c72a6db
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr55019.c
@@ -0,0 +1,43 @@
+/* { dg-do run } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+/* { 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);
+}
