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" } } */