public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [gcc-10 PATCH, i386]: Use accessible_reg_set to disable unsupported register sets
@ 2018-11-27 19:32 Uros Bizjak
  2018-11-28 11:38 ` Richard Sandiford
  0 siblings, 1 reply; 3+ messages in thread
From: Uros Bizjak @ 2018-11-27 19:32 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 1457 bytes --]

Hello!

This patch is based on the discussion in PR88178. Apparently, MIPS
uses accessible_reg_set array to disable register sets, unsupported by
currently active ISAs. The patch implements the same approach for x86,
which also results in IMO better error messages. The middle-end misses
to error out in asm having inaccessible clobber registers, so the
patch implements the missing handling (the error message could
probably be improved...)

A couple of test cases now emit better diagnostics, e.g.:

* gcc.target/i386/asm-1.c:5:23: error: the register specified for
'EAX' cannot be accessed by the current target

* gcc.target/i386/pr62120.c:6:16: error: the register specified for
'zmm_var' cannot be accessed by the current target
* gcc.target/i386/pr62120.c:7:16: error: the register specified for
'zmm_var2' cannot be accessed by the current target

instead of "invalid register name" messages.

2018-11-27  Uros Bizjak  <ubizjak@gmail.com>

    * cfgexpand.c (expand_asm_stmt): 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.

Patch was bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

This is gcc-10 material, so the patch is not committed to the repository.

Uros.

[-- Attachment #2: p.diff.txt --]
[-- Type: text/plain, Size: 3588 bytes --]

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 21bdcdaeaa35..691e0c7c1b0b 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -2981,6 +2981,14 @@ expand_asm_stmt (gasm *stmt)
 			   regname);
 		    return;
 		  }
+		else if (!in_hard_reg_set_p
+			 (accessible_reg_set, reg_raw_mode[reg], reg))
+		  {
+		    /* ??? Diagnose during gimplification?  */
+		    error ("the register %qs cannot be clobbered in %<asm%>"
+			   " for the current target", regname);
+		    return;
+		  }
 
 	        SET_HARD_REG_BIT (clobbered_regs, reg);
 	        rtx x = gen_rtx_REG (reg_raw_mode[reg], reg);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 95abde95f89d..9abd441930f4 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -4743,15 +4743,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.  */
@@ -4773,32 +4773,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]);
     }
 }
 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [gcc-10 PATCH, i386]: Use accessible_reg_set to disable unsupported register sets
  2018-11-27 19:32 [gcc-10 PATCH, i386]: Use accessible_reg_set to disable unsupported register sets Uros Bizjak
@ 2018-11-28 11:38 ` Richard Sandiford
  2019-05-07 15:43   ` Uros Bizjak
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Sandiford @ 2018-11-28 11:38 UTC (permalink / raw)
  To: Uros Bizjak; +Cc: gcc-patches, Jakub Jelinek

Uros Bizjak <ubizjak@gmail.com> writes:
> diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
> index 21bdcdaeaa35..691e0c7c1b0b 100644
> --- a/gcc/cfgexpand.c
> +++ b/gcc/cfgexpand.c
> @@ -2981,6 +2981,14 @@ expand_asm_stmt (gasm *stmt)
>  			   regname);
>  		    return;
>  		  }
> +		else if (!in_hard_reg_set_p
> +			 (accessible_reg_set, reg_raw_mode[reg], reg))
> +		  {
> +		    /* ??? Diagnose during gimplification?  */
> +		    error ("the register %qs cannot be clobbered in %<asm%>"
> +			   " for the current target", regname);
> +		    return;
> +		  }
>  
>  	        SET_HARD_REG_BIT (clobbered_regs, reg);
>  	        rtx x = gen_rtx_REG (reg_raw_mode[reg], reg);

There's an argument that clobbering an inaccessible register should
simply be a no-op, so that e.g. you can describe a syscall ABI's effect
on FP registers without having to check whether FP registers are
disabled.  But if an asm explicitly uses the clobbered register,
it would be surprising not to at least warn.  Since we can't reliably
distinguish the two cases, I agree going for the safest is best.

So OK (for GCC 10, like you say) if no-one objects in the meantime.

Thanks,
Richard

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [gcc-10 PATCH, i386]: Use accessible_reg_set to disable unsupported register sets
  2018-11-28 11:38 ` Richard Sandiford
@ 2019-05-07 15:43   ` Uros Bizjak
  0 siblings, 0 replies; 3+ messages in thread
From: Uros Bizjak @ 2019-05-07 15:43 UTC (permalink / raw)
  To: Uros Bizjak, gcc-patches, Jakub Jelinek, Richard Sandiford

On Wed, Nov 28, 2018 at 12:38 PM Richard Sandiford
<richard.sandiford@arm.com> wrote:
>
> Uros Bizjak <ubizjak@gmail.com> writes:
> > diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
> > index 21bdcdaeaa35..691e0c7c1b0b 100644
> > --- a/gcc/cfgexpand.c
> > +++ b/gcc/cfgexpand.c
> > @@ -2981,6 +2981,14 @@ expand_asm_stmt (gasm *stmt)
> >                          regname);
> >                   return;
> >                 }
> > +             else if (!in_hard_reg_set_p
> > +                      (accessible_reg_set, reg_raw_mode[reg], reg))
> > +               {
> > +                 /* ??? Diagnose during gimplification?  */
> > +                 error ("the register %qs cannot be clobbered in %<asm%>"
> > +                        " for the current target", regname);
> > +                 return;
> > +               }
> >
> >               SET_HARD_REG_BIT (clobbered_regs, reg);
> >               rtx x = gen_rtx_REG (reg_raw_mode[reg], reg);
>
> There's an argument that clobbering an inaccessible register should
> simply be a no-op, so that e.g. you can describe a syscall ABI's effect
> on FP registers without having to check whether FP registers are
> disabled.  But if an asm explicitly uses the clobbered register,
> it would be surprising not to at least warn.  Since we can't reliably
> distinguish the two cases, I agree going for the safest is best.
>
> So OK (for GCC 10, like you say) if no-one objects in the meantime.

Now committed.

Uros.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-05-07 15:43 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-27 19:32 [gcc-10 PATCH, i386]: Use accessible_reg_set to disable unsupported register sets Uros Bizjak
2018-11-28 11:38 ` Richard Sandiford
2019-05-07 15:43   ` Uros Bizjak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).