Fix ARM ICE for register var asm ("pc") (PR target/60606)

Alan Lawrence alan.lawrence@arm.com
Wed Sep 17 12:23:00 GMT 2014


We've just noticed this patch causes an ICE in 
gcc.c-torture/execute/scal-to-vec1.c at -O3 when running with -fPIC on 
arm-none-linux-gnueabi and arm-none-linux-gnueabihf; test logs:

spawn /tmp/alan/buildarm-none-linux-gnueabi/obj/gcc4/gcc/xgcc -B/tmp/alan/builda
rm-none-linux-gnueabi/obj/gcc4/gcc/ /work/alan/src/gcc/gcc/testsuite/gcc.c-tortu
re/execute/scal-to-vec1.c -fno-diagnostics-show-caret -fdiagnostics-color=never
-O3 -fomit-frame-pointer -w -lm -fPIC -o ./scal-to-vec1.exe
/work/alan/src/gcc/gcc/testsuite/gcc.c-torture/execute/scal-to-vec1.c: In functi
on 'main':
/work/alan/src/gcc/gcc/testsuite/gcc.c-torture/execute/scal-to-vec1.c:86:1: inte
rnal compiler error: in split_reg, at lra-constraints.c:4805
0x8b4cc7 split_reg
         /work/alan/src/gcc/gcc/lra-constraints.c:4805
0x8b4f52 split_if_necessary
         /work/alan/src/gcc/gcc/lra-constraints.c:4901
0x8b7d2c inherit_in_ebb
         /work/alan/src/gcc/gcc/lra-constraints.c:5395
0x8b8786 lra_inheritance()
         /work/alan/src/gcc/gcc/lra-constraints.c:5560
0x8abd84 lra(_IO_FILE*)
         /work/alan/src/gcc/gcc/lra.c:2218
0x8705f6 do_reload
         /work/alan/src/gcc/gcc/ira.c:5310
0x8705f6 execute
         /work/alan/src/gcc/gcc/ira.c:5469

Complete list (for both arm-none-linux-gnueabi and arm-none-linux-gnueabihf, 
both -fPIC):

FAIL: gcc.c-torture/execute/scal-to-vec1.c   -O3 -fomit-frame-pointer  (internal 
compiler error)
FAIL: gcc.c-torture/execute/scal-to-vec1.c   -O3 -fomit-frame-pointer  (test for 
excess errors)
FAIL: gcc.c-torture/execute/scal-to-vec1.c   -O3 -fomit-frame-pointer 
-funroll-loops  (internal compiler error)
FAIL: gcc.c-torture/execute/scal-to-vec1.c   -O3 -fomit-frame-pointer 
-funroll-loops  (test for excess errors)
FAIL: gcc.c-torture/execute/scal-to-vec1.c   -O3 -fomit-frame-pointer 
-funroll-all-loops -finline-functions  (internal compiler error)
FAIL: gcc.c-torture/execute/scal-to-vec1.c   -O3 -fomit-frame-pointer 
-funroll-all-loops -finline-functions  (test for excess errors)
FAIL: gcc.c-torture/execute/scal-to-vec1.c   -O3 -g  (internal compiler error)
FAIL: gcc.c-torture/execute/scal-to-vec1.c   -O3 -g  (test for excess errors)

Passing without -fPIC.

--Alan

Joseph S. Myers wrote:
> PR 60606 reports an ICE on ARM when declaring a register variable in
> register pc.  Discussion in that bug suggests this usage should be
> considered invalid and give an error.  It turns out similar ICEs also
> occur (after errors) for other cases of invalid register variables.
> 
> This patch fixes at least the original bug and others I observed in
> the course of fixing it (there may well be other cases of registers,
> on ARM and elsewhere, that still create such ICEs).  To make pc
> invalid for register variables, arm_regno_class is changed to return
> NO_REGS for PC_REGNUM (which is consistent with REG_CLASS_CONTENTS).
> Testing the scope of the bug showed similar issues for cc in Thumb
> mode; that is made invalid by making arm_hard_regno_mode_ok disallow
> it for non-MODE_CC modes (i.e. modes that might apply to a variable).
> To avoid ICEs after errors, make_decl_rtl is make to clear
> DECL_ASSEMBLER_NAME and DECL_HARD_REGISTER when a hard register
> specification turns out to be invalid.  cfgexpand.c:expand_one_var is
> then made to call expand_one_error_var in this case, consistent with
> other cases of erroneous variables.
> 
> Tested with no regressions for cross to arm-none-eabi (it also fixes
> failures of gcc.dg/noncompile/920507-1.c, which is PR 61330).  OK to
> commit?
> 
> 2014-08-22  Joseph Myers  <joseph@codesourcery.com>
> 
> 	PR target/60606
> 	PR target/61330
> 	* varasm.c (make_decl_rtl): Clear DECL_ASSEMBLER_NAME and
> 	DECL_HARD_REGISTER and return for invalid register specifications.
> 	* cfgexpand.c (expand_one_var): If expand_one_hard_reg_var clears
> 	DECL_HARD_REGISTER, call expand_one_error_var.
> 	* config/arm/arm.c (arm_hard_regno_mode_ok): Do not allow
> 	CC_REGNUM with non-MODE_CC modes.
> 	(arm_regno_class): Return NO_REGS for PC_REGNUM.
> 
> 2014-08-22  Joseph Myers  <joseph@codesourcery.com>
> 
> 	PR target/60606
> 	PR target/61330
> 	* gcc.dg/torture/pr60606-1.c, gcc.target/arm/pr60606-2.c,
> 	gcc.target/arm/pr60606-3.c, gcc.target/arm/pr60606-4.c: New tests.
> 
> Index: gcc/cfgexpand.c
> ===================================================================
> --- gcc/cfgexpand.c	(revision 214225)
> +++ gcc/cfgexpand.c	(working copy)
> @@ -1307,7 +1307,12 @@ expand_one_var (tree var, bool toplevel, bool real
>    else if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var))
>      {
>        if (really_expand)
> -        expand_one_hard_reg_var (var);
> +	{
> +	  expand_one_hard_reg_var (var);
> +	  if (!DECL_HARD_REGISTER (var))
> +	    /* Invalid register specification.  */
> +	    expand_one_error_var (var);
> +	}
>      }
>    else if (use_register_for_decl (var))
>      {
> Index: gcc/testsuite/gcc.dg/torture/pr60606-1.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/torture/pr60606-1.c	(revision 0)
> +++ gcc/testsuite/gcc.dg/torture/pr60606-1.c	(revision 0)
> @@ -0,0 +1,9 @@
> +/* { dg-do compile } */
> +/* { dg-options "-ffat-lto-objects" } */
> +
> +int
> +f (void)
> +{
> +  register unsigned int r asm ("no-such-register"); /* { dg-error "invalid register name" } */
> +  return r;
> +}
> Index: gcc/testsuite/gcc.target/arm/pr60606-2.c
> ===================================================================
> --- gcc/testsuite/gcc.target/arm/pr60606-2.c	(revision 0)
> +++ gcc/testsuite/gcc.target/arm/pr60606-2.c	(revision 0)
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O" } */
> +
> +int
> +f (void)
> +{
> +  register unsigned pc asm ("pc"); /* { dg-error "not general enough" } */
> +  
> +  return pc > 0x12345678;
> +}
> Index: gcc/testsuite/gcc.target/arm/pr60606-3.c
> ===================================================================
> --- gcc/testsuite/gcc.target/arm/pr60606-3.c	(revision 0)
> +++ gcc/testsuite/gcc.target/arm/pr60606-3.c	(revision 0)
> @@ -0,0 +1,9 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O" } */
> +
> +int
> +f (void)
> +{
> +  register unsigned int r asm ("cc"); /* { dg-error "not general enough|suitable for data type" } */
> +  return r;
> +}
> Index: gcc/testsuite/gcc.target/arm/pr60606-4.c
> ===================================================================
> --- gcc/testsuite/gcc.target/arm/pr60606-4.c	(revision 0)
> +++ gcc/testsuite/gcc.target/arm/pr60606-4.c	(revision 0)
> @@ -0,0 +1,9 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O" } */
> +
> +int
> +f (void)
> +{
> +  register unsigned int r[50] asm ("r1"); /* { dg-error "suitable for a register" } */
> +  return r[1];
> +}
> Index: gcc/config/arm/arm.c
> ===================================================================
> --- gcc/config/arm/arm.c	(revision 214225)
> +++ gcc/config/arm/arm.c	(working copy)
> @@ -22969,6 +22969,9 @@ arm_hard_regno_mode_ok (unsigned int regno, enum m
>  	    || (TARGET_HARD_FLOAT && TARGET_VFP
>  		&& regno == VFPCC_REGNUM));
>  
> +  if (regno == CC_REGNUM && GET_MODE_CLASS (mode) != MODE_CC)
> +    return false;
> +
>    if (TARGET_THUMB1)
>      /* For the Thumb we only allow values bigger than SImode in
>         registers 0 - 6, so that there is always a second low
> @@ -23065,6 +23068,9 @@ arm_modes_tieable_p (enum machine_mode mode1, enum
>  enum reg_class
>  arm_regno_class (int regno)
>  {
> +  if (regno == PC_REGNUM)
> +    return NO_REGS;
> +
>    if (TARGET_THUMB1)
>      {
>        if (regno == STACK_POINTER_REGNUM)
> Index: gcc/varasm.c
> ===================================================================
> --- gcc/varasm.c	(revision 214225)
> +++ gcc/varasm.c	(working copy)
> @@ -1372,6 +1372,11 @@ make_decl_rtl (tree decl)
>  	  /* As a register variable, it has no section.  */
>  	  return;
>  	}
> +      /* Avoid internal errors from invalid register
> +	 specifications.  */
> +      SET_DECL_ASSEMBLER_NAME (decl, NULL_TREE);
> +      DECL_HARD_REGISTER (decl) = 0;
> +      return;
>      }
>    /* Now handle ordinary static variables and functions (in memory).
>       Also handle vars declared register invalidly.  */
> 




More information about the Gcc-patches mailing list