Andreas Schwab <[email protected]> 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 <[email protected]>
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" } } */