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  <jos...@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  <jos...@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.  */



Reply via email to