From c348cab062adf3946fdadff884b7f43774d72d8f Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 7 Dec 2017 18:43:40 +0000 Subject: [PATCH] [AArch64] Fix ICEs in aarch64_print_operand Three related regression fixes: - We can't use asserts like: gcc_assert (GET_MODE_SIZE (mode) == 16); in aarch64_print_operand because it could trigger for invalid user input. - The output_operand_lossage in aarch64_print_address_internal: output_operand_lossage ("invalid operand for '%%%c'", op); wasn't right because "op" is an rtx_code enum rather than the prefix character. - aarch64_print_operand_address shouldn't call output_operand_lossage (because it doesn't have a prefix code) but instead fall back to output_addr_const. 2017-12-05 Richard Sandiford gcc/ * config/aarch64/aarch64.c (aarch64_print_address_internal): Return a bool success value. Don't call output_operand_lossage here. (aarch64_print_ldpstp_address): Return a bool success value. (aarch64_print_operand_address): Call output_addr_const if aarch64_print_address_internal fails. (aarch64_print_operand): Don't assert that the mode is 16 bytes for 'y'; call output_operand_lossage instead. Call output_operand_lossage if aarch64_print_ldpstp_address fails. gcc/testsuite/ * gcc.target/aarch64/asm-2.c: New test. * gcc.target/aarch64/asm-3.c: Likewise. From-SVN: r255481 --- gcc/ChangeLog | 11 +++++ gcc/config/aarch64/aarch64.c | 54 ++++++++++++------------ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.target/aarch64/asm-2.c | 10 +++++ gcc/testsuite/gcc.target/aarch64/asm-3.c | 10 +++++ 5 files changed, 63 insertions(+), 27 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/asm-2.c create mode 100644 gcc/testsuite/gcc.target/aarch64/asm-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1cee5e82907..7cf988956b7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2017-12-07 Richard Sandiford + + * config/aarch64/aarch64.c (aarch64_print_address_internal): Return + a bool success value. Don't call output_operand_lossage here. + (aarch64_print_ldpstp_address): Return a bool success value. + (aarch64_print_operand_address): Call output_addr_const if + aarch64_print_address_internal fails. + (aarch64_print_operand): Don't assert that the mode is 16 bytes for + 'y'; call output_operand_lossage instead. Call output_operand_lossage + if aarch64_print_ldpstp_address fails. + 2017-12-07 Richard Sandiford * tree-vector-builder.h diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 75a6c0d0421..83d86071312 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -150,7 +150,7 @@ static bool aarch64_builtin_support_vector_misalignment (machine_mode mode, bool is_packed); static machine_mode aarch64_simd_container_mode (scalar_mode mode, unsigned width); -static void aarch64_print_ldpstp_address (FILE *f, machine_mode mode, rtx x); +static bool aarch64_print_ldpstp_address (FILE *, machine_mode, rtx); /* Major revision number of the ARM Architecture implemented by the target. */ unsigned aarch64_architecture_version; @@ -5600,22 +5600,21 @@ aarch64_print_operand (FILE *f, rtx x, int code) { machine_mode mode = GET_MODE (x); - if (GET_CODE (x) != MEM) + if (GET_CODE (x) != MEM + || (code == 'y' && GET_MODE_SIZE (mode) != 16)) { output_operand_lossage ("invalid operand for '%%%c'", code); return; } if (code == 'y') - { - /* LDP/STP which uses a single double-width memory operand. - Adjust the mode to appear like a typical LDP/STP. - Currently this is supported for 16-byte accesses only. */ - gcc_assert (GET_MODE_SIZE (mode) == 16); - mode = DFmode; - } + /* LDP/STP which uses a single double-width memory operand. + Adjust the mode to appear like a typical LDP/STP. + Currently this is supported for 16-byte accesses only. */ + mode = DFmode; - aarch64_print_ldpstp_address (f, mode, XEXP (x, 0)); + if (!aarch64_print_ldpstp_address (f, mode, XEXP (x, 0))) + output_operand_lossage ("invalid operand prefix '%%%c'", code); } break; @@ -5628,7 +5627,7 @@ aarch64_print_operand (FILE *f, rtx x, int code) /* Print address 'x' of a memory access with mode 'mode'. 'op' is the context required by aarch64_classify_address. It can either be MEM for a normal memory access or PARALLEL for LDP/STP. */ -static void +static bool aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, RTX_CODE op) { struct aarch64_address_info addr; @@ -5645,7 +5644,7 @@ aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, RTX_CODE op) else asm_fprintf (f, "[%s, %wd]", reg_names [REGNO (addr.base)], INTVAL (addr.offset)); - return; + return true; case ADDRESS_REG_REG: if (addr.shift == 0) @@ -5654,7 +5653,7 @@ aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, RTX_CODE op) else asm_fprintf (f, "[%s, %s, lsl %u]", reg_names [REGNO (addr.base)], reg_names [REGNO (addr.offset)], addr.shift); - return; + return true; case ADDRESS_REG_UXTW: if (addr.shift == 0) @@ -5663,7 +5662,7 @@ aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, RTX_CODE op) else asm_fprintf (f, "[%s, w%d, uxtw %u]", reg_names [REGNO (addr.base)], REGNO (addr.offset) - R0_REGNUM, addr.shift); - return; + return true; case ADDRESS_REG_SXTW: if (addr.shift == 0) @@ -5672,7 +5671,7 @@ aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, RTX_CODE op) else asm_fprintf (f, "[%s, w%d, sxtw %u]", reg_names [REGNO (addr.base)], REGNO (addr.offset) - R0_REGNUM, addr.shift); - return; + return true; case ADDRESS_REG_WB: switch (GET_CODE (x)) @@ -5680,27 +5679,27 @@ aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, RTX_CODE op) case PRE_INC: asm_fprintf (f, "[%s, %d]!", reg_names [REGNO (addr.base)], GET_MODE_SIZE (mode)); - return; + return true; case POST_INC: asm_fprintf (f, "[%s], %d", reg_names [REGNO (addr.base)], GET_MODE_SIZE (mode)); - return; + return true; case PRE_DEC: asm_fprintf (f, "[%s, -%d]!", reg_names [REGNO (addr.base)], GET_MODE_SIZE (mode)); - return; + return true; case POST_DEC: asm_fprintf (f, "[%s], -%d", reg_names [REGNO (addr.base)], GET_MODE_SIZE (mode)); - return; + return true; case PRE_MODIFY: asm_fprintf (f, "[%s, %wd]!", reg_names [REGNO (addr.base)], INTVAL (addr.offset)); - return; + return true; case POST_MODIFY: asm_fprintf (f, "[%s], %wd", reg_names [REGNO (addr.base)], INTVAL (addr.offset)); - return; + return true; default: break; } @@ -5710,28 +5709,29 @@ aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, RTX_CODE op) asm_fprintf (f, "[%s, #:lo12:", reg_names [REGNO (addr.base)]); output_addr_const (f, addr.offset); asm_fprintf (f, "]"); - return; + return true; case ADDRESS_SYMBOLIC: output_addr_const (f, x); - return; + return true; } - output_operand_lossage ("invalid operand for '%%%c'", op); + return false; } /* Print address 'x' of a LDP/STP with mode 'mode'. */ -static void +static bool aarch64_print_ldpstp_address (FILE *f, machine_mode mode, rtx x) { - aarch64_print_address_internal (f, mode, x, PARALLEL); + return aarch64_print_address_internal (f, mode, x, PARALLEL); } /* Print address 'x' of a memory access with mode 'mode'. */ static void aarch64_print_operand_address (FILE *f, machine_mode mode, rtx x) { - aarch64_print_address_internal (f, mode, x, MEM); + if (!aarch64_print_address_internal (f, mode, x, MEM)) + output_addr_const (f, x); } bool diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fd46db71d2b..3a22f217a17 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-12-07 Richard Sandiford + + * gcc.target/aarch64/asm-2.c: New test. + * gcc.target/aarch64/asm-3.c: Likewise. + 2017-12-07 Bin Cheng Richard Biener diff --git a/gcc/testsuite/gcc.target/aarch64/asm-2.c b/gcc/testsuite/gcc.target/aarch64/asm-2.c new file mode 100644 index 00000000000..3f978f5b234 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/asm-2.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int x; + +void +f (void) +{ + asm volatile ("%a0" :: "X" (&x)); +} diff --git a/gcc/testsuite/gcc.target/aarch64/asm-3.c b/gcc/testsuite/gcc.target/aarch64/asm-3.c new file mode 100644 index 00000000000..75317bddb4a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/asm-3.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int x; + +void +f (void) +{ + asm volatile ("%y0" :: "X" (x)); /* { dg-error "invalid" } */ +} -- 2.30.2