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 >
