[PATCH][ARM] Fix PR89222
Ramana Radhakrishnan
ramana.gcc@googlemail.com
Mon Feb 11 21:32:00 GMT 2019
On Mon, Feb 11, 2019 at 5:35 PM Wilco Dijkstra <Wilco.Dijkstra@arm.com> wrote:
>
> The GCC optimizer can generate symbols with non-zero offset from simple
> if-statements. Bit zero is used for the Arm/Thumb state bit, so relocations
> with offsets fail if it changes bit zero and the relocation forces bit zero
> to true. The fix is to disable offsets on function pointer symbols.
>
> ARMv5te bootstrap OK, regression tests pass. OK for commit?
Interesting bug. armv5te-linux bootstrap ? Can you share your --target
and --with-arch flags ?
>
> ChangeLog:
> 2019-02-06 Wilco Dijkstra <wdijkstr@arm.com>
>
> gcc/
> PR target/89222
> * config/arm/arm.md (movsi): Use arm_cannot_force_const_mem
> to decide when to split off an offset from a symbol.
> * config/arm/arm.c (arm_cannot_force_const_mem): Disallow offsets
> in function symbols.
> * config/arm/arm-protos.h (arm_cannot_force_const_mem): Add.
>
> testsuite/
> PR target/89222
> * gcc.target/arm/pr89222.c: Add new test.
>
> --
> diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
> index 79ede0db174fcce87abe8b4d18893550d4c7e2f6..0bedbe5110853617ecf7456bbaa56b1405fb65dd 100644
> --- a/gcc/config/arm/arm-protos.h
> +++ b/gcc/config/arm/arm-protos.h
> @@ -184,6 +184,7 @@ extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
> extern bool arm_pad_reg_upward (machine_mode, tree, int);
> #endif
> extern int arm_apply_result_size (void);
> +extern bool arm_cannot_force_const_mem (machine_mode, rtx);
>
> #endif /* RTX_CODE */
>
> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> index c4c9b4a667100d81d918196713e40b01ee232ee2..ccd4211045066d8edb89dd4c23d554517639f8f6 100644
> --- a/gcc/config/arm/arm.c
> +++ b/gcc/config/arm/arm.c
> @@ -178,7 +178,6 @@ static void arm_internal_label (FILE *, const char *, unsigned long);
> static void arm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
> tree);
> static bool arm_have_conditional_execution (void);
> -static bool arm_cannot_force_const_mem (machine_mode, rtx);
> static bool arm_legitimate_constant_p (machine_mode, rtx);
> static bool arm_rtx_costs (rtx, machine_mode, int, int, int *, bool);
> static int arm_address_cost (rtx, machine_mode, addr_space_t, bool);
> @@ -8936,15 +8935,20 @@ arm_legitimate_constant_p (machine_mode mode, rtx x)
>
> /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
>
> -static bool
Let's keep this static ...
> +bool
> arm_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
> {
> rtx base, offset;
> + split_const (x, &base, &offset);
>
> - if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
> + if (GET_CODE (base) == SYMBOL_REF)
Isn't there a SYMBOL_REF_P predicate for this ?
> {
> - split_const (x, &base, &offset);
> - if (GET_CODE (base) == SYMBOL_REF
> + /* Function symbols cannot have an offset due to the Thumb bit. */
> + if ((SYMBOL_REF_FLAGS (base) & SYMBOL_FLAG_FUNCTION)
> + && INTVAL (offset) != 0)
> + return true;
> +
Can we look to allow anything that is a power of 2 as an offset i.e.
anything with bit 0 set to 0 ? Could you please file an enhancement
request on binutils for both gold and ld to catch the linker warning
case ? I suspect we are looking for addends which have the lower bit
set and function symbols ?
> + if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P
> && !offset_within_block_p (base, INTVAL (offset)))
> return true;
> }
this looks ok.
> diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
> index aa759624f8f617576773aa75fd6239d6e06e8a13..00fccd964a86dd814f15e4a1fdf5b47173a3ee3f 100644
> --- a/gcc/config/arm/arm.md
> +++ b/gcc/config/arm/arm.md
> @@ -5981,17 +5981,13 @@ (define_expand "movsi"
> }
> }
>
> - if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
> + if (arm_cannot_force_const_mem (SImode, operands[1]))
Firstly (targetm.cannot_force_const_mem (...)) please instead of
arm_cannot_force_const_mem , then that can remain static. Let's look
to use the targetm interface instead of direct calls here. We weren't
hitting this path for non-vxworks code , however now we do so if
arm_tls_referenced_p is true at the end of arm_cannot_force_const_mem
which means that we could well have a TLS address getting spat out or
am I mis-reading something ?
This is my main concern with this patch ..
> {
> split_const (operands[1], &base, &offset);
> - if (GET_CODE (base) == SYMBOL_REF
> - && !offset_within_block_p (base, INTVAL (offset)))
> - {
> - tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
> - emit_move_insn (tmp, base);
> - emit_insn (gen_addsi3 (operands[0], tmp, offset));
> - DONE;
> - }
> + tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
> + emit_move_insn (tmp, base);
> + emit_insn (gen_addsi3 (operands[0], tmp, offset));
> + DONE;
Can Olivier or someone who cares about vxworks also give this a quick
sanity run for the alternate code path once we resolve some of the
review questions here ? Don't we also need to worry about
-mslow-flash-data where we get rid of literal pools and have movw /
movt instructions ?
regards
Ramana
> }
>
> /* Recognize the case where operand[1] is a reference to thread-local
> diff --git a/gcc/testsuite/gcc.target/arm/pr89222.c b/gcc/testsuite/gcc.target/arm/pr89222.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..d26d7df17544db8426331e67b9a36d749ec6c6d1
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/pr89222.c
> @@ -0,0 +1,32 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +void g (void);
> +
> +void f1 (int x)
> +{
> + if (x != (int) g + 3)
> + return;
> + g();
> +}
> +
> +void (*a2)(void);
> +
> +void f2 (void)
> +{
> + a2 = &g + 3;
> +}
> +
> +typedef void (*__sighandler_t)(int);
> +void handler (int);
> +
> +void f3 (int x)
> +{
> + __sighandler_t h = &handler;
> + if (h != (__sighandler_t) 2 && h != (__sighandler_t) 1)
> + h (x);
> +}
> +
> +/* { dg-final { scan-assembler-times {add(?:s)?\tr[0-9]+, r[0-9]+, #3} 2 } } */
> +/* { dg-final { scan-assembler-not {.word\tg\+3} } } */
> +/* { dg-final { scan-assembler-not {.word\thandler-1} } } */
>
More information about the Gcc-patches
mailing list