final_1 already sets insn_current_address for each instruction, making
it possible to use some of the address functions in final.c during
assembly generation. This patch also sets insn_last_address, since
as the comment says, we can treat final as a shorten_branches pass that
does nothing. It's then possible to use insn_current_reference_address
during final as well.
This is needed for the aarch64.md definitions of far_branch to work:
(set (attr "far_branch")
(if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
(lt (minus (match_dup 2) (pc)) (const_int 1048572)))
This value (tested only during final) uses the difference between
the INSN_ADDRESSES of operand 2 and insn_current_reference_address
to calculate a conservatively-correct estimate of the branch distance.
It takes into account the worst-case gap due to alignment, whereas
a direct comparison of INSN_ADDRESSES would give an unreliable,
Tested on aarch64-linux-gnu and x86_64-linux-gnu. Sameera confirms
that it fixes the original bug, but there's no sharable testcase.
OK to install?
2018-04-09 Richard Sandiford <richard.sandif...@linaro.org>
* final.c (final_1): Set insn_last_address as well as
--- gcc/final.c 2018-04-09 18:40:26.887628387 +0100
+++ gcc/final.c 2018-04-09 18:40:27.033624471 +0100
@@ -2081,6 +2081,9 @@ final_1 (rtx_insn *first, FILE *file, in
insn_current_address = INSN_ADDRESSES (INSN_UID (insn));
+ /* final can be seen as an iteration of shorten_branches that
+ does nothing (since a fixed point has already been reached). */
+ insn_last_address = insn_current_address;
dump_basic_block_info (file, insn, start_to_bb, end_to_bb,