https://gcc.gnu.org/g:d956c5ad043f767bcde25e09ec48917afb2c8e8c
commit r17-4248-gd956c5ad043f767bcde25e09ec48917afb2c8e8c Author: Tamar Christina <[email protected]> Date: Tue Sep 15 08:10:40 2026 +0100 AArch64: use alternate fix for FFR CSE bug [PR126629] In the review for the fix for PR126629 Alfie pointed out that this would break FFR widening loads. At the time I thought I could fix REE to handle this, but the patch didn't look appropriate. So after revisiting Alfie's original idea, my main issue was that it would be had to maintain. This approach instead moves the entire SET src UNSPEC into the update_ffr "token" parameter. This allows us to fix the CSE issue, while keeping maintainability and supporting FFR widening loads from the vectorizer. gcc/ChangeLog: PR target/126629 * config/aarch64/aarch64-sve-builtins-base.cc (emit_ldf1_ffr_update): New. (svldff1_gather_impl, svldff1_gather_extend, svldxf1_impl, svldxf1_extend_impl): Use it. * config/aarch64/aarch64-sve.md (aarch64_update_ffr<mode>): Update insn. Diff: --- gcc/config/aarch64/aarch64-sve-builtins-base.cc | 20 ++++++++++++++++---- gcc/config/aarch64/aarch64-sve.md | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc b/gcc/config/aarch64/aarch64-sve-builtins-base.cc index cf18ce7a205d..96697319fdc9 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc @@ -72,6 +72,18 @@ is_undef (tree val) return false; } +/* Emit the notional FFR update for an LDFF1 or LDNF1 instruction. + Use the load expression rather than the load result, so that later RTL + optimizers can still treat the load result as single-use. */ +static void +emit_ldf1_ffr_update (rtx_insn *load_insn) +{ + rtx set = single_set (load_insn); + gcc_assert (set && GET_CODE (SET_SRC (set)) == UNSPEC); + emit_insn (gen_aarch64_update_ffr (GET_MODE (SET_SRC (set)), + copy_rtx (SET_SRC (set)))); +} + /* Return the UNSPEC_CMLA* unspec for rotation amount ROT. */ static unspec unspec_cmla (int rot) @@ -2028,7 +2040,7 @@ public: /* See the block comment in aarch64-sve.md for details about the FFR handling. */ - emit_insn (gen_aarch64_update_ffr (mem_mode, res)); + emit_ldf1_ffr_update (get_last_insn ()); return res; } @@ -2055,7 +2067,7 @@ public: rtx res = e.use_exact_insn (icode); /* See the block comment in aarch64-sve.md for details about the FFR handling. */ - emit_insn (gen_aarch64_update_ffr (e.vector_mode (0), res)); + emit_ldf1_ffr_update (get_last_insn ()); return res; } }; @@ -2100,7 +2112,7 @@ public: rtx res = e.use_contiguous_load_insn (icode); /* See the block comment in aarch64-sve.md for details about the FFR handling. */ - emit_insn (gen_aarch64_update_ffr (mode, res)); + emit_ldf1_ffr_update (get_last_insn ()); return res; } @@ -2131,7 +2143,7 @@ public: rtx res = e.use_contiguous_load_insn (icode); /* See the block comment in aarch64-sve.md for details about the FFR handling. */ - emit_insn (gen_aarch64_update_ffr (mode, res)); + emit_ldf1_ffr_update (get_last_insn ()); return res; } diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index 8b15e25e8b50..dc92cef4d888 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -1155,7 +1155,7 @@ (unspec:VNx16BI [(reg:VNx16BI FFRT_REGNUM) (reg:VNx16BI FFR_REGNUM) - (match_operand:SVE_ALL 0 "register_operand" "w") + (match_operand:SVE_ALL 0 "" "X") ] UNSPEC_UPDATE_FFR))] "TARGET_SVE" ""
