LGTM, thanks :)

Christoph Müllner <[email protected]> 於 2026年5月19日週二 下午7:20寫道:
>
> riscv-toolchain-conventions PR #156 defines separate alignment
> policies for RV32 Zilsd/Zclsd doubleword memory accesses.  Add
> -mzilsd-word-align and -mzilsd-strict-align to let users select
> the word-aligned and naturally aligned variants explicitly.
>
> Keep the existing -mstrict-align family in the same last-option-wins
> option group so code can opt in or out without depending on option
> order surprises.  When a 2 * XLEN access is not allowed by the
> selected policy, expand through scalar bit-field helpers instead of
> selecting Zilsd loads or stores.
>
> gcc/ChangeLog:
>
>         * common/config/riscv/riscv-common.cc (riscv_handle_option):
>         Handle Zilsd alignment options and clear the Zilsd-specific
>         explicit marker for -mstrict-align.
>         * config/riscv/riscv-opts.h (riscv_zilsd_align_type): New enum.
>         * config/riscv/riscv-protos.h
>         (riscv_expand_zilsd_misaligned_move): Declare as void.
>         (riscv_zilsd_valid_mem_p): Declare.
>         * config/riscv/riscv.cc (riscv_zilsd_required_align): New
>         functions.
>         (riscv_zilsd_valid_mem_p): New function.
>         (riscv_rtx_costs): Honor Zilsd alignment policy.
>         (riscv_split_64bit_move_p): Split invalid Zilsd GPR accesses.
>         (riscv_expand_zilsd_misaligned_move): New function.
>         (riscv_can_inline_p): Check effective Zilsd alignment policy.
>         (riscv_override_options_internal): Reject explicit Zilsd
>         alignment options for RV64.
>         * config/riscv/riscv.md (movmisaligndi): New expander.
>         (movmisaligndf): New expander.
>         * config/riscv/riscv.opt: Add -mzilsd-word-align and
>         -mzilsd-strict-align.
>         * config/riscv/riscv.opt.urls: Regenerate.
>         * doc/invoke.texi: Document the new options.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/riscv/zilsd-align-default-1.c: New test.
>         * gcc.target/riscv/zilsd-align-df-1.c: New test.
>         * gcc.target/riscv/zilsd-align-rv64-1.c: New test.
>         * gcc.target/riscv/zilsd-align-rv64-2.c: New test.
>         * gcc.target/riscv/zilsd-align-rv64-3.c: New test.
>         * gcc.target/riscv/zilsd-align-rv64-4.c: New test.
>         * gcc.target/riscv/zilsd-align-word-1.c: New test.
>         * gcc.target/riscv/zilsd-align-word-2.c: New test.
>         * gcc.target/riscv/zilsd-align-word-3.c: New test.
>         * gcc.target/riscv/zilsd-align-word-4.c: New test.
>         * gcc.target/riscv/zilsd-align-word-5.c: New test.
>
> Signed-off-by: Christoph Müllner <[email protected]>
>
> v2: Address review by Kito Cheng:
> - Remove redundant !TARGET_64BIT guard from riscv_zilsd_valid_mem_p
> - Change riscv_expand_zilsd_misaligned_move return type from void to bool
> - Use DONE/FAIL based on bool return in movmisaligndi and movmisaligndf
> - Drop !TARGET_DOUBLE_FLOAT guard from movmisaligndf
> ---
>  gcc/common/config/riscv/riscv-common.cc       |  33 ++++-
>  gcc/config/riscv/riscv-opts.h                 |   8 ++
>  gcc/config/riscv/riscv-protos.h               |   2 +
>  gcc/config/riscv/riscv.cc                     | 126 +++++++++++++++++-
>  gcc/config/riscv/riscv.md                     |  22 +++
>  gcc/config/riscv/riscv.opt                    |  14 ++
>  gcc/config/riscv/riscv.opt.urls               |   7 +-
>  gcc/doc/invoke.texi                           |  15 +++
>  .../gcc.target/riscv/zilsd-align-default-1.c  |  17 +++
>  .../gcc.target/riscv/zilsd-align-df-1.c       |  19 +++
>  .../gcc.target/riscv/zilsd-align-rv64-1.c     |   6 +
>  .../gcc.target/riscv/zilsd-align-rv64-2.c     |   6 +
>  .../gcc.target/riscv/zilsd-align-rv64-3.c     |   5 +
>  .../gcc.target/riscv/zilsd-align-rv64-4.c     |   5 +
>  .../gcc.target/riscv/zilsd-align-word-1.c     |  20 +++
>  .../gcc.target/riscv/zilsd-align-word-2.c     |  20 +++
>  .../gcc.target/riscv/zilsd-align-word-3.c     |  20 +++
>  .../gcc.target/riscv/zilsd-align-word-4.c     |  20 +++
>  .../gcc.target/riscv/zilsd-align-word-5.c     |  20 +++
>  19 files changed, 378 insertions(+), 7 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/zilsd-align-default-1.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/zilsd-align-df-1.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/zilsd-align-rv64-1.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/zilsd-align-rv64-2.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/zilsd-align-rv64-3.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/zilsd-align-rv64-4.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/zilsd-align-word-1.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/zilsd-align-word-2.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/zilsd-align-word-3.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/zilsd-align-word-4.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/zilsd-align-word-5.c
>
> diff --git a/gcc/common/config/riscv/riscv-common.cc 
> b/gcc/common/config/riscv/riscv-common.cc
> index 5d3d37c7a7b..b149393e35f 100644
> --- a/gcc/common/config/riscv/riscv-common.cc
> +++ b/gcc/common/config/riscv/riscv-common.cc
> @@ -1705,12 +1705,43 @@ riscv_find_cpu (const char *cpu)
>
>  static bool
>  riscv_handle_option (struct gcc_options *opts,
> -                    struct gcc_options *opts_set ATTRIBUTE_UNUSED,
> +                    struct gcc_options *opts_set,
>                      const struct cl_decoded_option *decoded,
>                      location_t loc)
>  {
>    switch (decoded->opt_index)
>      {
> +    case OPT_mstrict_align:
> +      opts->x_riscv_zilsd_align
> +       = decoded->value ? RISCV_ZILSD_ALIGN_STRICT : RISCV_ZILSD_ALIGN_BYTE;
> +      opts->x_riscv_zilsd_align_explicit = 0;
> +      if (opts_set)
> +       {
> +         opts_set->x_riscv_zilsd_align = opts->x_riscv_zilsd_align;
> +         opts_set->x_riscv_zilsd_align_explicit = 0;
> +       }
> +      return true;
> +
> +    case OPT_mzilsd_word_align:
> +      opts->x_riscv_zilsd_align = RISCV_ZILSD_ALIGN_WORD;
> +      opts->x_riscv_zilsd_align_explicit = 1;
> +      if (opts_set)
> +       {
> +         opts_set->x_riscv_zilsd_align = opts->x_riscv_zilsd_align;
> +         opts_set->x_riscv_zilsd_align_explicit = 1;
> +       }
> +      return true;
> +
> +    case OPT_mzilsd_strict_align:
> +      opts->x_riscv_zilsd_align = RISCV_ZILSD_ALIGN_STRICT;
> +      opts->x_riscv_zilsd_align_explicit = 1;
> +      if (opts_set)
> +       {
> +         opts_set->x_riscv_zilsd_align = opts->x_riscv_zilsd_align;
> +         opts_set->x_riscv_zilsd_align_explicit = 1;
> +       }
> +      return true;
> +
>      case OPT_march_:
>        if (riscv_find_cpu (decoded->arg) == NULL)
>         riscv_parse_arch_string (decoded->arg, opts, loc);
> diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
> index 88a4aa33926..036680117c3 100644
> --- a/gcc/config/riscv/riscv-opts.h
> +++ b/gcc/config/riscv/riscv-opts.h
> @@ -75,6 +75,14 @@ enum riscv_align_data {
>    riscv_align_data_type_natural
>  };
>
> +/* Alignment policy for Zilsd 2 * XLEN memory accesses.  */
> +enum riscv_zilsd_align_type {
> +  RISCV_ZILSD_ALIGN_DEFAULT,
> +  RISCV_ZILSD_ALIGN_BYTE,
> +  RISCV_ZILSD_ALIGN_WORD,
> +  RISCV_ZILSD_ALIGN_STRICT
> +};
> +
>  /* Where to get the canary for the stack protector.  */
>  enum stack_protector_guard {
>    SSP_TLS,                     /* per-thread canary in TLS block */
> diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
> index f8eee0fd844..2748c88f499 100644
> --- a/gcc/config/riscv/riscv-protos.h
> +++ b/gcc/config/riscv/riscv-protos.h
> @@ -156,6 +156,8 @@ extern rtx riscv_emit_binary (enum rtx_code code, rtx 
> dest, rtx x, rtx y);
>  #endif
>  extern bool riscv_expand_conditional_move (rtx, rtx, rtx, rtx);
>  extern rtx riscv_legitimize_call_address (rtx);
> +extern bool riscv_expand_zilsd_misaligned_move (rtx, rtx);
> +extern bool riscv_zilsd_valid_mem_p (rtx, machine_mode);
>  extern void riscv_set_return_address (rtx, rtx);
>  extern rtx riscv_return_addr (int, rtx);
>  extern poly_int64 riscv_initial_elimination_offset (int, int);
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 2a2193767c7..427bb75afe6 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -53,6 +53,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "basic-block.h"
>  #include "expr.h"
>  #include "optabs.h"
> +#include "expmed.h"
>  #include "bitmap.h"
>  #include "df.h"
>  #include "function-abi.h"
> @@ -1018,6 +1019,59 @@ riscv_2x_xlen_mode_p (machine_mode mode)
>          && (mode_size.to_constant () == UNITS_PER_WORD * 2);
>  }
>
> +/* Return the required alignment, in bytes, for Zilsd memory accesses.  */
> +
> +static unsigned int
> +riscv_zilsd_required_align (enum riscv_zilsd_align_type align,
> +                           bool strict_align_p)
> +{
> +  switch (align)
> +    {
> +    case RISCV_ZILSD_ALIGN_BYTE:
> +      return 1;
> +
> +    case RISCV_ZILSD_ALIGN_WORD:
> +      return 4;
> +
> +    case RISCV_ZILSD_ALIGN_STRICT:
> +      return 8;
> +
> +    case RISCV_ZILSD_ALIGN_DEFAULT:
> +      return strict_align_p ? 8 : 1;
> +
> +    default:
> +      gcc_unreachable ();
> +    }
> +}
> +
> +/* Return the required alignment, in bytes, for Zilsd memory accesses.  */
> +
> +static unsigned int
> +riscv_zilsd_required_align (void)
> +{
> +  return riscv_zilsd_required_align (riscv_zilsd_align, TARGET_STRICT_ALIGN);
> +}
> +
> +/* Return true if MEM can be accessed by a Zilsd 2 * XLEN load/store.  */
> +
> +bool
> +riscv_zilsd_valid_mem_p (rtx mem, machine_mode mode)
> +{
> +  return (TARGET_ZILSD
> +         && riscv_2x_xlen_mode_p (mode)
> +         && MEM_P (mem)
> +         && MEM_ALIGN (mem) >= riscv_zilsd_required_align () * 
> BITS_PER_UNIT);
> +}
> +
> +/* Return the effective Zilsd memory access alignment policy.  */
> +
> +static unsigned int
> +riscv_zilsd_required_align (const struct cl_target_option *opts)
> +{
> +  return riscv_zilsd_required_align
> +    (opts->x_riscv_zilsd_align, TARGET_STRICT_ALIGN_P 
> (opts->x_target_flags));
> +}
> +
>  /* Implement TARGET_MIN_ARITHMETIC_PRECISION.  */
>
>  static unsigned int
> @@ -4263,8 +4317,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int 
> outer_code, int opno ATTRIBUTE_UN
>             }
>
>           /* Load for XLEN * 2.  */
> -         if (TARGET_ZILSD && MEM_P (SET_SRC (x))
> -             && riscv_2x_xlen_mode_p (mode))
> +         if (riscv_zilsd_valid_mem_p (SET_SRC (x), mode))
>             {
>               /* TODO: Add riscv_tune_param for this.  */
>               *total = COSTS_N_INSNS (1);
> @@ -4276,8 +4329,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int 
> outer_code, int opno ATTRIBUTE_UN
>         }
>
>        /* Store for XLEN * 2.  */
> -      if (TARGET_ZILSD && MEM_P (SET_DEST (x)) && REG_P (SET_SRC (x))
> -         && riscv_2x_xlen_mode_p (mode))
> +      if (REG_P (SET_SRC (x)) && riscv_zilsd_valid_mem_p (SET_DEST (x), 
> mode))
>         {
>           /* TODO: Add riscv_tune_param for this.  */
>           *total = COSTS_N_INSNS (1);
> @@ -4995,7 +5047,13 @@ riscv_split_64bit_move_p (rtx dest, rtx src)
>        /* GCC may still generating some load/store with odd-even reg pair
>          because the ABI handling, but that's fine, just split that later.  */
>        if (GP_REG_P (regno))
> -       return (regno < FIRST_PSEUDO_REGISTER) && ((regno % 2) != 0);
> +       {
> +         rtx mem = MEM_P (dest) ? dest : src;
> +         if (!riscv_zilsd_valid_mem_p (mem, GET_MODE (mem)))
> +           return true;
> +
> +         return (regno < FIRST_PSEUDO_REGISTER) && ((regno % 2) != 0);
> +       }
>      }
>
>    /* There is no need to split if the FLI instruction in the `Zfa` extension 
> can be used.  */
> @@ -5014,6 +5072,56 @@ riscv_split_64bit_move_p (rtx dest, rtx src)
>    return true;
>  }
>
> +/* Expand a potentially misaligned Zilsd-sized memory move.  */
> +
> +bool
> +riscv_expand_zilsd_misaligned_move (rtx dest, rtx src)
> +{
> +  machine_mode mode = GET_MODE (dest);
> +  if (mode == VOIDmode)
> +    mode = GET_MODE (src);
> +
> +  if (TARGET_64BIT || !TARGET_ZILSD || !riscv_2x_xlen_mode_p (mode))
> +    return false;
> +
> +  if (!MEM_P (src) && !MEM_P (dest))
> +    return false;
> +
> +  if (MEM_P (src) && MEM_P (dest))
> +    {
> +      rtx tmp = gen_reg_rtx (mode);
> +      if (!riscv_expand_zilsd_misaligned_move (tmp, src))
> +       return false;
> +      return riscv_expand_zilsd_misaligned_move (dest, tmp);
> +    }
> +
> +  if ((MEM_P (src) && riscv_zilsd_valid_mem_p (src, mode))
> +      || (MEM_P (dest) && riscv_zilsd_valid_mem_p (dest, mode)))
> +    {
> +      emit_move_insn (dest, src);
> +      return true;
> +    }
> +
> +  if (MEM_P (src))
> +    {
> +      rtx target = REG_P (dest) ? dest : NULL_RTX;
> +      rtx value = extract_bit_field (src, GET_MODE_BITSIZE (mode), 0,
> +                                    false, target, mode, mode, false, NULL);
> +      if (value != dest)
> +       emit_move_insn (dest, value);
> +      return true;
> +    }
> +
> +  if (MEM_P (dest))
> +    {
> +      store_bit_field (dest, GET_MODE_BITSIZE (mode), 0, 0, 0, mode, src,
> +                      false, false);
> +      return true;
> +    }
> +
> +  return false;
> +}
> +
>  /* Split a doubleword move from SRC to DEST.  On 32-bit targets,
>     this function handles 64-bit moves for which riscv_split_64bit_move_p
>     holds.  For 64-bit targets, this function handles 128-bit moves.  */
> @@ -9039,6 +9147,10 @@ riscv_can_inline_p (tree caller, tree callee)
>        != callee_opts->x_rvv_vector_strict_align)
>      return false;
>
> +  if (riscv_zilsd_required_align (caller_opts)
> +      != riscv_zilsd_required_align (callee_opts))
> +    return false;
> +
>    return true;
>  }
>
> @@ -11688,6 +11800,10 @@ riscv_override_options_internal (struct gcc_options 
> *opts)
>        && ((target_flags_explicit & MASK_FDIV) == 0))
>      opts->x_target_flags |= MASK_FDIV;
>
> +  if (TARGET_64BIT && opts->x_riscv_zilsd_align_explicit)
> +    error ("%<-mzilsd-word-align%> and %<-mzilsd-strict-align%> are only "
> +          "supported for RV32");
> +
>    /* Handle -mtune, use -mcpu if -mtune is not given, and use default -mtune
>       if both -mtune and -mcpu are not given.  */
>    const char *tune_string = get_tune_str (opts);
> diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
> index 869061e18ae..6b917cc8109 100644
> --- a/gcc/config/riscv/riscv.md
> +++ b/gcc/config/riscv/riscv.md
> @@ -2578,6 +2578,17 @@ (define_insn "*movdi_64bit"
>     (set_attr "type" "move,move,load,store,mtc,fpload,mfc,fmove,fpstore,move")
>     (set_attr "ext" "base,base,base,base,d,d,d,d,d,vector")])
>
> +(define_expand "movmisaligndi"
> +  [(set (match_operand:DI 0 "nonimmediate_operand")
> +       (match_operand:DI 1 "general_operand"))]
> +  "!TARGET_64BIT && TARGET_ZILSD"
> +{
> +  if (riscv_expand_zilsd_misaligned_move (operands[0], operands[1]))
> +    DONE;
> +  else
> +    FAIL;
> +})
> +
>  ;; 32-bit Integer moves
>
>  (define_expand "mov<mode>"
> @@ -2752,6 +2763,17 @@ (define_insn "*movdf_softfloat"
>     (set_attr "type" "fmove,fpload,fpstore")
>     (set_attr "mode" "DF")])
>
> +(define_expand "movmisaligndf"
> +  [(set (match_operand:DF 0 "nonimmediate_operand")
> +       (match_operand:DF 1 "general_operand"))]
> +  "!TARGET_64BIT && TARGET_ZILSD"
> +{
> +  if (riscv_expand_zilsd_misaligned_move (operands[0], operands[1]))
> +    DONE;
> +  else
> +    FAIL;
> +})
> +
>  (define_insn "movsidf2_low_rv32"
>    [(set (match_operand:SI      0 "register_operand" "=  r")
>         (unspec:SI
> diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
> index c6e099eb47e..c2670ad87b2 100644
> --- a/gcc/config/riscv/riscv.opt
> +++ b/gcc/config/riscv/riscv.opt
> @@ -132,6 +132,14 @@ mscalar-strict-align
>  Target Save Alias(mstrict-align)
>  Do not generate unaligned scalar memory accesses.
>
> +mzilsd-word-align
> +Target RejectNegative
> +Allow Zilsd/Zclsd memory accesses to be 4-byte aligned.
> +
> +mzilsd-strict-align
> +Target RejectNegative
> +Force Zilsd/Zclsd memory accesses to be 8-byte aligned.
> +
>  mvector-strict-align
>  Target Save Var(rvv_vector_strict_align) Init(1)
>  Do not create element-misaligned vector memory accesses.
> @@ -171,6 +179,12 @@ Omit the frame pointer in leaf functions.
>  TargetVariable
>  int riscv_isa_flags
>
> +TargetVariable
> +enum riscv_zilsd_align_type riscv_zilsd_align = RISCV_ZILSD_ALIGN_DEFAULT
> +
> +TargetVariable
> +int riscv_zilsd_align_explicit = 0
> +
>  Mask(64BIT) Var(riscv_isa_flags)
>
>  Mask(VECTOR) Var(riscv_isa_flags)
> diff --git a/gcc/config/riscv/riscv.opt.urls b/gcc/config/riscv/riscv.opt.urls
> index 8111d34b22e..232bf9200e5 100644
> --- a/gcc/config/riscv/riscv.opt.urls
> +++ b/gcc/config/riscv/riscv.opt.urls
> @@ -50,6 +50,12 @@ UrlSuffix(gcc/RISC-V-Options.html#index-mstrict-align-4)
>  mscalar-strict-align
>  UrlSuffix(gcc/RISC-V-Options.html#index-mscalar-strict-align)
>
> +mzilsd-word-align
> +UrlSuffix(gcc/RISC-V-Options.html#index-mzilsd-word-align)
> +
> +mzilsd-strict-align
> +UrlSuffix(gcc/RISC-V-Options.html#index-mzilsd-strict-align)
> +
>  mvector-strict-align
>  UrlSuffix(gcc/RISC-V-Options.html#index-mvector-strict-align)
>
> @@ -122,4 +128,3 @@ mautovec-segment
>  UrlSuffix(gcc/RISC-V-Options.html#index-mautovec-segment)
>
>  ; skipping UrlSuffix for 'mmpy-option=' due to finding no URLs
> -
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 6d1da9f610e..8bfa73598c2 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -1338,6 +1338,7 @@ See RS/6000 and PowerPC Options.
>  -msmall-data-limit=@var{N-bytes}
>  -msave-restore  -mno-shorten-memrefs
>  -mstrict-align  -mscalar-strict-align  -mno-vector-strict-align
> +-mzilsd-word-align  -mzilsd-strict-align
>  -mcmodel=medlow  -mcmodel=medany  -mcmodel=large
>  -mexplicit-relocs  -mrelax  -mriscv-attribute
>  -malign-data=@var{type}
> @@ -31425,6 +31426,20 @@ Do not or do generate unaligned vector memory 
> accesses.  The default is set
>  to off unless the processor we are optimizing for explicitly supports
>  element-misaligned vector memory access.
>
> +@opindex mzilsd-word-align
> +@item -mzilsd-word-align
> +Allow Zilsd/Zclsd memory accesses to be generated when they are known to be
> +4-byte aligned.
> +
> +@opindex mzilsd-strict-align
> +@item -mzilsd-strict-align
> +Require Zilsd/Zclsd memory accesses to be naturally 8-byte aligned.
> +
> +The precedence among @option{-mzilsd-word-align},
> +@option{-mzilsd-strict-align}, @option{-mstrict-align},
> +@option{-mno-strict-align}, @option{-mscalar-strict-align}, and
> +@option{-mno-scalar-strict-align} is determined by the last one specified.
> +
>  @opindex mmax-vectorization
>  @opindex mno-max-vectorization
>  @item -mmax-vectorization
> diff --git a/gcc/testsuite/gcc.target/riscv/zilsd-align-default-1.c 
> b/gcc/testsuite/gcc.target/riscv/zilsd-align-default-1.c
> new file mode 100644
> index 00000000000..8793cda2f9c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/zilsd-align-default-1.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -march=rv32i_zilsd -mabi=ilp32" } */
> +
> +long long
> +load_ll (long long *p)
> +{
> +  return *p;
> +}
> +
> +void
> +store_ll (long long *p, long long x)
> +{
> +  *p = x;
> +}
> +
> +/* { dg-final { scan-assembler-times "ld\t" 1 } } */
> +/* { dg-final { scan-assembler-times "sd\t" 1 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/zilsd-align-df-1.c 
> b/gcc/testsuite/gcc.target/riscv/zilsd-align-df-1.c
> new file mode 100644
> index 00000000000..6e4b1829ec5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/zilsd-align-df-1.c
> @@ -0,0 +1,19 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -march=rv32i_zilsd -mabi=ilp32 -mzilsd-strict-align" } 
> */
> +
> +typedef double df4 __attribute__((aligned(4)));
> +
> +double
> +load_df4 (df4 *p)
> +{
> +  return *p;
> +}
> +
> +void
> +store_df4 (df4 *p, double x)
> +{
> +  *p = x;
> +}
> +
> +/* { dg-final { scan-assembler-not "ld\t" } } */
> +/* { dg-final { scan-assembler-not "sd\t" } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/zilsd-align-rv64-1.c 
> b/gcc/testsuite/gcc.target/riscv/zilsd-align-rv64-1.c
> new file mode 100644
> index 00000000000..f68b143f34e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/zilsd-align-rv64-1.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc -mabi=lp64d -mzilsd-word-align" } */
> +
> +int i;
> +
> +/* { dg-error "only supported for RV32" "" { target *-*-* } 0 } */
> diff --git a/gcc/testsuite/gcc.target/riscv/zilsd-align-rv64-2.c 
> b/gcc/testsuite/gcc.target/riscv/zilsd-align-rv64-2.c
> new file mode 100644
> index 00000000000..0600fd9c09e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/zilsd-align-rv64-2.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc -mabi=lp64d -mzilsd-strict-align" } */
> +
> +int i;
> +
> +/* { dg-error "only supported for RV32" "" { target *-*-* } 0 } */
> diff --git a/gcc/testsuite/gcc.target/riscv/zilsd-align-rv64-3.c 
> b/gcc/testsuite/gcc.target/riscv/zilsd-align-rv64-3.c
> new file mode 100644
> index 00000000000..65eeed377e7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/zilsd-align-rv64-3.c
> @@ -0,0 +1,5 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc -mabi=lp64d" } */
> +/* { dg-additional-options "-mzilsd-word-align -mstrict-align" } */
> +
> +int i;
> diff --git a/gcc/testsuite/gcc.target/riscv/zilsd-align-rv64-4.c 
> b/gcc/testsuite/gcc.target/riscv/zilsd-align-rv64-4.c
> new file mode 100644
> index 00000000000..fea394a466a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/zilsd-align-rv64-4.c
> @@ -0,0 +1,5 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc -mabi=lp64d" } */
> +/* { dg-additional-options "-mzilsd-strict-align -mno-strict-align" } */
> +
> +int i;
> diff --git a/gcc/testsuite/gcc.target/riscv/zilsd-align-word-1.c 
> b/gcc/testsuite/gcc.target/riscv/zilsd-align-word-1.c
> new file mode 100644
> index 00000000000..eeaed6cba91
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/zilsd-align-word-1.c
> @@ -0,0 +1,20 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -march=rv32i_zilsd -mabi=ilp32" } */
> +/* { dg-additional-options "-mstrict-align -mzilsd-word-align" } */
> +
> +typedef long long ll4 __attribute__((aligned(4)));
> +
> +long long
> +load_ll4 (ll4 *p)
> +{
> +  return *p;
> +}
> +
> +void
> +store_ll4 (ll4 *p, long long x)
> +{
> +  *p = x;
> +}
> +
> +/* { dg-final { scan-assembler-times "ld\t" 1 } } */
> +/* { dg-final { scan-assembler-times "sd\t" 1 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/zilsd-align-word-2.c 
> b/gcc/testsuite/gcc.target/riscv/zilsd-align-word-2.c
> new file mode 100644
> index 00000000000..47d26279c6a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/zilsd-align-word-2.c
> @@ -0,0 +1,20 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -march=rv32i_zilsd -mabi=ilp32" } */
> +/* { dg-additional-options "-mzilsd-word-align -mstrict-align" } */
> +
> +typedef long long ll4 __attribute__((aligned(4)));
> +
> +long long
> +load_ll4 (ll4 *p)
> +{
> +  return *p;
> +}
> +
> +void
> +store_ll4 (ll4 *p, long long x)
> +{
> +  *p = x;
> +}
> +
> +/* { dg-final { scan-assembler-not "ld\t" } } */
> +/* { dg-final { scan-assembler-not "sd\t" } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/zilsd-align-word-3.c 
> b/gcc/testsuite/gcc.target/riscv/zilsd-align-word-3.c
> new file mode 100644
> index 00000000000..816bd553b29
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/zilsd-align-word-3.c
> @@ -0,0 +1,20 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -march=rv32i_zilsd -mabi=ilp32" } */
> +/* { dg-additional-options "-mstrict-align -mzilsd-word-align" } */
> +
> +typedef long long ll1 __attribute__((aligned(1)));
> +
> +long long
> +load_ll1 (ll1 *p)
> +{
> +  return *p;
> +}
> +
> +void
> +store_ll1 (ll1 *p, long long x)
> +{
> +  *p = x;
> +}
> +
> +/* { dg-final { scan-assembler-not "ld\t" } } */
> +/* { dg-final { scan-assembler-not "sd\t" } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/zilsd-align-word-4.c 
> b/gcc/testsuite/gcc.target/riscv/zilsd-align-word-4.c
> new file mode 100644
> index 00000000000..5babf22e17c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/zilsd-align-word-4.c
> @@ -0,0 +1,20 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -march=rv32i_zilsd -mabi=ilp32" } */
> +/* { dg-additional-options "-mzilsd-strict-align -mno-strict-align" } */
> +
> +typedef long long ll1 __attribute__((aligned(1)));
> +
> +long long
> +load_ll1 (ll1 *p)
> +{
> +  return *p;
> +}
> +
> +void
> +store_ll1 (ll1 *p, long long x)
> +{
> +  *p = x;
> +}
> +
> +/* { dg-final { scan-assembler-times "ld\t" 1 } } */
> +/* { dg-final { scan-assembler-times "sd\t" 1 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/zilsd-align-word-5.c 
> b/gcc/testsuite/gcc.target/riscv/zilsd-align-word-5.c
> new file mode 100644
> index 00000000000..990a208cd14
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/zilsd-align-word-5.c
> @@ -0,0 +1,20 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -march=rv32i_zilsd -mabi=ilp32" } */
> +/* { dg-additional-options "-mno-strict-align -mzilsd-strict-align" } */
> +
> +typedef long long ll4 __attribute__((aligned(4)));
> +
> +long long
> +load_ll4 (ll4 *p)
> +{
> +  return *p;
> +}
> +
> +void
> +store_ll4 (ll4 *p, long long x)
> +{
> +  *p = x;
> +}
> +
> +/* { dg-final { scan-assembler-not "ld\t" } } */
> +/* { dg-final { scan-assembler-not "sd\t" } } */
> --
> 2.54.0
>

Reply via email to