cfgexpand.c (asm_clobber_reg_is_valid): Also produce error when stack pointer is...
authorDimitar Dimitrov <dimitar@dinux.eu>
Tue, 11 Dec 2018 15:50:51 +0000 (15:50 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 11 Dec 2018 15:50:51 +0000 (15:50 +0000)
gcc/
2018-12-11  Dimitar Dimitrov  <dimitar@dinux.eu>

* cfgexpand.c (asm_clobber_reg_is_valid): Also produce
error when stack pointer is clobbered.
(expand_asm_stmt): Refactor clobber check in separate function.

gcc/testsuite/
2018-12-11  Dimitar Dimitrov  <dimitar@dinux.eu>

* gcc.target/i386/pr52813.c: New test.

From-SVN: r267025

gcc/ChangeLog
gcc/cfgexpand.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr52813.c [new file with mode: 0644]

index 99ba8bdd7fa0a677f5260c8e4d4a38ab0e88b7d3..cc126c7e3ee83d50874e755563e1baf81bce9fbb 100644 (file)
@@ -1,3 +1,9 @@
+2018-12-11  Dimitar Dimitrov  <dimitar@dinux.eu>
+
+       * cfgexpand.c (asm_clobber_reg_is_valid): Also produce
+       error when stack pointer is clobbered.
+       (expand_asm_stmt): Refactor clobber check in separate function.
+
 2018-12-11  Eric Botcazou  <botcazou@adacore.com>
 
        * config/rs6000/vxworks.h (RS6000_STARTING_FRAME_OFFSET): Define,
index 9b3259d12ed198b3e8330751b25d7a87d39eaa0c..0d04bbcafcee8f60050d8ec47009c5355785341c 100644 (file)
@@ -2850,6 +2850,38 @@ tree_conflicts_with_clobbers_p (tree t, HARD_REG_SET *clobbered_regs)
   return false;
 }
 
+/* Check that the given REGNO spanning NREGS is a valid
+   asm clobber operand.  Some HW registers cannot be
+   saved/restored, hence they should not be clobbered by
+   asm statements.  */
+static bool
+asm_clobber_reg_is_valid (int regno, int nregs, const char *regname)
+{
+  bool is_valid = true;
+  HARD_REG_SET regset;
+
+  CLEAR_HARD_REG_SET (regset);
+
+  add_range_to_hard_reg_set (&regset, regno, nregs);
+
+  /* Clobbering the PIC register is an error.  */
+  if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
+      && overlaps_hard_reg_set_p (regset, Pmode, PIC_OFFSET_TABLE_REGNUM))
+    {
+      /* ??? Diagnose during gimplification?  */
+      error ("PIC register clobbered by %qs in %<asm%>", regname);
+      is_valid = false;
+    }
+  /* Clobbering the STACK POINTER register is an error.  */
+  if (overlaps_hard_reg_set_p (regset, Pmode, STACK_POINTER_REGNUM))
+    {
+      error ("Stack Pointer register clobbered by %qs in %<asm%>", regname);
+      is_valid = false;
+    }
+
+  return is_valid;
+}
+
 /* Generate RTL for an asm statement with arguments.
    STRING is the instruction template.
    OUTPUTS is a list of output arguments (lvalues); INPUTS a list of inputs.
@@ -2982,14 +3014,8 @@ expand_asm_stmt (gasm *stmt)
          else
            for (int reg = j; reg < j + nregs; reg++)
              {
-               /* Clobbering the PIC register is an error.  */
-               if (reg == (int) PIC_OFFSET_TABLE_REGNUM)
-                 {
-                   /* ??? Diagnose during gimplification?  */
-                   error ("PIC register clobbered by %qs in %<asm%>",
-                          regname);
-                   return;
-                 }
+               if (!asm_clobber_reg_is_valid (reg, nregs, regname))
+                 return;
 
                SET_HARD_REG_BIT (clobbered_regs, reg);
                rtx x = gen_rtx_REG (reg_raw_mode[reg], reg);
index 12acfe31ad54d9e9e3e89cbd77e93b1b98bfe3dd..3c15bf7c152185cedc2707a0625f5c7633dc8c7d 100644 (file)
@@ -1,3 +1,7 @@
+2018-12-11  Dimitar Dimitrov  <dimitar@dinux.eu>
+
+       * gcc.target/i386/pr52813.c: New test.
+
 2018-12-11  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/88425
diff --git a/gcc/testsuite/gcc.target/i386/pr52813.c b/gcc/testsuite/gcc.target/i386/pr52813.c
new file mode 100644 (file)
index 0000000..154ebbf
--- /dev/null
@@ -0,0 +1,9 @@
+/* Ensure that stack pointer cannot be an asm clobber.  */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2" } */
+
+void
+test1 (void)
+{
+  asm volatile ("" : : : "%esp"); /* { dg-error "Stack Pointer register clobbered" } */
+}