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.

Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.

Ok for master?

Thanks,
Tamar

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 --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc 
b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
index 
cf18ce7a205d813b9e1b6b240507a03ca98987b6..96697319fdc9d3d08e031a7f57540e44ef21b71f
 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 
1667145d3c71c14b7d19e32d14f521c8f3c91ad7..1b1b2bc403f4d56278c8ea051d3407583d4c5dc4
 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -1155,7 +1155,7 @@ (define_insn "@aarch64_update_ffr<mode>"
        (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"
   ""


-- 
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
index cf18ce7a205d813b9e1b6b240507a03ca98987b6..96697319fdc9d3d08e031a7f57540e44ef21b71f 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 1667145d3c71c14b7d19e32d14f521c8f3c91ad7..1b1b2bc403f4d56278c8ea051d3407583d4c5dc4 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -1155,7 +1155,7 @@ (define_insn "@aarch64_update_ffr<mode>"
 	(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"
   ""

Reply via email to