Andreas Schwab <sch...@linux-m68k.org> writes:
> FAIL: gfortran.dg/class_array_1.f03   -O3 -fomit-frame-pointer -funroll-loops 
> -fpeel-loops -ftracer -finline-functions  (test for excess errors)
> Excess errors:
> /opt/gcc/gcc-20171104/gcc/testsuite/gfortran.dg/class_array_1.f03:31:0: 
> Error: could not split insn
> (insn 527 1444 562 (set (reg:TI 0 x0 [847])
>         (const_wide_int 0x10000000000000001)) 
> "/opt/gcc/gcc-20171104/gcc/testsuite/gfortran.dg/class_array_1.f03":21 50 
> {*movti_aarch64}
>      (nil))
> during RTL pass: final
> /opt/gcc/gcc-20171104/gcc/testsuite/gfortran.dg/class_array_1.f03:31:0: 
> internal compiler error: in final_scan_insn, at final.c:3018
> 0x58be1b _fatal_insn(char const*, rtx_def const*, char const*, int, char 
> const*)
>         ../../gcc/rtl-error.c:108
> 0x8aeed7 final_scan_insn(rtx_insn*, _IO_FILE*, int, int, int*)
>         ../../gcc/final.c:3018
> 0x8af12f final(rtx_insn*, _IO_FILE*, int)
>         ../../gcc/final.c:2046
> 0x8af483 rest_of_handle_final
>         ../../gcc/final.c:4477
> 0x8af483 execute
>         ../../gcc/final.c:4551

Yeah, I'd hit this too.  I think it's a latent bug that just
happened to be exposed by Wilco's patch: although the *movti_aarch64
predicate disallows const_wide_int, the constraints allow it via "n",
which means that the RA can rematerialise a const_wide_int that would
otherwise be spilled or forced to memory.

Maybe the best fix would be just to go ahead and add support for
const_wide_int, as with the patch below.

This means that we now implement:

   __int128
   t (void)
   {
     return (__int128)1 << 80;
   }

as:

        mov     x0, 0
        mov     x1, 65536

which probably defeats what pr78733.c and pr79041-2.c were trying
to test, but should be better than loading from memory.

Tested on aarch64-elf and aarch64-linux-gnu.  OK to install?

Thanks,
Richard


2017-11-06  Richard Sandiford  <richard.sandif...@linaro.org>

gcc/
        * config/aarch64/aarch64.c (aarch64_legitimate_constant_p): Allow
        CONST_WIDE_INTs.
        * config/aarch64/predicates.md (aarch64_movti_operand)
        (aarch64_reg_or_imm): Use const_scalar_int_operand rather than
        const_int_operand.

gcc/testsuite/
        * gcc.target/aarch64/pr78733.c: Expect immediate moves.
        * gcc.target/aarch64/pr79041-2.c: Likewise.

Index: gcc/config/aarch64/aarch64.c
===================================================================
--- gcc/config/aarch64/aarch64.c        2017-11-06 08:58:24.140007587 +0000
+++ gcc/config/aarch64/aarch64.c        2017-11-06 10:42:55.272329213 +0000
@@ -10378,7 +10378,9 @@ aarch64_legitimate_pic_operand_p (rtx x)
 aarch64_legitimate_constant_p (machine_mode mode, rtx x)
 {
   /* Support CSE and rematerialization of common constants.  */
-  if (CONST_INT_P (x) || CONST_DOUBLE_P (x) || GET_CODE (x) == CONST_VECTOR)
+  if (CONST_SCALAR_INT_P (x)
+      || CONST_DOUBLE_P (x)
+      || GET_CODE (x) == CONST_VECTOR)
     return true;
 
   /* Do not allow vector struct mode constants.  We could support
@@ -10386,10 +10388,6 @@ aarch64_legitimate_constant_p (machine_m
   if (aarch64_vect_struct_mode_p (mode))
     return false;
 
-  /* Do not allow wide int constants - this requires support in movti.  */
-  if (CONST_WIDE_INT_P (x))
-    return false;
-
   /* Do not allow const (plus (anchor_symbol, const_int)).  */
   if (GET_CODE (x) == CONST)
     {
Index: gcc/config/aarch64/predicates.md
===================================================================
--- gcc/config/aarch64/predicates.md    2017-11-06 08:56:19.855082230 +0000
+++ gcc/config/aarch64/predicates.md    2017-11-06 10:42:55.273229537 +0000
@@ -250,15 +250,13 @@ (define_predicate "aarch64_mov_operand"
                 (match_test "aarch64_mov_operand_p (op, mode)")))))
 
 (define_predicate "aarch64_movti_operand"
-  (and (match_code "reg,subreg,mem,const_int")
-       (ior (match_operand 0 "register_operand")
-           (ior (match_operand 0 "memory_operand")
-                (match_operand 0 "const_int_operand")))))
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "memory_operand")
+       (match_operand 0 "const_scalar_int_operand")))
 
 (define_predicate "aarch64_reg_or_imm"
-  (and (match_code "reg,subreg,const_int")
-       (ior (match_operand 0 "register_operand")
-           (match_operand 0 "const_int_operand"))))
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "const_scalar_int_operand")))
 
 ;; True for integer comparisons and for FP comparisons other than LTGT or UNEQ.
 (define_special_predicate "aarch64_comparison_operator"
Index: gcc/testsuite/gcc.target/aarch64/pr78733.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/pr78733.c  2017-02-23 19:54:05.000000000 
+0000
+++ gcc/testsuite/gcc.target/aarch64/pr78733.c  2017-11-06 10:42:55.273229537 
+0000
@@ -7,4 +7,5 @@ t (void)
   return (__int128)1 << 80;
 }
 
-/* { dg-final { scan-assembler "adr" } } */
+/* { dg-final { scan-assembler "\tmov\tx0, 0" } } */
+/* { dg-final { scan-assembler "\tmov\tx1, 65536" } } */
Index: gcc/testsuite/gcc.target/aarch64/pr79041-2.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/pr79041-2.c        2017-07-27 
10:37:55.117035178 +0100
+++ gcc/testsuite/gcc.target/aarch64/pr79041-2.c        2017-11-06 
10:42:55.273229537 +0000
@@ -8,5 +8,6 @@ t (void)
   return (__int128)1 << 80;
 }
 
-/* { dg-final { scan-assembler "adr" } } */
+/* { dg-final { scan-assembler "\tmov\tx0, 0" } } */
+/* { dg-final { scan-assembler "\tmov\tx1, 65536" } } */
 /* { dg-final { scan-assembler-not "adrp" } } */

Reply via email to