[PATCH] [RFC] PR target/52813 and target/11807
Dimitar Dimitrov
dimitar@dinux.eu
Sun Dec 9 10:09:00 GMT 2018
I have tested this fix on x86_64 host, and found no regression in the C
and C++ testsuites. I'm marking this patch as RFC simply because I don't
have experience with other architectures, and I don't have a setup to
test all architectures supported by GCC.
gcc/ChangeLog:
2018-12-07 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/ChangeLog:
2018-12-07 Dimitar Dimitrov <dimitar@dinux.eu>
* gcc.target/i386/pr52813.c: New test.
Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu>
---
gcc/cfgexpand.c | 42 ++++++++++++++++++++++++++-------
gcc/testsuite/gcc.target/i386/pr52813.c | 9 +++++++
2 files changed, 43 insertions(+), 8 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/i386/pr52813.c
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 5e23bc242b9..8474372a216 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -2845,6 +2845,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 (®set, 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.
@@ -2977,14 +3009,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);
diff --git a/gcc/testsuite/gcc.target/i386/pr52813.c b/gcc/testsuite/gcc.target/i386/pr52813.c
new file mode 100644
index 00000000000..154ebbfc423
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr52813.c
@@ -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" } */
+}
--
2.11.0
More information about the Gcc-patches
mailing list