From 0a59215131c02dee4c8829f93d1ee678647614da Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Tue, 7 May 2019 17:42:42 +0200 Subject: [PATCH] cfgexpand.c (asm_clobber_reg_is_valid): Reject clobbers outside of accessible_reg_set. * cfgexpand.c (asm_clobber_reg_is_valid): Reject clobbers outside of accessible_reg_set. * config/i386/i386.c (ix86_conditional_register_usage): Disable register sets by clearing corresponding bits in accessible_reg_set. Do not set corresponding bits in fixed_regs, call_used_regs and don't clear corresponding reg_names array members. testsuite/ChangeLog: * gcc.target/i386/asm-7.c: New test. * gcc.target/i386/asm-1.c: Update expected error string. * gcc.target/i386/pr62120.c: Ditto. From-SVN: r270955 --- gcc/ChangeLog | 9 ++++++ gcc/cfgexpand.c | 9 ++++++ gcc/config/i386/i386.c | 37 ++++++++++++------------- gcc/testsuite/ChangeLog | 6 ++++ gcc/testsuite/gcc.target/i386/asm-1.c | 2 +- gcc/testsuite/gcc.target/i386/asm-7.c | 8 ++++++ gcc/testsuite/gcc.target/i386/pr62120.c | 4 +-- 7 files changed, 52 insertions(+), 23 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/asm-7.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8770f865335..cf2ea44035b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2019-05-07 Uroš Bizjak + + * cfgexpand.c (asm_clobber_reg_is_valid): Reject + clobbers outside of accessible_reg_set. + * config/i386/i386.c (ix86_conditional_register_usage): + Disable register sets by clearing corresponding bits in + accessible_reg_set. Do not set corresponding bits in fixed_regs, + call_used_regs and don't clear corresponding reg_names array members. + 2019-05-07 Richard Biener * tree-vect-stmts.c (vect_is_simple_cond): When vectype is diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 518d71c74c8..3a4bd354bf9 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -2874,6 +2874,15 @@ asm_clobber_reg_is_valid (int regno, int nregs, const char *regname) error ("PIC register clobbered by %qs in %", regname); is_valid = false; } + else if (!in_hard_reg_set_p + (accessible_reg_set, reg_raw_mode[regno], regno)) + { + /* ??? Diagnose during gimplification? */ + error ("the register %qs cannot be clobbered in %" + " for the current target", regname); + is_valid = false; + } + /* Clobbering the stack pointer register is deprecated. GCC expects the value of the stack pointer after an asm statement to be the same as it was before, so no asm can validly clobber the stack pointer in diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 2f23986a9dd..ab1524c3524 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -480,15 +480,15 @@ ix86_conditional_register_usage (void) if (!fixed_regs[i] && !ix86_function_value_regno_p (i)) call_used_regs[i] = 0; - /* For 32-bit targets, squash the REX registers. */ + /* For 32-bit targets, disable the REX registers. */ if (! TARGET_64BIT) { for (i = FIRST_REX_INT_REG; i <= LAST_REX_INT_REG; i++) - fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; + CLEAR_HARD_REG_BIT (accessible_reg_set, i); for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++) - fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; + CLEAR_HARD_REG_BIT (accessible_reg_set, i); for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++) - fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; + CLEAR_HARD_REG_BIT (accessible_reg_set, i); } /* See the definition of CALL_USED_REGISTERS in i386.h. */ @@ -510,32 +510,29 @@ ix86_conditional_register_usage (void) SET_HARD_REG_BIT (reg_class_contents[(int)CLOBBERED_REGS], i); } - /* If MMX is disabled, squash the registers. */ + /* If MMX is disabled, disable the registers. */ if (! TARGET_MMX) - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (TEST_HARD_REG_BIT (reg_class_contents[(int)MMX_REGS], i)) - fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; + AND_COMPL_HARD_REG_SET (accessible_reg_set, + reg_class_contents[(int) MMX_REGS]); - /* If SSE is disabled, squash the registers. */ + /* If SSE is disabled, disable the registers. */ if (! TARGET_SSE) - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (TEST_HARD_REG_BIT (reg_class_contents[(int)SSE_REGS], i)) - fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; + AND_COMPL_HARD_REG_SET (accessible_reg_set, + reg_class_contents[(int) ALL_SSE_REGS]); - /* If the FPU is disabled, squash the registers. */ + /* If the FPU is disabled, disable the registers. */ if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387)) - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (TEST_HARD_REG_BIT (reg_class_contents[(int)FLOAT_REGS], i)) - fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; + AND_COMPL_HARD_REG_SET (accessible_reg_set, + reg_class_contents[(int) FLOAT_REGS]); - /* If AVX512F is disabled, squash the registers. */ + /* If AVX512F is disabled, disable the registers. */ if (! TARGET_AVX512F) { for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++) - fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; + CLEAR_HARD_REG_BIT (accessible_reg_set, i); - for (i = FIRST_MASK_REG; i <= LAST_MASK_REG; i++) - fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; + AND_COMPL_HARD_REG_SET (accessible_reg_set, + reg_class_contents[(int) ALL_MASK_REGS]); } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 28157d3198c..ae46a726139 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-05-07 Uroš Bizjak + + * gcc.target/i386/asm-7.c: New test. + * gcc.target/i386/asm-1.c: Update expected error string. + * gcc.target/i386/pr62120.c: Ditto. + 2019-05-07 Li Jia He * gcc.dg/tree-ssa/pr37508.c: Add the no-ssa-phiopt option to skip phi diff --git a/gcc/testsuite/gcc.target/i386/asm-1.c b/gcc/testsuite/gcc.target/i386/asm-1.c index cd60a09bd7f..5e516d88291 100644 --- a/gcc/testsuite/gcc.target/i386/asm-1.c +++ b/gcc/testsuite/gcc.target/i386/asm-1.c @@ -2,7 +2,7 @@ /* { dg-require-effective-target ia32 } */ /* { dg-options "" } */ -register unsigned int EAX asm ("r14"); /* { dg-error "register name" } */ +register unsigned int EAX asm ("r14"); /* { dg-error "cannot be accessed" } */ void foo () { diff --git a/gcc/testsuite/gcc.target/i386/asm-7.c b/gcc/testsuite/gcc.target/i386/asm-7.c new file mode 100644 index 00000000000..d2d113626a7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/asm-7.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target ia32 } */ +/* { dg-options "" } */ + +void foo (void) +{ + asm volatile ("" : : : "%r12"); /* { dg-error "cannot be clobbered" } */ +} diff --git a/gcc/testsuite/gcc.target/i386/pr62120.c b/gcc/testsuite/gcc.target/i386/pr62120.c index bfb8c4703eb..28d85d37712 100644 --- a/gcc/testsuite/gcc.target/i386/pr62120.c +++ b/gcc/testsuite/gcc.target/i386/pr62120.c @@ -3,6 +3,6 @@ void foo () { - register int zmm_var asm ("ymm9");/* { dg-error "invalid register name" } */ - register int zmm_var2 asm ("23");/* { dg-error "invalid register name" } */ + register int zmm_var asm ("ymm9");/* { dg-error "cannot be accessed" } */ + register int zmm_var2 asm ("23");/* { dg-error "cannot be accessed" } */ } -- 2.30.2