> -----Original Message-----
> From: Alfie Richards <[email protected]>
> Sent: 17 September 2026 15:40
> To: [email protected]
> Cc: Alex Coplan <[email protected]>; Alice Carlotti
> <[email protected]>; Andrea Pinski
> <[email protected]>; Richard Biener <[email protected]>;
> Tamar Christina <[email protected]>; Zdenek Dvorak <[email protected]>;
> Robin Dapp <[email protected]>; Richard Sandiford
> <[email protected]>; Kyrylo Tkachov <[email protected]>;
> Alfie Richards <[email protected]>
> Subject: [PATCH v3 14/16] aarch64: Implement HSSR for aarch64
> 
> Implements the HSSR optabs.
> 
> Additionally, changes the relevant intrinsics to use the HSSR ifns and
> optabs where possible.
> 
> We also require support for parial modes (VNx8BI, VNx4BI, and VNx2BI)
> of the FFR register for HSSR optabs.
> 
> gcc/ChangeLog:
> 
>       * config/aarch64/aarch64-sve-builtins-base.cc
>       (svldxf1_impl): Update to use hssr internal functions and optabs.
>       (svrdffr_impl): Likewise.
>       (svsetffr_impl): Likewise.
>       (svwrffr_impl): Likewise.
>       * config/aarch64/aarch64-sve.md (aarch64_wrffr): Change to...
>       (@set_hssr_state<mode>): ... this and add other required modes.
>       (aarch64_rdffr): Change to...
>       (aarch64_rdffr<mode>): ...this and add support for new modes.
>       (read_hssr_state<mode>): New define expand.
>       (aarch64_rdffr_z): Change to...
>       (aarch64_rdffr_z<mode>): ...this and add support for new modes.
>       (*aarch64_rdffr_z_ptest): Change to...
>       (*aarch64_rdffr_z_ptest<mode>): ...this and add support for new
> modes.
>       (*aarch64_rdffr_ptest): Change to...
>       (*aarch64_rdffr_ptest<mode>): ...this and add support for new
> modes.
>       (*aarch64_rdffr_z_cc): Change to...
>       (*aarch64_rdffr_z_cc<mode>): ...this and add support for new modes.
>       (*aarch64_rdffr_cc): Change to...
>       (*aarch64_rdffr_cc<mode>): ...this and add support for new modes.
>       (detect_hssr_fault<mode>): New define expand.
>       (aarch64_ld<fn>f1<mode>): Add support for parial mode loads via
>       extending loads.
>       (mask_ff_hssr_load<mode><vpred>): New define expand.
> 
> gcc/testsuite/ChangeLog:
> 
>       * lib/target-supports.exp
>       (check_effective_target_implements_vect_hssr): Update as aarch64
>       sve now supports hssr.
> ---
>  .../aarch64/aarch64-sve-builtins-base.cc      |  79 ++++--
>  gcc/config/aarch64/aarch64-sve.md             | 228 ++++++++++++++++--
>  gcc/testsuite/lib/target-supports.exp         |   2 +-
>  3 files changed, 264 insertions(+), 45 deletions(-)
> 
> diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
> b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
> index 39e7109abd8..2e47de19bc1 100644
> --- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
> +++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
> @@ -2080,7 +2080,10 @@ public:
>  class svldxf1_impl : public full_width_access
>  {
>  public:
> -  constexpr svldxf1_impl (unspec unspec) : m_unspec (unspec) {}
> +  constexpr svldxf1_impl (unspec unspec) : m_first (unspec ==
> UNSPEC_LDFF1)
> +  {
> +    gcc_checking_assert (m_first || unspec == UNSPEC_LDNF1);
> +  }
> 
>    unsigned int
>    call_properties (const function_instance &) const override
> @@ -2088,20 +2091,35 @@ public:
>      return CP_READ_MEMORY | CP_READ_FFR | CP_WRITE_FFR;
>    }
> 
> -  rtx
> -  expand (function_expander &e) const override
> +  gimple *fold (gimple_folder &f) const override
>    {
> -    machine_mode mode = e.vector_mode (0);
> -    insn_code icode = code_for_aarch64_ldf1 (m_unspec, mode);
> -    rtx res = e.use_contiguous_load_insn (icode);
> -    /* See the block comment in aarch64-sve.md for details about the
> -       FFR handling.  */
> -    emit_ldf1_ffr_update (get_last_insn ());
> -    return res;
> +    if (m_first)
> +      return f.fold_contiguous_load (IFN_MASK_FF_HSSR_LOAD);
> +    else
> +      return nullptr;
>    }
> 
> -  /* The unspec associated with the load.  */
> -  unspec m_unspec;
> +  rtx expand (function_expander &e) const override
> +  {
> +    if (m_first)
> +      {
> +     auto icode = convert_optab_handler (mask_ff_hssr_load_optab,
> +                                         e.vector_mode (0), e.gp_mode (0));
> +     return e.use_contiguous_load_insn (icode, true);

Can you add a comment saying that this doesn't require emit_ldf1_ffr_update
since the expander expands it inline in the PARALLEL.  It's not entirely 
obvious :)
 
> +      }
> +    else
> +      {
> +     machine_mode mode = e.vector_mode (0);
> +     insn_code icode = code_for_aarch64_ldf1 (UNSPEC_LDNF1, mode);
> +     rtx res = e.use_contiguous_load_insn (icode, true);
> +     /* See the block comment in aarch64-sve.md for details about the
> +        FFR handling.  */
> +     emit_ldf1_ffr_update (get_last_insn ());
> +     return res;
> +      }
> +  }
> +
> +  bool m_first;
>  };
> 
>  /* Implements extending contiguous forms of svldff1 and svldnf1.  */
> @@ -2892,15 +2910,24 @@ public:
>      return CP_READ_FFR;
>    }
> 
> -  rtx
> -  expand (function_expander &e) const override
> +  gimple *fold (gimple_folder &f) const override
> +  {
> +    if (f.pred == PRED_z)
> +      return nullptr;
> +
> +    gcall *new_call = gimple_build_call_internal (IFN_READ_HSSR_STATE, 0);
> +    gimple_call_set_lhs (new_call, f.lhs);
> +    return new_call;
> +  }
> +
> +  rtx expand (function_expander &e) const override
>    {
>      /* See the block comment in aarch64-sve.md for details about the
>         FFR handling.  */
>      emit_insn (gen_aarch64_copy_ffr_to_ffrt ());
>      rtx result = e.use_exact_insn (e.pred == PRED_z
> -                                ? CODE_FOR_aarch64_rdffr_z
> -                                : CODE_FOR_aarch64_rdffr);
> +                                ? CODE_FOR_aarch64_rdffr_zvnx16bi
> +                                : CODE_FOR_aarch64_rdffrvnx16bi);
>      emit_insn (gen_aarch64_update_ffrt ());
>      return result;
>    }
> @@ -3085,11 +3112,17 @@ public:
>      return CP_WRITE_FFR;
>    }
> 
> -  rtx
> -  expand (function_expander &e) const override
> +  gimple *fold (gimple_folder &f ATTRIBUTE_UNUSED) const override
> +  {
> +    tree bool_type = acle_vector_types[0][VECTOR_TYPE_svbool_t];
> +    return gimple_build_call_internal (IFN_SET_HSSR_STATE, 1,
> +                                    build_all_ones_cst (bool_type));
> +  }
> +
> +  rtx expand (function_expander &e) const override
>    {
>      e.args.quick_push (CONSTM1_RTX (VNx16BImode));
> -    return e.use_exact_insn (CODE_FOR_aarch64_wrffr);
> +    return e.use_exact_insn (code_for_set_hssr_state (VNx16BImode));
>    }
>  };
> 
> @@ -3516,10 +3549,16 @@ public:
>      return CP_WRITE_FFR;
>    }
> 
> +  gimple *fold (gimple_folder &f) const override
> +  {
> +    return gimple_build_call_internal (IFN_SET_HSSR_STATE, 1,
> +                                    gimple_call_arg (f.call, 0));
> +  }
> +
>    rtx
>    expand (function_expander &e) const override
>    {
> -    return e.use_exact_insn (CODE_FOR_aarch64_wrffr);
> +    return e.use_exact_insn (code_for_set_hssr_state (VNx16BImode));
>    }
>  };
> 
> diff --git a/gcc/config/aarch64/aarch64-sve.md
> b/gcc/config/aarch64/aarch64-sve.md
> index fc53b212ac6..1c337b2858f 100644
> --- a/gcc/config/aarch64/aarch64-sve.md
> +++ b/gcc/config/aarch64/aarch64-sve.md
> @@ -1131,9 +1131,23 @@ (define_insn_and_split "mov<mode>"
>  ;; [W1 in the block comment above about FFR handling]
>  ;;
>  ;; Write to the FFR and start a new FFRT scheduling region.
> -(define_insn "aarch64_wrffr"
> +(define_insn "@set_hssr_state<mode>"
>    [(set (reg:VNx16BI FFR_REGNUM)
> -     (match_operand:VNx16BI 0 "aarch64_simd_reg_or_minus_one"))
> +     (match_operand:VNx16BI_ONLY 0
> "aarch64_simd_reg_or_minus_one"))
> +   (set (reg:VNx16BI FFRT_REGNUM)
> +     (unspec:VNx16BI [(match_dup 0)] UNSPEC_WRFFR))]
> +  "TARGET_SVE && TARGET_NON_STREAMING"
> +  {@ [ cons: 0 ]
> +     [ Dm      ] setffr
> +     [ Upa     ] wrffr\t%0.b
> +  }
> +  [(set_attr "sve_type" "sve_ffr_read")]
> +)
> +

Should this be sve_ff_write?

> +(define_insn "@set_hssr_state<mode>"
> +  [(set (reg:VNx16BI FFR_REGNUM)
> +     (subreg:VNx16BI
> +       (match_operand:PRED_HSD 0 "aarch64_simd_reg_or_minus_one")
> 0))
>     (set (reg:VNx16BI FFRT_REGNUM)
>       (unspec:VNx16BI [(match_dup 0)] UNSPEC_WRFFR))]
>    "TARGET_SVE && TARGET_NON_STREAMING"
> @@ -1179,20 +1193,63 @@ (define_insn "aarch64_copy_ffr_to_ffrt"
>  ;; [R2 in the block comment above about FFR handling]
>  ;;
>  ;; Read the FFR via the FFRT.
> -(define_insn "aarch64_rdffr"
> -  [(set (match_operand:VNx16BI 0 "register_operand" "=Upa")
> +(define_insn "aarch64_rdffr<mode>"
> +  [(set (match_operand:VNx16BI_ONLY 0 "register_operand" "=Upa")
>       (reg:VNx16BI FFRT_REGNUM))]
>    "TARGET_SVE && TARGET_NON_STREAMING"
>    "rdffr\t%0.b"
>    [(set_attr "sve_type" "sve_ffr_read")]
>  )
> 
> +(define_insn "aarch64_rdffr<mode>"
> +  [(set (match_operand:PRED_HSD 0 "register_operand" "=Upa")
> +     (subreg:PRED_HSD (reg:VNx16BI FFRT_REGNUM) 0))]
> +  "TARGET_SVE && TARGET_NON_STREAMING"
> +  "rdffr\t%0.b"
> +  [(set_attr "sve_type" "sve_ffr_read")]
> +)
> +
> +;; [R2 in the block comment above about FFR handling]
> +;;
> +(define_expand "read_hssr_state<mode>"
> +  [(set (reg:VNx16BI FFRT_REGNUM) ; copy_ffr_to_ffrt
> +     (reg:VNx16BI FFR_REGNUM))
> +   (set (match_operand:VNx16BI_ONLY 0 "register_operand" "=Upa") ; rdffr
> +     (reg:VNx16BI FFRT_REGNUM))
> +   (set (reg:VNx16BI FFRT_REGNUM) ; update ffrt
> +     (unspec:VNx16BI [(reg:VNx16BI FFRT_REGNUM)]
> UNSPEC_UPDATE_FFRT))]
> +  "TARGET_SVE && TARGET_NON_STREAMING"
> +)
> +
> +(define_expand "read_hssr_state<mode>"
> +  [(set (reg:VNx16BI FFRT_REGNUM) ; copy_ffr_to_ffrt
> +     (reg:VNx16BI FFR_REGNUM))
> +   (set (match_operand:PRED_HSD 0 "register_operand" "=Upa") ; rdffr
> +     (subreg:PRED_HSD (reg:VNx16BI FFRT_REGNUM) 0))
> +   (set (reg:VNx16BI FFRT_REGNUM) ; update ffrt
> +     (unspec:VNx16BI [(reg:VNx16BI FFRT_REGNUM)]
> UNSPEC_UPDATE_FFRT))]
> +  "TARGET_SVE && TARGET_NON_STREAMING"
> +)
> +
>  ;; Likewise with zero predication.
> -(define_insn "aarch64_rdffr_z"
> -  [(set (match_operand:VNx16BI 0 "register_operand")
> -     (and:VNx16BI
> +(define_insn "aarch64_rdffr_z<mode>"
> +  [(set (match_operand:VNx16BI_ONLY 0 "register_operand")
> +     (and:VNx16BI_ONLY
>         (reg:VNx16BI FFRT_REGNUM)
> -       (match_operand:VNx16BI 1 "register_operand")))]
> +       (match_operand:VNx16BI_ONLY 1 "register_operand")))]
> +  "TARGET_SVE && TARGET_NON_STREAMING"
> +  {@ [ cons: =0, 1   ; attrs: pred_clobber ]
> +     [ &Upa    , Upa ; yes                 ] rdffr\t%0.b, %1/z
> +     [ ?Upa    , 0Upa; yes                 ] ^
> +     [ Upa     , Upa ; no                  ] ^
> +  }
> +  [(set_attr "sve_type" "sve_ffr_read")]
> +)
> +(define_insn "aarch64_rdffr_z<mode>"
> +  [(set (match_operand:PRED_HSD 0 "register_operand")
> +     (and:PRED_HSD
> +       (subreg:PRED_HSD (reg:VNx16BI FFRT_REGNUM) 0)
> +       (match_operand:PRED_HSD 1 "register_operand")))]
>    "TARGET_SVE && TARGET_NON_STREAMING"
>    {@ [ cons: =0, 1   ; attrs: pred_clobber ]
>       [ &Upa    , Upa ; yes                 ] rdffr\t%0.b, %1/z
> @@ -1203,17 +1260,36 @@ (define_insn "aarch64_rdffr_z"
>  )
> 
>  ;; Read the FFR to test for a fault, without using the predicate result.
> -(define_insn "*aarch64_rdffr_z_ptest"
> +(define_insn "*aarch64_rdffr_z_ptest<mode>"
>    [(set (reg:CC_NZC CC_REGNUM)
>       (unspec:CC_NZC
>         [(match_operand:VNx16BI 1 "register_operand")
>          (match_dup 1)
>          (match_operand:SI 2 "aarch64_sve_ptrue_flag")
> -        (and:VNx16BI
> +        (and:VNx16BI_ONLY
>            (reg:VNx16BI FFRT_REGNUM)
>            (match_dup 1))]
>         UNSPEC_PTEST))
> -   (clobber (match_scratch:VNx16BI 0))]
> +   (clobber (match_scratch:VNx16BI_ONLY 0))]
> +  "TARGET_SVE && TARGET_NON_STREAMING"
> +  {@ [ cons: =0, 1   ; attrs: pred_clobber ]
> +     [ &Upa    , Upa ; yes                 ] rdffrs\t%0.b, %1/z
> +     [ ?Upa    , 0Upa; yes                 ] ^
> +     [ Upa     , Upa ; no                  ] ^
> +  }
> +  [(set_attr "sve_type" "sve_ffr_read")]
> +)
> +(define_insn "*aarch64_rdffr_z_ptest<mode>"
> +  [(set (reg:CC_NZC CC_REGNUM)
> +     (unspec:CC_NZC
> +       [(match_operand:VNx16BI 1 "register_operand")
> +        (match_operand:PRED_HSD 3)
> +        (match_operand:SI 2 "aarch64_sve_ptrue_flag")
> +        (and:PRED_HSD
> +          (subreg:PRED_HSD (reg:VNx16BI FFRT_REGNUM) 0)
> +          (match_dup 3))]
> +       UNSPEC_PTEST))
> +   (clobber (match_scratch:PRED_HSD 0))]
>    "TARGET_SVE && TARGET_NON_STREAMING"
>    {@ [ cons: =0, 1   ; attrs: pred_clobber ]
>       [ &Upa    , Upa ; yes                 ] rdffrs\t%0.b, %1/z
> @@ -1224,15 +1300,32 @@ (define_insn "*aarch64_rdffr_z_ptest"
>  )
> 
>  ;; Same for unpredicated RDFFR when tested with a known PTRUE.
> -(define_insn "*aarch64_rdffr_ptest"
> +(define_insn "*aarch64_rdffr_ptest<mode>"
>    [(set (reg:CC_NZC CC_REGNUM)
>       (unspec:CC_NZC
>         [(match_operand:VNx16BI 1 "register_operand")
> -        (match_dup 1)
> +        (match_operand:VNx16BI_ONLY 2)
>          (const_int SVE_KNOWN_PTRUE)
>          (reg:VNx16BI FFRT_REGNUM)]
>         UNSPEC_PTEST))
> -   (clobber (match_scratch:VNx16BI 0))]
> +   (clobber (match_scratch:VNx16BI_ONLY 0))]
> +  "TARGET_SVE && TARGET_NON_STREAMING"
> +  {@ [ cons: =0, 1   ; attrs: pred_clobber ]
> +     [ &Upa    , Upa ; yes                 ] rdffrs\t%0.b, %1/z
> +     [ ?Upa    , 0Upa; yes                 ] ^
> +     [ Upa     , Upa ; no                  ] ^
> +  }
> +  [(set_attr "sve_type" "sve_ffr_read")]
> +)
> +(define_insn "*aarch64_rdffr_ptest<mode>"
> +  [(set (reg:CC_NZC CC_REGNUM)
> +     (unspec:CC_NZC
> +       [(match_operand:VNx16BI 1 "register_operand")
> +        (match_operand:PRED_HSD 2)
> +        (const_int SVE_KNOWN_PTRUE)
> +        (subreg:PRED_HSD (reg:VNx16BI FFRT_REGNUM) 0)]
> +       UNSPEC_PTEST))
> +   (clobber (match_scratch:PRED_HSD 0))]
>    "TARGET_SVE && TARGET_NON_STREAMING"
>    {@ [ cons: =0, 1   ; attrs: pred_clobber ]
>       [ &Upa    , Upa ; yes                 ] rdffrs\t%0.b, %1/z
> @@ -1243,18 +1336,18 @@ (define_insn "*aarch64_rdffr_ptest"
>  )
> 
>  ;; Read the FFR with zero predication and test the result.
> -(define_insn "*aarch64_rdffr_z_cc"
> +(define_insn "*aarch64_rdffr_z_cc<mode>"
>    [(set (reg:CC_NZC CC_REGNUM)
>       (unspec:CC_NZC
>         [(match_operand:VNx16BI 1 "register_operand")
>          (match_dup 1)
>          (match_operand:SI 2 "aarch64_sve_ptrue_flag")
> -        (and:VNx16BI
> +        (and:VNx16BI_ONLY
>            (reg:VNx16BI FFRT_REGNUM)
>            (match_dup 1))]
>         UNSPEC_PTEST))
> -   (set (match_operand:VNx16BI 0 "register_operand")
> -     (and:VNx16BI
> +   (set (match_operand:VNx16BI_ONLY 0 "register_operand")
> +     (and:VNx16BI_ONLY
>         (reg:VNx16BI FFRT_REGNUM)
>         (match_dup 1)))]
>    "TARGET_SVE && TARGET_NON_STREAMING"
> @@ -1265,9 +1358,31 @@ (define_insn "*aarch64_rdffr_z_cc"
>    }
>    [(set_attr "sve_type" "sve_ffr_read")]
>  )
> +(define_insn "*aarch64_rdffr_z_cc<mode>"
> +  [(set (reg:CC_NZC CC_REGNUM)
> +     (unspec:CC_NZC
> +       [(match_operand:VNx16BI 1 "register_operand")
> +        (match_operand:PRED_HSD 3)
> +        (match_operand:SI 2 "aarch64_sve_ptrue_flag")
> +        (and:PRED_HSD
> +          (subreg:PRED_HSD (reg:VNx16BI FFRT_REGNUM) 0)
> +          (match_dup 3))]
> +       UNSPEC_PTEST))
> +   (set (match_operand:PRED_HSD 0 "register_operand")
> +     (and:PRED_HSD
> +       (subreg:PRED_HSD (reg:VNx16BI FFRT_REGNUM) 0)
> +       (match_dup 3)))]
> +  "TARGET_SVE && TARGET_NON_STREAMING"
> +  {@ [ cons: =0, 1   ; attrs: pred_clobber ]
> +     [ &Upa    , Upa ; yes                 ] rdffrs\t%0.b, %1/z
> +     [ ?Upa    , 0Upa; yes                 ] ^
> +     [ Upa     , Upa ; no                  ] ^
> +  }
> +  [(set_attr "sve_type" "sve_ffr_read")]
> +)
> 
>  ;; Same for unpredicated RDFFR when tested with a known PTRUE.
> -(define_insn "*aarch64_rdffr_cc"
> +(define_insn "*aarch64_rdffr_cc<mode>"
>    [(set (reg:CC_NZC CC_REGNUM)
>       (unspec:CC_NZC
>         [(match_operand:VNx16BI 1 "register_operand")
> @@ -1275,7 +1390,7 @@ (define_insn "*aarch64_rdffr_cc"
>          (const_int SVE_KNOWN_PTRUE)
>          (reg:VNx16BI FFRT_REGNUM)]
>         UNSPEC_PTEST))
> -   (set (match_operand:VNx16BI 0 "register_operand")
> +   (set (match_operand:VNx16BI_ONLY 0 "register_operand")
>       (reg:VNx16BI FFRT_REGNUM))]
>    "TARGET_SVE && TARGET_NON_STREAMING"
>    {@ [ cons: =0, 1   ; attrs: pred_clobber ]
> @@ -1285,6 +1400,24 @@ (define_insn "*aarch64_rdffr_cc"
>    }
>    [(set_attr "sve_type" "sve_ffr_read")]
>  )
> +(define_insn "*aarch64_rdffr_cc<mode>"
> +  [(set (reg:CC_NZC CC_REGNUM)
> +     (unspec:CC_NZC
> +       [(match_operand:VNx16BI 1 "register_operand")
> +        (match_operand:PRED_HSD 2)
> +        (const_int SVE_KNOWN_PTRUE)
> +        (subreg:PRED_HSD (reg:VNx16BI FFRT_REGNUM) 0)]
> +       UNSPEC_PTEST))
> +   (set (match_operand:PRED_HSD 0 "register_operand")
> +     (subreg:PRED_HSD (reg:VNx16BI FFRT_REGNUM) 0))]
> +  "TARGET_SVE && TARGET_NON_STREAMING"
> +  {@ [ cons: =0, 1   ; attrs: pred_clobber ]
> +     [ &Upa    , Upa ; yes                 ] rdffrs\t%0.b, %1/z
> +     [ ?Upa    , 0Upa; yes                 ] ^
> +     [ Upa     , Upa ; no                  ] ^
> +  }
> +  [(set_attr "sve_type" "sve_ffr_read")]
> +)
> 
>  ;; [R3 in the block comment above about FFR handling]
>  ;;
> @@ -1298,6 +1431,27 @@ (define_insn "aarch64_update_ffrt"
>    [(set_attr "type" "no_insn")]
>  )
> 
> +/* Test if the last element of the predicate is not true.  */
> +(define_expand "detect_hssr_fault<mode>"
> +  [(match_operand:QI       0 "register_operand")
> +   (match_operand:PRED_ALL 1 "register_operand")]
> +  "TARGET_SVE && TARGET_NON_STREAMING"
> +  {
> +    rtx ptrue = force_reg (VNx16BImode, aarch64_ptrue_all (<data_bytes>));
> +    rtx cast_ptrue = gen_lowpart (<MODE>mode, ptrue);
> +    rtx ptrue_flag = gen_int_mode (SVE_KNOWN_PTRUE, SImode);
> +    emit_insn (gen_aarch64_ptestvnx16bi (ptrue, cast_ptrue, ptrue_flag,
> +                                      operands[1]));
> +
> +    rtx cc_reg = gen_rtx_REG (CC_NZCmode, CC_REGNUM);
> +    rtx cmp = gen_rtx_fmt_ee (GEU, QImode, cc_reg, const0_rtx);
> +
> +    emit_insn (gen_aarch64_cstoreqi (operands[0], cmp, cc_reg));
> +
> +    DONE;
> +  }
> +)

This really does look like what cbranch would generate :)

> +
>  ;;
> ===================================================================
> ======
>  ;; == Loads
>  ;;
> ===================================================================
> ======
> @@ -1451,18 +1605,44 @@ (define_insn_and_rewrite
> "*aarch64_load_<ANY_EXTEND:optab>_mov<SVE_HSDI:mode><SV
>  ;; -------------------------------------------------------------------------
> 
>  ;; Contiguous non-extending first-faulting or non-faulting loads.
> +;; Also supports sparse vectors via extending loads
>  (define_insn "@aarch64_ld<fn>f1<mode>"
> -  [(set (match_operand:SVE_FULL 0 "register_operand" "=w")
> -     (unspec:SVE_FULL
> +  [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
> +     (unspec:SVE_ALL
>         [(match_operand:<VPRED> 2 "register_operand" "Upl")
> -        (match_operand:SVE_FULL 1 "aarch64_sve_ld<fn>f1_operand"
> "Ut<fn>")
> +        (match_operand:SVE_ALL 1 "aarch64_sve_ld<fn>f1_operand"
> "Ut<fn>")
> +        (match_operand:SVE_ALL 3 "aarch64_maskload_else_operand")
>          (reg:VNx16BI FFRT_REGNUM)]
>         SVE_LDFF1_LDNF1))]
>    "TARGET_SVE && TARGET_NON_STREAMING"
> -  "ld<fn>f1<Vesize>\t%0.<Vetype>, %2/z, %1"
> +  "ld<fn>f1<Vesize>\t%0.<Vctype>, %2/z, %1"
>    [(set_attr "sve_type" "sve_load_1reg")]
>  )
> 
> +;; Expose {non,first}-faulting loads to the middle-end.
> +(define_expand "mask_ff_hssr_load<mode><vpred>"
> +  [(set (match_operand:SVE_ALL 0 "register_operand")
> +     (unspec:SVE_ALL
> +       [(match_operand:<VPRED> 2 "register_operand")
> +        (match_operand:SVE_ALL 1 "aarch64_sve_ldff1_operand")
> +        (match_operand:SVE_ALL 3 "aarch64_maskload_else_operand")
> +        (reg:VNx16BI FFRT_REGNUM)]
> +       UNSPEC_LDFF1))
> +   (set (reg:VNx16BI FFR_REGNUM)
> +     (unspec:VNx16BI
> +      [(reg:VNx16BI FFRT_REGNUM)
> +       (reg:VNx16BI FFR_REGNUM)
> +       (unspec:SVE_ALL
> +        [(match_dup 2)
> +         (match_dup 1)
> +         (match_dup 3)
> +         (reg:VNx16BI FFRT_REGNUM)]
> +        UNSPEC_LDFF1)
> +      ] UNSPEC_UPDATE_FFR))]
> +  "TARGET_SVE && TARGET_NON_STREAMING"
> +  {}

Drop the {},

Patch is OK with the changes above.

Thanks,
Tamar

> +)
> +
>  ;; -------------------------------------------------------------------------
>  ;; ---- First-faulting extending contiguous loads
>  ;; -------------------------------------------------------------------------
> diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-
> supports.exp
> index 8876f41a4ae..46c97ffdd4a 100644
> --- a/gcc/testsuite/lib/target-supports.exp
> +++ b/gcc/testsuite/lib/target-supports.exp
> @@ -9626,7 +9626,7 @@ proc check_effective_target_vect_partial_vectors {
> } {
>  # Return true if hssr loops are supported.
> 
>  proc check_effective_target_implements_vect_hssr { } {
> -    return 0
> +    return [check_effective_target_aarch64_sve]
>  }
> 
>  # Return the value of parameter vect-hssr-usage specified for
> --
> 2.43.0

Reply via email to