From 5b238a4591932c5e5a28fa8f9b3a413a3ce641a6 Mon Sep 17 00:00:00 2001 From: Dimitar Dimitrov Date: Tue, 11 Dec 2018 15:50:51 +0000 Subject: [PATCH] cfgexpand.c (asm_clobber_reg_is_valid): Also produce error when stack pointer is clobbered. gcc/ 2018-12-11 Dimitar Dimitrov * 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 * gcc.target/i386/pr52813.c: New test. From-SVN: r267025 --- gcc/ChangeLog | 6 ++++ gcc/cfgexpand.c | 42 ++++++++++++++++++++----- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.target/i386/pr52813.c | 9 ++++++ 4 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr52813.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 99ba8bdd7fa..cc126c7e3ee 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-12-11 Dimitar Dimitrov + + * 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 * config/rs6000/vxworks.h (RS6000_STARTING_FRAME_OFFSET): Define, diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 9b3259d12ed..0d04bbcafce 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -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 (®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 %", 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 %", 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 %", - 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/ChangeLog b/gcc/testsuite/ChangeLog index 12acfe31ad5..3c15bf7c152 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-12-11 Dimitar Dimitrov + + * gcc.target/i386/pr52813.c: New test. + 2018-12-11 Jakub Jelinek 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 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.30.2