Re: [RFC 1/2] RISC-V: Add support for _Bfloat16.

2023-10-08 Thread Jin Ma
> On 9/19/23 02:44, Jin Ma wrote:
> > gcc/ChangeLog:
> > 
> > * config/riscv/iterators.md (HFBF): New.
> > * config/riscv/riscv-builtins.cc (riscv_init_builtin_types):
> > Initialize data type_Bfloat16.
> > * config/riscv/riscv-modes.def (FLOAT_MODE): New.
> > (ADJUST_FLOAT_FORMAT): New.
> > * config/riscv/riscv.cc (riscv_mangle_type): Support for BFmode.
> > (riscv_scalar_mode_supported_p): Ditto.
> > (riscv_libgcc_floating_mode_supported_p): Ditto.
> > (riscv_block_arith_comp_libfuncs_for_mode): New.
> > (riscv_init_libfuncs): Opening and closing some libfuncs for BFmode.
> > * config/riscv/riscv.md (mode" ): Add BF.
> > (truncdfbf2): New.
> > (movhf): Support for BFmode.
> > (mov): Ditto.
> > (*mov_softfloat):  Ditto.
> > (fix_truncbf2): New.
> > (fixuns_truncbf2): New.
> > (floatbf2): New.
> > (floatunsbf2): New.
> > 
> > libgcc/ChangeLog:
> > 
> > * config/riscv/sfp-machine.h (_FP_NANFRAC_B): New.
> > (_FP_NANSIGN_B): New.
> > * config/riscv/t-softfp32: Add support for BF libfuncs.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * gcc.target/riscv/bf16_arithmetic.c: New test.
> > * gcc.target/riscv/bf16_call.c: New test.
> > * gcc.target/riscv/bf16_comparisons.c: New test.
> > * gcc.target/riscv/bf16_convert-1.c: New test.
> > * gcc.target/riscv/bf16_convert-2.c: New test.
> > * gcc.target/riscv/bf16_convert_run.c: New test.
> So this can't go in the tree until the extension has moved into a frozen 
> state.  Hopefully that'll happen before we close stage1 development in Nov.

Ok, this is very reasonable.

> 
> 
> > diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
> > index e00b8ee3579..5048628c784 100644
> > --- a/gcc/config/riscv/riscv.md
> > +++ b/gcc/config/riscv/riscv.md
> > @@ -1631,6 +1631,20 @@ (define_insn "truncdfhf2"
> > [(set_attr "type" "fcvt")
> >  (set_attr "mode" "HF")])
> >   
> > +;; The conversion of DF to BF needs to be done with SF if there is a
> > +;; chance to generate at least one instruction, otherwise just using
> > +;; libfunc __truncdfbf2.
> > +(define_expand "truncdfbf2"
> > +  [(set (match_operand:BF 0 "register_operand" "=f")
> > +   (float_truncate:BF
> > +   (match_operand:DF 1 "register_operand" " f")))]
> > +  "TARGET_DOUBLE_FLOAT || TARGET_ZDINX"
> > +  {
> > +convert_move (operands[0],
> > + convert_modes (SFmode, DFmode, operands[1], 0), 0);
> > +DONE;
> > +  })
> So for conversions to/from BFmode, doesn't generic code take care of 
> this for us?  Search for convert_mode_scalar in expr.cc. That code will 
> utilize SFmode as an intermediate step just like your expander.   Is 
> there some reason that generic code is insufficient?
>
> Similarly for the the other conversions.

As far as I can see, the function 'convert_mode_scalar' doesn't seem to be 
perfect for
dealing with the conversions to/from BFmode. It can only handle BF to HF, SF, 
DF and
SF to BF well, but the rest of the conversion without any processing, directly 
using
the libcall.

Maybe I should choose to enhance its functionality? This seems to be a
good choice, I'm not sure.

Jin

> 
> Otherwise it looks pretty good.
> 
> Jeff

Re: [RFC 1/2] RISC-V: Add support for _Bfloat16.

2023-10-25 Thread Jin Ma
> >>> +;; The conversion of DF to BF needs to be done with SF if there is a
> >>> +;; chance to generate at least one instruction, otherwise just using
> >>> +;; libfunc __truncdfbf2.
> >>> +(define_expand "truncdfbf2"
> >>> +  [(set (match_operand:BF 0 "register_operand" "=f")
> >>> +   (float_truncate:BF
> >>> +   (match_operand:DF 1 "register_operand" " f")))]
> >>> +  "TARGET_DOUBLE_FLOAT || TARGET_ZDINX"
> >>> +  {
> >>> +convert_move (operands[0],
> >>> +   convert_modes (SFmode, DFmode, operands[1], 0), 0);
> >>> +DONE;
> >>> +  })
> >> So for conversions to/from BFmode, doesn't generic code take care of
> >> this for us?  Search for convert_mode_scalar in expr.cc. That code will
> >> utilize SFmode as an intermediate step just like your expander.   Is
> >> there some reason that generic code is insufficient?
> >>
> >> Similarly for the the other conversions.
> > 
> > As far as I can see, the function 'convert_mode_scalar' doesn't seem to be 
> > perfect for
> > dealing with the conversions to/from BFmode. It can only handle BF to HF, 
> > SF, DF and
> > SF to BF well, but the rest of the conversion without any processing, 
> > directly using
> > the libcall.
> > 
> > Maybe I should choose to enhance its functionality? This seems to be a
> > good choice, I'm not sure.My recollection was that BF could be converted 
> > to/from SF trivially and 
> if we wanted BF->DF we'd first convert to SF, then to DF.
> 
> Direct BF<->DF conversions aren't actually important from a performance 
> standpoint.  So it's OK if they have an extra step IMHO.

Thank you very much for your review and detailed reply. Maybe there are some 
problems with my expression
and I am a little confused about your guidance. My understanding is that you 
also think that it is reasonable to
convert through SF, right? In fact, this is what I did.

In this patch, my thoughts are as follows:

The general principle is to use the real instructions instead of libcall as 
much as possible for conversions,
while minimizing the definition of libcall(only reusing which has been defined 
by other architectures such
as aarch64). If SF can be used as a transit, it is preferred to convert to SF, 
otherwise libcall is directly used.

1. For the conversions between floating points

For BF->DF, as you said, the function 'convert_mode_scalar' in the general code 
has been well implemented,
which will be expressed as BF->SF->DF. And the generated instruction list may 
be as follows:
  'call __extendbfsf2' + 'call __extendsfdf2' (when only soft floating point 
support);
  'call __extendbfsf2' + 'fcvt.d.s'   (when (TARGET_DOUBLE_FLOAT || 
TARGET_ZDINX) is true);
  'fcvt.s.bf16'+ 'fcvt.d.s'   (when ((TARGET_DOUBLE_FLOAT || 
TARGET_ZDINX) && TARGET_ZFBFMIN) is true)

For DF->BF, if any of fcvt.s.d and fcvt.bf16.s cannot be generated, the 'call 
__truncdfbf2' is directly generated
by the function 'convert_mode_scalar'. Otherwise the new pattern(define_expand 
"truncdfbf2") is used. This
makes it possible to implement DF->BF by 'fcvt.s.d' + 'fcvt.bf16.s', which 
cannot be generated by the function
'convert_mode_scala'.

2. For the conversions between integer and BF, it seems that gcc only uses 
libcall to implement it, but this is
obviously wrong. For example, the conversion BF->SI directly calls the 
unimplemented libcall __fixunsbfsi.
So I added some new pattern to handle these transformations with SF.

Thanks,

Jin

> 
> jeff

[RE] [7/7] riscv: Add basic extension support for XTheadFmv and XTheadInt

2023-11-02 Thread Jin Ma
Hi, I see that XTheadInt is not implemented in the compiler. Is there any plan 
here?
If there is no patch for it, can I try to implement it with you?

Thanks

Jin


Re:[PATCH v2 1/1] [RISC-V] Add support for _Bfloat16

2024-04-02 Thread Jin Ma
> gcc/testsuite/ChangeLog:
> 
>   * gcc.target/riscv/bf16_arithmetic.c: New test.
>   * gcc.target/riscv/bf16_call.c: New test.
>   * gcc.target/riscv/bf16_comparison.c: New test.
>   * gcc.target/riscv/bf16_float_libcall_convert.c: New test.
>   * gcc.target/riscv/bf16_integer_libcall_convert.c: New test.

  Hi, I have test this patch and it is very good. I think we need to add some
runable tests to ensure that the results are right for various types of
conversions, operations, and libfuncs.

BR,
Jin


[PATCH] RISC-V: THEAD: Fix ICE caused by split optimizations for XTheadFMemIdx.

2024-01-11 Thread Jin Ma
Due to the premature split optimizations for XTheadFMemIdx, GPR
is allocated when reload allocates registers, resulting in the
following insn.

(insn 66 21 64 5 (set (reg:DF 14 a4 [orig:136  ] [136])
(mem:DF (plus:SI (reg/f:SI 15 a5 [141])
(ashift:SI (reg/v:SI 10 a0 [orig:137 i ] [137])
(const_int 3 [0x3]))) [0  S8 A64])) 218 
{*movdf_hardfloat_rv32}
 (nil))

Since we currently do not support adjustments to th_m_mir/th_m_miu,
which will trigger ICE. So it is recommended to place the split
optimizations after reload to ensure FPR when registers are allocated.

gcc/ChangeLog:

* config/riscv/thead.md: Add limits for splits.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadfmemidx-medany.c: New test.
---
 gcc/config/riscv/thead.md | 22 ---
 .../gcc.target/riscv/xtheadfmemidx-medany.c   | 38 +++
 2 files changed, 54 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-medany.c

diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index e370774d518..5c7d4beb1b6 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -933,14 +933,17 @@ (define_insn_and_split "*th_fmemidx_I_a"
&& pow2p_hwi (INTVAL (operands[2]))
&& IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)"
   "#"
-  "&& 1"
+  "&& reload_completed"
   [(set (match_dup 0)
 (mem:TH_M_NOEXTF (plus:X
   (match_dup 3)
   (ashift:X (match_dup 1) (match_dup 2)]
   { operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
   }
-)
+  [(set_attr "move_type" "fpload")
+   (set_attr "mode" "")
+   (set_attr "type" "fmove")
+   (set (attr "length") (const_int 16))])
 
 (define_insn_and_split "*th_fmemidx_I_c"
   [(set (mem:TH_M_ANYF (plus:X
@@ -977,7 +980,7 @@ (define_insn_and_split "*th_fmemidx_US_a"
&& CONST_INT_P (operands[3])
&& (INTVAL (operands[3]) >> exact_log2 (INTVAL (operands[2]))) == 
0x"
   "#"
-  "&& 1"
+  "&& reload_completed"
   [(set (match_dup 0)
 (mem:TH_M_NOEXTF (plus:DI
   (match_dup 4)
@@ -985,7 +988,10 @@ (define_insn_and_split "*th_fmemidx_US_a"
   { operands[1] = gen_lowpart (SImode, operands[1]);
 operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
   }
-)
+  [(set_attr "move_type" "fpload")
+   (set_attr "mode" "")
+   (set_attr "type" "fmove")
+   (set (attr "length") (const_int 16))])
 
 (define_insn_and_split "*th_fmemidx_US_c"
   [(set (mem:TH_M_ANYF (plus:DI
@@ -1020,12 +1026,16 @@ (define_insn_and_split "*th_fmemidx_UZ_a"
   "TARGET_64BIT && TARGET_XTHEADMEMIDX && TARGET_XTHEADFMEMIDX
&& (!HARD_REGISTER_NUM_P (REGNO (operands[0])) || HARDFP_REG_P (REGNO 
(operands[0])))"
   "#"
-  "&& 1"
+  "&& reload_completed"
   [(set (match_dup 0)
 (mem:TH_M_NOEXTF (plus:DI
   (match_dup 2)
   (zero_extend:DI (match_dup 1)]
-)
+  ""
+  [(set_attr "move_type" "fpload")
+   (set_attr "mode" "")
+   (set_attr "type" "fmove")
+   (set (attr "length") (const_int 16))])
 
 (define_insn_and_split "*th_fmemidx_UZ_c"
   [(set (mem:TH_M_ANYF (plus:DI
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-medany.c 
b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-medany.c
new file mode 100644
index 000..0c8060d0632
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-medany.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O3" "-Og" "-Os" "-Oz"} } */
+/* { dg-options "-march=rv32gc_xtheadfmemidx_xtheadfmv_xtheadmemidx 
-mabi=ilp32d -mcmodel=medany -O2" } */
+
+typedef union {
+  double v;
+  unsigned w;
+} my_t;
+
+double z;
+
+double foo (int i, int j)
+{
+
+  if (j)
+{
+  switch (i)
+   {
+   case 0:
+ return 1;
+   case 1:
+ return 0;
+   case 2:
+ return 3.0;
+   }
+}
+
+  if (i == 1)
+{
+  my_t u;
+  u.v = z;
+  u.w = 1;
+  z = u.v;
+}
+  return z;
+}
+
+/* { dg-final { scan-assembler-times {\mth\.flrd\M} 1 } } */
-- 
2.17.1



[PATCH] RISC-V: THEAD: Fix improper immediate value for MODIFY_DISP instruction on 32-bit systems.

2024-01-29 Thread Jin Ma
When using  '%ld' to print 'long long int' variable, 'fprintf' will
produce messy output on a 32-bit system, in an incorrect instruction
being generated, such as 'th.lwib a1,(a0),-16,4294967295'. And the
following error occurred during compilation:

Assembler messages:
Error: improper immediate value (18446744073709551615)

gcc/ChangeLog:

* config/riscv/thead.cc (th_print_operand_address): Change %ld
to %lld.
---
 gcc/config/riscv/thead.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc
index 2955bc5f8a9..9ee6444b627 100644
--- a/gcc/config/riscv/thead.cc
+++ b/gcc/config/riscv/thead.cc
@@ -1141,7 +1141,7 @@ th_print_operand_address (FILE *file, machine_mode mode, 
rtx x)
   return true;
 
 case ADDRESS_REG_WB:
-  fprintf (file, "(%s),%ld,%u", reg_names[REGNO (addr.reg)],
+  fprintf (file, "(%s),%lld,%u", reg_names[REGNO (addr.reg)],
   INTVAL (addr.offset) >> addr.shift, addr.shift);
return true;
 
-- 
2.17.1



Re:[PATCH] RISC-V: THEAD: Fix improper immediate value for MODIFY_DISP instruction on 32-bit systems.

2024-01-29 Thread Jin Ma
>On Mon, Jan 29, 2024 at 1:21=E2=80=AFAM Jin Ma  wr=
>ote:
>>
>> When using  '%ld' to print 'long long int' variable, 'fprintf' will
>> produce messy output on a 32-bit system, in an incorrect instruction
>> being generated, such as 'th.lwib a1,(a0),-16,4294967295'. And the
>> following error occurred during compilation:
>>
>> Assembler messages:
>> Error: improper immediate value (18446744073709551615)
>>
>> gcc/ChangeLog:
>>
>> * config/riscv/thead.cc (th_print_operand_address): Change %ld
>> to %lld.
>> ---
>>  gcc/config/riscv/thead.cc | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc
>> index 2955bc5f8a9..9ee6444b627 100644
>> --- a/gcc/config/riscv/thead.cc
>> +++ b/gcc/config/riscv/thead.cc
>> @@ -1141,7 +1141,7 @@ th_print_operand_address (FILE *file, machine_mode =
>mode, rtx x)
>>return true;
>>
>>  case ADDRESS_REG_WB:
>> -  fprintf (file, "(%s),%ld,%u", reg_names[REGNO (addr.reg)],
>> +  fprintf (file, "(%s),%lld,%u", reg_names[REGNO (addr.reg)],
>>INTVAL (addr.offset) >> addr.shift, addr.shift);


>This is wrong, you should instead use HOST_WIDE_INT_PRINT_DEC or
>HOST_WIDE_INT_PRINT_UNSIGNED.

>Thanks,
>Andrew Pinski

Yes, thank you very much for your guidance. It will be better to
use HOST_WIDE_INT_PRINT_DEC. I will make changes later :)

BR

Jin

>> return true;

[PATCH v2] RISC-V: THEAD: Fix improper immediate value for MODIFY_DISP instruction on 32-bit systems.

2024-01-29 Thread Jin Ma
When using  '%ld' to print 'long long int' variable, 'fprintf' will
produce messy output on a 32-bit system, in an incorrect instruction
being generated, such as 'th.lwib a1,(a0),-16,4294967295'. And the
following error occurred during compilation:

Assembler messages:
Error: improper immediate value (18446744073709551615)

gcc/ChangeLog:

* config/riscv/thead.cc (th_print_operand_address): Change %ld
to %lld.
---
 gcc/config/riscv/thead.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc
index 2955bc5f8a9..e4b8c37bc28 100644
--- a/gcc/config/riscv/thead.cc
+++ b/gcc/config/riscv/thead.cc
@@ -1141,7 +1141,7 @@ th_print_operand_address (FILE *file, machine_mode mode, 
rtx x)
   return true;
 
 case ADDRESS_REG_WB:
-  fprintf (file, "(%s),%ld,%u", reg_names[REGNO (addr.reg)],
+  fprintf (file, "(%s),"HOST_WIDE_INT_PRINT_DEC",%u", reg_names[REGNO 
(addr.reg)],
   INTVAL (addr.offset) >> addr.shift, addr.shift);
return true;
 
-- 
2.17.1



[PATCH] Support libcall __float{, un}sibf by SF when it is not supported for _bf16

2023-12-20 Thread Jin Ma
We don't have SI -> BF library functions, use SI -> SF -> BF
instead. Although this can also be implemented in a target
machine description, it is more appropriate to move
into target independent code.

gcc/ChangeLog:

* optabs.cc (expand_float): Split SI -> BF into SI -> SF -> BF.
---
 gcc/optabs.cc | 13 +
 1 file changed, 13 insertions(+)

diff --git a/gcc/optabs.cc b/gcc/optabs.cc
index 6a34276c239..c58a0321bbd 100644
--- a/gcc/optabs.cc
+++ b/gcc/optabs.cc
@@ -5727,6 +5727,19 @@ expand_float (rtx to, rtx from, int unsignedp)
   if (is_narrower_int_mode (GET_MODE (from), SImode))
from = convert_to_mode (SImode, from, unsignedp);
 
+#ifdef HAVE_SFmode
+  if (REAL_MODE_FORMAT (GET_MODE (to)) == &arm_bfloat_half_format
+ && REAL_MODE_FORMAT (SFmode) == &ieee_single_format
+ && GET_MODE (from) == SImode)
+   /* We don't have SI -> BF library functions, use SI -> SF -> BF
+  instead.  */
+   {
+ target = gen_reg_rtx (SFmode);
+ expand_float (target, from, unsignedp);
+ goto done;
+   }
+#endif
+
   libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
   gcc_assert (libfunc);
 
-- 
2.17.1



Re:[PATCH] Support libcall __float{,un}sibf by SF when it is not supported for _bf16

2024-01-09 Thread Jin Ma
ping


Re:[PATCH v2] RISC-V: T-HEAD: Add support for the XTheadInt ISA extension

2024-01-09 Thread Jin Ma
ping

Ref: https://gcc.gnu.org/pipermail/gcc-patches/2023-November/636932.html

Re:[PATCH] Support libcall __float{,un}sibf by SF when it is not supported for _bf16

2024-01-09 Thread Jin Ma
I apologize for not attaching a reference link.

Ref:
https://patchwork.ozlabs.org/project/gcc/patch/2023091908.2089-1-ji...@linux.alibaba.com/
https://gcc.gnu.org/pipermail/gcc-patches/2023-December/641119.html

BR
Jin


[PATCH] riscv: thead: Add support for the XTheadInt ISA extension

2023-11-06 Thread Jin Ma
The XTheadInt ISA extension provides acceleration interruption
instructions as defined in T-Head-specific:

* th.ipush
* th.ipop

gcc/ChangeLog:

* config/riscv/riscv-protos.h (th_int_get_mask): New prototype.
(th_int_get_save_adjustment): Likewise.
(th_int_adjust_cfi_prologue): Likewise.
* config/riscv/riscv.cc (TH_INT_INTERRUPT): New macro.
(riscv_expand_prologue): Add the processing of XTheadInt.
(riscv_expand_epilogue): Likewise.
* config/riscv/riscv.md: New unspec.
* config/riscv/thead.cc (BITSET_P): New macro.
* config/riscv/thead.md (th_int_push): New pattern.
(th_int_pop): New pattern.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadint-push-pop.c: New test.
---
 gcc/config/riscv/riscv-protos.h   |  3 +
 gcc/config/riscv/riscv.cc | 58 +-
 gcc/config/riscv/riscv.md |  4 +
 gcc/config/riscv/thead.cc | 78 +++
 gcc/config/riscv/thead.md | 67 
 .../gcc.target/riscv/xtheadint-push-pop.c | 36 +
 6 files changed, 245 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c

diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 85d4f6ed9ea..05d1fc2b3a0 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -627,6 +627,9 @@ extern void th_mempair_prepare_save_restore_operands 
(rtx[4], bool,
  int, HOST_WIDE_INT,
  int, HOST_WIDE_INT);
 extern void th_mempair_save_restore_regs (rtx[4], bool, machine_mode);
+extern unsigned int th_int_get_mask(unsigned int);
+extern unsigned int th_int_get_save_adjustment();
+extern rtx th_int_adjust_cfi_prologue (unsigned int);
 #ifdef RTX_CODE
 extern const char*
 th_mempair_output_move (rtx[4], bool, machine_mode, RTX_CODE);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 08ff05dcc3f..c623101b05e 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -101,6 +101,16 @@ along with GCC; see the file COPYING3.  If not see
 /* True the mode switching has static frm, or false.  */
 #define STATIC_FRM_P(c) ((c)->machine->mode_sw_info.static_frm_p)
 
+/* True if we can use the instructions in the XTheadInt extension
+   to handle interrupts, or false.  */
+#define TH_INT_INTERRUPT(c)\
+  (TARGET_XTHEADINT\
+   /* The XTheadInt extension only supports rv32.  */  \
+   && !TARGET_64BIT\
+   && (c)->machine->interrupt_handler_p\
+   /* This instruction can be executed in M-mode only.*/   \
+   && (c)->machine->interrupt_mode == MACHINE_MODE)
+
 /* Information about a function's frame layout.  */
 struct GTY(())  riscv_frame_info {
   /* The size of the frame in bytes.  */
@@ -6703,6 +6713,7 @@ riscv_expand_prologue (void)
   unsigned fmask = frame->fmask;
   int spimm, multi_push_additional, stack_adj;
   rtx insn, dwarf = NULL_RTX;
+  unsigned th_int_mask = 0;
 
   if (flag_stack_usage_info)
 current_function_static_stack_size = constant_lower_bound (remaining_size);
@@ -6771,6 +6782,28 @@ riscv_expand_prologue (void)
   REG_NOTES (insn) = dwarf;
 }
 
+  th_int_mask = th_int_get_mask(frame->mask);
+  if (th_int_mask && TH_INT_INTERRUPT (cfun))
+{
+  frame->mask &= ~th_int_mask;
+
+  /* RISCV_PROLOGUE_TEMP may be used to handle some CSR for
+interrupts, such as fcsr. */
+  if ((TARGET_HARD_FLOAT  && frame->fmask)
+ || (TARGET_ZFINX && frame->mask))
+   frame->mask |= (1 << RISCV_PROLOGUE_TEMP_REGNUM);
+
+  unsigned save_adjustment = th_int_get_save_adjustment ();
+  frame->gp_sp_offset -= save_adjustment;
+  remaining_size -= save_adjustment;
+
+  insn = emit_insn (gen_th_int_push ());
+
+  rtx dwarf = th_int_adjust_cfi_prologue (th_int_mask);
+  RTX_FRAME_RELATED_P (insn) = 1;
+  REG_NOTES (insn) = dwarf;
+}
+
   /* Save the GP, FP registers.  */
   if ((frame->mask | frame->fmask) != 0)
 {
@@ -6999,6 +7032,7 @@ riscv_expand_epilogue (int style)
 = use_multi_pop ? frame->multi_push_adj_base + frame->multi_push_adj_addi
: 0;
   rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
+  unsigned th_int_mask = 0;
   rtx insn;
 
   /* We need to add memory barrier to prevent read from deallocated stack.  */
@@ -7161,12 +7195,32 @@ riscv_expand_epilogue (int style)
   else if (use_restore_libcall)
 frame->mask = 0; /* Temporarily fib that we need not restore GPRs.  */
 
+  th_int_mask = th_int_get_mask(frame->mask);
+  if (th_int_mask && TH_INT_INTERRUPT (cfun))
+{
+  frame->mask &= ~th_int_mask;
+
+  /* RISCV_PROLOGUE_TEM

[PATCH] RISC-V: Fix the illegal operands for the XTheadMemidx extension.

2023-11-08 Thread Jin Ma
The pattern "*extend2_bitmanip" and
"*zero_extendhi2_bitmanip" in bitmanip.md are similar
to the pattern "*th_memidx_bb_extendqi2" and
"*th_memidx_bb_zero_extendhi2" in thead.md, which will
cause the wrong instruction to be generated and report the
following error in binutils:
Assembler messages:
Error: illegal operands `lb a5,(a0),1,0'

In fact, the correct instruction is "th.lbia a5,(a0),1,0".

gcc/ChangeLog:

* config/riscv/bitmanip.md: Avoid the conflict between
zbb and xtheadmemidx in patterns.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadfmemidx-uindex-zbb.c: New test.
---
 gcc/config/riscv/bitmanip.md  |  4 +--
 .../riscv/xtheadfmemidx-uindex-zbb.c  | 30 +++
 2 files changed, 32 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-zbb.c

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index a9c8275fca7..878395c3ffa 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -290,7 +290,7 @@ (define_insn "*di2"
 (define_insn "*zero_extendhi2_bitmanip"
   [(set (match_operand:GPR 0 "register_operand" "=r,r")
 (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
-  "TARGET_ZBB"
+  "TARGET_ZBB  && !TARGET_XTHEADMEMIDX"
   "@
zext.h\t%0,%1
lhu\t%0,%1"
@@ -301,7 +301,7 @@ (define_insn "*extend2_bitmanip"
   [(set (match_operand:SUPERQI   0 "register_operand" "=r,r")
(sign_extend:SUPERQI
(match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
-  "TARGET_ZBB"
+  "TARGET_ZBB && !TARGET_XTHEADMEMIDX"
   "@
sext.\t%0,%1
l\t%0,%1"
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-zbb.c 
b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-zbb.c
new file mode 100644
index 000..a05bc220cba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx-uindex-zbb.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+/* { dg-options "-march=rv64gc_zbb_xtheadmemidx -mabi=lp64d" { target { rv64 } 
} } */
+/* { dg-options "-march=rv32imafc_zbb_xtheadmemidx -mabi=ilp32f" { target { 
rv32 } } } */
+
+const unsigned char *
+read_uleb128(const unsigned char *p, unsigned long *val)
+{
+  unsigned int shift = 0;
+  unsigned char byte;
+  unsigned long result;
+
+  result = 0;
+  do
+  {
+byte = *p++;
+result |= ((unsigned long)byte & 0x7f) << shift;
+shift += 7;
+  } while (byte & 0x80);
+
+  *val = result;
+  return p;
+}
+
+void test(const unsigned char *p, unsigned long utmp)
+{
+  p = read_uleb128(p, &utmp);
+}
+
+/* { dg-final { scan-assembler-not {\mlb\ta[0-9],\(a[0-9]\),1,0\M} } } */

base-commit: 04d8a47608dcae7f61805e3566e3a1571b574405
-- 
2.17.1



[PATCH] RISC-V: Fix bug that XTheadMemPair extension caused fcsr not to be saved and restored before and after interrupt.

2023-11-09 Thread Jin Ma
The t0 register is used as a temporary register for interrupts, so it needs
special treatment. It is necessary to avoid using "th.ldd" in the interrupt
program to stop the subsequent operation of the t0 register, so they need to
exchange positions in the function "riscv_for_each_saved_reg".

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_for_each_saved_reg): Place the interrupt
operation before the XTheadMemPair.
---
 gcc/config/riscv/riscv.cc | 56 +--
 .../riscv/xtheadmempair-interrupt-fcsr.c  | 18 ++
 2 files changed, 46 insertions(+), 28 deletions(-)
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadmempair-interrupt-fcsr.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index e25692b86fc..fa2d4d4b779 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -6346,6 +6346,34 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, 
riscv_save_restore_fn fn,
  && riscv_is_eh_return_data_register (regno))
continue;
 
+  /* In an interrupt function, save and restore some necessary CSRs in the 
stack
+to avoid changes in CSRs.  */
+  if (regno == RISCV_PROLOGUE_TEMP_REGNUM
+ && cfun->machine->interrupt_handler_p
+ && ((TARGET_HARD_FLOAT  && cfun->machine->frame.fmask)
+ || (TARGET_ZFINX
+ && (cfun->machine->frame.mask & ~(1 << 
RISCV_PROLOGUE_TEMP_REGNUM)
+   {
+ unsigned int fcsr_size = GET_MODE_SIZE (SImode);
+ if (!epilogue)
+   {
+ riscv_save_restore_reg (word_mode, regno, offset, fn);
+ offset -= fcsr_size;
+ emit_insn (gen_riscv_frcsr (RISCV_PROLOGUE_TEMP (SImode)));
+ riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM,
+ offset, riscv_save_reg);
+   }
+ else
+   {
+ riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM,
+ offset - fcsr_size, riscv_restore_reg);
+ emit_insn (gen_riscv_fscsr (RISCV_PROLOGUE_TEMP (SImode)));
+ riscv_save_restore_reg (word_mode, regno, offset, fn);
+ offset -= fcsr_size;
+   }
+ continue;
+   }
+
   if (TARGET_XTHEADMEMPAIR)
{
  /* Get the next reg/offset pair.  */
@@ -6376,34 +6404,6 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, 
riscv_save_restore_fn fn,
}
}
 
-  /* In an interrupt function, save and restore some necessary CSRs in the 
stack
-to avoid changes in CSRs.  */
-  if (regno == RISCV_PROLOGUE_TEMP_REGNUM
- && cfun->machine->interrupt_handler_p
- && ((TARGET_HARD_FLOAT  && cfun->machine->frame.fmask)
- || (TARGET_ZFINX
- && (cfun->machine->frame.mask & ~(1 << 
RISCV_PROLOGUE_TEMP_REGNUM)
-   {
- unsigned int fcsr_size = GET_MODE_SIZE (SImode);
- if (!epilogue)
-   {
- riscv_save_restore_reg (word_mode, regno, offset, fn);
- offset -= fcsr_size;
- emit_insn (gen_riscv_frcsr (RISCV_PROLOGUE_TEMP (SImode)));
- riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM,
- offset, riscv_save_reg);
-   }
- else
-   {
- riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM,
- offset - fcsr_size, riscv_restore_reg);
- emit_insn (gen_riscv_fscsr (RISCV_PROLOGUE_TEMP (SImode)));
- riscv_save_restore_reg (word_mode, regno, offset, fn);
- offset -= fcsr_size;
-   }
- continue;
-   }
-
   riscv_save_restore_reg (word_mode, regno, offset, fn);
 }
 
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-interrupt-fcsr.c 
b/gcc/testsuite/gcc.target/riscv/xtheadmempair-interrupt-fcsr.c
new file mode 100644
index 000..d06f05f5c7c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-interrupt-fcsr.c
@@ -0,0 +1,18 @@
+/* Verify that fcsr instructions emitted.  */
+/* { dg-do compile } */
+/* { dg-require-effective-target hard_float } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os" "-flto" } } */
+/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906 
-funwind-tables" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906 
-funwind-tables" { target { rv32 } } } */
+
+
+extern int foo (void);
+
+void __attribute__ ((interrupt))
+sub (void)
+{
+  foo ();
+}
+
+/* { dg-final { scan-assembler-times "frcsr\t" 1 } } */
+/* { dg-final { scan-assembler-times "fscsr\t" 1 } } */

base-commit: e7f4040d9d6ec40c48ada940168885d7dde03af9
-- 
2.17.1



[PATCH v2] RISC-V: Fixbug for that XTheadMemPair causes interrupt to fail.

2023-11-10 Thread Jin Ma
The t0 register is used as a temporary register for interrupts, so it needs
special treatment. It is necessary to avoid using "th.ldd" in the interrupt
program to stop the subsequent operation of the t0 register, so they need to
exchange positions in the function "riscv_for_each_saved_reg".

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_for_each_saved_reg): Place the interrupt
operation before the XTheadMemPair.
---
 gcc/config/riscv/riscv.cc | 56 +--
 .../riscv/xtheadmempair-interrupt-fcsr.c  | 18 ++
 2 files changed, 46 insertions(+), 28 deletions(-)
 create mode 100644 
gcc/testsuite/gcc.target/riscv/xtheadmempair-interrupt-fcsr.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index e25692b86fc..fa2d4d4b779 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -6346,6 +6346,34 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, 
riscv_save_restore_fn fn,
  && riscv_is_eh_return_data_register (regno))
continue;
 
+  /* In an interrupt function, save and restore some necessary CSRs in the 
stack
+to avoid changes in CSRs.  */
+  if (regno == RISCV_PROLOGUE_TEMP_REGNUM
+ && cfun->machine->interrupt_handler_p
+ && ((TARGET_HARD_FLOAT  && cfun->machine->frame.fmask)
+ || (TARGET_ZFINX
+ && (cfun->machine->frame.mask & ~(1 << 
RISCV_PROLOGUE_TEMP_REGNUM)
+   {
+ unsigned int fcsr_size = GET_MODE_SIZE (SImode);
+ if (!epilogue)
+   {
+ riscv_save_restore_reg (word_mode, regno, offset, fn);
+ offset -= fcsr_size;
+ emit_insn (gen_riscv_frcsr (RISCV_PROLOGUE_TEMP (SImode)));
+ riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM,
+ offset, riscv_save_reg);
+   }
+ else
+   {
+ riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM,
+ offset - fcsr_size, riscv_restore_reg);
+ emit_insn (gen_riscv_fscsr (RISCV_PROLOGUE_TEMP (SImode)));
+ riscv_save_restore_reg (word_mode, regno, offset, fn);
+ offset -= fcsr_size;
+   }
+ continue;
+   }
+
   if (TARGET_XTHEADMEMPAIR)
{
  /* Get the next reg/offset pair.  */
@@ -6376,34 +6404,6 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, 
riscv_save_restore_fn fn,
}
}
 
-  /* In an interrupt function, save and restore some necessary CSRs in the 
stack
-to avoid changes in CSRs.  */
-  if (regno == RISCV_PROLOGUE_TEMP_REGNUM
- && cfun->machine->interrupt_handler_p
- && ((TARGET_HARD_FLOAT  && cfun->machine->frame.fmask)
- || (TARGET_ZFINX
- && (cfun->machine->frame.mask & ~(1 << 
RISCV_PROLOGUE_TEMP_REGNUM)
-   {
- unsigned int fcsr_size = GET_MODE_SIZE (SImode);
- if (!epilogue)
-   {
- riscv_save_restore_reg (word_mode, regno, offset, fn);
- offset -= fcsr_size;
- emit_insn (gen_riscv_frcsr (RISCV_PROLOGUE_TEMP (SImode)));
- riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM,
- offset, riscv_save_reg);
-   }
- else
-   {
- riscv_save_restore_reg (SImode, RISCV_PROLOGUE_TEMP_REGNUM,
- offset - fcsr_size, riscv_restore_reg);
- emit_insn (gen_riscv_fscsr (RISCV_PROLOGUE_TEMP (SImode)));
- riscv_save_restore_reg (word_mode, regno, offset, fn);
- offset -= fcsr_size;
-   }
- continue;
-   }
-
   riscv_save_restore_reg (word_mode, regno, offset, fn);
 }
 
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmempair-interrupt-fcsr.c 
b/gcc/testsuite/gcc.target/riscv/xtheadmempair-interrupt-fcsr.c
new file mode 100644
index 000..d06f05f5c7c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadmempair-interrupt-fcsr.c
@@ -0,0 +1,18 @@
+/* Verify that fcsr instructions emitted.  */
+/* { dg-do compile } */
+/* { dg-require-effective-target hard_float } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-g" "-Oz" "-Os" "-flto" } } */
+/* { dg-options "-march=rv64gc_xtheadmempair -mtune=thead-c906 
-funwind-tables" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadmempair -mtune=thead-c906 
-funwind-tables" { target { rv32 } } } */
+
+
+extern int foo (void);
+
+void __attribute__ ((interrupt))
+sub (void)
+{
+  foo ();
+}
+
+/* { dg-final { scan-assembler-times "frcsr\t" 1 } } */
+/* { dg-final { scan-assembler-times "fscsr\t" 1 } } */

base-commit: e7f4040d9d6ec40c48ada940168885d7dde03af9
-- 
2.17.1



Re: [PATCH v2] In the pipeline, USE or CLOBBER should delay execution if it starts a new live range.

2023-11-12 Thread Jin Ma
> > 
> > Unfortunately this patch has triggered a bootstrap comparison failure on
> > loongarch64-linux-gnu: https://gcc.gnu.org/PR112497.
> It's also causing simple build failures on other targets.  For example 
> c6x-elf aborts when compiling gcc.c-torture/execute/pr82210 (and others) 
> with -O2 with that patch applied.
> 
> I've reverted it for now.  I'm not going to have time to investigate 
> this week.

I'm sorry to have caused this and had a bad effect. This patch has
been a long time since I verified it, so I don't know what happened, I
will check it out :)

BR
Jin

> Jeff
> >

[PATCH v2] RISC-V: T-HEAD: Add support for the XTheadInt ISA extension

2023-11-16 Thread Jin Ma
The XTheadInt ISA extension provides acceleration interruption
instructions as defined in T-Head-specific:
* th.ipush
* th.ipop

Ref:
https://github.com/T-head-Semi/thead-extension-spec/releases/download/2.3.0/xthead-2023-11-10-2.3.0.pdf

gcc/ChangeLog:

* config/riscv/riscv-protos.h (th_int_get_mask): New prototype.
(th_int_get_save_adjustment): Likewise.
(th_int_adjust_cfi_prologue): Likewise.
* config/riscv/riscv.cc (TH_INT_INTERRUPT): New macro.
(riscv_expand_prologue): Add the processing of XTheadInt.
(riscv_expand_epilogue): Likewise.
* config/riscv/riscv.md: New unspec.
* config/riscv/thead.cc (BITSET_P): New macro.
* config/riscv/thead.md (th_int_push): New pattern.
(th_int_pop): New pattern.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadint-push-pop.c: New test.
---
 gcc/config/riscv/riscv-protos.h   |  3 +
 gcc/config/riscv/riscv.cc | 61 ++-
 gcc/config/riscv/riscv.h  |  3 +
 gcc/config/riscv/riscv.md |  4 +
 gcc/config/riscv/thead.cc | 77 +++
 gcc/config/riscv/thead.md | 67 
 .../gcc.target/riscv/xtheadint-push-pop.c | 36 +
 7 files changed, 247 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c

diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 196b53f10f3..91d1e99f672 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -633,6 +633,9 @@ extern void th_mempair_prepare_save_restore_operands 
(rtx[4], bool,
  int, HOST_WIDE_INT,
  int, HOST_WIDE_INT);
 extern void th_mempair_save_restore_regs (rtx[4], bool, machine_mode);
+extern unsigned int th_int_get_mask (unsigned int);
+extern unsigned int th_int_get_save_adjustment (void);
+extern rtx th_int_adjust_cfi_prologue (unsigned int);
 #ifdef RTX_CODE
 extern const char*
 th_mempair_output_move (rtx[4], bool, machine_mode, RTX_CODE);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index c2bd1c2ed29..6ff6f4789a4 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -94,15 +94,22 @@ along with GCC; see the file COPYING3.  If not see
 #define UNSPEC_ADDRESS_TYPE(X) \
   ((enum riscv_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST))
 
-/* True if bit BIT is set in VALUE.  */
-#define BITSET_P(VALUE, BIT) (((VALUE) & (1ULL << (BIT))) != 0)
-
 /* Extract the backup dynamic frm rtl.  */
 #define DYNAMIC_FRM_RTL(c) ((c)->machine->mode_sw_info.dynamic_frm)
 
 /* True the mode switching has static frm, or false.  */
 #define STATIC_FRM_P(c) ((c)->machine->mode_sw_info.static_frm_p)
 
+/* True if we can use the instructions in the XTheadInt extension
+   to handle interrupts, or false.  */
+#define TH_INT_INTERRUPT(c)\
+  (TARGET_XTHEADINT\
+   /* The XTheadInt extension only supports rv32.  */  \
+   && !TARGET_64BIT\
+   && (c)->machine->interrupt_handler_p
\
+   /* The XTheadInt instructions can only be executed in M-mode.  */   \
+   && (c)->machine->interrupt_mode == MACHINE_MODE)
+
 /* Information about a function's frame layout.  */
 struct GTY(())  riscv_frame_info {
   /* The size of the frame in bytes.  */
@@ -6737,6 +6744,7 @@ riscv_expand_prologue (void)
   unsigned fmask = frame->fmask;
   int spimm, multi_push_additional, stack_adj;
   rtx insn, dwarf = NULL_RTX;
+  unsigned th_int_mask = 0;
 
   if (flag_stack_usage_info)
 current_function_static_stack_size = constant_lower_bound (remaining_size);
@@ -6805,6 +6813,28 @@ riscv_expand_prologue (void)
   REG_NOTES (insn) = dwarf;
 }
 
+  th_int_mask = th_int_get_mask (frame->mask);
+  if (th_int_mask && TH_INT_INTERRUPT (cfun))
+{
+  frame->mask &= ~th_int_mask;
+
+  /* RISCV_PROLOGUE_TEMP may be used to handle some CSR for
+interrupts, such as fcsr.  */
+  if ((TARGET_HARD_FLOAT  && frame->fmask)
+ || (TARGET_ZFINX && frame->mask))
+   frame->mask |= (1 << RISCV_PROLOGUE_TEMP_REGNUM);
+
+  unsigned save_adjustment = th_int_get_save_adjustment ();
+  frame->gp_sp_offset -= save_adjustment;
+  remaining_size -= save_adjustment;
+
+  insn = emit_insn (gen_th_int_push ());
+
+  rtx dwarf = th_int_adjust_cfi_prologue (th_int_mask);
+  RTX_FRAME_RELATED_P (insn) = 1;
+  REG_NOTES (insn) = dwarf;
+}
+
   /* Save the GP, FP registers.  */
   if ((frame->mask | frame->fmask) != 0)
 {
@@ -7033,6 +7063,7 @@ riscv_expand_epilogue (int style)
 = use_multi_pop ? frame->multi_push_adj_base + frame->multi_push_

[RFC 1/2] RISC-V: Add support for _Bfloat16.

2023-09-19 Thread Jin Ma
gcc/ChangeLog:

* config/riscv/iterators.md (HFBF): New.
* config/riscv/riscv-builtins.cc (riscv_init_builtin_types):
Initialize data type_Bfloat16.
* config/riscv/riscv-modes.def (FLOAT_MODE): New.
(ADJUST_FLOAT_FORMAT): New.
* config/riscv/riscv.cc (riscv_mangle_type): Support for BFmode.
(riscv_scalar_mode_supported_p): Ditto.
(riscv_libgcc_floating_mode_supported_p): Ditto.
(riscv_block_arith_comp_libfuncs_for_mode): New.
(riscv_init_libfuncs): Opening and closing some libfuncs for BFmode.
* config/riscv/riscv.md (mode" ): Add BF.
(truncdfbf2): New.
(movhf): Support for BFmode.
(mov): Ditto.
(*mov_softfloat):  Ditto.
(fix_truncbf2): New.
(fixuns_truncbf2): New.
(floatbf2): New.
(floatunsbf2): New.

libgcc/ChangeLog:

* config/riscv/sfp-machine.h (_FP_NANFRAC_B): New.
(_FP_NANSIGN_B): New.
* config/riscv/t-softfp32: Add support for BF libfuncs.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/bf16_arithmetic.c: New test.
* gcc.target/riscv/bf16_call.c: New test.
* gcc.target/riscv/bf16_comparisons.c: New test.
* gcc.target/riscv/bf16_convert-1.c: New test.
* gcc.target/riscv/bf16_convert-2.c: New test.
* gcc.target/riscv/bf16_convert_run.c: New test.
---
 gcc/config/riscv/iterators.md |   2 +
 gcc/config/riscv/riscv-builtins.cc|  16 ++
 gcc/config/riscv/riscv-modes.def  |   4 +
 gcc/config/riscv/riscv.cc |  93 --
 gcc/config/riscv/riscv.md |  94 --
 .../gcc.target/riscv/bf16_arithmetic.c|  36 
 gcc/testsuite/gcc.target/riscv/bf16_call.c|  17 ++
 .../gcc.target/riscv/bf16_comparisons.c   |  25 +++
 .../gcc.target/riscv/bf16_convert-1.c |  39 +
 .../gcc.target/riscv/bf16_convert-2.c |  38 
 .../gcc.target/riscv/bf16_convert_run.c   | 163 ++
 libgcc/config/riscv/sfp-machine.h |   3 +
 libgcc/config/riscv/t-softfp32|   7 +-
 13 files changed, 503 insertions(+), 34 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_arithmetic.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_call.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_comparisons.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_convert-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_convert-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/bf16_convert_run.c

diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md
index ecf033f2fa7..73523b73fdd 100644
--- a/gcc/config/riscv/iterators.md
+++ b/gcc/config/riscv/iterators.md
@@ -84,6 +84,8 @@ (define_mode_iterator SOFTF [SF (DF "TARGET_64BIT") (HF 
"TARGET_ZFHMIN")])
 ;; instruction.
 (define_mode_attr size [(QI "b") (HI "h")])
 
+(define_mode_iterator HFBF [HF BF])
+
 ;; Mode attributes for loads.
 (define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (HF "flh") (SF 
"flw") (DF "fld")])
 
diff --git a/gcc/config/riscv/riscv-builtins.cc 
b/gcc/config/riscv/riscv-builtins.cc
index 3fe3a89dcc2..b7bb89794f7 100644
--- a/gcc/config/riscv/riscv-builtins.cc
+++ b/gcc/config/riscv/riscv-builtins.cc
@@ -192,6 +192,7 @@ static GTY(()) int riscv_builtin_decl_index[NUM_INSN_CODES];
   riscv_builtin_decls[riscv_builtin_decl_index[(CODE)]]
 
 tree riscv_float16_type_node = NULL_TREE;
+tree riscv_bfloat16_type_node = NULL_TREE;
 
 /* Return the function type associated with function prototype TYPE.  */
 
@@ -235,6 +236,21 @@ riscv_init_builtin_types (void)
   if (!maybe_get_identifier ("_Float16"))
 lang_hooks.types.register_builtin_type (riscv_float16_type_node,
"_Float16");
+
+  /* Provide the _Bfloat16 type and bfloat16_type_node if needed.  */
+  if (!bfloat16_type_node)
+{
+  riscv_bfloat16_type_node = make_node (REAL_TYPE);
+  TYPE_PRECISION (riscv_bfloat16_type_node) = 16;
+  SET_TYPE_MODE (riscv_bfloat16_type_node, BFmode);
+  layout_type (riscv_bfloat16_type_node);
+}
+  else
+riscv_bfloat16_type_node = bfloat16_type_node;
+
+  if (!maybe_get_identifier ("_Bfloat16"))
+lang_hooks.types.register_builtin_type (riscv_bfloat16_type_node,
+   "_Bfloat16");
 }
 
 /* Implement TARGET_INIT_BUILTINS.  */
diff --git a/gcc/config/riscv/riscv-modes.def b/gcc/config/riscv/riscv-modes.def
index e3c6ccb2809..723bfaee42d 100644
--- a/gcc/config/riscv/riscv-modes.def
+++ b/gcc/config/riscv/riscv-modes.def
@@ -22,6 +22,10 @@ along with GCC; see the file COPYING3.  If not see
 FLOAT_MODE (HF, 2, ieee_half_format);
 FLOAT_MODE (TF, 16, ieee_quad_format);
 
+FLOAT_MODE (BF, 2, 0);
+/* Reuse definition from arm.  */
+ADJUST_FLOAT_FORMAT (BF, &arm_bfloat_half_format);
+
 /* Vector modes.  */
 
 /* Encode the ratio of SEW/

[RFC 2/2] RISC-V: Add 'Zfbfmin' extension.

2023-09-19 Thread Jin Ma
This patch adds the 'Zfbfmin' extension for riscv, which is based on spec of 
bfloat16:
https://github.com/riscv/riscv-bfloat16/commit/5578e34e15a44e9ad13246072a29f51274b4d999

The 'Zfbfmin' extension of binutils-gdb (REVIEW ONLY):
https://sourceware.org/pipermail/binutils/2023-August/128773.html

The 'Zfbfmin' extension of qemu:
https://github.com/qemu/qemu/commit/5d1270caac2ef7b8c887d4cb5a2444ba6d237516

Because the binutils does not yet support the 'Zfbfmin' extension, test case
zfbfmin_convert_run.c is invalidated with '#if 0' and '#endif'.

gcc/ChangeLog:

* common/config/riscv/riscv-common.cc: Add 'Zfbfmin' extension.
* config/riscv/riscv-opts.h (MASK_ZFBFMIN): New.
(TARGET_ZFBFMIN): New.
* config/riscv/riscv.cc (riscv_output_move): Enable FMV.X.H, and FMV.H.X
for 'Zfbfmin' extension.
(riscv_excess_precision): Likewise.
* config/riscv/riscv.md (truncsfbf2): New.
(extendbfsf2):  New.
(*mov_hardfloat): Support for BFmode.
(*mov_softfloat): Disable for BFmode  when 'Zfbfmin' extension is
enabled.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/zfbfmin_arithmetic.c: New test.
* gcc.target/riscv/zfbfmin_call.c: New test.
* gcc.target/riscv/zfbfmin_comparisons.c: New test.
* gcc.target/riscv/zfbfmin_convert.c: New test.
* gcc.target/riscv/zfbfmin_convert_run.c: New test.
* gcc.target/riscv/zfbfmin_fsh_and_flh.c: New test.
---
 gcc/common/config/riscv/riscv-common.cc   |   3 +
 gcc/config/riscv/riscv-opts.h |   2 +
 gcc/config/riscv/riscv.cc |   4 +-
 gcc/config/riscv/riscv.md |  40 ++--
 .../gcc.target/riscv/zfbfmin_arithmetic.c |  31 
 gcc/testsuite/gcc.target/riscv/zfbfmin_call.c |  17 ++
 .../gcc.target/riscv/zfbfmin_comparisons.c|  22 +++
 .../gcc.target/riscv/zfbfmin_convert.c|  38 
 .../gcc.target/riscv/zfbfmin_convert_run.c| 173 ++
 .../gcc.target/riscv/zfbfmin_fsh_and_flh.c|  12 ++
 10 files changed, 329 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/zfbfmin_arithmetic.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zfbfmin_call.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zfbfmin_comparisons.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zfbfmin_convert.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zfbfmin_convert_run.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zfbfmin_fsh_and_flh.c

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index 9a0a68fe5db..1fcbb862aa4 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -123,6 +123,7 @@ static const riscv_implied_info_t riscv_implied_info[] =
 
   {"zfh", "zfhmin"},
   {"zfhmin", "f"},
+  {"zfbfmin", "f"},
 
   {"zfa", "f"},
 
@@ -284,6 +285,7 @@ static const struct riscv_ext_version 
riscv_ext_version_table[] =
   {"zfhmin",ISA_SPEC_CLASS_NONE, 1, 0},
   {"zvfhmin",   ISA_SPEC_CLASS_NONE, 1, 0},
   {"zvfh",  ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zfbfmin", ISA_SPEC_CLASS_NONE, 0, 8},
 
   {"zfa", ISA_SPEC_CLASS_NONE, 0, 1},
 
@@ -1461,6 +1463,7 @@ static const riscv_ext_flag_table_t 
riscv_ext_flag_table[] =
   {"zfh",   &gcc_options::x_riscv_zf_subext, MASK_ZFH},
   {"zvfhmin",   &gcc_options::x_riscv_zf_subext, MASK_ZVFHMIN},
   {"zvfh",  &gcc_options::x_riscv_zf_subext, MASK_ZVFH},
+  {"zfbfmin",  &gcc_options::x_riscv_zf_subext, MASK_ZFBFMIN},
 
   {"zfa",   &gcc_options::x_riscv_zfa_subext, MASK_ZFA},
 
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index a525f679683..900a46fcae0 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -256,11 +256,13 @@ enum riscv_entity
 #define MASK_ZFH  (1 << 1)
 #define MASK_ZVFHMIN  (1 << 2)
 #define MASK_ZVFH (1 << 3)
+#define MASK_ZFBFMIN  (1 << 4)
 
 #define TARGET_ZFHMIN  ((riscv_zf_subext & MASK_ZFHMIN) != 0)
 #define TARGET_ZFH ((riscv_zf_subext & MASK_ZFH) != 0)
 #define TARGET_ZVFHMIN ((riscv_zf_subext & MASK_ZVFHMIN) != 0)
 #define TARGET_ZVFH((riscv_zf_subext & MASK_ZVFH) != 0)
+#define TARGET_ZFBFMIN((riscv_zf_subext & MASK_ZFBFMIN) != 0)
 
 #define MASK_ZMMUL  (1 << 0)
 #define TARGET_ZMMUL((riscv_zm_subext & MASK_ZMMUL) != 0)
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 910523ee2b9..6362c3f83c8 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -3372,7 +3372,7 @@ riscv_output_move (rtx dest, rtx src)
switch (width)
  {
  case 2:
-   if (TARGET_ZFHMIN)
+   if (TARGET_ZFHMIN || TARGET_ZFBFMIN)
  return "fmv.x.h\t%0,%1";
/* Using fmv.x.s + sign-extend to emulate fmv.x.h.  */
return "fmv.x.s\t%0,%1;slli\t%0,%0,16;srai\t%0,%0,16";
@@ -3428,7 +3428,7 @@ riscv_output_move 

[PATCH v2] RISC-V: Fix ICE for vector single-width integer multiply-add intrinsics

2024-08-07 Thread Jin Ma
When rs1 is the immediate 0, the following ICE occurs:

error: unrecognizable insn:
(insn 8 5 12 2 (set (reg:RVVM1DI 134 [  ])
(if_then_else:RVVM1DI (unspec:RVVMF64BI [
(const_vector:RVVMF64BI repeat [
(const_int 1 [0x1])
   ])
(reg/v:DI 137 [ vl ])
(const_int 2 [0x2]) repeated x2
(const_int 0 [0])
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
(plus:RVVM1DI (mult:RVVM1DI (vec_duplicate:RVVM1DI (const_int 0 
[0]))
(reg/v:RVVM1DI 136 [ vs2 ]))
(reg/v:RVVM1DI 135 [ vd ]))
(reg/v:RVVM1DI 135 [ vd ])))

gcc/ChangeLog:

* config/riscv/vector.md: Allow scalar operand to be 0.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/bug-7.c: New test.
* gcc.target/riscv/rvv/base/bug-8.c: New test.
---
 gcc/config/riscv/vector.md| 80 +--
 .../gcc.target/riscv/rvv/base/bug-7.c | 26 ++
 .../gcc.target/riscv/rvv/base/bug-8.c | 26 ++
 3 files changed, 92 insertions(+), 40 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/bug-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/bug-8.c

diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index fb625f611d5..20420b74964 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -5331,16 +5331,16 @@ (define_insn "*pred_madd_scalar"
  (plus:V_VLSI
(mult:V_VLSI
  (vec_duplicate:V_VLSI
-   (match_operand: 2 "register_operand" "  r,   r,  r,   r"))
+   (match_operand: 2 "reg_or_0_operand" " rJ,  rJ, rJ,  rJ"))
  (match_operand:V_VLSI 3 "register_operand"  "  0,  vr,  0,  
vr"))
(match_operand:V_VLSI 4 "register_operand"" vr,  vr, vr,  
vr"))
  (match_dup 3)))]
   "TARGET_VECTOR"
   "@
-   vmadd.vx\t%0,%2,%4%p1
-   vmv%m3r.v\t%0,%3\;vmadd.vx\t%0,%2,%4%p1
-   vmadd.vx\t%0,%2,%4%p1
-   vmv%m3r.v\t%0,%3\;vmadd.vx\t%0,%2,%4%p1"
+   vmadd.vx\t%0,%z2,%4%p1
+   vmv%m3r.v\t%0,%3\;vmadd.vx\t%0,%z2,%4%p1
+   vmadd.vx\t%0,%z2,%4%p1
+   vmv%m3r.v\t%0,%3\;vmadd.vx\t%0,%z2,%4%p1"
   [(set_attr "type" "vimuladd")
(set_attr "mode" "")
(set_attr "merge_op_idx" "3")
@@ -5363,16 +5363,16 @@ (define_insn "*pred_macc_scalar"
  (plus:V_VLSI
(mult:V_VLSI
  (vec_duplicate:V_VLSI
-   (match_operand: 2 "register_operand" "  r,   r,  r,   r"))
+   (match_operand: 2 "reg_or_0_operand" " rJ,  rJ, rJ,  rJ"))
  (match_operand:V_VLSI 3 "register_operand"  " vr,  vr, vr,  
vr"))
(match_operand:V_VLSI 4 "register_operand""  0,  vr,  0,  
vr"))
  (match_dup 4)))]
   "TARGET_VECTOR"
   "@
-   vmacc.vx\t%0,%2,%3%p1
-   vmv%m4r.v\t%0,%4\;vmacc.vx\t%0,%2,%3%p1
-   vmacc.vx\t%0,%2,%3%p1
-   vmv%m4r.v\t%0,%4\;vmacc.vx\t%0,%2,%3%p1"
+   vmacc.vx\t%0,%z2,%3%p1
+   vmv%m4r.v\t%0,%4\;vmacc.vx\t%0,%z2,%3%p1
+   vmacc.vx\t%0,%z2,%3%p1
+   vmv%m4r.v\t%0,%4\;vmacc.vx\t%0,%z2,%3%p1"
   [(set_attr "type" "vimuladd")
(set_attr "mode" "")
(set_attr "merge_op_idx" "4")
@@ -5431,16 +5431,16 @@ (define_insn "*pred_madd_extended_scalar"
(mult:V_VLSI_D
  (vec_duplicate:V_VLSI_D
(sign_extend:
- (match_operand: 2 "register_operand" "  r,   r,  r,   
r")))
+ (match_operand: 2 "reg_or_0_operand" " rJ,  rJ, rJ,  
rJ")))
  (match_operand:V_VLSI_D 3 "register_operand" "  0,  vr,  
0,  vr"))
(match_operand:V_VLSI_D 4 "register_operand"   " vr,  vr, 
vr,  vr"))
  (match_dup 3)))]
   "TARGET_VECTOR && !TARGET_64BIT"
   "@
-   vmadd.vx\t%0,%2,%4%p1
-   vmv%m2r.v\t%0,%2\;vmadd.vx\t%0,%2,%4%p1
-   vmadd.vx\t%0,%2,%4%p1
-   vmv%m2r.v\t%0,%2\;vmadd.vx\t%0,%2,%4%p1"
+   vmadd.vx\t%0,%z2,%4%p1
+   vmv%m2r.v\t%0,%z2\;vmadd.vx\t%0,%z2,%4%p1
+   vmadd.vx\t%0,%z2,%4%p1
+   vmv%m2r.v\t%0,%z2\;vmadd.vx\t%0,%z2,%4%p1"
   [(set_attr "type" "vimuladd")
(set_attr "mode" "")
(set_attr "merge_op_idx" "3")
@@ -5464,16 +5464,16 @@ (define_insn "*pred_macc_extended_scalar"
(mult:V_VLSI_D
  (vec_duplicate:V_VLSI_D
(sign_extend:
- (match_operand: 2 "register_operand" "  r,   r,  r,   
r")))
+ (match_operand: 2 "reg_or_0_operand" " rJ,  rJ, rJ,  
rJ")))
  (match_operand:V_VLSI_D 3 "register_operand" " vr,  vr, 
vr,  vr"))
(match_operand:V_VLSI_D 4 "register_operand"   "  0,  vr,  
0,  vr"))
  (match_dup 4)))]
   "TARGET_VECTOR && !TARGET_64BIT"
   "@
-   vmacc.vx\t%0,%2,%3%p1
-   vmv%m4r.v\t%0,%4\;vmacc.vx\t%0,%2,%3%p1
-   vmacc.vx\t%0,%2,%3%p1
-   vmv%m4r.v\t%0,%4\;vmacc.vx\t%0,%2,%3%p1"
+   vmacc.vx\t%0,%z2,%3

[PATCH] RISC-V: Bugfix for RVV rounding intrinsic ICE in function checker

2024-08-09 Thread Jin Ma
When compiling an interface for rounding of type 'vfloat16*' without using zvfh
or zvfhmin, it is not enough to use FLOAT_MODE_P because the type does not 
support
it. Although the subsequent riscv_validate_vector_type checks will still fail
and throw exceptions, I don't think we should have ICE here.

internal compiler error: in check, at 
config/riscv/riscv-vector-builtins-shapes.cc:444
   10 |   return __riscv_vfadd_vv_f16m1_rm (vs2, vs1, 0, vl);
  |   ^~
0x4191794 internal_error(char const*, ...)
/iothome/jin.ma/code/master/gcc/gcc/diagnostic-global-context.cc:491
0x416ebf5 fancy_abort(char const*, int, char const*)
/iothome/jin.ma/code/master/gcc/gcc/diagnostic.cc:1772
0x220aae6 riscv_vector::build_frm_base::check(riscv_vector::function_checker&) 
const

/iothome/jin.ma/code/master/gcc/gcc/config/riscv/riscv-vector-builtins-shapes.cc:444
0x2205323 riscv_vector::function_checker::check()

/iothome/jin.ma/code/master/gcc/gcc/config/riscv/riscv-vector-builtins.cc:4414

gcc/ChangeLog:

* config/riscv/riscv-protos.h (riscv_vector_float_type_p): New.
* config/riscv/riscv-vector-builtins.cc 
(function_instance::any_type_float_p):
Use riscv_vector_float_type_p instead of FLOAT_MODE_P for judgment.
* config/riscv/riscv.cc (riscv_vector_int_type_p): Change static to 
extern.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/bug-9.c: New test.
---
 gcc/config/riscv/riscv-protos.h |  1 +
 gcc/config/riscv/riscv-vector-builtins.cc   |  4 ++--
 gcc/config/riscv/riscv.cc   |  2 +-
 gcc/testsuite/gcc.target/riscv/rvv/base/bug-9.c | 13 +
 4 files changed, 17 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/bug-9.c

diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 124ae2c073a..f8fc2874cbb 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -171,6 +171,7 @@ extern enum memmodel riscv_union_memmodels (enum memmodel, 
enum memmodel);
 extern bool riscv_reg_frame_related (rtx);
 extern void riscv_split_sum_of_two_s12 (HOST_WIDE_INT, HOST_WIDE_INT *,
HOST_WIDE_INT *);
+extern bool riscv_vector_float_type_p (const_tree type);
 
 /* Routines implemented in riscv-c.cc.  */
 void riscv_cpu_cpp_builtins (cpp_reader *);
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc 
b/gcc/config/riscv/riscv-vector-builtins.cc
index 49a1cb1708f..fa940d30caa 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -3497,11 +3497,11 @@ function_instance::operator== (const function_instance 
&other) const
 bool
 function_instance::any_type_float_p () const
 {
-  if (FLOAT_MODE_P (TYPE_MODE (get_return_type (
+  if (riscv_vector_float_type_p (get_return_type ()))
 return true;
 
   for (int i = 0; op_info->args[i].base_type != NUM_BASE_TYPES; ++i)
-if (FLOAT_MODE_P (TYPE_MODE (get_arg_type (i
+if (riscv_vector_float_type_p (get_arg_type (i)))
   return true;
 
   return false;
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 3d0a1d12b14..84dc906c04d 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -5929,7 +5929,7 @@ riscv_vector_int_type_p (const_tree type)
   return strstr (name, "int") != NULL || strstr (name, "uint") != NULL;
 }
 
-static bool
+bool
 riscv_vector_float_type_p (const_tree type)
 {
   machine_mode mode = TYPE_MODE (type);
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/bug-9.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-9.c
new file mode 100644
index 000..20ae9ebf6f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-9.c
@@ -0,0 +1,13 @@
+/* Test that we do not have ice when compile */
+/* { dg-do assemble } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O2"  { target { rv64 } } } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32d -O2"  { target { rv32 } } } */
+
+#include 
+
+vfloat16m1_t f0 (vfloat16m1_t vs2, vfloat16m1_t vs1, size_t vl)
+{
+  return __riscv_vfadd_vv_f16m1_rm (vs2, vs1, 0, vl); 
+}
+
+/* { dg-error "return type 'vfloat16m1_t' requires the zvfhmin or zvfh ISA 
extension" "" { target { "riscv*-*-*" } } 0 } */
-- 
2.17.1



Re: [PATCH] RISC-V: Bugfix for RVV rounding intrinsic ICE in function checker

2024-08-09 Thread Jin Ma
> Hi Jin Ma,> 
> Precommit has flagged a large number of ICEs with this patch on vector
> targets when applied to yesterday's daily bump[1]:
> https://github.com/ewlu/gcc-precommit-ci/issues/2037#issuecomment-2277469412
> 
> Thanks,
> Patrick
> 
> [1]
> https://github.com/gcc-mirror/gcc/commit/77ccfa6ac8d6e4dfefdea45c4259a2873ff9eb3d

I am very sorry for causing that, I will check and try to solve it as soon as 
possible. Sorry again!

BR

Jin


[PATCH v2] RISC-V: Bugfix for RVV rounding intrinsic ICE in function checker

2024-08-12 Thread Jin Ma
When compiling an interface for rounding of type 'vfloat16*' without using zvfh
or zvfhmin, it is not enough to use FLOAT_MODE_P because the type does not 
support
it. Although the subsequent riscv_validate_vector_type checks will still fail
and throw exceptions, I don't think we should have ICE here.

internal compiler error: in check, at 
config/riscv/riscv-vector-builtins-shapes.cc:444
   10 |   return __riscv_vfadd_vv_f16m1_rm (vs2, vs1, 0, vl);
  |   ^~
0x4191794 internal_error(char const*, ...)
/iothome/jin.ma/code/master/gcc/gcc/diagnostic-global-context.cc:491
0x416ebf5 fancy_abort(char const*, int, char const*)
/iothome/jin.ma/code/master/gcc/gcc/diagnostic.cc:1772
0x220aae6 riscv_vector::build_frm_base::check(riscv_vector::function_checker&) 
const

/iothome/jin.ma/code/master/gcc/gcc/config/riscv/riscv-vector-builtins-shapes.cc:444
0x2205323 riscv_vector::function_checker::check()

/iothome/jin.ma/code/master/gcc/gcc/config/riscv/riscv-vector-builtins.cc:4414

gcc/ChangeLog:

* config/riscv/riscv-protos.h (riscv_vector_float_type_p): New.
* config/riscv/riscv-vector-builtins.cc 
(function_instance::any_type_float_p):
Use riscv_vector_float_type_p instead of FLOAT_MODE_P for judgment.
* config/riscv/riscv.cc (riscv_vector_int_type_p): Change static to 
extern.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/bug-9.c: New test.
---
 gcc/config/riscv/riscv-protos.h |  1 +
 gcc/config/riscv/riscv-vector-builtins.cc   |  4 ++--
 gcc/config/riscv/riscv.cc   |  5 -
 gcc/testsuite/gcc.target/riscv/rvv/base/bug-9.c | 13 +
 4 files changed, 20 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/bug-9.c

diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 124ae2c073a..f8fc2874cbb 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -171,6 +171,7 @@ extern enum memmodel riscv_union_memmodels (enum memmodel, 
enum memmodel);
 extern bool riscv_reg_frame_related (rtx);
 extern void riscv_split_sum_of_two_s12 (HOST_WIDE_INT, HOST_WIDE_INT *,
HOST_WIDE_INT *);
+extern bool riscv_vector_float_type_p (const_tree type);
 
 /* Routines implemented in riscv-c.cc.  */
 void riscv_cpu_cpp_builtins (cpp_reader *);
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc 
b/gcc/config/riscv/riscv-vector-builtins.cc
index 49a1cb1708f..fa940d30caa 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -3497,11 +3497,11 @@ function_instance::operator== (const function_instance 
&other) const
 bool
 function_instance::any_type_float_p () const
 {
-  if (FLOAT_MODE_P (TYPE_MODE (get_return_type (
+  if (riscv_vector_float_type_p (get_return_type ()))
 return true;
 
   for (int i = 0; op_info->args[i].base_type != NUM_BASE_TYPES; ++i)
-if (FLOAT_MODE_P (TYPE_MODE (get_arg_type (i
+if (riscv_vector_float_type_p (get_arg_type (i)))
   return true;
 
   return false;
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a1b09e865ea..eb0bdb8e024 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -5898,9 +5898,12 @@ riscv_vector_int_type_p (const_tree type)
   return strstr (name, "int") != NULL || strstr (name, "uint") != NULL;
 }
 
-static bool
+bool
 riscv_vector_float_type_p (const_tree type)
 {
+  if (!riscv_vector_type_p (type))
+return false;
+
   machine_mode mode = TYPE_MODE (type);
 
   if (VECTOR_MODE_P (mode))
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/bug-9.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-9.c
new file mode 100644
index 000..20ae9ebf6f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-9.c
@@ -0,0 +1,13 @@
+/* Test that we do not have ice when compile */
+/* { dg-do assemble } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O2"  { target { rv64 } } } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32d -O2"  { target { rv32 } } } */
+
+#include 
+
+vfloat16m1_t f0 (vfloat16m1_t vs2, vfloat16m1_t vs1, size_t vl)
+{
+  return __riscv_vfadd_vv_f16m1_rm (vs2, vs1, 0, vl); 
+}
+
+/* { dg-error "return type 'vfloat16m1_t' requires the zvfhmin or zvfh ISA 
extension" "" { target { "riscv*-*-*" } } 0 } */
-- 
2.17.1



[PATCH] haifa-sched: Avoid the fusion priority of the fused insn to affect the subsequent insn sequence.

2024-06-04 Thread Jin Ma
When the insn 1 and 2, 3 and 4 can be fusioned, then there is the
following sequence:

;;insn |
;;  1  | sp=sp-0x18
;;  +   2  | [sp+0x10]=ra
;;  3  | [sp+0x8]=s0
;;  4  | [sp+0x0]=s1

The fusion priority of the insn 2, 3, and 4 are the same. According to
the current algorithm, since abs(0x10-0x8)

Re:[PATCH] Support libcall __float{,un}sibf by SF when it is not supported for _bf16

2024-06-04 Thread Jin Ma
> On 12/20/23 4:17 AM, Jin Ma wrote:
> > We don't have SI -> BF library functions, use SI -> SF -> BF
> > instead. Although this can also be implemented in a target
> > machine description, it is more appropriate to move
> > into target independent code.
> > 
> > gcc/ChangeLog:
> > 
> >  * optabs.cc (expand_float): Split SI -> BF into SI -> SF -> BF.
> > ---
> >   gcc/optabs.cc | 13 +
> >   1 file changed, 13 insertions(+)
> > 
> > diff --git a/gcc/optabs.cc b/gcc/optabs.cc
> > index 6a34276c239..c58a0321bbd 100644
> > --- a/gcc/optabs.cc
> > +++ b/gcc/optabs.cc
> > @@ -5727,6 +5727,19 @@ expand_float (rtx to, rtx from, int unsignedp)
> >         if (is_narrower_int_mode (GET_MODE (from), SImode))
> >    from = convert_to_mode (SImode, from, unsignedp);
> >   
> > +#ifdef HAVE_SFmode
> > +      if (REAL_MODE_FORMAT (GET_MODE (to)) == &arm_bfloat_half_format
> > +   && REAL_MODE_FORMAT (SFmode) == &ieee_single_format
> > +   && GET_MODE (from) == SImode)
> > + /* We don't have SI -> BF library functions, use SI -> SF -> BF
> > +    instead.  */
> > + {
> > +   target = gen_reg_rtx (SFmode);
> > +   expand_float (target, from, unsignedp);
> > +   goto done;
> > + }
> > +#endif
> Why do you have the #ifdef HAVE_SFmode?  That seems odd, I think the 
> only place we do anything like that is in targhooks.  Why did you add 
> those cpp conditionals?

Hi, jeff
I'm sorry I haven't noticed this email for so long. For this patch, my
original idea  was to use SF to complete the SI to BF conversion. This
is because RSICV did not support that when the patch was submitted, and
the relevant soft floating point library '__floatsibf' was not defined,
so I used a new pattern to do this. The soft floating-point library
'__floatsibf' has been added now, which seems to be the most correct
approach. So this patch is no longer meaningful in this respect.

Ref:
https://patchwork.ozlabs.org/project/gcc/patch/2023091908.2089-1-ji...@linux.alibaba.com/

BR,
Jin

> 
> Bring the comment "We don't have SI -> BF ..." inside the open curly and 
> indent it two more spaces.  That should be more consistent with GCC style.
> 
> So generally OK.  I suspect this can move forward once we figure out why 
> you added those cpp conditionals and fix the formatting nit.
> 
> jeff

Re:[PATCH] haifa-sched: Avoid the fusion priority of the fused insn to affect the subsequent insn sequence.

2024-06-06 Thread Jin Ma

I am very sorry that I did not check the commit information carefully. The 
statement is somewhat inaccurate.

> When the insn 1 and 2, 3 and 4 can be fusioned, then there is the
> following sequence:
> 
> ;;    insn |
> ;;      1  | sp=sp-0x18
> ;;  +   2  | [sp+0x10]=ra
> ;;      3  | [sp+0x8]=s0
> ;;      4  | [sp+0x0]=s1

> The fusion priority of the insn 2, 3, and 4 are the same. According to
> the current algorithm, since abs(0x10-0x8) is followed by the insn 3. It is obviously unreasonable to do so.
> 
> Therefore, when we issue the insn 3 and 4, we should consider the fusion
> priority of the insn 1 instead of the insn 2. And the final instruction
> sequence is as follows:

> ;;    insn |
> ;;      1  | sp=sp-0x18
> ;;  +   2  | [sp+0x10]=ra
> ;;      4  | [sp+0x8]=s1
> ;;  +   3  | [sp+0x0]=s0
> 
> gcc/ChangeLog:

>  * haifa-sched.cc (rank_for_schedule): Likewise.

When the insn 1 and 2, 4 and 3 can be fusioned, then there is the
following sequence:

;;    insn |
;;      1  | sp=sp-0x18
;;  +   2  | [sp+0x10]=ra
;;      3  | [sp+0x8]=s0
;;      4  | [sp+0x0]=s1

The fusion priority of the insn 2, 3, and 4 are the same. According to
the current algorithm, since abs(0x10-0x8)

[RE] [v2] RISC-V: Add Zfbfmin extension

2024-06-07 Thread Jin Ma
Hi,
 
Is there a plan to implement zvfbfmin and zvfbfwma? Or how can I get the 
relevant patches
in advance for testing? By the way, The LLVM seems to be fully implemented now 
:-)

Ref:

https://github.com/riscv-non-isa/rvv-intrinsic-doc/pull/293

https://github.com/riscv-non-isa/rvv-intrinsic-doc/blob/main/auto-generated/bfloat16/intrinsic_funcs.adoc



Thanks,
Jin


Re: [RE] [v2] RISC-V: Add Zfbfmin extension

2024-06-18 Thread Jin Ma

Hi, Feng
  Any new developments here on zvfbfmin and zvfbfwma?

BR,
Jin



















--
From:Fei Gao 
Send Time:2024 Jun. 7 (Fri.) 17:34
To:jinma; "gcc-patches"; 
zengxiao; wangfeng
Cc:jeffreyalaw; Kito Cheng; 
"juzhe.zhong"; "jinma.contrib"; 
jinma
Subject:Re: [RE] [v2] RISC-V: Add Zfbfmin extension







Hi Jin


We have completed zvfbfmin and zvfbfwma in GCC. 
Wang Feng will post after dragon boat festival. 


BR, 
Fei
From: Jin Ma
Date: 2024-06-07 15:35
To: gcc-patches; zengxiao
CC: jeffreyalaw; kito.cheng; juzhe.zhong; jinma.contrib; Jin Ma
Subject: [RE] [v2] RISC-V: Add Zfbfmin extension

Hi,
 
Is there a plan to implement zvfbfmin and zvfbfwma? Or how can I get the 
relevant patches
in advance for testing? By the way, The LLVM seems to be fully implemented now 
:-)
 
Ref:
 
https://github.com/riscv-non-isa/rvv-intrinsic-doc/pull/293
 
https://github.com/riscv-non-isa/rvv-intrinsic-doc/blob/main/auto-generated/bfloat16/intrinsic_funcs.adoc
 
 
 
Thanks,
Jin






Re: Re: [RE] [v2] RISC-V: Add Zfbfmin extension

2024-06-18 Thread Jin Ma

Great news, thanks for the quick reply.

BR,
Jin













--
From:wangf...@eswincomputing.com 
Send Time:2024 Jun. 19 (Wed.) 08:18
To:Jin Ma
Cc:"kito.cheng"; "juzhe.zhong"; 
"jinma.contrib"; 
zengxiao; "gcc-patches"; 
gaofei
Subject:Re: Re: [RE] [v2] RISC-V: Add Zfbfmin extension


Hi Jin,


Will submit patch after internal review,maybe today.


wangf...@eswincomputing.com

 
From: Jin Ma
Date: 2024-06-18 18:25
To: wangfeng
CC: Kito Cheng; juzhe.zhong; jinma.contrib; zengxiao; gcc-patches; Fei Gao
Subject: Re: [RE] [v2] RISC-V: Add Zfbfmin extension

 
Hi, Feng
  Any new developments here on zvfbfmin and zvfbfwma?
 
BR,
Jin
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--
From:Fei Gao 
Send Time:2024 Jun. 7 (Fri.) 17:34
To:jinma; "gcc-patches"; 
zengxiao; wangfeng
Cc:jeffreyalaw; Kito Cheng; 
"juzhe.zhong"; "jinma.contrib"; 
jinma
Subject:Re: [RE] [v2] RISC-V: Add Zfbfmin extension
 
 
 
 
 
 
 
Hi Jin
 
 
We have completed zvfbfmin and zvfbfwma in GCC. 
Wang Feng will post after dragon boat festival. 
 
 
BR, 
Fei
From: Jin Ma
Date: 2024-06-07 15:35
To: gcc-patches; zengxiao
CC: jeffreyalaw; kito.cheng; juzhe.zhong; jinma.contrib; Jin Ma
Subject: [RE] [v2] RISC-V: Add Zfbfmin extension
 
Hi,
 
Is there a plan to implement zvfbfmin and zvfbfwma? Or how can I get the 
relevant patches
in advance for testing? By the way, The LLVM seems to be fully implemented now 
:-)
 
Ref:
 
https://github.com/riscv-non-isa/rvv-intrinsic-doc/pull/293
 
https://github.com/riscv-non-isa/rvv-intrinsic-doc/blob/main/auto-generated/bfloat16/intrinsic_funcs.adoc
 
 
 
Thanks,
Jin
 
 
 
 






[PATCH] RISC-V: Delete duplicate '#define RISCV_DWARF_VLENB'

2024-08-03 Thread Jin Ma
gcc/ChangeLog:

* config/riscv/riscv.h (RISCV_DWARF_VLENB): Delete.
---
 gcc/config/riscv/riscv.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 6f040011864..74926f3f8ca 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -1234,8 +1234,6 @@ extern void riscv_remove_unneeded_save_restore_calls 
(void);
 
 #define REGMODE_NATURAL_SIZE(MODE) riscv_regmode_natural_size (MODE)
 
-#define RISCV_DWARF_VLENB (4096 + 0xc22)
-
 #define DWARF_FRAME_REGISTERS (FIRST_PSEUDO_REGISTER + 1 /* VLENB */)
 
 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) \
-- 
2.17.1



[PATCH] RISC-V: Fix ICE for vector single-width integer multiply-add intrinsics

2024-08-07 Thread Jin Ma
When rs1 is the immediate 0, the following ICE occurs:

error: unrecognizable insn:
(insn 8 5 12 2 (set (reg:RVVM1DI 134 [  ])
(if_then_else:RVVM1DI (unspec:RVVMF64BI [
(const_vector:RVVMF64BI repeat [
(const_int 1 [0x1])
])
(reg/v:DI 137 [ vl ])
(const_int 2 [0x2]) repeated x2
(const_int 0 [0])
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
(plus:RVVM1DI (mult:RVVM1DI (vec_duplicate:RVVM1DI (const_int 0 
[0]))
(reg/v:RVVM1DI 136 [ vs2 ]))
(reg/v:RVVM1DI 135 [ vd ]))
(reg/v:RVVM1DI 135 [ vd ])))

gcc/ChangeLog:

* config/riscv/vector.md: Allow scalar operand to be 0.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/bug-7.c: New test.
* gcc.target/riscv/rvv/base/bug-8.c: New test.
---
 gcc/config/riscv/vector.md| 80 +--
 .../gcc.target/riscv/rvv/base/bug-7.c | 26 ++
 .../gcc.target/riscv/rvv/base/bug-8.c | 26 ++
 3 files changed, 92 insertions(+), 40 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/bug-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/bug-8.c

diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index fb625f611d5..ab60a5bce32 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -5331,16 +5331,16 @@ (define_insn "*pred_madd_scalar"
  (plus:V_VLSI
(mult:V_VLSI
  (vec_duplicate:V_VLSI
-   (match_operand: 2 "register_operand" "  r,   r,  r,   r"))
+   (match_operand: 2 "reg_or_0_operand" " rJ,  rJ, rJ,  rJ"))
  (match_operand:V_VLSI 3 "register_operand"  "  0,  vr,  0,  
vr"))
(match_operand:V_VLSI 4 "register_operand"" vr,  vr, vr,  
vr"))
  (match_dup 3)))]
   "TARGET_VECTOR"
   "@
-   vmadd.vx\t%0,%2,%4%p1
-   vmv%m3r.v\t%0,%3\;vmadd.vx\t%0,%2,%4%p1
-   vmadd.vx\t%0,%2,%4%p1
-   vmv%m3r.v\t%0,%3\;vmadd.vx\t%0,%2,%4%p1"
+   vmadd.vx\t%0,%z2,%4%p1
+   vmv%m3r.v\t%0,%3\;vmadd.vx\t%0,%z2,%4%p1
+   vmadd.vx\t%0,%z2,%4%p1
+   vmv%m3r.v\t%0,%3\;vmadd.vx\t%0,%z2,%4%p1"
   [(set_attr "type" "vimuladd")
(set_attr "mode" "")
(set_attr "merge_op_idx" "3")
@@ -5363,16 +5363,16 @@ (define_insn "*pred_macc_scalar"
  (plus:V_VLSI
(mult:V_VLSI
  (vec_duplicate:V_VLSI
-   (match_operand: 2 "register_operand" "  r,   r,  r,   r"))
+   (match_operand: 2 "reg_or_0_operand" " rJ,  rJ, rJ,  rJ"))
  (match_operand:V_VLSI 3 "register_operand"  " vr,  vr, vr,  
vr"))
(match_operand:V_VLSI 4 "register_operand""  0,  vr,  0,  
vr"))
  (match_dup 4)))]
   "TARGET_VECTOR"
   "@
-   vmacc.vx\t%0,%2,%3%p1
-   vmv%m4r.v\t%0,%4\;vmacc.vx\t%0,%2,%3%p1
-   vmacc.vx\t%0,%2,%3%p1
-   vmv%m4r.v\t%0,%4\;vmacc.vx\t%0,%2,%3%p1"
+   vmacc.vx\t%0,%z2,%3%p1
+   vmv%m4r.v\t%0,%4\;vmacc.vx\t%0,%z2,%3%p1
+   vmacc.vx\t%0,%z2,%3%p1
+   vmv%m4r.v\t%0,%4\;vmacc.vx\t%0,%z2,%3%p1"
   [(set_attr "type" "vimuladd")
(set_attr "mode" "")
(set_attr "merge_op_idx" "4")
@@ -5431,16 +5431,16 @@ (define_insn "*pred_madd_extended_scalar"
(mult:V_VLSI_D
  (vec_duplicate:V_VLSI_D
(sign_extend:
- (match_operand: 2 "register_operand" "  r,   r,  r,   
r")))
+ (match_operand: 2 "reg_or_0_operand" " rJ,  rJ, rJ,  
rJ")))
  (match_operand:V_VLSI_D 3 "register_operand" "  0,  vr,  
0,  vr"))
(match_operand:V_VLSI_D 4 "register_operand"   " vr,  vr, 
vr,  vr"))
  (match_dup 3)))]
   "TARGET_VECTOR && !TARGET_64BIT"
   "@
-   vmadd.vx\t%0,%2,%4%p1
-   vmv%m2r.v\t%0,%2\;vmadd.vx\t%0,%2,%4%p1
-   vmadd.vx\t%0,%2,%4%p1
-   vmv%m2r.v\t%0,%2\;vmadd.vx\t%0,%2,%4%p1"
+   vmadd.vx\t%0,%z2,%4%p1
+   vmv%m2r.v\t%0,%z2\;vmadd.vx\t%0,%z2,%4%p1
+   vmadd.vx\t%0,%z2,%4%p1
+   vmv%m2r.v\t%0,%z2\;vmadd.vx\t%0,%z2,%4%p1"
   [(set_attr "type" "vimuladd")
(set_attr "mode" "")
(set_attr "merge_op_idx" "3")
@@ -5464,16 +5464,16 @@ (define_insn "*pred_macc_extended_scalar"
(mult:V_VLSI_D
  (vec_duplicate:V_VLSI_D
(sign_extend:
- (match_operand: 2 "register_operand" "  r,   r,  r,   
r")))
+ (match_operand: 2 "reg_or_0_operand" " rJ,  rJ, rJ,  
rJ")))
  (match_operand:V_VLSI_D 3 "register_operand" " vr,  vr, 
vr,  vr"))
(match_operand:V_VLSI_D 4 "register_operand"   "  0,  vr,  
0,  vr"))
  (match_dup 4)))]
   "TARGET_VECTOR && !TARGET_64BIT"
   "@
-   vmacc.vx\t%0,%2,%3%p1
-   vmv%m4r.v\t%0,%4\;vmacc.vx\t%0,%2,%3%p1
-   vmacc.vx\t%0,%2,%3%p1
-   vmv%m4r.v\t%0,%4\;vmacc.vx\t%0,%2,%3%p1"
+   vmacc.vx\t%0,%z2,%

[PATCH] RISC-V: Fix illegal operands "th.vsetvli zero, 0, e32, m8" for xtheadvector

2024-09-06 Thread Jin Ma
Since the THeadVector vsetvli does not support vl as an immediate, we
need to convert 0 to zero when outputting asm.

Ref:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116592

gcc/ChangeLog:

* config/riscv/thead.cc (th_asm_output_opcode): Change '0' to
"zero"

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/xtheadvector/bug-116592.c: New test.

Reported-by: nihui 
---
 gcc/config/riscv/thead.cc |  4 +--
 .../riscv/rvv/xtheadvector/bug-116592.c   | 36 +++
 2 files changed, 38 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/bug-116592.c

diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc
index 2f1d83fbbc7f..707d91076eb5 100644
--- a/gcc/config/riscv/thead.cc
+++ b/gcc/config/riscv/thead.cc
@@ -960,11 +960,11 @@ th_asm_output_opcode (FILE *asm_out_file, const char *p)
  if (strstr (p, "zero,zero"))
return "th.vsetvli\tzero,zero,e%0,%m1";
  else
-   return "th.vsetvli\tzero,%0,e%1,%m2";
+   return "th.vsetvli\tzero,%z0,e%1,%m2";
}
  else
{
- return "th.vsetvli\t%0,%1,e%2,%m3";
+ return "th.vsetvli\t%z0,%z1,e%2,%m3";
}
}
 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/bug-116592.c 
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/bug-116592.c
new file mode 100644
index ..937efbfd1b09
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/bug-116592.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zfh_xtheadvector -mabi=ilp32d -O2" { target { 
rv32 } } } */
+/* { dg-options "-march=rv64gc_zfh_xtheadvector -mabi=lp64d -O2" { target { 
rv64 } } } */
+
+#include 
+#include 
+
+static vfloat32m8_t atan2_ps(vfloat32m8_t a, vfloat32m8_t b, size_t vl)
+{
+  float tmpx[vl];
+  float tmpy[vl];
+  __riscv_vse32_v_f32m8(tmpx, a, vl);
+  __riscv_vse32_v_f32m8(tmpy, b, vl);
+  for (size_t i = 0; i < vl; i++)
+  {
+tmpx[i] = atan2(tmpx[i], tmpy[i]);
+  }
+  return __riscv_vle32_v_f32m8(tmpx, vl);
+}
+
+void my_atan2(const float *x, const float *y, float *out, int size)
+{
+  int n = size;
+  while (n > 0)
+  {
+size_t vl = __riscv_vsetvl_e32m8(n);
+vfloat32m8_t _x = __riscv_vle32_v_f32m8(x, vl);
+vfloat32m8_t _y = __riscv_vle32_v_f32m8(y, vl);
+vfloat32m8_t _out = atan2_ps(_x, _y, vl);
+__riscv_vse32_v_f32m8(out, _out, vl);
+n -= vl;
+x += vl;
+y += vl;
+out += vl;
+  }
+}
-- 
2.17.1



Re: [PATCH] RISC-V: Fix illegal operands "th.vsetvli zero, 0, e32, m8" for xtheadvector

2024-09-06 Thread Jin Ma
> See the "bug number" section of https://gcc.gnu.org/contribute.html for
> how to refer to a PR correctly, instead of putting an URL here.

I am very sorry to make this mistake, thank you for reminding me. I will make 
corrections.

BR
Jin

[PATCH v2] RISC-V: Fix illegal operands "th.vsetvli zero, 0, e32, m8" for XTheadVector

2024-09-06 Thread Jin Ma
Since the THeadVector vsetvli does not support vl as an immediate, we
need to convert 0 to zero when outputting asm.

PR target/116592

gcc/ChangeLog:

* config/riscv/thead.cc (th_asm_output_opcode): Change '0' to
"zero"

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/xtheadvector/pr116592.c: New test.

Reported-by: nihui 
---
 gcc/config/riscv/thead.cc |  4 +--
 .../riscv/rvv/xtheadvector/pr116592.c | 36 +++
 2 files changed, 38 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116592.c

diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc
index 2f1d83fbbc7f..707d91076eb5 100644
--- a/gcc/config/riscv/thead.cc
+++ b/gcc/config/riscv/thead.cc
@@ -960,11 +960,11 @@ th_asm_output_opcode (FILE *asm_out_file, const char *p)
  if (strstr (p, "zero,zero"))
return "th.vsetvli\tzero,zero,e%0,%m1";
  else
-   return "th.vsetvli\tzero,%0,e%1,%m2";
+   return "th.vsetvli\tzero,%z0,e%1,%m2";
}
  else
{
- return "th.vsetvli\t%0,%1,e%2,%m3";
+ return "th.vsetvli\t%z0,%z1,e%2,%m3";
}
}
 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116592.c 
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116592.c
new file mode 100644
index ..937efbfd1b09
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116592.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zfh_xtheadvector -mabi=ilp32d -O2" { target { 
rv32 } } } */
+/* { dg-options "-march=rv64gc_zfh_xtheadvector -mabi=lp64d -O2" { target { 
rv64 } } } */
+
+#include 
+#include 
+
+static vfloat32m8_t atan2_ps(vfloat32m8_t a, vfloat32m8_t b, size_t vl)
+{
+  float tmpx[vl];
+  float tmpy[vl];
+  __riscv_vse32_v_f32m8(tmpx, a, vl);
+  __riscv_vse32_v_f32m8(tmpy, b, vl);
+  for (size_t i = 0; i < vl; i++)
+  {
+tmpx[i] = atan2(tmpx[i], tmpy[i]);
+  }
+  return __riscv_vle32_v_f32m8(tmpx, vl);
+}
+
+void my_atan2(const float *x, const float *y, float *out, int size)
+{
+  int n = size;
+  while (n > 0)
+  {
+size_t vl = __riscv_vsetvl_e32m8(n);
+vfloat32m8_t _x = __riscv_vle32_v_f32m8(x, vl);
+vfloat32m8_t _y = __riscv_vle32_v_f32m8(y, vl);
+vfloat32m8_t _out = atan2_ps(_x, _y, vl);
+__riscv_vse32_v_f32m8(out, _out, vl);
+n -= vl;
+x += vl;
+y += vl;
+out += vl;
+  }
+}
-- 
2.17.1



Re: [PATCH v2] RISC-V: Fix illegal operands "th.vsetvli zero,0,e32,m8" for XTheadVector

2024-09-06 Thread Jin Ma
> I think it's better to add a "vsetvli" assembly check in testcase.

> juzhe.zh...@rivai.ai

Yeah, apparently I forgot to modify it  :)

Thanks.
Jin


[PATCH v3] RISC-V: Fix illegal operands "th.vsetvli zero, 0, e32, m8" for XTheadVector

2024-09-06 Thread Jin Ma
Since the THeadVector vsetvli does not support vl as an immediate, we
need to convert 0 to zero when outputting asm.

PR target/116592

gcc/ChangeLog:

* config/riscv/thead.cc (th_asm_output_opcode): Change '0' to
"zero"

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/xtheadvector/pr116592.c: New test.

Reported-by: nihui 
---
 gcc/config/riscv/thead.cc |  4 +--
 .../riscv/rvv/xtheadvector/pr116592.c | 36 +++
 2 files changed, 38 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116592.c

diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc
index 2f1d83fbbc7f..707d91076eb5 100644
--- a/gcc/config/riscv/thead.cc
+++ b/gcc/config/riscv/thead.cc
@@ -960,11 +960,11 @@ th_asm_output_opcode (FILE *asm_out_file, const char *p)
  if (strstr (p, "zero,zero"))
return "th.vsetvli\tzero,zero,e%0,%m1";
  else
-   return "th.vsetvli\tzero,%0,e%1,%m2";
+   return "th.vsetvli\tzero,%z0,e%1,%m2";
}
  else
{
- return "th.vsetvli\t%0,%1,e%2,%m3";
+ return "th.vsetvli\t%z0,%z1,e%2,%m3";
}
}
 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116592.c 
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116592.c
new file mode 100644
index ..1350f739c42a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116592.c
@@ -0,0 +1,36 @@
+/* { dg-do assemble } */
+/* { dg-options "-march=rv32gc_zfh_xtheadvector -mabi=ilp32d -O2" { target { 
rv32 } } } */
+/* { dg-options "-march=rv64gc_zfh_xtheadvector -mabi=lp64d -O2" { target { 
rv64 } } } */
+
+#include 
+#include 
+
+static vfloat32m8_t atan2_ps(vfloat32m8_t a, vfloat32m8_t b, size_t vl)
+{
+  float tmpx[vl];
+  float tmpy[vl];
+  __riscv_vse32_v_f32m8(tmpx, a, vl);
+  __riscv_vse32_v_f32m8(tmpy, b, vl);
+  for (size_t i = 0; i < vl; i++)
+  {
+tmpx[i] = atan2(tmpx[i], tmpy[i]);
+  }
+  return __riscv_vle32_v_f32m8(tmpx, vl);
+}
+
+void my_atan2(const float *x, const float *y, float *out, int size)
+{
+  int n = size;
+  while (n > 0)
+  {
+size_t vl = __riscv_vsetvl_e32m8(n);
+vfloat32m8_t _x = __riscv_vle32_v_f32m8(x, vl);
+vfloat32m8_t _y = __riscv_vle32_v_f32m8(y, vl);
+vfloat32m8_t _out = atan2_ps(_x, _y, vl);
+__riscv_vse32_v_f32m8(out, _out, vl);
+n -= vl;
+x += vl;
+y += vl;
+out += vl;
+  }
+}
-- 
2.17.1



[PATCH] RISC-V: Fixed incorrect semantic description in DF to DI pattern in the Zfa extension on rv32.

2024-09-06 Thread Jin Ma
In the process of DF to SI, we generally use "unsigned_fix" rather than
"truncate" for conversion. Although this has no effect in general,
unexpected ICE often occurs when precise semantic analysis is required,
such as analysis in function "simplify_const_unary_operation" in
simplify-rtx.cc.

gcc/ChangeLog:

* config/riscv/riscv.md: Change "truncate" to "unsigned_fix" for
the Zfa extension on rv32.
---
 gcc/config/riscv/riscv.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 9f94b5aa0232..36d7b333c456 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2627,7 +2627,7 @@ (define_insn "*movdf_softfloat"
 
 (define_insn "movsidf2_low_rv32"
   [(set (match_operand:SI  0 "register_operand" "=  r")
-   (truncate:SI
+   (unsigned_fix:SI
(match_operand:DF 1 "register_operand"  "zmvf")))]
   "TARGET_HARD_FLOAT && !TARGET_64BIT && TARGET_ZFA"
   "fmv.x.w\t%0,%1"
@@ -2638,7 +2638,7 @@ (define_insn "movsidf2_low_rv32"
 
 (define_insn "movsidf2_high_rv32"
   [(set (match_operand:SI  0 "register_operand""=  r")
-   (truncate:SI
+   (unsigned_fix:SI
 (lshiftrt:DF
 (match_operand:DF 1 "register_operand" "zmvf")
 (const_int 32]
-- 
2.17.1



Re: [PATCH] RISC-V: Fixed incorrect semantic description in DF to DI pattern in the Zfa extension on rv32.

2024-09-06 Thread Jin Ma
> Do you have a test case for this or does it fail already in the test suite?
>
> -- 
> Regards
>  Robin

Sorry, I'll try to write it.

BR
Jin

[PATCH v2] RISC-V: Fixed incorrect semantic description in DF to DI pattern in the Zfa extension on rv32.

2024-09-06 Thread Jin Ma
In the process of DF to SI, we generally use "unsigned_fix" rather than
"truncate" for conversion. Although this has no effect in general,
unexpected ICE often occurs when precise semantic analysis is required.

gcc/ChangeLog:

* config/riscv/riscv.md:  Change "truncate" to "unsigned_fix" for
the Zfa extension on rv32.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/zfa-fmovh-fmovp-bug.c: New test.
---
 gcc/config/riscv/riscv.md| 4 ++--
 gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-bug.c | 9 +
 2 files changed, 11 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-bug.c

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 9f94b5aa0232..36d7b333c456 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2627,7 +2627,7 @@ (define_insn "*movdf_softfloat"
 
 (define_insn "movsidf2_low_rv32"
   [(set (match_operand:SI  0 "register_operand" "=  r")
-   (truncate:SI
+   (unsigned_fix:SI
(match_operand:DF 1 "register_operand"  "zmvf")))]
   "TARGET_HARD_FLOAT && !TARGET_64BIT && TARGET_ZFA"
   "fmv.x.w\t%0,%1"
@@ -2638,7 +2638,7 @@ (define_insn "movsidf2_low_rv32"
 
 (define_insn "movsidf2_high_rv32"
   [(set (match_operand:SI  0 "register_operand""=  r")
-   (truncate:SI
+   (unsigned_fix:SI
 (lshiftrt:DF
 (match_operand:DF 1 "register_operand" "zmvf")
 (const_int 32]
diff --git a/gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-bug.c 
b/gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-bug.c
new file mode 100644
index ..e00047b09e3a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-bug.c
@@ -0,0 +1,9 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zfa -mabi=ilp32d -O2 -g" } */
+
+unsigned int
+foo (double a) {
+  unsigned int tt = *(unsigned long long *)&a & 0x;
+  return tt;
+}
-- 
2.17.1



[PATCH] RISC-V: Fix ICE for rvv in lto

2024-09-06 Thread Jin Ma
When we use flto, the function list of rvv will be generated twice,
once in the cc1 phase and once in the lto phase. However, due to
the different generation methods, the two lists are different.

For example, when there is no zvfh or zvfhmin in arch, it is
generated by calling function "riscv_pragma_intrinsic". since the
TARGET_VECTOR_ELEN_FP_16 is enabled before rvv function generation,
a list of rvv functions related to float16 will be generated. In
the lto phase, the rvv function list is generated only by calling
the function "riscv_init_builtins", but the TARGET_VECTOR_ELEN_FP_16
is disabled, so that the float16-related rvv function list cannot
be generated like cc1. This will cause confusion, resulting in
matching tothe wrong function due to inconsistent fcode in the lto
phase, eventually leading to ICE.

So I think we should be consistent with their generated lists, which
is exactly what this patch does.

But there is still a problem here. If we use "-fchecking", we still
have ICE. This is because in the lto phase, after the rvv function
list is generated and before the expand_builtin, the ggc_grow will
be called to clean up the memory, resulting in
"(* registered_functions)[code]->decl" being cleaned up to
", and finally ICE".

I think this is wrong and needs to be fixed, maybe we shouldn't
use "ggc_alloc ()", or is there another better
way to implement it?

I'm trying to fix it here. Any comments here?

gcc/ChangeLog:

* config/riscv/riscv-c.cc (struct pragma_intrinsic_flags): Mov
to riscv-protos.h.
(riscv_pragma_intrinsic_flags_pollute): Mov to riscv-vector-builtins.c.
(riscv_pragma_intrinsic_flags_restore): Likewise.
(riscv_pragma_intrinsic): Likewise.
* config/riscv/riscv-protos.h (struct pragma_intrinsic_flags):
New.
(riscv_pragma_intrinsic_flags_restore): New.
(riscv_pragma_intrinsic_flags_pollute): New.
* config/riscv/riscv-vector-builtins.cc 
(riscv_pragma_intrinsic_flags_pollute): New.
(riscv_pragma_intrinsic_flags_restore): New.
(handle_pragma_vector_for_lto): New.
(init_builtins): Correct the processing logic for lto.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/bug-10.c: New test.
---
 gcc/config/riscv/riscv-c.cc   | 70 +---
 gcc/config/riscv/riscv-protos.h   | 13 +++
 gcc/config/riscv/riscv-vector-builtins.cc | 83 ++-
 .../gcc.target/riscv/rvv/base/bug-10.c| 18 
 4 files changed, 114 insertions(+), 70 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/bug-10.c

diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
index 71112d9c66d7..7037ecc1268a 100644
--- a/gcc/config/riscv/riscv-c.cc
+++ b/gcc/config/riscv/riscv-c.cc
@@ -34,72 +34,6 @@ along with GCC; see the file COPYING3.  If not see
 
 #define builtin_define(TXT) cpp_define (pfile, TXT)
 
-struct pragma_intrinsic_flags
-{
-  int intrinsic_target_flags;
-
-  int intrinsic_riscv_vector_elen_flags;
-  int intrinsic_riscv_zvl_flags;
-  int intrinsic_riscv_zvb_subext;
-  int intrinsic_riscv_zvk_subext;
-};
-
-static void
-riscv_pragma_intrinsic_flags_pollute (struct pragma_intrinsic_flags *flags)
-{
-  flags->intrinsic_target_flags = target_flags;
-  flags->intrinsic_riscv_vector_elen_flags = riscv_vector_elen_flags;
-  flags->intrinsic_riscv_zvl_flags = riscv_zvl_flags;
-  flags->intrinsic_riscv_zvb_subext = riscv_zvb_subext;
-  flags->intrinsic_riscv_zvk_subext = riscv_zvk_subext;
-
-  target_flags = target_flags
-| MASK_VECTOR;
-
-  riscv_zvl_flags = riscv_zvl_flags
-| MASK_ZVL32B
-| MASK_ZVL64B
-| MASK_ZVL128B;
-
-  riscv_vector_elen_flags = riscv_vector_elen_flags
-| MASK_VECTOR_ELEN_32
-| MASK_VECTOR_ELEN_64
-| MASK_VECTOR_ELEN_FP_16
-| MASK_VECTOR_ELEN_FP_32
-| MASK_VECTOR_ELEN_FP_64;
-
-  riscv_zvb_subext = riscv_zvb_subext
-| MASK_ZVBB
-| MASK_ZVBC
-| MASK_ZVKB;
-
-  riscv_zvk_subext = riscv_zvk_subext
-| MASK_ZVKG
-| MASK_ZVKNED
-| MASK_ZVKNHA
-| MASK_ZVKNHB
-| MASK_ZVKSED
-| MASK_ZVKSH
-| MASK_ZVKN
-| MASK_ZVKNC
-| MASK_ZVKNG
-| MASK_ZVKS
-| MASK_ZVKSC
-| MASK_ZVKSG
-| MASK_ZVKT;
-}
-
-static void
-riscv_pragma_intrinsic_flags_restore (struct pragma_intrinsic_flags *flags)
-{
-  target_flags = flags->intrinsic_target_flags;
-
-  riscv_vector_elen_flags = flags->intrinsic_riscv_vector_elen_flags;
-  riscv_zvl_flags = flags->intrinsic_riscv_zvl_flags;
-  riscv_zvb_subext = flags->intrinsic_riscv_zvb_subext;
-  riscv_zvk_subext = flags->intrinsic_riscv_zvk_subext;
-}
-
 static int
 riscv_ext_version_value (unsigned major, unsigned minor)
 {
@@ -269,14 +203,14 @@ riscv_pragma_intrinsic (cpp_reader *)
 {
   struct pragma_intrinsic_flags backup_flags;
 
-  riscv_pragma_intrinsic_flags_pollute (&backup_flags);
+  riscv_vector::riscv_pragma_intrinsic_flags_pollute (&backup_flags);
 
  

[PATCH v4] RISC-V: Fix illegal operands "th.vsetvli zero, 0, e32, m8" for XTheadVector

2024-09-06 Thread Jin Ma
Since the THeadVector vsetvli does not support vl as an immediate, we
need to convert 0 to zero when outputting asm.

PR target/116592

gcc/ChangeLog:

* config/riscv/thead.cc (th_asm_output_opcode): Change '0' to
"zero"

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/xtheadvector/pr116592.c: New test.

Reported-by: nihui 
---
 gcc/config/riscv/thead.cc |  4 +-
 .../riscv/rvv/xtheadvector/pr116592.c | 38 +++
 2 files changed, 40 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116592.c

diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc
index 2f1d83fbbc7f..707d91076eb5 100644
--- a/gcc/config/riscv/thead.cc
+++ b/gcc/config/riscv/thead.cc
@@ -960,11 +960,11 @@ th_asm_output_opcode (FILE *asm_out_file, const char *p)
  if (strstr (p, "zero,zero"))
return "th.vsetvli\tzero,zero,e%0,%m1";
  else
-   return "th.vsetvli\tzero,%0,e%1,%m2";
+   return "th.vsetvli\tzero,%z0,e%1,%m2";
}
  else
{
- return "th.vsetvli\t%0,%1,e%2,%m3";
+ return "th.vsetvli\t%z0,%z1,e%2,%m3";
}
}
 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116592.c 
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116592.c
new file mode 100644
index ..a7cd8c5bdb72
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116592.c
@@ -0,0 +1,38 @@
+/* { dg-do assemble } */
+/* { dg-options "-march=rv32gc_zfh_xtheadvector -mabi=ilp32d -O2 -save-temps" 
{ target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zfh_xtheadvector -mabi=lp64d -O2 -save-temps" { 
target { rv64 } } } */
+
+#include 
+#include 
+
+static vfloat32m8_t atan2_ps(vfloat32m8_t a, vfloat32m8_t b, size_t vl)
+{
+  float tmpx[vl];
+  float tmpy[vl];
+  __riscv_vse32_v_f32m8(tmpx, a, vl);
+  __riscv_vse32_v_f32m8(tmpy, b, vl);
+  for (size_t i = 0; i < vl; i++)
+  {
+tmpx[i] = atan2(tmpx[i], tmpy[i]);
+  }
+  return __riscv_vle32_v_f32m8(tmpx, vl);
+}
+
+void my_atan2(const float *x, const float *y, float *out, int size)
+{
+  int n = size;
+  while (n > 0)
+  {
+size_t vl = __riscv_vsetvl_e32m8(n);
+vfloat32m8_t _x = __riscv_vle32_v_f32m8(x, vl);
+vfloat32m8_t _y = __riscv_vle32_v_f32m8(y, vl);
+vfloat32m8_t _out = atan2_ps(_x, _y, vl);
+__riscv_vse32_v_f32m8(out, _out, vl);
+n -= vl;
+x += vl;
+y += vl;
+out += vl;
+  }
+}
+
+/* { dg-final { scan-assembler-not {th\.vsetvli\s+zero,0} } } */
-- 
2.17.1



Re: [PATCH v3] RISC-V: Fix illegal operands "th.vsetvli zero,0,e32,m8" for XTheadVector

2024-09-06 Thread Jin Ma

> Sorry, I still don't see assembly check.

I am very sorry, I uploaded the wrong patch and I tried to correct it :)

By the way, there seems to be no exp here to really test the XTheadVector test 
cases,
which may have been missed when the XTheadVector extension was first 
implemented.

Maybe I should write one for that.

BR
Jin

Re: [PATCH] RISC-V: Fix ICE for rvv in lto

2024-09-07 Thread Jin Ma
> > +/* Test that we do not have ice when compile */
> > +
> > +/* { dg-do run } */
> > +/* { dg-options "-march=rv64gcv -mabi=lp64d -mrvv-vector-bits=zvl -flto 
> > -O2 -fno-checking" } */
> > +
> > +#include 
> > +
> > +int
> > +main ()
> > +{
> > +  size_t vl = 8;
> > +  vint32m1_t vs1 = {};
> > +  vint32m1_t vs2 = {};
> > +
> > +  __volatile__ vint32m1_t vd = __riscv_vadd_vv_i32m1(vs1, vs2, vl);
> > +
> > +  return 0;
> > +}
> 
> Interesting, do we still have ice when there is no __voltaile__ for vd? As 
> well as gcc-14 branch.
> Because it is quite a common case that should be covered by test already.
> 
> Pan

Yes, I am also surprised that this kind of ICE will appear. It really should be 
covered by
test cases. But in fact, if we do not use zvfh or zvfhmin in arch, rvv cannot 
be used in LTO.

This has nothing to do with "__voltaile__". "__voltaile__" in the case is just 
that I want it
to be compiled to the end and not optimized.

In fact, a simple case can reproduce ICE, including gcc-14 and master, for 
example:

#include 

vint32m1_t foo(vint32m1_t vs1, vint32m1_t vs2, size_t vl) 
{
  return __riscv_vadd_vv_i32m1(vs1, vs2, vl);
}

If we compile this case with the option " -march=rv64gcv -mabi=lp64d  -flto 
-O0", we will
get the following error:

during RTL pass: expand
../test.c: In function 'foo':
../test.c:5:10: internal compiler error: tree check: expected tree that 
contains 'typed' structure, have 'ggc_freed' in function_returns_void_p, at 
config/riscv/riscv-vector-builtins.h:456
5 |   return __riscv_vadd_vv_i32m1(vs1, vs2, vl);
  |  ^
0x4081948 internal_error(char const*, ...)
/iothome/jin.ma/code/master/gcc/gcc/diagnostic-global-context.cc:492
0x1dc584d tree_contains_struct_check_failed(tree_node const*, 
tree_node_structure_enum, char const*, int, char const*)
/iothome/jin.ma/code/master/gcc/gcc/tree.cc:9177
0x10d8230 contains_struct_check(tree_node*, tree_node_structure_enum, char 
const*, int, char const*)
/iothome/jin.ma/code/master/gcc/gcc/tree.h:3779
0x2078f0c riscv_vector::function_call_info::function_returns_void_p()

/iothome/jin.ma/code/master/gcc/gcc/config/riscv/riscv-vector-builtins.h:456
0x2074f54 
riscv_vector::function_expander::function_expander(riscv_vector::function_instance
 const&, tree_node*, tree_node*, rtx_def*)

/iothome/jin.ma/code/master/gcc/gcc/config/riscv/riscv-vector-builtins.cc:3920
0x20787b8 riscv_vector::expand_builtin(unsigned int, tree_node*, rtx_def*)

/iothome/jin.ma/code/master/gcc/gcc/config/riscv/riscv-vector-builtins.cc:4775
0x2029b60 riscv_expand_builtin(tree_node*, rtx_def*, rtx_def*, machine_mode, 
int)
/iothome/jin.ma/code/master/gcc/gcc/config/riscv/riscv-builtins.cc:433
0x1167cb7 expand_builtin(tree_node*, rtx_def*, rtx_def*, machine_mode, int)
/iothome/jin.ma/code/master/gcc/gcc/builtins.cc:7763
0x137e5d2 expand_expr_real_1(tree_node*, rtx_def*, machine_mode, 
expand_modifier, rtx_def**, bool)
/iothome/jin.ma/code/master/gcc/gcc/expr.cc:12390
0x1370068 expand_expr_real(tree_node*, rtx_def*, machine_mode, expand_modifier, 
rtx_def**, bool)
/iothome/jin.ma/code/master/gcc/gcc/expr.cc:9473
0x136434a store_expr(tree_node*, rtx_def*, int, bool, bool)
/iothome/jin.ma/code/master/gcc/gcc/expr.cc:6766
0x13629e3 expand_assignment(tree_node*, tree_node*, bool)
/iothome/jin.ma/code/master/gcc/gcc/expr.cc:6487
0x11a8419 expand_call_stmt
/iothome/jin.ma/code/master/gcc/gcc/cfgexpand.cc:2893
0x11ac48e expand_gimple_stmt_1
/iothome/jin.ma/code/master/gcc/gcc/cfgexpand.cc:3962
0x11acaad expand_gimple_stmt
/iothome/jin.ma/code/master/gcc/gcc/cfgexpand.cc:4104
0x11b55a1 expand_gimple_basic_block
/iothome/jin.ma/code/master/gcc/gcc/cfgexpand.cc:6160
0x11b7b96 execute
/iothome/jin.ma/code/master/gcc/gcc/cfgexpand.cc:6899
Please submit a full bug report, with preprocessed source (by using 
-freport-bug).
Please include the complete backtrace with any bug report.
See  for instructions.
lto-wrapper: fatal error: riscv64-unknown-linux-gnu-gcc returned 1 exit status
compilation terminated.
/mnt/ssd/jin.ma/install/master/bin/../lib/gcc/riscv64-unknown-linux-gnu/15.0.0/../../../../riscv64-unknown-linux-gnu/bin/ld:
 error: lto-wrapper failed
collect2: error: ld returned 1 exit status

This patch tried to fix it, but it didn't fix it completely. If we use 
"-fchecking", we still
have ICE. This has to do with function ggc_grow in the LTO phase. Maybe the fix 
for this ICE
is that we use something like "malloc" instead of "ggc_alloc" for 
"registered_functions",
I'm not sure there is a better way.

If this is a problem and needs to be fixed, I am happy to try to solve it.


Re: [PATCH] RISC-V: Fix ICE for rvv in lto

2024-09-07 Thread Jin Ma
> > #include 
> > 
> > vint32m1_t foo(vint32m1_t vs1, vint32m1_t vs2, size_t vl) 
> > {
> >   return __riscv_vadd_vv_i32m1(vs1, vs2, vl);
> > }
> 
> To double confirm, you mean "riscv64-linux-gnu-gcc-14 -march=rv64gcv 
> -mabi=lp64d -flto -O0 tmp.c -c -S -o -" with above is able to reproduce this 
> ICE?
> 
> Pan

Not too accurate, please don't add "-S" or "-c", let the compilation go to the 
linker and try to generate the binary.
The normal result of compilation should be to throw an error that the main 
function cannot be found, but unfortunately
ICE appears.

By the way, The gcc-14 in my environment is built on releases/gcc-14, I didn't 
download any compiled gcc.

Of course, it is also possible that my local environment is broken, and I will 
check it again.

BR
Jin

Re: [PATCH v2] RISC-V: Fixed incorrect semantic description in DF to DI pattern in the Zfa extension on rv32.

2024-09-08 Thread Jin Ma
> Having matching pattern for these Zfa moves seems pointless because
> the optimization that utilizes the instructions in
> riscv_split_doubleword_move() uses:
> gen_movdfsisi3_rv32(), gen_movsidf2_low_rv32() and gen_movsidf2_high_rv32().
> In the XTheadFmv pattern, we use unspec, so the pattern won't match.
> I think this should be done for Zfa as well.

Yes, that's a very good suggestion. I will try.

Thanks.
Jin


Re: [PATCH] RISC-V: Fix ICE for rvv in lto

2024-09-09 Thread Jin Ma
> > I think this is wrong and needs to be fixed, maybe we shouldn't
> > use "ggc_alloc ()", or is there another better
> > way to implement it?
> 
> From the root we're marking the registered_functions vector via
> the
> 
> template
> void
> gt_ggc_mx (vec *v)
> 
> overload which will eventually mark registered_function * but since
> you do not provide a gt_ggc_mx overload for the pointer type
> this pointer will _not_ be marked.

Very helpful guide, I will try to fix it.

BR,
Jin


[PATCH v3] RISC-V: Fixed incorrect semantic description in DF to DI pattern in the Zfa extension on rv32.

2024-09-09 Thread Jin Ma
gcc/ChangeLog:

* config/riscv/riscv.md: Change "truncate" to unspec for the Zfa 
extension on rv32.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/zfa-fmovh-fmovp-bug.c: New test.
---
 gcc/config/riscv/riscv.md| 16 +---
 .../gcc.target/riscv/zfa-fmovh-fmovp-bug.c   |  9 +
 2 files changed, 18 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-bug.c

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 9f94b5aa0232..13b360d6a701 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -56,6 +56,8 @@ (define_c_enum "unspec" [
   UNSPEC_FLT_QUIET
   UNSPEC_FLE_QUIET
   UNSPEC_COPYSIGN
+  UNSPEC_FMV_X_W
+  UNSPEC_FMVH_X_D
   UNSPEC_RINT
   UNSPEC_ROUND
   UNSPEC_FLOOR
@@ -2627,8 +2629,9 @@ (define_insn "*movdf_softfloat"
 
 (define_insn "movsidf2_low_rv32"
   [(set (match_operand:SI  0 "register_operand" "=  r")
-   (truncate:SI
-   (match_operand:DF 1 "register_operand"  "zmvf")))]
+   (unspec:SI
+   [(match_operand:DF 1 "register_operand" "zmvf")]
+   UNSPEC_FMV_X_W))]
   "TARGET_HARD_FLOAT && !TARGET_64BIT && TARGET_ZFA"
   "fmv.x.w\t%0,%1"
   [(set_attr "move_type" "fmove")
@@ -2637,11 +2640,10 @@ (define_insn "movsidf2_low_rv32"
 
 
 (define_insn "movsidf2_high_rv32"
-  [(set (match_operand:SI  0 "register_operand""=  r")
-   (truncate:SI
-(lshiftrt:DF
-(match_operand:DF 1 "register_operand" "zmvf")
-(const_int 32]
+  [(set (match_operand:SI  0 "register_operand" "=  r")
+   (unspec:SI
+   [(match_operand:DF 1 "register_operand" "zmvf")]
+   UNSPEC_FMVH_X_D))]
   "TARGET_HARD_FLOAT && !TARGET_64BIT && TARGET_ZFA"
   "fmvh.x.d\t%0,%1"
   [(set_attr "move_type" "fmove")
diff --git a/gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-bug.c 
b/gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-bug.c
new file mode 100644
index ..e00047b09e3a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-bug.c
@@ -0,0 +1,9 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zfa -mabi=ilp32d -O2 -g" } */
+
+unsigned int
+foo (double a) {
+  unsigned int tt = *(unsigned long long *)&a & 0x;
+  return tt;
+}
-- 
2.17.1



Re: [PATCH] RISC-V: Fix ICE for rvv in lto

2024-09-09 Thread Jin Ma
> I see, I can reproduce this when build "-march=rv64gcv -mabi=lp64d -flto -O0 
> test.c -o test.elf".
> 
> #include 
> 
> int
> main ()
> {
>   size_t vl = 8;
>   vint32m1_t vs1 = {};
>   vint32m1_t vs2 = {};
>   vint32m1_t vd = __riscv_vadd_vv_i32m1(vs1, vs2, vl);
> 
>   return (int)&vd;
> }
> 
> Pan

Hi, Pan

Any comments on this patch?

I think this patch is quite important, because RVV is completely unavailable on 
LTO at
present. In fact, I discovered this ICE while trying to compile some 
computational
libraries using LTO. Unfortunately, none of the libraries currently compile 
through
properly.

BR
Jin


[PATCH v2 1/2] RISC-V: Fix ICE caused by early ggc_free on DECL for RVV intrinsics in LTO.

2024-09-09 Thread Jin Ma
gcc/ChangeLog:

* config/riscv/riscv-vector-builtins.cc 
(function_builder::add_function):
Check the final DECl to make sure it is valid.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/bug-10.c: New test.
---
 gcc/config/riscv/riscv-vector-builtins.cc   |  9 +++--
 .../gcc.target/riscv/rvv/base/bug-10.c  | 17 +
 2 files changed, 24 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/bug-10.c

diff --git a/gcc/config/riscv/riscv-vector-builtins.cc 
b/gcc/config/riscv/riscv-vector-builtins.cc
index 41730c483ee1..0176670fbdf2 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -79,7 +79,7 @@ public:
   function_instance GTY ((skip)) instance;
 
   /* The decl itself.  */
-  tree GTY ((skip)) decl;
+  tree decl;
 
   /* The overload hash of non-overloaded intrinsic is determined by
  the overload name and argument list. Adding the overload name to
@@ -3771,7 +3771,6 @@ function_builder::add_function (const function_instance 
&instance,
 {
   unsigned int code = vec_safe_length (registered_functions);
   code = (code << RISCV_BUILTIN_SHIFT) + RISCV_BUILTIN_VECTOR;
-
   /* We need to be able to generate placeholders to ensure that we have a
  consistent numbering scheme for function codes between the C and C++
  frontends, so that everything ties up in LTO.
@@ -3790,6 +3789,12 @@ function_builder::add_function (const function_instance 
&instance,
: simulate_builtin_function_decl (input_location, name, fntype,
  code, NULL, attrs);
 
+  /* If the code of DECL is ERROR_MARK or invalid code, usually "ggc_freed", we
+ use integer_zero_node instead of it. This will be very helpful for the
+ ggc_free.  */
+  if (TREE_CODE (decl) == ERROR_MARK || TREE_CODE (decl) >= MAX_TREE_CODES)
+decl = integer_zero_node;
+
   registered_function &rfn = *ggc_alloc ();
   rfn.instance = instance;
   rfn.decl = decl;
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/bug-10.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-10.c
new file mode 100644
index ..f685792a2c65
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-10.c
@@ -0,0 +1,17 @@
+/* Test that we do not have ice when compile */
+/* { dg-do link } */
+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d -O2 -flto"  { target { rv64 } 
} } */
+/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32d -O2 -flto"  { target { rv32 
} } } */
+
+ #include 
+
+int
+main ()
+{
+  size_t vl = 8;
+  vint32m1_t vs1 = {};
+  vint32m1_t vs2 = {};
+  vint32m1_t vd = __riscv_vadd_vv_i32m1(vs1, vs2, vl);
+ 
+  return *(int*)&vd;
+}
-- 
2.17.1



[PATCH v2 2/2] RISC-V: Fix ICE due to inconsistency of RVV intrinsic list in lto and cc1.

2024-09-09 Thread Jin Ma
When we use flto, the function list of rvv will be generated twice,
once in the cc1 phase and once in the lto phase. However, due to
the different generation methods, the two lists are different.

For example, when there is no zvfh or zvfhmin in arch, it is
generated by calling function "riscv_pragma_intrinsic". since the
TARGET_VECTOR_ELEN_FP_16 is enabled before rvv function generation,
a list of rvv functions related to float16 will be generated. In
the lto phase, the rvv function list is generated only by calling
the function "riscv_init_builtins", but the TARGET_VECTOR_ELEN_FP_16
is disabled, so that the float16-related rvv function list cannot
be generated like cc1. This will cause confusion, resulting in
matching tothe wrong function due to inconsistent fcode in the lto
phase, eventually leading to ICE.

So I think we should be consistent with their generated lists, which
is exactly what this patch does.

gcc/ChangeLog:

* config/riscv/riscv-c.cc (struct pragma_intrinsic_flags): Mov
to riscv-protos.h.
(riscv_pragma_intrinsic_flags_pollute): Mov to riscv-vector-builtins.c.
(riscv_pragma_intrinsic_flags_restore): Likewise.
(riscv_pragma_intrinsic): Likewise.
* config/riscv/riscv-protos.h (struct pragma_intrinsic_flags):
New.
(riscv_pragma_intrinsic_flags_restore): New.
(riscv_pragma_intrinsic_flags_pollute): New.
* config/riscv/riscv-vector-builtins.cc 
(riscv_pragma_intrinsic_flags_pollute): New.
(riscv_pragma_intrinsic_flags_restore): New.
(handle_pragma_vector_for_lto): New.
(init_builtins): Correct the processing logic for lto.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/bug-11.c: New test.
---
 gcc/config/riscv/riscv-c.cc   | 70 +--
 gcc/config/riscv/riscv-protos.h   | 13 
 gcc/config/riscv/riscv-vector-builtins.cc | 83 ++-
 3 files changed, 96 insertions(+), 70 deletions(-)

diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
index 71112d9c66d7..7037ecc1268a 100644
--- a/gcc/config/riscv/riscv-c.cc
+++ b/gcc/config/riscv/riscv-c.cc
@@ -34,72 +34,6 @@ along with GCC; see the file COPYING3.  If not see
 
 #define builtin_define(TXT) cpp_define (pfile, TXT)
 
-struct pragma_intrinsic_flags
-{
-  int intrinsic_target_flags;
-
-  int intrinsic_riscv_vector_elen_flags;
-  int intrinsic_riscv_zvl_flags;
-  int intrinsic_riscv_zvb_subext;
-  int intrinsic_riscv_zvk_subext;
-};
-
-static void
-riscv_pragma_intrinsic_flags_pollute (struct pragma_intrinsic_flags *flags)
-{
-  flags->intrinsic_target_flags = target_flags;
-  flags->intrinsic_riscv_vector_elen_flags = riscv_vector_elen_flags;
-  flags->intrinsic_riscv_zvl_flags = riscv_zvl_flags;
-  flags->intrinsic_riscv_zvb_subext = riscv_zvb_subext;
-  flags->intrinsic_riscv_zvk_subext = riscv_zvk_subext;
-
-  target_flags = target_flags
-| MASK_VECTOR;
-
-  riscv_zvl_flags = riscv_zvl_flags
-| MASK_ZVL32B
-| MASK_ZVL64B
-| MASK_ZVL128B;
-
-  riscv_vector_elen_flags = riscv_vector_elen_flags
-| MASK_VECTOR_ELEN_32
-| MASK_VECTOR_ELEN_64
-| MASK_VECTOR_ELEN_FP_16
-| MASK_VECTOR_ELEN_FP_32
-| MASK_VECTOR_ELEN_FP_64;
-
-  riscv_zvb_subext = riscv_zvb_subext
-| MASK_ZVBB
-| MASK_ZVBC
-| MASK_ZVKB;
-
-  riscv_zvk_subext = riscv_zvk_subext
-| MASK_ZVKG
-| MASK_ZVKNED
-| MASK_ZVKNHA
-| MASK_ZVKNHB
-| MASK_ZVKSED
-| MASK_ZVKSH
-| MASK_ZVKN
-| MASK_ZVKNC
-| MASK_ZVKNG
-| MASK_ZVKS
-| MASK_ZVKSC
-| MASK_ZVKSG
-| MASK_ZVKT;
-}
-
-static void
-riscv_pragma_intrinsic_flags_restore (struct pragma_intrinsic_flags *flags)
-{
-  target_flags = flags->intrinsic_target_flags;
-
-  riscv_vector_elen_flags = flags->intrinsic_riscv_vector_elen_flags;
-  riscv_zvl_flags = flags->intrinsic_riscv_zvl_flags;
-  riscv_zvb_subext = flags->intrinsic_riscv_zvb_subext;
-  riscv_zvk_subext = flags->intrinsic_riscv_zvk_subext;
-}
-
 static int
 riscv_ext_version_value (unsigned major, unsigned minor)
 {
@@ -269,14 +203,14 @@ riscv_pragma_intrinsic (cpp_reader *)
 {
   struct pragma_intrinsic_flags backup_flags;
 
-  riscv_pragma_intrinsic_flags_pollute (&backup_flags);
+  riscv_vector::riscv_pragma_intrinsic_flags_pollute (&backup_flags);
 
   riscv_option_override ();
   init_adjust_machine_modes ();
   riscv_vector::reinit_builtins ();
   riscv_vector::handle_pragma_vector ();
 
-  riscv_pragma_intrinsic_flags_restore (&backup_flags);
+  riscv_vector::riscv_pragma_intrinsic_flags_restore (&backup_flags);
 
   /* Re-initialize after the flags are restored.  */
   riscv_option_override ();
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 3358e3887b95..651df2310da6 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -102,6 +102,15 @@ struct riscv_address_info {
   int shift;
 

Re: [PATCH v2 1/2] RISC-V: Fix ICE caused by early ggc_free on DECL for RVV intrinsics in LTO.

2024-09-10 Thread Jin Ma
> > +  /* If the code of DECL is ERROR_MARK or invalid code, usually 
> > "ggc_freed", we
> > + use integer_zero_node instead of it. This will be very helpful for the
> > + ggc_free.  */
> > +  if (TREE_CODE (decl) == ERROR_MARK || TREE_CODE (decl) >= MAX_TREE_CODES)
> > +decl = integer_zero_node;
> > +
> 
> ... this one looks like a hack (note ggc_free only poisons memory when
> checking is enabled).

Hi, I just built the compiler with "--enable-multilib" from riscv-gnu-toolchain 
source,
and it seems to have "CHECKING_P"/"ENABLE_EXTRA_CHECKING" on by default, 
resulting in
"flag_checking=2".

I haven't located it in detail, so I'm not sure if it is.

> I'm curious why you ever get a ggc_freed decl here.

It seems that the overloaded interface of RVV has been registered repeatedly, 
resulting
in invalid registrations except for the first registration, and these invalid 
registrations
have been ggc_freed. But anyway, I think it is necessary to do a check here. I 
think using
"integer_zero_node" is to meet the needs, although direct return would be 
better.

BR
Jin


Re: [PATCH v2 1/2] RISC-V: Fix ICE caused by early ggc_free on DECL for RVV intrinsics in LTO.

2024-09-11 Thread Jin Ma
> > > I'm curious why you ever get a ggc_freed decl here.
> >
> > It seems that the overloaded interface of RVV has been registered 
> > repeatedly, resulting
> > in invalid registrations except for the first registration, and these 
> > invalid registrations
> > have been ggc_freed. But anyway, I think it is necessary to do a check 
> > here. I think using
> > "integer_zero_node" is to meet the needs, although direct return would be 
> > better.
> 
> But there isn't any way to check whether 'decl' has been freed ...
> just make sure it isn't - you
> should not even have a reference to it.
> Richard.

I'm trying to understand what you mean. You mean that directly using 
"integer_zero_node" to
overwrite decl will not guarantee whether the memory of the original decl has 
been properly
cleaned up, right?

If so, then the current method is really not appropriate. Maybe I should check 
whether
the function has been registered before registering the current function. If it 
has
been registered, I will skip it directly. This will lead to a decrease in 
efficiency.
I am not sure whether this is appropriate. In fact, I see a similar patch on 
aarch64:

https://github.com/gcc-mirror/gcc/commit/685d822e524cc8b2726ad6c44c2ccaabe55a198c

Or any other comments?

BR
Jin


Re: [PATCH v3] RISC-V: Fixed incorrect semantic description in DF to DI pattern in the Zfa extension on rv32.

2024-09-13 Thread Jin Ma

Hi, any more comments about this patch to fix zfa's ICE?

BR,
Jin

[PATCH] RISC-V: Bugfix for unrecognizable insn for XTheadVector

2024-11-13 Thread Jin Ma
error: unrecognizable insn:

(insn 35 34 36 2 (set (subreg:RVVM1SF (reg/v:RVVM1x4SF 142 [ _r ]) 0)
(unspec:RVVM1SF [
(const_vector:RVVM1SF repeat [
(const_double:SF 0.0 [0x0.0p+0])
])
(reg:DI 0 zero)
(const_int 1 [0x1])
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_TH_VWLDST)) -1
 (nil))
during RTL pass: mode_sw

PR 116591

gcc/ChangeLog:

* config/riscv/vector.md: Add restriction to call pred_th_whole_mov.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/xtheadvector/pr116591.c: New test.

Reported-by: nihui 
---
 gcc/config/riscv/vector.md |  4 ++--
 .../gcc.target/riscv/rvv/xtheadvector/pr116591.c   | 14 ++
 2 files changed, 16 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116591.c

diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 8bbae41c9f32..c29e69d5c36d 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -1175,7 +1175,7 @@ (define_expand "mov"
- We can not leave it to TARGET_SECONDARY_RELOAD since it happens
 before spilling. The clobber scratch is used by spilling fractional
 registers in IRA/LRA so it's too early.  */
-  if (TARGET_XTHEADVECTOR)
+  if (TARGET_XTHEADVECTOR && reg_or_mem_operand (operands[1], mode))
 {
   emit_insn (gen_pred_th_whole_mov (mode, operands[0], operands[1],
RVV_VLMAX, 
GEN_INT(riscv_vector::VLMAX)));
@@ -1238,7 +1238,7 @@ (define_expand "mov"
(match_operand:VB 1 "general_operand"))]
   "TARGET_VECTOR"
 {
-  if (TARGET_XTHEADVECTOR)
+  if (TARGET_XTHEADVECTOR && reg_or_mem_operand (operands[1], mode))
 {
   emit_insn (gen_pred_th_whole_mov (mode, operands[0], operands[1],
RVV_VLMAX, 
GEN_INT(riscv_vector::VLMAX)));
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116591.c 
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116591.c
new file mode 100644
index ..dfaf82ce1ca8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116591.c
@@ -0,0 +1,14 @@
+/* { dg-do assemble } */
+/* { dg-options "-march=rv32gc_xtheadvector -mabi=ilp32d -O2 -save-temps" { 
target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xtheadvector -mabi=lp64d -O2 -save-temps" { 
target { rv64 } } } */
+
+#include 
+
+void
+foo (float *a, int b)
+{
+  vfloat32m1x4_t c;
+  __riscv_vsseg4e32_v_f32m1x4(a, c, b);
+}
+
+/* { dg-final { scan-assembler-times {th\.vmv\.v\.i\tv[0-9]+,0} 4 } } */
-- 
2.25.1



[PATCH] RSIC-V: Fix ICE for unrecognizable insn `UNSPEC_VSETVL` for XTheadVector

2024-11-13 Thread Jin Ma
Since XTheadvector does not support vsetivli, vl needs to be put into
registers during the expand phase.

PR 116593

gcc/ChangeLog:

* config/riscv/riscv-vector-builtins.cc 
(function_expander::add_input_operand):
Put const to GPR for vl
* config/riscv/thead-vector.md (@th_pred_vl_mov): New.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/xtheadvector/pr116593.c: New test.

Reported-by: nihui 
---
 gcc/config/riscv/riscv-vector-builtins.cc  | 18 +-
 gcc/config/riscv/thead-vector.md   | 13 +
 .../riscv/rvv/xtheadvector/pr116593.c  | 13 +
 3 files changed, 43 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116593.c

diff --git a/gcc/config/riscv/riscv-vector-builtins.cc 
b/gcc/config/riscv/riscv-vector-builtins.cc
index 458d9b0886e3..cf2344e54c21 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -3936,7 +3936,23 @@ function_expander::add_input_operand (unsigned argno)
 {
   tree arg = CALL_EXPR_ARG (exp, argno);
   rtx x = expand_normal (arg);
-  add_input_operand (TYPE_MODE (TREE_TYPE (arg)), x);
+
+  /* Since the parameter vl of XTheadVector does not support
+ immediate numbers, we need to put it in the register
+ in advance.  */
+  if (TARGET_XTHEADVECTOR
+  && CONST_INT_P (x)
+  && base->apply_vl_p ()
+  && argno == (unsigned) (call_expr_nargs (exp) - 1)
+  && !rtx_equal_p (x, const0_rtx))
+{
+  rtx tmp = gen_reg_rtx (Pmode);
+  /* Use UNSPEC to avoid being optimized before vsetvl pass.  */
+  emit_insn (gen_th_pred_vl_mov (Pmode, tmp, x));
+  add_input_operand (TYPE_MODE (TREE_TYPE (arg)), tmp);
+}
+  else
+add_input_operand (TYPE_MODE (TREE_TYPE (arg)), x);
 }
 
 /* Since we may normalize vop/vop_tu/vop_m/vop_tumu.. into a single patter.
diff --git a/gcc/config/riscv/thead-vector.md b/gcc/config/riscv/thead-vector.md
index 5fe9ba08c4eb..0e00514c6b2d 100644
--- a/gcc/config/riscv/thead-vector.md
+++ b/gcc/config/riscv/thead-vector.md
@@ -25,6 +25,7 @@ (define_c_enum "unspec" [
   UNSPEC_TH_VSUXW
 
   UNSPEC_TH_VWLDST
+  UNSPEC_TH_VL_MOV
 ])
 
 (define_int_iterator UNSPEC_TH_VLMEM_OP [
@@ -93,6 +94,18 @@ (define_int_iterator UNSPEC_TH_VSXMEM_OP [
 (define_mode_iterator V_VLS_VT [V VLS VT])
 (define_mode_iterator V_VB_VLS_VT [V VB VLS VT])
 
+(define_insn_and_split "@th_pred_vl_mov"
+  [(set (match_operand:P 0 "register_operand""=r")
+   (unspec:P
+ [(match_operand:P 1 "const_int_operand" " i")]
+   UNSPEC_TH_VL_MOV))]
+  "TARGET_XTHEADVECTOR"
+  "li\t%0,%1"
+  "&& epilogue_completed"
+  [(set (match_dup 0) (match_dup 1))]
+  {}
+  [(set_attr "type" "arith")])
+
 (define_split
   [(set (match_operand:V_VB_VLS_VT 0 "reg_or_mem_operand")
(match_operand:V_VB_VLS_VT 1 "reg_or_mem_operand"))]
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116593.c 
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116593.c
new file mode 100644
index ..2d5b04207962
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr116593.c
@@ -0,0 +1,13 @@
+/* { dg-do assemble } */
+/* { dg-options "-march=rv32gc_zfh_xtheadvector -mabi=ilp32d -O2 -save-temps" 
{ target { rv32 } } } */
+/* { dg-options "-march=rv64gc_zfh_xtheadvector -mabi=lp64d -O2 -save-temps" { 
target { rv64 } } } */
+
+#include 
+
+vfloat16m1_t
+foo (vfloat16m1_t x)
+{ 
+  return __riscv_vfadd_vf_f16m1 (x, 1, 1);
+}
+
+/* { dg-final { scan-assembler-times {th\.vfadd\.vf} 1 } } */
-- 
2.25.1



Re: [PATCH v3] RISC-V: Fixed incorrect semantic description in DF to DI pattern in the Zfa extension on rv32.

2024-09-18 Thread Jin Ma
> > gcc/ChangeLog:
> >
> >  * config/riscv/riscv.md: Change "truncate" to unspec for the Zfa extension 
> > on rv32.
> >
> > gcc/testsuite/ChangeLog:
> >
> >  * gcc.target/riscv/zfa-fmovh-fmovp-bug.c: New test.
> I've pushed this version to the trunk.
> 
> Thanks,
> jeff

Thanks Jeff and Christoph for the review work on this :)

BR
Jin


Re: [PATCH] RSIC-V: Fix ICE for unrecognizable insn `UNSPEC_VSETVL` for XTheadVector

2024-12-02 Thread Jin Ma
HI, Jeff

I am very sorry that I took so long to reply because I was ill and hospitalized.

> > +
> > +  /* Since the parameter vl of XTheadVector does not support
> > + immediate numbers, we need to put it in the register
> > + in advance.  */
> > +  if (TARGET_XTHEADVECTOR
> > +  && CONST_INT_P (x)
> > +  && base->apply_vl_p ()
> > +  && argno == (unsigned) (call_expr_nargs (exp) - 1)
> > +  && !rtx_equal_p (x, const0_rtx))
> Last condition is better written as
> x != CONST0_RTX (GET_MODE (x))

Ok

> 
> > +{
> > +  rtx tmp = gen_reg_rtx (Pmode);
> > +  /* Use UNSPEC to avoid being optimized before vsetvl pass.  */
> > +  emit_insn (gen_th_pred_vl_mov (Pmode, tmp, x));
> Pmode seems wrong.  word_mode would likely be better.  That would mean
> some adjustment to your new insn.
> 
> Additionally, I'd like to understand better why you can't just
>   tmp = force_reg (word_mode, x);
> 
> Can you explain in more detail what you're trying to avoid?  ie, RTL
> before/after the problematical optimization?  It feels like you're
> papering over a bigger problem using the UNSPEC.

In fact, we inserted the vsetvl instruction in the "vsetvl" pass. Before it,
there will be many opportunities to eliminate the mov instruction we need,
such as "combine" pass or "reload" pass(curr_insn_transform), which will
eventually lead to vl in the vector pattern being an immediate instead of
a register. This will lead to only "vsetivli" being generated in the "vsetvl"
pass, which is obviously inconsistent with expectations. So we need a special
mov with UNSPEC to avoid it being optimized before the "vsetvl" pass.

> 
> Can you also resubmit with the RSIC-V in the subject line fixed to
> RISC-V that way the pre-commit tester will pick it up.

Ok

> Thanks,
> 
> Jeff

BR
Jin


[PATCH v2] RISC-V: Fix ICE for unrecognizable insn `UNSPEC_VSETVL` for XTheadVector

2024-12-02 Thread Jin Ma
Since XTheadvector does not support vsetivli, vl needs to be put into
registers during the expand phase.

PR 116593

gcc/ChangeLog:

* config/riscv/riscv-vector-builtins.cc 
(function_expander::add_input_operand):
Put const to GPR for vl.
* config/riscv/thead-vector.md (@th_pred_vl_mov): New.

gcc/testsuite/ChangeLog:

* g++.target/riscv/xtheadvector/pr116593.C: New test.
* g++.target/riscv/xtheadvector/xtheadvector.exp: New test.

Reported-by: nihui 
---
 gcc/config/riscv/riscv-vector-builtins.cc | 18 +++-
 gcc/config/riscv/thead-vector.md  | 13 ++
 .../g++.target/riscv/xtheadvector/pr116593.C  | 45 +++
 .../riscv/xtheadvector/xtheadvector.exp   | 37 +++
 4 files changed, 112 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.target/riscv/xtheadvector/pr116593.C
 create mode 100644 gcc/testsuite/g++.target/riscv/xtheadvector/xtheadvector.exp

diff --git a/gcc/config/riscv/riscv-vector-builtins.cc 
b/gcc/config/riscv/riscv-vector-builtins.cc
index b9b9d33adab6..cced0461a7bb 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -4089,7 +4089,23 @@ function_expander::add_input_operand (unsigned argno)
 {
   tree arg = CALL_EXPR_ARG (exp, argno);
   rtx x = expand_normal (arg);
-  add_input_operand (TYPE_MODE (TREE_TYPE (arg)), x);
+
+  /* Since the parameter vl of XTheadVector does not support
+ immediate numbers, we need to put it in the register
+ in advance.  */
+  if (TARGET_XTHEADVECTOR
+  && CONST_INT_P (x)
+  && base->apply_vl_p ()
+  && argno == (unsigned) (call_expr_nargs (exp) - 1)
+  && x != CONST0_RTX (GET_MODE (x)))
+{
+  rtx tmp = gen_reg_rtx (word_mode);
+  /* Use UNSPEC to avoid being optimized before vsetvl pass.  */
+  emit_insn (gen_th_pred_vl_mov (word_mode, tmp, x));
+  add_input_operand (TYPE_MODE (TREE_TYPE (arg)), tmp);
+}
+  else
+add_input_operand (TYPE_MODE (TREE_TYPE (arg)), x);
 }
 
 /* Since we may normalize vop/vop_tu/vop_m/vop_tumu.. into a single patter.
diff --git a/gcc/config/riscv/thead-vector.md b/gcc/config/riscv/thead-vector.md
index 5fe9ba08c4eb..0e00514c6b2d 100644
--- a/gcc/config/riscv/thead-vector.md
+++ b/gcc/config/riscv/thead-vector.md
@@ -25,6 +25,7 @@ (define_c_enum "unspec" [
   UNSPEC_TH_VSUXW
 
   UNSPEC_TH_VWLDST
+  UNSPEC_TH_VL_MOV
 ])
 
 (define_int_iterator UNSPEC_TH_VLMEM_OP [
@@ -93,6 +94,18 @@ (define_int_iterator UNSPEC_TH_VSXMEM_OP [
 (define_mode_iterator V_VLS_VT [V VLS VT])
 (define_mode_iterator V_VB_VLS_VT [V VB VLS VT])
 
+(define_insn_and_split "@th_pred_vl_mov"
+  [(set (match_operand:P 0 "register_operand""=r")
+   (unspec:P
+ [(match_operand:P 1 "const_int_operand" " i")]
+   UNSPEC_TH_VL_MOV))]
+  "TARGET_XTHEADVECTOR"
+  "li\t%0,%1"
+  "&& epilogue_completed"
+  [(set (match_dup 0) (match_dup 1))]
+  {}
+  [(set_attr "type" "arith")])
+
 (define_split
   [(set (match_operand:V_VB_VLS_VT 0 "reg_or_mem_operand")
(match_operand:V_VB_VLS_VT 1 "reg_or_mem_operand"))]
diff --git a/gcc/testsuite/g++.target/riscv/xtheadvector/pr116593.C 
b/gcc/testsuite/g++.target/riscv/xtheadvector/pr116593.C
new file mode 100644
index ..e44e7437ad70
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/xtheadvector/pr116593.C
@@ -0,0 +1,45 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zfh_xtheadvector -mabi=ilp32d -O2" { target { 
rv32 } } } */
+/* { dg-options "-march=rv64gc_zfh_xtheadvector -mabi=lp64d -O2" { target { 
rv64 } } } */
+
+#include 
+#include 
+#include 
+
+static vfloat32m8_t atan2_ps(vfloat32m8_t a, vfloat32m8_t b, size_t vl)
+{
+  std::vector tmpx(vl);
+  std::vector tmpy(vl);
+  __riscv_vse32_v_f32m8(tmpx.data(), a, vl);
+  __riscv_vse32_v_f32m8(tmpy.data(), b, vl);
+  for (size_t i = 0; i < vl; i++)
+  {
+tmpx[i] = atan2(tmpx[i], tmpy[i]);
+  }
+  return __riscv_vle32_v_f32m8(tmpx.data(), vl);
+}
+
+void atan2(const float *x, const float *y, float *out, int size, int ch)
+{
+  for (int i = 0; i < ch; i++)
+  {
+const float *xx = x + size * i;
+const float *yy = y + size * i;
+float *zz = out + size * i;
+
+int n = size;
+while (n > 0)
+{
+  size_t vl = __riscv_vsetvl_e32m8(n);
+  vfloat32m8_t _xx = __riscv_vle32_v_f32m8(xx, vl);
+  vfloat32m8_t _yy = __riscv_vle32_v_f32m8(yy, vl);
+  vfloat32m8_t _zz = atan2_ps(_xx, _yy, vl);
+  __riscv_vse32_v_f32m8(zz, _zz, vl);
+  n -= vl;
+  xx += vl;
+  yy += vl;
+  zz += vl;
+}
+  }
+}
diff --git a/gcc/testsuite/g++.target/riscv/xtheadvector/xtheadvector.exp 
b/gcc/testsuite/g++.target/riscv/xtheadvector/xtheadvector.exp
new file mode 100644
index ..551fd9c92670
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/xtheadvector/xtheadvector.exp
@@ -0,0 +1,37 @@
+# Copyright (C) 2023-2024 Free Software Found

[PATCH] MAINTAINERS: Add myself to write after approval

2024-12-03 Thread Jin Ma
ChangeLog:

* MAINTAINERS: Add myself.
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 7d65ed64bdda..a81ba5d70fec 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -639,6 +639,7 @@ H.J. Lu hjl 

 Xiong Hu Luo-   
 Bin Bin Lv  shlb
 Christophe Lyon clyon   
+Jin Ma  majin   
 Jun Ma  junma   
 Andrew MacLeod  -   
 Luis Machadoluisgpm 
-- 
2.25.1



Re: [PATCH] RISC-V: unrecognizable insn ICE in xtheadvector/pr114194.c on 32bit targets

2025-02-10 Thread Jin Ma
On Sun, 09 Feb 2025 14:04:00 +0800, Jin Ma wrote:
>   PR target/118601

Ok for trunk?

Best regards,
Jin Ma

> gcc/ChangeLog:
> 
>   * config/riscv/riscv.cc (riscv_use_by_pieces_infrastructure_p):
>   Exclude XTheadVector.
> 
> Reported-by: Edwin Lu 
> ---
>  gcc/config/riscv/riscv.cc | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 819e1538741..e5776aa0fbe 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -13826,7 +13826,7 @@ riscv_use_by_pieces_infrastructure_p (unsigned 
> HOST_WIDE_INT size,
>/* For set/clear with size > UNITS_PER_WORD, by pieces uses vector 
> broadcasts
>   with UNITS_PER_WORD size pieces.  Use setmem instead which can use
>   bigger chunks.  */
> -  if (TARGET_VECTOR && stringop_strategy & STRATEGY_VECTOR
> +  if (TARGET_VECTOR && !TARGET_XTHEADVECTOR && stringop_strategy & 
> STRATEGY_VECTOR
>&& (op == CLEAR_BY_PIECES || op == SET_BY_PIECES)
>&& speed_p && size > UNITS_PER_WORD)
>  return false;
> -- 
> 2.25.1



[PATCH] RISC-V: unrecognizable insn ICE in xtheadvector/pr114194.c on 32bit targets

2025-02-08 Thread Jin Ma
PR target/118601

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_use_by_pieces_infrastructure_p):
Exclude XTheadVector.

Reported-by: Edwin Lu 
---
 gcc/config/riscv/riscv.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 819e1538741..e5776aa0fbe 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -13826,7 +13826,7 @@ riscv_use_by_pieces_infrastructure_p (unsigned 
HOST_WIDE_INT size,
   /* For set/clear with size > UNITS_PER_WORD, by pieces uses vector broadcasts
  with UNITS_PER_WORD size pieces.  Use setmem instead which can use
  bigger chunks.  */
-  if (TARGET_VECTOR && stringop_strategy & STRATEGY_VECTOR
+  if (TARGET_VECTOR && !TARGET_XTHEADVECTOR && stringop_strategy & 
STRATEGY_VECTOR
   && (op == CLEAR_BY_PIECES || op == SET_BY_PIECES)
   && speed_p && size > UNITS_PER_WORD)
 return false;
-- 
2.25.1



[PATCH v2] RISC-V: unrecognizable insn ICE in xtheadvector/pr114194.c on 32bit targets

2025-02-11 Thread Jin Ma
This is a follow-up to the patch below to avoid generating unrecognized
vsetivl instructions for XTheadVector.

https://gcc.gnu.org/pipermail/gcc-patches/2025-January/674185.html

PR target/118601

gcc/ChangeLog:

* config/riscv/riscv-string.cc (expand_block_move): Check with new
constraint 'vl' instead of 'K'.
(expand_vec_setmem): Likewise.
(expand_vec_cmpmem): Likewise.
* config/riscv/riscv-v.cc (force_vector_length_operand): Likewise.
(expand_load_store): Likewise.
(expand_strided_load): Likewise.
(expand_strided_store): Likewise.
(expand_lanes_load_store): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/xtheadvector/pr114194.c: Move to...
* gcc.target/riscv/rvv/xtheadvector/pr114194-rv64.c: ...here.
* gcc.target/riscv/rvv/xtheadvector/pr114194-rv32.c: New test.
* gcc.target/riscv/rvv/xtheadvector/pr118601.c: New test.

Reported-by: Edwin Lu 
---
 gcc/config/riscv/riscv-string.cc  |  6 +--
 gcc/config/riscv/riscv-v.cc   | 10 ++--
 .../riscv/rvv/xtheadvector/pr114194-rv32.c| 51 +++
 .../{pr114194.c => pr114194-rv64.c}   |  5 +-
 .../riscv/rvv/xtheadvector/pr118601.c | 18 +++
 5 files changed, 79 insertions(+), 11 deletions(-)
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr114194-rv32.c
 rename gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/{pr114194.c => 
pr114194-rv64.c} (80%)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr118601.c

diff --git a/gcc/config/riscv/riscv-string.cc b/gcc/config/riscv/riscv-string.cc
index 97e20bdb002..408eb07e87f 100644
--- a/gcc/config/riscv/riscv-string.cc
+++ b/gcc/config/riscv/riscv-string.cc
@@ -1275,7 +1275,7 @@ expand_block_move (rtx dst_in, rtx src_in, rtx length_in, 
bool movmem_p)
   machine_mode mask_mode = riscv_vector::get_vector_mode
(BImode, GET_MODE_NUNITS (info.vmode)).require ();
   rtx mask =  CONSTM1_RTX (mask_mode);
-  if (!satisfies_constraint_K (cnt))
+  if (!satisfies_constraint_vl (cnt))
cnt= force_reg (Pmode, cnt);
   rtx m_ops[] = {vec, mask, src};
   emit_nonvlmax_insn (code_for_pred_mov (info.vmode),
@@ -1626,7 +1626,7 @@ expand_vec_setmem (rtx dst_in, rtx length_in, rtx 
fill_value_in)
 }
   else
 {
-  if (!satisfies_constraint_K (info.avl))
+  if (!satisfies_constraint_vl (info.avl))
info.avl = force_reg (Pmode, info.avl);
   emit_nonvlmax_insn (code_for_pred_broadcast (info.vmode),
  riscv_vector::UNARY_OP, broadcast_ops, info.avl);
@@ -1694,7 +1694,7 @@ expand_vec_cmpmem (rtx result_out, rtx blk_a_in, rtx 
blk_b_in, rtx length_in)
 }
   else
 {
-  if (!satisfies_constraint_K (length_in))
+  if (!satisfies_constraint_vl (length_in))
  length_in = force_reg (Pmode, length_in);
 
   rtx memmask = CONSTM1_RTX (mask_mode);
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 9847439ca77..62456c7ef79 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -2103,7 +2103,7 @@ get_unknown_min_value (machine_mode mode)
 static rtx
 force_vector_length_operand (rtx vl)
 {
-  if (CONST_INT_P (vl) && !satisfies_constraint_K (vl))
+  if (CONST_INT_P (vl) && !satisfies_constraint_vl (vl))
 return force_reg (Pmode, vl);
   return vl;
 }
@@ -4130,7 +4130,7 @@ expand_load_store (rtx *ops, bool is_load)
 }
   else
 {
-  if (!satisfies_constraint_K (len))
+  if (!satisfies_constraint_vl (len))
len = force_reg (Pmode, len);
   if (is_load)
{
@@ -4165,7 +4165,7 @@ expand_strided_load (machine_mode mode, rtx *ops)
 emit_vlmax_insn (icode, BINARY_OP_TAMA, emit_ops);
   else
 {
-  len = satisfies_constraint_K (len) ? len : force_reg (Pmode, len);
+  len = satisfies_constraint_vl (len) ? len : force_reg (Pmode, len);
   emit_nonvlmax_insn (icode, BINARY_OP_TAMA, emit_ops, len);
 }
 }
@@ -4191,7 +4191,7 @@ expand_strided_store (machine_mode mode, rtx *ops)
 }
   else
 {
-  len = satisfies_constraint_K (len) ? len : force_reg (Pmode, len);
+  len = satisfies_constraint_vl (len) ? len : force_reg (Pmode, len);
   vl_type = get_avl_type_rtx (NONVLMAX);
 }
 
@@ -4642,7 +4642,7 @@ expand_lanes_load_store (rtx *ops, bool is_load)
 }
   else
 {
-  if (!satisfies_constraint_K (len))
+  if (!satisfies_constraint_vl (len))
len = force_reg (Pmode, len);
   if (is_load)
{
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr114194-rv32.c 
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr114194-rv32.c
new file mode 100644
index 000..f95e713ea24
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr114194-rv32.c
@@ -0,0 +1,51 @@
+/* { dg-do compile { target { { ! riscv_abi_e } && rv32 } } } */
+/* { dg-options "-march=rv3

Re: [PATCH] RISC-V: unrecognizable insn ICE in xtheadvector/pr114194.c on 32bit targets

2025-02-11 Thread Jin Ma
On Tue, 11 Feb 2025 20:29:03 +0800, Craig Blackmore wrote:
> On 10/02/2025 08:37, Jin Ma wrote:
> > On Sun, 09 Feb 2025 14:04:00 +0800, Jin Ma wrote:
> >>PR target/118601
> > 
> > Ok for trunk?
> > 
> > Best regards,
> > Jin Ma
> > 
> >> gcc/ChangeLog:
> >>
> >>* config/riscv/riscv.cc (riscv_use_by_pieces_infrastructure_p):
> >>Exclude XTheadVector.
> >>
> >> Reported-by: Edwin Lu 
> >> ---
> >>   gcc/config/riscv/riscv.cc | 2 +-
> >>   1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> >> index 819e1538741..e5776aa0fbe 100644
> >> --- a/gcc/config/riscv/riscv.cc
> >> +++ b/gcc/config/riscv/riscv.cc
> >> @@ -13826,7 +13826,7 @@ riscv_use_by_pieces_infrastructure_p (unsigned 
> >> HOST_WIDE_INT size,
> >> /* For set/clear with size > UNITS_PER_WORD, by pieces uses vector 
> >> broadcasts
> >>with UNITS_PER_WORD size pieces.  Use setmem instead which 
> >> can use
> >>bigger chunks.  */
> >> -  if (TARGET_VECTOR && stringop_strategy & STRATEGY_VECTOR
> >> +  if (TARGET_VECTOR && !TARGET_XTHEADVECTOR && stringop_strategy & 
> >> STRATEGY_VECTOR
> >> && (op == CLEAR_BY_PIECES || op == SET_BY_PIECES)
> >> && speed_p && size > UNITS_PER_WORD)
> >>   return false;
> 
> `riscv_vector::expand_vec_setmem` generates the unrecognizable
> instruction and your patch avoids calling it in some, but not all,
> cases. Here is a case that still ICEs with `-march=rv32gc_xtheadvector
> -mabi=ilp32d` and `-march=rv64gc_xtheadvector -mabi=lp64d` after
> applying your patch:
> ```
> void foo1_16 (void *p)
> {
>__builtin_memset (p, 1, 16);
> }
> ```
> I suggest returning `false` in `riscv_vector::expand_vec_setmem` for
> `TARGET_XTHEADVECTOR` or trying to generate something that is valid for
> `TARGET_XTHEADVECTOR`. If you do bail out of
> `riscv_vector::expand_vec_setmem` then you probably want to keep your
> existing change too so that by pieces is still used for smaller lengths
> rather than a libcall.

Thank you very much for your professional reply. I think this problem is very
simple and wrong judgment has occurred. I will rethink and think about this.

Best regards,
Jin Ma

> >> -- 
> >> 2.25.1
> > 


Re: [PATCH v2] RISC-V: Fix ICE for unrecognizable insn `UNSPEC_VSETVL` for XTheadVector

2024-12-16 Thread Jin Ma
> So I would just do:
> 
> 
> tmp = force_reg (word_mode, x);
> add_input_operand (TYPE_MODE (TREE_TYPE (arg)), tmp);
> 
> In the thead specific code. That generates the initial code correctly.
> At that point we just need to make sure nothing like combine, cprop, etc
> propagates the constant into the vsetvl. The way to prevent that is
> with the operand predicates on the vsetvl insns.
>
> jeff
Thank you so much for your patient guidance. I understand what you mean and
will update the patch accordingly :)
BR
Jin


Re: [PATCH v2] RISC-V: Fix ICE for unrecognizable insn `UNSPEC_VSETVL` for XTheadVector

2024-12-17 Thread Jin Ma
> > --- a/gcc/config/riscv/riscv-vector-builtins.cc
> > +++ b/gcc/config/riscv/riscv-vector-builtins.cc
> > @@ -4089,7 +4089,23 @@ function_expander::add_input_operand (unsigned argno)
> >   {
> > tree arg = CALL_EXPR_ARG (exp, argno);
> > rtx x = expand_normal (arg);
> > -  add_input_operand (TYPE_MODE (TREE_TYPE (arg)), x);
> > +
> > +  /* Since the parameter vl of XTheadVector does not support
> > + immediate numbers, we need to put it in the register
> > + in advance.  */
> > +  if (TARGET_XTHEADVECTOR
> > +  && CONST_INT_P (x)
> > +  && base->apply_vl_p ()
> > +  && argno == (unsigned) (call_expr_nargs (exp) - 1)
> > +  && x != CONST0_RTX (GET_MODE (x)))
> > +{
> > +  rtx tmp = gen_reg_rtx (word_mode);
> > +  /* Use UNSPEC to avoid being optimized before vsetvl pass.  */
> > +  emit_insn (gen_th_pred_vl_mov (word_mode, tmp, x));
> > +  add_input_operand (TYPE_MODE (TREE_TYPE (arg)), tmp);
> > +}
> > +  else
> > +add_input_operand (TYPE_MODE (TREE_TYPE (arg)), x);
> >   }
> So I would just do:
> 
> 
> tmp = force_reg (word_mode, x);
> add_input_operand (TYPE_MODE (TREE_TYPE (arg)), tmp);
> 
> In the thead specific code.  That generates the initial code correctly. 
> At that point we just need to make sure nothing like combine, cprop, etc 
> propagates the constant into the vsetvl.  The way to prevent that is 
> with the operand predicates on the vsetvl insns.
> 
> 
> jeff

Hi, jeff

I missed some information because of the long time.

As I said before, instead of using UNSPEC, In the curr_insn_transform function, 
the insn is transformed from:
(insn 69 67 225 12 (set (mem:RVVM8SF (reg/f:DI 218 [ _77 ]) [0  S[128, 128] 
A32])
(if_then_else:RVVM8SF (unspec:RVVMF4BI [
(const_vector:RVVMF4BI repeat [
(const_int 1 [0x1])
])
(reg:DI 209)
(const_int 0 [0])
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
(reg/v:RVVM8SF 143 [ _xx ])
(mem:RVVM8SF (reg/f:DI 218 [ _77 ]) [0  S[128, 128] A32]))) 
"pr116593.C":14:24 discrim 1 3883 {pred_storervvm8sf}
 (expr_list:REG_DEAD (reg/v:RVVM8SF 143 [ _xx ])
(nil)))
to
(insn 69 284 225 11 (set (mem:RVVM8SF (reg/f:DI 18 s2 [orig:218 _77 ] [218]) [0 
 S[128, 128] A32])
(if_then_else:RVVM8SF (unspec:RVVMF4BI [
(const_vector:RVVMF4BI repeat [
(const_int 1 [0x1])
])
(const_int 1 [0x1])
(const_int 0 [0])
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
(reg/v:RVVM8SF 104 v8 [orig:143 _xx ] [143])
(mem:RVVM8SF (reg/f:DI 18 s2 [orig:218 _77 ] [218]) [0  S[128, 128] 
A32]))) "pr116593.C":14:24 discrim 1 3883 {pred_storervvm8sf}
 (nil))

Looking at the log for the reload pass, it is found that "Changing pseudo 209 
in operand 3 of insn 69 on equiv 0x 1".
It converts the vl operand in insn from the expected register(reg:DI 209) to 
the constant 1(const_int 1 [0x1]).

This conversion occurs because, although the predicate for the vl operand is 
restricted by "vector_length_operand" in the pattern, 
the constraint is still "rK", which allows the transformation.

The issue is that changing the "rK" constraint to "rJ" for the constraint of vl 
operand in the pattern would prevent this conversion,
But unfortunately this will conflict with RVV (RISC-V Vector Extension).

This is why I initially considered using UNSPEC to address the XTheadVector 
problem while minimizing interference with RVV.

I'm not sure if there is a better way, do you have any suggestions?

BR
Jin


Re: [PATCH v3 1/2] RISC-V: Allocate the initial register in the expand phase for the vl of XTheadVector

2025-01-19 Thread Jin Ma
> On 1/17/25 7:37 AM, Jin Ma wrote:
> >>> Since the parameter vl of XTheadVector does not support immediate 
> >>> numbers, we need
> >>> to put it in the register in advance. That generates the initial code 
> >>> correctly.
> >>>
> >>>   PR 116593
> >>>
> >>> gcc/ChangeLog:
> >>>
> >>>   * config/riscv/riscv-vector-builtins.cc 
> >>> (function_expander::add_input_operand):
> >>>   Put immediate for vl to GPR for XTheadVector.
> >>
> >> Generally both patches look reasonable to me and the change is less 
> >> invasive
> >> than going via spec_restriction.
> >>
> >> How was this tested?  The Rivos CI has already picked it up but please 
> >> still
> >> always specify.  Thanks.
> > 
> > I'm not sure what you mean, but I'll do my best to understand.
> > If you're referring to how to test the logic of this code to ensure it works
> > as intended, it can be quite challenging to explain. Testing this particular
> > code is not straightforward. Even without any specific processing, the 
> > predicate
> > "vector_length_operand" still constrains the XTheadVector, and the immediate
> > value for VL will be stored in the register. In this sense, the code itself
> > may seem redundant.
> I suspect Robin is referring to running the GCC testsuite for 
> regressions.  That is standard practice for any patch.
> 
> Essentially build & run make check before and after your patch and 
> verify there are no new failures.  Ideally you'd also verify that your 
> testcase is fixed :-)

I see, thank you very much for dispelling my doubts. As there is currently
no good way to test, perhaps the first patch should be ignored.
Let's look at the second patch, which really solves ICE.

V4:
https://gcc.gnu.org/pipermail/gcc-patches/2025-January/674001.html

Thanks,
Jin

> If you're writing a patch that touches target independent parts of the 
> compiler, then the bar is even higher.  You need to bootstrap & 
> regression test such patches on one of the primary platforms such as 
> x86_64, aarch64.
> 
> Jeff

[PATCH v4] RISC-V: Add a new constraint to ensure that the vl of XTheadVector does not produce a non-zero immediate.

2025-01-19 Thread Jin Ma
Although we have handled the vl of XTheadVector correctly in the
expand phase and predicates, the results show that the work is
still insufficient.

In the curr_insn_transform function, the insn is transformed from:
(insn 69 67 225 12 (set (mem:RVVM8SF (reg/f:DI 218 [ _77 ]) [0  S[128, 128] 
A32])
(if_then_else:RVVM8SF (unspec:RVVMF4BI [
(const_vector:RVVMF4BI repeat [
(const_int 1 [0x1])
])
(reg:DI 209)
(const_int 0 [0])
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
(reg/v:RVVM8SF 143 [ _xx ])
(mem:RVVM8SF (reg/f:DI 218 [ _77 ]) [0  S[128, 128] A32])))
 (expr_list:REG_DEAD (reg/v:RVVM8SF 143 [ _xx ])
(nil)))
to
(insn 69 284 225 11 (set (mem:RVVM8SF (reg/f:DI 18 s2 [orig:218 _77 ] [218]) [0 
 S[128, 128] A32])
(if_then_else:RVVM8SF (unspec:RVVMF4BI [
(const_vector:RVVMF4BI repeat [
(const_int 1 [0x1])
])
(const_int 1 [0x1])
(const_int 0 [0])
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
(reg/v:RVVM8SF 104 v8 [orig:143 _xx ] [143])
(mem:RVVM8SF (reg/f:DI 18 s2 [orig:218 _77 ] [218]) [0  S[128, 128] 
A32])))
 (nil))

Looking at the log for the reload pass, it is found that "Changing pseudo 209 in
operand 3 of insn 69 on equiv 0x1".
It converts the vl operand in insn from the expected register(reg:DI 209) to the
constant 1(const_int 1 [0x1]).

This conversion occurs because, although the predicate for the vl operand is
restricted by "vector_length_operand" in the pattern, the constraint is still
"rK", which allows the transformation.

The issue is that changing the "rK" constraint to "rJ" for the constraint of vl
operand in the pattern would prevent this conversion, But unfortunately this 
will
conflict with RVV (RISC-V Vector Extension).

Based on the review's recommendations, the best solution for now is to create
a new constraint to distinguish between RVV and XTheadVector, which is exactly
what this patch does.

PR 116593

gcc/ChangeLog:

* config/riscv/constraints.md (vl): New.
* config/riscv/thead-vector.md: Replacing rK with rvl.
* config/riscv/vector.md: Likewise.

gcc/testsuite/ChangeLog:

* g++.target/riscv/xtheadvector/pr116593.C: New test.
* g++.target/riscv/xtheadvector/xtheadvector.exp: New test.

Reported-by: nihui 
---
 gcc/config/riscv/constraints.md   |   6 +
 gcc/config/riscv/thead-vector.md  |  18 +-
 gcc/config/riscv/vector.md| 476 +-
 .../g++.target/riscv/xtheadvector/pr116593.C  |  47 ++
 .../riscv/xtheadvector/xtheadvector.exp   |  34 ++
 5 files changed, 334 insertions(+), 247 deletions(-)
 create mode 100644 gcc/testsuite/g++.target/riscv/xtheadvector/pr116593.C
 create mode 100644 gcc/testsuite/g++.target/riscv/xtheadvector/xtheadvector.exp

diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index f25975dc0208..ba3c6e6a4c44 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -209,6 +209,12 @@ (define_constraint "vk"
   (and (match_code "const_vector")
(match_test "riscv_vector::const_vec_all_same_in_range_p (op, 0, 31)")))
 
+(define_constraint "vl"
+  "A uimm5 for Vector or zero for XTheadVector."
+  (and (match_code "const_int")
+   (ior (match_test "!TARGET_XTHEADVECTOR && satisfies_constraint_K (op)")
+   (match_test "TARGET_XTHEADVECTOR && satisfies_constraint_J (op)"
+
 (define_constraint "Wc0"
   "@internal
  A constraint that matches a vector of immediate all zeros."
diff --git a/gcc/config/riscv/thead-vector.md b/gcc/config/riscv/thead-vector.md
index 5fe9ba08c4eb..5a02debdd207 100644
--- a/gcc/config/riscv/thead-vector.md
+++ b/gcc/config/riscv/thead-vector.md
@@ -108,7 +108,7 @@ (define_insn_and_split "@pred_th_whole_mov"
   [(set (match_operand:V_VLS_VT 0 "reg_or_mem_operand"  "=vr,vr, m")
(unspec:V_VLS_VT
  [(match_operand:V_VLS_VT 1 "reg_or_mem_operand" " vr, m,vr")
-  (match_operand 2 "vector_length_operand"   " rK, rK, rK")
+  (match_operand 2 "vector_length_operand"   "rvl,rvl,rvl")
   (match_operand 3 "const_1_operand" "  i, i, i")
   (reg:SI VL_REGNUM)
   (reg:SI VTYPE_REGNUM)]
@@ -133,7 +133,7 @@ (define_insn_and_split "@pred_th_whole_mov"
   [(set (match_operand:VB 0 "reg_or_mem_operand"  "=vr,vr, m")
(unspec:VB
  [(match_operand:VB 1 "reg_or_mem_operand" " vr, m,vr")
-  (match_operand 2 "vector_length_operand"   " rK, rK, rK")
+  (match_operand 2 "vector_length_operand"   "rvl,rvl,rvl")
   (match_operand 3 "const_1_operand" "  i, i, 

[PATCH] RISC-V: Fix ICE when prefetching addresses less than 12 bits for zicbop

2025-01-19 Thread Jin Ma
gcc/ChangeLog:

* config/riscv/riscv.md: Change 'r' to 'p'.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/prefetch-zicbop-ice.c: New test.
---
 gcc/config/riscv/riscv.md| 2 +-
 gcc/testsuite/gcc.target/riscv/prefetch-zicbop-ice.c | 9 +
 2 files changed, 10 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/prefetch-zicbop-ice.c

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index c2a9de610526..86c39628ae8d 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -4370,7 +4370,7 @@ (define_insn "riscv_zero_"
 )
 
 (define_insn "prefetch"
-  [(prefetch (match_operand 0 "address_operand" "r")
+  [(prefetch (match_operand 0 "address_operand" "p")
  (match_operand 1 "imm5_operand" "i")
  (match_operand 2 "const_int_operand" "n"))]
   "TARGET_ZICBOP"
diff --git a/gcc/testsuite/gcc.target/riscv/prefetch-zicbop-ice.c 
b/gcc/testsuite/gcc.target/riscv/prefetch-zicbop-ice.c
new file mode 100644
index ..31908debb5cc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/prefetch-zicbop-ice.c
@@ -0,0 +1,9 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicbop -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicbop -mabi=ilp32d" { target { rv32 } } } */
+
+void foo ()
+{
+  __builtin_prefetch ((int*)0xff, 1, 0);
+}
-- 
2.25.1



[PATCH] RISC-V: Correct the mode that is causing the program to fail for XTheadCondMov

2025-01-19 Thread Jin Ma
For XTheadCondMov, the bit width of rs2 should always be XLEN-sized, otherwise
the program logic will be wrong.

Reference form
https://github.com/XUANTIE-RV/thead-extension-spec/releases/download/2.3.0/xthead-2023-11-10-2.3.0.pdf

Synopsis
Move if equal zero.

Mnemonic
th.mveqz rd, rs1, rs2

Description
This instruction moves the content of register rs1 into rd if the content of 
rs2 is 0x0.
Otherwise, the value of rd does not change.

Operation
if (reg[rs2] == 0x0)
  reg[rd] := reg[rs1]

gcc/ChangeLog:

* config/riscv/thead.md (*th_cond_mov):
Change GPR2 to X.
(*th_cond_mov): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadcondmov-bug.c: New test.
---
 gcc/config/riscv/thead.md  |  4 ++--
 gcc/testsuite/gcc.target/riscv/xtheadcondmov-bug.c | 12 
 2 files changed, 14 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-bug.c

diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 54b9737b4308..d816f3b86dde 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -154,11 +154,11 @@ (define_insn "*th_tst3"
 
 ;; XTheadCondMov
 
-(define_insn "*th_cond_mov"
+(define_insn "*th_cond_mov"
   [(set (match_operand:GPR 0 "register_operand" "=r,r")
(if_then_else:GPR
 (match_operator 4 "equality_operator"
-   [(match_operand:GPR2 1 "register_operand" "r,r")
+   [(match_operand:X 1 "register_operand" "r,r")
 (const_int 0)])
 (match_operand:GPR 2 "reg_or_0_operand" "rJ,0")
 (match_operand:GPR 3 "reg_or_0_operand" "0,rJ")))]
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-bug.c 
b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-bug.c
new file mode 100644
index ..33658b863514
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-bug.c
@@ -0,0 +1,12 @@
+/* { dg-do compile  { target { rv64 } } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mabi=lp64d -O2" } */
+
+__attribute__((noinline, noclone)) long long int
+foo (long long int x, long long int y)
+{
+  if (((int) x | (int) y) != 0)
+return 6;
+  return x + y;
+}
+
+/* { dg-final { scan-assembler-times {\msext\.w\M} 1 } } */
-- 
2.25.1



[PATCH v5] RISC-V: Add a new constraint to ensure that the vl of XTheadVector does not get a non-zero immediate

2025-01-21 Thread Jin Ma
Although we have handled the vl of XTheadVector correctly in the
expand phase and predicates, the results show that the work is
still insufficient.

In the curr_insn_transform function, the insn is transformed from:
(insn 69 67 225 12 (set (mem:RVVM8SF (reg/f:DI 218 [ _77 ]) [0  S[128, 128] 
A32])
(if_then_else:RVVM8SF (unspec:RVVMF4BI [
(const_vector:RVVMF4BI repeat [
(const_int 1 [0x1])
])
(reg:DI 209)
(const_int 0 [0])
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
(reg/v:RVVM8SF 143 [ _xx ])
(mem:RVVM8SF (reg/f:DI 218 [ _77 ]) [0  S[128, 128] A32])))
 (expr_list:REG_DEAD (reg/v:RVVM8SF 143 [ _xx ])
(nil)))
to
(insn 69 284 225 11 (set (mem:RVVM8SF (reg/f:DI 18 s2 [orig:218 _77 ] [218]) [0 
 S[128, 128] A32])
(if_then_else:RVVM8SF (unspec:RVVMF4BI [
(const_vector:RVVMF4BI repeat [
(const_int 1 [0x1])
])
(const_int 1 [0x1])
(const_int 0 [0])
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
(reg/v:RVVM8SF 104 v8 [orig:143 _xx ] [143])
(mem:RVVM8SF (reg/f:DI 18 s2 [orig:218 _77 ] [218]) [0  S[128, 128] 
A32])))
 (nil))

Looking at the log for the reload pass, it is found that "Changing pseudo 209 in
operand 3 of insn 69 on equiv 0x1".
It converts the vl operand in insn from the expected register(reg:DI 209) to the
constant 1(const_int 1 [0x1]).

This conversion occurs because, although the predicate for the vl operand is
restricted by "vector_length_operand" in the pattern, the constraint is still
"rK", which allows the transformation.

The issue is that changing the "rK" constraint to "rJ" for the constraint of vl
operand in the pattern would prevent this conversion, But unfortunately this 
will
conflict with RVV (RISC-V Vector Extension).

Based on the review's recommendations, the best solution for now is to create
a new constraint to distinguish between RVV and XTheadVector, which is exactly
what this patch does.

PR 116593

gcc/ChangeLog:

* config/riscv/constraints.md (vl): New.
* config/riscv/thead-vector.md: Replacing rK with rvl.
* config/riscv/vector.md: Likewise.

gcc/testsuite/ChangeLog:

* g++.target/riscv/rvv/rvv.exp: Enable testsuite of XTheadVector.
* g++.target/riscv/rvv/xtheadvector/pr116593.C: New test.

Reported-by: nihui 
---
 gcc/config/riscv/constraints.md   |   6 +
 gcc/config/riscv/thead-vector.md  |  18 +-
 gcc/config/riscv/vector.md| 476 +-
 gcc/testsuite/g++.target/riscv/rvv/rvv.exp|   3 +
 .../riscv/rvv/xtheadvector/pr116593.C |  47 ++
 5 files changed, 303 insertions(+), 247 deletions(-)
 create mode 100644 gcc/testsuite/g++.target/riscv/rvv/xtheadvector/pr116593.C

diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index f25975dc0208..ba3c6e6a4c44 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -209,6 +209,12 @@ (define_constraint "vk"
   (and (match_code "const_vector")
(match_test "riscv_vector::const_vec_all_same_in_range_p (op, 0, 31)")))
 
+(define_constraint "vl"
+  "A uimm5 for Vector or zero for XTheadVector."
+  (and (match_code "const_int")
+   (ior (match_test "!TARGET_XTHEADVECTOR && satisfies_constraint_K (op)")
+   (match_test "TARGET_XTHEADVECTOR && satisfies_constraint_J (op)"
+
 (define_constraint "Wc0"
   "@internal
  A constraint that matches a vector of immediate all zeros."
diff --git a/gcc/config/riscv/thead-vector.md b/gcc/config/riscv/thead-vector.md
index 5fe9ba08c4eb..5a02debdd207 100644
--- a/gcc/config/riscv/thead-vector.md
+++ b/gcc/config/riscv/thead-vector.md
@@ -108,7 +108,7 @@ (define_insn_and_split "@pred_th_whole_mov"
   [(set (match_operand:V_VLS_VT 0 "reg_or_mem_operand"  "=vr,vr, m")
(unspec:V_VLS_VT
  [(match_operand:V_VLS_VT 1 "reg_or_mem_operand" " vr, m,vr")
-  (match_operand 2 "vector_length_operand"   " rK, rK, rK")
+  (match_operand 2 "vector_length_operand"   "rvl,rvl,rvl")
   (match_operand 3 "const_1_operand" "  i, i, i")
   (reg:SI VL_REGNUM)
   (reg:SI VTYPE_REGNUM)]
@@ -133,7 +133,7 @@ (define_insn_and_split "@pred_th_whole_mov"
   [(set (match_operand:VB 0 "reg_or_mem_operand"  "=vr,vr, m")
(unspec:VB
  [(match_operand:VB 1 "reg_or_mem_operand" " vr, m,vr")
-  (match_operand 2 "vector_length_operand"   " rK, rK, rK")
+  (match_operand 2 "vector_length_operand"   "rvl,rvl,rvl")
   (match_operand 3 "const_1_operand" "  i, i, i")
   (reg:SI VL_REGNUM)
   (reg:SI VTYPE_REGNUM)]

[PATCH v2] RISC-V: Enable and adjust the testsuite for XTheadVector.

2025-01-21 Thread Jin Ma
gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/rvv.exp: Enable testsuite of
XTheadVector.
* gcc.target/riscv/rvv/xtheadvector/pr114194.c: Adjust correctly.
* gcc.target/riscv/rvv/xtheadvector/prefix.c: Likewise.
* gcc.target/riscv/rvv/xtheadvector/vlb-vsb.c: Likewise.
* gcc.target/riscv/rvv/xtheadvector/vlbu-vsb.c: Likewise.
* gcc.target/riscv/rvv/xtheadvector/vlh-vsh.c: Likewise.
* gcc.target/riscv/rvv/xtheadvector/vlhu-vsh.c: Likewise.
* gcc.target/riscv/rvv/xtheadvector/vlw-vsw.c: Likewise.
* gcc.target/riscv/rvv/xtheadvector/vlwu-vsw.c: Likewise.
---
 gcc/testsuite/gcc.target/riscv/rvv/rvv.exp|  2 ++
 .../riscv/rvv/xtheadvector/pr114194.c | 32 +--
 .../riscv/rvv/xtheadvector/prefix.c   |  2 +-
 .../riscv/rvv/xtheadvector/vlb-vsb.c  | 17 ++
 .../riscv/rvv/xtheadvector/vlbu-vsb.c | 17 ++
 .../riscv/rvv/xtheadvector/vlh-vsh.c  | 17 ++
 .../riscv/rvv/xtheadvector/vlhu-vsh.c | 17 ++
 .../riscv/rvv/xtheadvector/vlw-vsw.c  | 17 ++
 .../riscv/rvv/xtheadvector/vlwu-vsw.c | 17 ++
 9 files changed, 79 insertions(+), 59 deletions(-)

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp 
b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
index d82710e9c416..3824997c9082 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
+++ b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
@@ -41,6 +41,8 @@ dg-runtest [lsort [glob -nocomplain 
$srcdir/$subdir/base/*.\[cS\]]] \
"" $CFLAGS
 dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/xsfvector/*.\[cS\]]] \
"" $CFLAGS
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/xtheadvector/*.\[cS\]]] \
+   "" $CFLAGS
 gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/vsetvl/*.\[cS\]]] \
"" $CFLAGS
 dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/*.\[cS\]]] \
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr114194.c 
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr114194.c
index a82e2d3fbfe6..5c9777b071b5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr114194.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr114194.c
@@ -1,11 +1,11 @@
 /* { dg-do compile { target { ! riscv_abi_e } } } */
-/* { dg-options "-march=rv32gc_xtheadvector" { target { rv32 } } } */
-/* { dg-options "-march=rv64gc_xtheadvector" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadvector -O2" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xtheadvector -O2" { target { rv64 } } } */
 /* { dg-final { check-function-bodies "**" "" } } */
 
 /*
 ** foo0_1:
-** sb\tzero,0([a-x0-9]+)
+** sb\tzero,0\([a-x0-9]+\)
 ** ret
 */
 void foo0_1 (void *p)
@@ -15,13 +15,13 @@ void foo0_1 (void *p)
 
 /*
 ** foo0_7:
-** sb\tzero,0([a-x0-9]+)
-** sb\tzero,1([a-x0-9]+)
-** sb\tzero,2([a-x0-9]+)
-** sb\tzero,3([a-x0-9]+)
-** sb\tzero,4([a-x0-9]+)
-** sb\tzero,5([a-x0-9]+)
-** sb\tzero,6([a-x0-9]+)
+** sb\tzero,0\([a-x0-9]+\)
+** sb\tzero,1\([a-x0-9]+\)
+** sb\tzero,2\([a-x0-9]+\)
+** sb\tzero,3\([a-x0-9]+\)
+** sb\tzero,4\([a-x0-9]+\)
+** sb\tzero,5\([a-x0-9]+\)
+** sb\tzero,6\([a-x0-9]+\)
 ** ret
 */
 void foo0_7 (void *p)
@@ -32,7 +32,7 @@ void foo0_7 (void *p)
 /*
 ** foo1_1:
 ** li\t[a-x0-9]+,1
-** sb\t[a-x0-9]+,0([a-x0-9]+)
+** sb\t[a-x0-9]+,0\([a-x0-9]+\)
 ** ret
 */
 void foo1_1 (void *p)
@@ -43,11 +43,11 @@ void foo1_1 (void *p)
 /*
 ** foo1_5:
 ** li\t[a-x0-9]+,1
-** sb\t[a-x0-9]+,0([a-x0-9]+)
-** sb\t[a-x0-9]+,1([a-x0-9]+)
-** sb\t[a-x0-9]+,2([a-x0-9]+)
-** sb\t[a-x0-9]+,3([a-x0-9]+)
-** sb\t[a-x0-9]+,4([a-x0-9]+)
+** sb\t[a-x0-9]+,0\([a-x0-9]+\)
+** sb\t[a-x0-9]+,1\([a-x0-9]+\)
+** sb\t[a-x0-9]+,2\([a-x0-9]+\)
+** sb\t[a-x0-9]+,3\([a-x0-9]+\)
+** sb\t[a-x0-9]+,4\([a-x0-9]+\)
 ** ret
 */
 void foo1_5 (void *p)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/prefix.c 
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/prefix.c
index eee727ef6b42..0a18e697830c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/prefix.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/prefix.c
@@ -9,4 +9,4 @@ prefix (vint32m1_t vx, vint32m1_t vy, size_t vl)
   return __riscv_vadd_vv_i32m1 (vx, vy, vl);
 }
 
-/* { dg-final { scan-assembler {\mth\.v\M} } } */
+/* { dg-final { scan-assembler {\mth\.vadd\.vv\M} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlb-vsb.c 
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlb-vsb.c
index 3c12c1245974..16073ccb2366 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlb-vsb.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlb-vsb.c
@@ -5,7 +5,8 @@
 
 /*
 ** f1:
-** th.vsetivli\tzero,4,e32,m1,tu,ma
+** li\t[a-x0-9]+,4
+** th.vsetvli\tzero,[a-x0-9]+,e32,m1
 ** th.vlb\.v\tv[0-9]+,0

Re: [PATCH] RISC-V: Correct the mode that is causing the program to fail for XTheadCondMov

2025-01-19 Thread Jin Ma
> > diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-bug.c 
> > b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-bug.c
> > new file mode 100644
> > index ..33658b863514
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-bug.c
> > @@ -0,0 +1,12 @@
> > +/* { dg-do compile  { target { rv64 } } } */
> > +/* { dg-options "-march=rv64gc_xtheadcondmov -mabi=lp64d -O2" } */
> > +
> > +__attribute__((noinline, noclone)) long long int
> 
> The attributes are useless as nothing is calling the function in the
> tests.

Yes, my mistake, thanks.

BR
Jin


[PATCH v2] RISC-V: Correct the mode that is causing the program to fail for XTheadCondMov

2025-01-19 Thread Jin Ma
For XTheadCondMov, the bit width of rs2 should always be XLEN-sized, otherwise
the program logic will be wrong.

Reference form
https://github.com/XUANTIE-RV/thead-extension-spec/releases/download/2.3.0/xthead-2023-11-10-2.3.0.pdf

Synopsis
Move if equal zero.

Mnemonic
th.mveqz rd, rs1, rs2

Description
This instruction moves the content of register rs1 into rd if the content of 
rs2 is 0x0.
Otherwise, the value of rd does not change.

Operation
if (reg[rs2] == 0x0)
  reg[rd] := reg[rs1]

gcc/ChangeLog:

* config/riscv/thead.md (*th_cond_mov):
Change GPR2 to X.
(*th_cond_mov): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xtheadcondmov-bug.c: New test.
---
 gcc/config/riscv/thead.md  |  4 ++--
 gcc/testsuite/gcc.target/riscv/xtheadcondmov-bug.c | 12 
 2 files changed, 14 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-bug.c

diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 54b9737b4308..d816f3b86dde 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -154,11 +154,11 @@ (define_insn "*th_tst3"
 
 ;; XTheadCondMov
 
-(define_insn "*th_cond_mov"
+(define_insn "*th_cond_mov"
   [(set (match_operand:GPR 0 "register_operand" "=r,r")
(if_then_else:GPR
 (match_operator 4 "equality_operator"
-   [(match_operand:GPR2 1 "register_operand" "r,r")
+   [(match_operand:X 1 "register_operand" "r,r")
 (const_int 0)])
 (match_operand:GPR 2 "reg_or_0_operand" "rJ,0")
 (match_operand:GPR 3 "reg_or_0_operand" "0,rJ")))]
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-bug.c 
b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-bug.c
new file mode 100644
index ..01cec6292919
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-bug.c
@@ -0,0 +1,12 @@
+/* { dg-do compile  { target { rv64 } } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mabi=lp64d -O2" } */
+
+long long int
+foo (long long int x, long long int y)
+{
+  if (((int) x | (int) y) != 0)
+return 6;
+  return x + y;
+}
+
+/* { dg-final { scan-assembler-times {\msext\.w\M} 1 } } */
-- 
2.25.1



Re: [PATCH] RISC-V: Fix the result error caused by not updating ratio when using "use_max_sew" to merge vsetvl.

2025-01-13 Thread Jin Ma
> So as written this test will be totally skipped (and I've verified that 
> locally).  It looks like you just wanted -O2 and we're not cycling 
> through options, so we don't need/want the dg-skip-if.   I'll fix that too.

Sorry, I made a mistake again :(

> 
> I'll make the obvious changes and push the result to the trunk.

Thanks,
Jin


Re: [PATCH v2] RISC-V: Fix ICE for unrecognizable insn `UNSPEC_VSETVL` for XTheadVector

2025-01-13 Thread Jin Ma
> > Thank you very much for your professional reply. I am trying to solve the 
> > problem
> > using the "spec_restriction" way. But unfortunately, I have a new problem. 
> > As
> > pattern below, how can I enable "r" and disable "K" when XTheadVector? "rK" 
> > already
> > seems to be the smallest unit and not able to be
> > controlled separately using spec_restriction?
> >
> > (define_insn "@pred_madc"
> >   [(set (match_operand: 0 "register_operand" "=vr, &vr, &vr")
> >  (unspec:
> > [(plus:VI
> >   (match_operand:VI 1 "register_operand" "  %0,  vr,  vr")
> >   (match_operand:VI 2 "vector_arith_operand" "vrvi,  vr,  vi"))
> >  (match_operand: 3 "register_operand""  vm,  vm,  vm")
> >  (unspec:
> >[(match_operand 4 "vector_length_operand" "  rK,  rK,  rK")
> > (match_operand 5 "const_int_operand" "   i,   i,   i")
> > (reg:SI VL_REGNUM)
> > (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMADC))]
> >   "TARGET_VECTOR"
> >   "vmadc.v%o2m\t%0,%1,%v2,%3"
> >   [(set_attr "type" "vicalu")
> >(set_attr "mode" "")
> >(set_attr "vl_op_idx" "4")
> >(set (attr "avl_type_idx") (const_int 5))
> >(set_attr "spec_restriction" "thv,none,none")])
> 
> "rK" can be split up further into "r" and "K" so I'd say you
> need to adjust (and split) the alternatives accordingly.  The new "r"
> alternative would have spec_restriction "none" and the "K" alternative "rvv".

Yes. This will solve the problem, but it will lead to very large-scale changes
(splitting each rK, adding 1 column constraint), and make the pattern more 
complex
and more difficult to maintain. In contrast, how about replacing "rK" with a new
constrain in the way jeff mentioned? For example, "Vvl".

Jeff: We could also create a new constraint that mostly behaves like rK, but 
rejects (const_int 1) when thead-vector is enabled and use that in the 
vsetvl pattern instead of rK. ( 
https://gcc.gnu.org/pipermail/gcc-patches/2024-December/671836.html )

BR
Jin

> -- 
> Regards
>  Robin

Re: [PATCH v2] RISC-V: Fix ICE for unrecognizable insn `UNSPEC_VSETVL` for XTheadVector

2025-01-12 Thread Jin Ma
> > Looking at the log for the reload pass, it is found that "Changing pseudo 
> > 209
> > in operand 3 of insn 69 on equiv 0x 1". It converts the vl operand in insn
> > from the expected register(reg:DI 209) to the constant 1(const_int 1 [0x1]).
> >
> > This conversion occurs because, although the predicate for the vl operand is
> > restricted by "vector_length_operand" in the pattern, the constraint is 
> > still
> > "rK", which allows the transformation.
> >
> > The issue is that changing the "rK" constraint to "rJ" for the constraint of
> > vl operand in the pattern would prevent this conversion, But unfortunately
> > this will conflict with RVV (RISC-V Vector Extension).
> >
> > This is why I initially considered using UNSPEC to address the XTheadVector
> > problem while minimizing interference with RVV.
> >
> > I'm not sure if there is a better way, do you have any suggestions?
> 
> We'd probably need to disable the alternatives via the "spec_restriction"
> attribute as we do for the fma ops.

Hi, Robin
Thank you very much for your professional reply. I am trying to solve the 
problem
using the "spec_restriction" way. But unfortunately, I have a new problem. As
pattern below, how can I enable "r" and disable "K" when XTheadVector? "rK" 
already
seems to be the smallest unit and not able to be
controlled separately using spec_restriction?

(define_insn "@pred_madc"
  [(set (match_operand: 0 "register_operand" "=vr, &vr, &vr")
(unspec:
   [(plus:VI
 (match_operand:VI 1 "register_operand" "  %0,  vr,  vr")
 (match_operand:VI 2 "vector_arith_operand" "vrvi,  vr,  vi"))
(match_operand: 3 "register_operand""  vm,  vm,  vm")
(unspec:
  [(match_operand 4 "vector_length_operand" "  rK,  rK,  rK")
   (match_operand 5 "const_int_operand" "   i,   i,   i")
   (reg:SI VL_REGNUM)
   (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMADC))]
  "TARGET_VECTOR"
  "vmadc.v%o2m\t%0,%1,%v2,%3"
  [(set_attr "type" "vicalu")
   (set_attr "mode" "")
   (set_attr "vl_op_idx" "4")
   (set (attr "avl_type_idx") (const_int 5))
   (set_attr "spec_restriction" "thv,none,none")])
  
BR
Jin

> --
> Regards
> Robin
> 

[PATCH] RISC-V: Fix program logic errors caused by data truncation on 32-bit host for zbs, such as i386.

2025-01-13 Thread Jin Ma
Correct logic on 64-bit host:
...
bseti   a5,zero,38
bseti   a5,a5,63
addia5,a5,-1
and a4,a4,a5
...

Wrong logic on 32-bit host:
...
li  a5,64
bseti   a5,a5,31
addia5,a5,-1
and a4,a4,a5
...

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_build_integer_1): Change
1UL/1ULL to HOST_WIDE_INT_1U.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/zbs-bug.c: New test.
---
 gcc/config/riscv/riscv.cc|  4 ++--
 gcc/testsuite/gcc.target/riscv/zbs-bug.c | 15 +++
 2 files changed, 17 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbs-bug.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 65e09842fde8..3b5712429e46 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -1112,10 +1112,10 @@ riscv_build_integer_1 (struct riscv_integer_op 
codes[RISCV_MAX_INTEGER_OPS],
{
  HOST_WIDE_INT bit = ctz_hwi (value);
  alt_codes[i].code = (i == 0 ? UNKNOWN : IOR);
- alt_codes[i].value = 1UL << bit;
+ alt_codes[i].value = HOST_WIDE_INT_1U << bit;
  alt_codes[i].use_uw = false;
  alt_codes[i].save_temporary = false;
- value &= ~(1ULL << bit);
+ value &= ~(HOST_WIDE_INT_1U << bit);
  i++;
}
 
diff --git a/gcc/testsuite/gcc.target/riscv/zbs-bug.c 
b/gcc/testsuite/gcc.target/riscv/zbs-bug.c
new file mode 100644
index ..10dde5801334
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zbs-bug.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { rv64 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O1" "-O2" "-O3" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_zbb_zbs -mabi=lp64d -O0" } */
+
+struct a {
+  unsigned : 29;
+  signed : 6;
+  signed b : 25;
+};
+
+void c() {
+  struct a d = {808};
+}
+
+/* { dg-final { scan-assembler-not "bseti.*31" } }*/
-- 
2.25.1



[PATCH] RISC-V: Fix the result error caused by not updating ratio when using "use_max_sew" to merge vsetvl.

2025-01-13 Thread Jin Ma
When the vsetvl instructions of the two RVV instructions are merged
using "use_max_sew", it is possible to update the sew of prev if
prev.sew < next.sew, but keep the original ratio, which is obviously
wrong. when the subsequent instructions are equal to the wrong ratio,
it is possible to generate the wrong "vsetvli zero,zero" instruction,
which will lead to unknown avl.

gcc/ChangeLog:

* config/riscv/riscv-vsetvl.cc:

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/bug-10.c: New test.
---
 gcc/config/riscv/riscv-vsetvl.cc |  1 +
 gcc/testsuite/gcc.target/riscv/rvv/base/bug-10.c | 15 +++
 2 files changed, 16 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/bug-10.c

diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index 851e52a20ba6..e9de21787dda 100644
--- a/gcc/config/riscv/riscv-vsetvl.cc
+++ b/gcc/config/riscv/riscv-vsetvl.cc
@@ -1722,6 +1722,7 @@ private:
   {
 int max_sew = MAX (prev.get_sew (), next.get_sew ());
 prev.set_sew (max_sew);
+prev.set_ratio (calculate_ratio (prev.get_sew (), prev.get_vlmul ()));
 use_min_of_max_sew (prev, next);
   }
   inline void use_next_sew_lmul (vsetvl_info &prev, const vsetvl_info &next)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/bug-10.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-10.c
new file mode 100644
index ..c1a8ac95c17f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-10.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { rv64 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O3" "-Og" "-Os" "-Oz" } } */
+/* { dg-options " -march=rv64gcv_zvfh -mabi=lp64d -O2 
--param=vsetvl-strategy=optim -fno-schedule-insns  -fno-schedule-insns2 
-fno-schedule-fusion " } */
+
+#include 
+
+void
+foo (uint8_t *ptr, vfloat16m4_t *v1, vuint32m8_t *v2, vuint8m2_t *v3, size_t 
vl)
+{
+  *v1 = __riscv_vfmv_s_f_f16m4 (1, vl);
+  *v2 = __riscv_vmv_s_x_u32m8 (2963090659u, vl);
+  *v3 = __riscv_vsll_vx_u8m2 (__riscv_vid_v_u8m2 (vl), 2, vl);
+}
+
+/* { dg-final { scan-assembler-not {vsetvli.*zero,zero} } }*/
-- 
2.25.1



[PATCH] RISC-V: Enable and adjust the testsuite for XTheadVector.

2025-01-17 Thread Jin Ma
gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/xtheadvector/pr114194.c: Adjust correctly.
* gcc.target/riscv/rvv/xtheadvector/prefix.c: Likewise.
* gcc.target/riscv/rvv/xtheadvector/vlb-vsb.c: Likewise.
* gcc.target/riscv/rvv/xtheadvector/vlbu-vsb.c: Likewise.
* gcc.target/riscv/rvv/xtheadvector/vlh-vsh.c: Likewise.
* gcc.target/riscv/rvv/xtheadvector/vlhu-vsh.c: Likewise.
* gcc.target/riscv/rvv/xtheadvector/vlw-vsw.c: Likewise.
* gcc.target/riscv/rvv/xtheadvector/vlwu-vsw.c: Likewise.
* gcc.target/riscv/rvv/xtheadvector/xtheadvector.exp: New test.
---
 .../riscv/rvv/xtheadvector/pr114194.c | 32 +++
 .../riscv/rvv/xtheadvector/prefix.c   |  2 +-
 .../riscv/rvv/xtheadvector/vlb-vsb.c  | 17 
 .../riscv/rvv/xtheadvector/vlbu-vsb.c | 17 
 .../riscv/rvv/xtheadvector/vlh-vsh.c  | 17 
 .../riscv/rvv/xtheadvector/vlhu-vsh.c | 17 
 .../riscv/rvv/xtheadvector/vlw-vsw.c  | 17 
 .../riscv/rvv/xtheadvector/vlwu-vsw.c | 17 
 .../riscv/rvv/xtheadvector/xtheadvector.exp   | 40 +++
 9 files changed, 117 insertions(+), 59 deletions(-)
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/xtheadvector.exp

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr114194.c 
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr114194.c
index a82e2d3fbfe6..5c9777b071b5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr114194.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr114194.c
@@ -1,11 +1,11 @@
 /* { dg-do compile { target { ! riscv_abi_e } } } */
-/* { dg-options "-march=rv32gc_xtheadvector" { target { rv32 } } } */
-/* { dg-options "-march=rv64gc_xtheadvector" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadvector -O2" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xtheadvector -O2" { target { rv64 } } } */
 /* { dg-final { check-function-bodies "**" "" } } */
 
 /*
 ** foo0_1:
-** sb\tzero,0([a-x0-9]+)
+** sb\tzero,0\([a-x0-9]+\)
 ** ret
 */
 void foo0_1 (void *p)
@@ -15,13 +15,13 @@ void foo0_1 (void *p)
 
 /*
 ** foo0_7:
-** sb\tzero,0([a-x0-9]+)
-** sb\tzero,1([a-x0-9]+)
-** sb\tzero,2([a-x0-9]+)
-** sb\tzero,3([a-x0-9]+)
-** sb\tzero,4([a-x0-9]+)
-** sb\tzero,5([a-x0-9]+)
-** sb\tzero,6([a-x0-9]+)
+** sb\tzero,0\([a-x0-9]+\)
+** sb\tzero,1\([a-x0-9]+\)
+** sb\tzero,2\([a-x0-9]+\)
+** sb\tzero,3\([a-x0-9]+\)
+** sb\tzero,4\([a-x0-9]+\)
+** sb\tzero,5\([a-x0-9]+\)
+** sb\tzero,6\([a-x0-9]+\)
 ** ret
 */
 void foo0_7 (void *p)
@@ -32,7 +32,7 @@ void foo0_7 (void *p)
 /*
 ** foo1_1:
 ** li\t[a-x0-9]+,1
-** sb\t[a-x0-9]+,0([a-x0-9]+)
+** sb\t[a-x0-9]+,0\([a-x0-9]+\)
 ** ret
 */
 void foo1_1 (void *p)
@@ -43,11 +43,11 @@ void foo1_1 (void *p)
 /*
 ** foo1_5:
 ** li\t[a-x0-9]+,1
-** sb\t[a-x0-9]+,0([a-x0-9]+)
-** sb\t[a-x0-9]+,1([a-x0-9]+)
-** sb\t[a-x0-9]+,2([a-x0-9]+)
-** sb\t[a-x0-9]+,3([a-x0-9]+)
-** sb\t[a-x0-9]+,4([a-x0-9]+)
+** sb\t[a-x0-9]+,0\([a-x0-9]+\)
+** sb\t[a-x0-9]+,1\([a-x0-9]+\)
+** sb\t[a-x0-9]+,2\([a-x0-9]+\)
+** sb\t[a-x0-9]+,3\([a-x0-9]+\)
+** sb\t[a-x0-9]+,4\([a-x0-9]+\)
 ** ret
 */
 void foo1_5 (void *p)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/prefix.c 
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/prefix.c
index eee727ef6b42..0a18e697830c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/prefix.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/prefix.c
@@ -9,4 +9,4 @@ prefix (vint32m1_t vx, vint32m1_t vy, size_t vl)
   return __riscv_vadd_vv_i32m1 (vx, vy, vl);
 }
 
-/* { dg-final { scan-assembler {\mth\.v\M} } } */
+/* { dg-final { scan-assembler {\mth\.vadd\.vv\M} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlb-vsb.c 
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlb-vsb.c
index 3c12c1245974..16073ccb2366 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlb-vsb.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlb-vsb.c
@@ -5,7 +5,8 @@
 
 /*
 ** f1:
-** th.vsetivli\tzero,4,e32,m1,tu,ma
+** li\t[a-x0-9]+,4
+** th.vsetvli\tzero,[a-x0-9]+,e32,m1
 ** th.vlb\.v\tv[0-9]+,0\([a-x0-9]+\)
 ** th.vlb\.v\tv[0-9]+,0\([a-x0-9]+\)
 ** th.vadd\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
@@ -24,9 +25,10 @@ void f1 (void * in, void *out)
 
 /*
 ** f2:
-** th.vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
-** th.vlm.v\tv[0-9]+,0\([a-x0-9]+\)
-** th.vsetivli\tzero,4,e32,m1,ta,ma
+** th.vsetvli\tzero,zero,e8,m1
+** th.vle.v\tv[0-9]+,0\([a-x0-9]+\)
+** li\t[a-x0-9]+,4
+** th.vsetvli\tzero,[a-x0-9]+,e32,m1
 ** th.vlb.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
 ** th.vadd\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
 ** th.vadd\.vv\tv[1-9][0-9]?,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t
@@ -46,9 +48,10 @@ void f2 (

Re: [PATCH] MAINTAINERS: Add myself to write after approval

2025-01-17 Thread Jin Ma
Ping

BR,
Jin


Re: [PATCH v3 1/2] RISC-V: Allocate the initial register in the expand phase for the vl of XTheadVector

2025-01-17 Thread Jin Ma
> > Since the parameter vl of XTheadVector does not support immediate numbers, 
> > we need
> > to put it in the register in advance. That generates the initial code 
> > correctly.
> >
> >  PR 116593
> >
> > gcc/ChangeLog:
> >
> >  * config/riscv/riscv-vector-builtins.cc 
> > (function_expander::add_input_operand):
> >  Put immediate for vl to GPR for XTheadVector.
> 
> Generally both patches look reasonable to me and the change is less invasive
> than going via spec_restriction.
> 
> How was this tested?  The Rivos CI has already picked it up but please still
> always specify.  Thanks.

I'm not sure what you mean, but I'll do my best to understand.
If you're referring to how to test the logic of this code to ensure it works
as intended, it can be quite challenging to explain. Testing this particular
code is not straightforward. Even without any specific processing, the 
predicate 
"vector_length_operand" still constrains the XTheadVector, and the immediate
value for VL will be stored in the register. In this sense, the code itself
may seem redundant.

However, I submitted the patch to generate the correct pattern in generate_insn
rather than relying solely on "vector_length_operand" to ensure correctness.
This approach aims to make the code more robust and reliable.

As for how to test, I don't have a good idea yet. At present, it is just a
simple test to store the immediate number of Vl in the register. Obviously,
this coincides with the function of "vector_length_operand.

In fact, I was also hesitating whether we needed this patch, and finally
submitted it in order to see your opinion.

> > +  /* Since the parameter vl of XTheadVector does not support
> > + immediate numbers, we need to put it in the register
> > + in advance.  */
> > +  if (TARGET_XTHEADVECTOR
> > +  && CONST_INT_P (x)
> > +  && base->apply_vl_p ()
> > +  && argno == (unsigned) (call_expr_nargs (exp) - 1)
> > +  && x != CONST0_RTX (GET_MODE (x)))
> > +{
> > +  x = force_reg (word_mode, x);
> > +  add_input_operand (TYPE_MODE (TREE_TYPE (arg)), x);
> > +}
> > +  else
> > +add_input_operand (TYPE_MODE (TREE_TYPE (arg)), x);
> >  }
> 
> To me it feels as if this would better fit one level higher rather than
> checking ARGNO and apply_vl_p here.  Is that somehow too cumbersome?

While it is generally preferable to handle operations at the upper layer, 
involving
multiple upper layers could complicate maintenance. Additionally, the 
processing for
VL has already been largely completed by ARGNO and apply_vl_p. Therefore, I 
prefer
not to introduce further changes at the upper level, even though this means 
that every
call to add_input_operand will be checked, potentially leading to a slight 
decrease in
compilation efficiency.

> > +# GCC testsuite that uses the `dg.exp' driver.
> > +
> > +# Test the front-end for C++.
> > +# We don't need to test back-end code-gen in RV32 system for C++
> > +# Because it is already tested in C.
> > +# Exit immediately if this isn't a RISC-V target.
> > +if ![istarget riscv*-*-*] then {
> > +  return
> > +}
> 
> Might want to adjust those comments slightly ;)
>
> Apologies, I mixed up patches.  Still it's not really a front-end test IMHO
> but just a minor nit anyway.

Here I simply copied it form rvv.exp and didn't notice the comments, my fault. 
I will modify, thanks. :)

Regards,
Jin

> 
> -- 
> Regards
>  Robin

[PATCH v3 1/2] RISC-V: Allocate the initial register in the expand phase for the vl of XTheadVector

2025-01-16 Thread Jin Ma
Since the parameter vl of XTheadVector does not support immediate numbers, we 
need
to put it in the register in advance. That generates the initial code correctly.

PR 116593

gcc/ChangeLog:

* config/riscv/riscv-vector-builtins.cc 
(function_expander::add_input_operand):
Put immediate for vl to GPR for XTheadVector.

gcc/testsuite/ChangeLog:

* g++.target/riscv/xtheadvector/pr116593-1.C: New test.
* g++.target/riscv/xtheadvector/xtheadvector.exp: New test.
---
 gcc/config/riscv/riscv-vector-builtins.cc | 16 +++-
 .../riscv/xtheadvector/pr116593-1.C   | 12 ++
 .../riscv/xtheadvector/xtheadvector.exp   | 37 +++
 3 files changed, 64 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.target/riscv/xtheadvector/pr116593-1.C
 create mode 100644 gcc/testsuite/g++.target/riscv/xtheadvector/xtheadvector.exp

diff --git a/gcc/config/riscv/riscv-vector-builtins.cc 
b/gcc/config/riscv/riscv-vector-builtins.cc
index d2fe849c693e..b77f0b1567c1 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -4120,7 +4120,21 @@ function_expander::add_input_operand (unsigned argno)
 {
   tree arg = CALL_EXPR_ARG (exp, argno);
   rtx x = expand_normal (arg);
-  add_input_operand (TYPE_MODE (TREE_TYPE (arg)), x);
+
+  /* Since the parameter vl of XTheadVector does not support
+ immediate numbers, we need to put it in the register
+ in advance.  */
+  if (TARGET_XTHEADVECTOR
+  && CONST_INT_P (x)
+  && base->apply_vl_p ()
+  && argno == (unsigned) (call_expr_nargs (exp) - 1)
+  && x != CONST0_RTX (GET_MODE (x)))
+{
+  x = force_reg (word_mode, x);
+  add_input_operand (TYPE_MODE (TREE_TYPE (arg)), x);
+}
+  else
+add_input_operand (TYPE_MODE (TREE_TYPE (arg)), x);
 }
 
 /* Since we may normalize vop/vop_tu/vop_m/vop_tumu.. into a single patter.
diff --git a/gcc/testsuite/g++.target/riscv/xtheadvector/pr116593-1.C 
b/gcc/testsuite/g++.target/riscv/xtheadvector/pr116593-1.C
new file mode 100644
index ..6590dcbe5030
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/xtheadvector/pr116593-1.C
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_xtheadvector -mabi=ilp32d -O2" { target { rv32 
} } } */
+/* { dg-options "-march=rv64gc_xtheadvector -mabi=lp64d -O2" { target { rv64 } 
} } */
+
+#include 
+
+vint32m1_t foo (vint32m1_t vs2, vint32m1_t vs1)
+{
+   return __riscv_vadd_vv_i32m1(vs2, vs1, 3);
+}
+
+/* { dg-final { scan-assembler-times "li\ta\[0-9\],3\n" 1 } } */
diff --git a/gcc/testsuite/g++.target/riscv/xtheadvector/xtheadvector.exp 
b/gcc/testsuite/g++.target/riscv/xtheadvector/xtheadvector.exp
new file mode 100644
index ..40c868b0d805
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/xtheadvector/xtheadvector.exp
@@ -0,0 +1,37 @@
+# Copyright (C) 2023-2025 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# .
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Test the front-end for C++.
+# We don't need to test back-end code-gen in RV32 system for C++
+# Because it is already tested in C.
+# Exit immediately if this isn't a RISC-V target.
+if ![istarget riscv*-*-*] then {
+  return
+}
+
+# Load support procs.
+load_lib g++-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] "" ""
+
+# All done.
+dg-finish
-- 
2.25.1



[PATCH v3 2/2] RISC-V: Add a new constraint to ensure that the vl of XTheadVector does not produce a non-zero immediate.

2025-01-16 Thread Jin Ma
Although we have handled the vl of XTheadVector correctly in the
expand phase and predicates, the results show that the work is
still insufficient.

In the curr_insn_transform function, the insn is transformed from:
(insn 69 67 225 12 (set (mem:RVVM8SF (reg/f:DI 218 [ _77 ]) [0  S[128, 128] 
A32])
(if_then_else:RVVM8SF (unspec:RVVMF4BI [
(const_vector:RVVMF4BI repeat [
(const_int 1 [0x1])
])
(reg:DI 209)
(const_int 0 [0])
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
(reg/v:RVVM8SF 143 [ _xx ])
(mem:RVVM8SF (reg/f:DI 218 [ _77 ]) [0  S[128, 128] A32])))
 (expr_list:REG_DEAD (reg/v:RVVM8SF 143 [ _xx ])
(nil)))
to
(insn 69 284 225 11 (set (mem:RVVM8SF (reg/f:DI 18 s2 [orig:218 _77 ] [218]) [0 
 S[128, 128] A32])
(if_then_else:RVVM8SF (unspec:RVVMF4BI [
(const_vector:RVVMF4BI repeat [
(const_int 1 [0x1])
])
(const_int 1 [0x1])
(const_int 0 [0])
(reg:SI 66 vl)
(reg:SI 67 vtype)
] UNSPEC_VPREDICATE)
(reg/v:RVVM8SF 104 v8 [orig:143 _xx ] [143])
(mem:RVVM8SF (reg/f:DI 18 s2 [orig:218 _77 ] [218]) [0  S[128, 128] 
A32])))
 (nil))

Looking at the log for the reload pass, it is found that "Changing pseudo 209 in
operand 3 of insn 69 on equiv 0x1".
It converts the vl operand in insn from the expected register(reg:DI 209) to the
constant 1(const_int 1 [0x1]).

This conversion occurs because, although the predicate for the vl operand is
restricted by "vector_length_operand" in the pattern, the constraint is still
"rK", which allows the transformation.

The issue is that changing the "rK" constraint to "rJ" for the constraint of vl
operand in the pattern would prevent this conversion, But unfortunately this 
will
conflict with RVV (RISC-V Vector Extension).

Based on the review's recommendations, the best solution for now is to create
a new constraint to distinguish between RVV and XTheadVector, which is exactly
what this patch does.

PR 116593

gcc/ChangeLog:

* config/riscv/constraints.md (vl): New.
* config/riscv/thead-vector.md: Likewise.
* config/riscv/vector.md: Likewise.

gcc/testsuite/ChangeLog:

* g++.target/riscv/xtheadvector/pr116593-2.C: New test.
---
 gcc/config/riscv/constraints.md   |   6 +
 gcc/config/riscv/thead-vector.md  |  18 +-
 gcc/config/riscv/vector.md| 466 +-
 .../riscv/xtheadvector/pr116593-2.C   |  47 ++
 4 files changed, 295 insertions(+), 242 deletions(-)
 create mode 100644 gcc/testsuite/g++.target/riscv/xtheadvector/pr116593-2.C

diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index f25975dc0208..df62491b2edc 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -209,6 +209,12 @@ (define_constraint "vk"
   (and (match_code "const_vector")
(match_test "riscv_vector::const_vec_all_same_in_range_p (op, 0, 31)")))
 
+(define_constraint "vl"
+  "A uimm5 for vector or zero for XTheadVector."
+  (and (match_code "const_int")
+   (ior (match_test "!TARGET_XTHEADVECTOR && satisfies_constraint_K (op)")
+   (match_test "TARGET_XTHEADVECTOR && satisfies_constraint_J (op)"
+
 (define_constraint "Wc0"
   "@internal
  A constraint that matches a vector of immediate all zeros."
diff --git a/gcc/config/riscv/thead-vector.md b/gcc/config/riscv/thead-vector.md
index 5fe9ba08c4eb..5a02debdd207 100644
--- a/gcc/config/riscv/thead-vector.md
+++ b/gcc/config/riscv/thead-vector.md
@@ -108,7 +108,7 @@ (define_insn_and_split "@pred_th_whole_mov"
   [(set (match_operand:V_VLS_VT 0 "reg_or_mem_operand"  "=vr,vr, m")
(unspec:V_VLS_VT
  [(match_operand:V_VLS_VT 1 "reg_or_mem_operand" " vr, m,vr")
-  (match_operand 2 "vector_length_operand"   " rK, rK, rK")
+  (match_operand 2 "vector_length_operand"   "rvl,rvl,rvl")
   (match_operand 3 "const_1_operand" "  i, i, i")
   (reg:SI VL_REGNUM)
   (reg:SI VTYPE_REGNUM)]
@@ -133,7 +133,7 @@ (define_insn_and_split "@pred_th_whole_mov"
   [(set (match_operand:VB 0 "reg_or_mem_operand"  "=vr,vr, m")
(unspec:VB
  [(match_operand:VB 1 "reg_or_mem_operand" " vr, m,vr")
-  (match_operand 2 "vector_length_operand"   " rK, rK, rK")
+  (match_operand 2 "vector_length_operand"   "rvl,rvl,rvl")
   (match_operand 3 "const_1_operand" "  i, i, i")
   (reg:SI VL_REGNUM)
   (reg:SI VTYPE_REGNUM)]
@@ -161,7 +161,7 @@ (define_insn_and_split "*pred_th_mov"
(if_then_else:VB_VLS
  (unspec:VB_VLS
[(match_operand:VB_VLS 1 "vector_all_trues_

[PATCH] RISC-V: Disable fusing vsetvl instructions by VSETVL_VTYPE_CHANGE_ONLY for XTheadVector.

2025-01-17 Thread Jin Ma
In RVV 1.0, the instruction "vsetvlizero,zero,*" indicates that the
available vector length (avl) does not change. However, in XTheadVector,
this same instruction signifies that the avl should take the maximum value.
Consequently, when fusing vsetvl instructions, the optimization labeled
"VSETVL_VTYPE_CHANGE_ONLY" is disabled for XTheadVector.

PR 118357

gcc/ChangeLog:

* config/riscv/riscv-vsetvl.cc: Function change_vtype_only_p always
returns false for XTheadVector.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/xtheadvector/pr118357.c: New test.

Reported-by: nihui 
---
 gcc/config/riscv/riscv-vsetvl.cc|  3 ++-
 .../gcc.target/riscv/rvv/xtheadvector/pr118357.c| 13 +
 2 files changed, 15 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr118357.c

diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index a4016beebc0c..72c4c59514e5 100644
--- a/gcc/config/riscv/riscv-vsetvl.cc
+++ b/gcc/config/riscv/riscv-vsetvl.cc
@@ -903,7 +903,8 @@ public:
   bool valid_p () const { return m_state == state_type::VALID; }
   bool unknown_p () const { return m_state == state_type::UNKNOWN; }
   bool empty_p () const { return m_state == state_type::EMPTY; }
-  bool change_vtype_only_p () const { return m_change_vtype_only; }
+  bool change_vtype_only_p () const { return m_change_vtype_only
+&& !TARGET_XTHEADVECTOR; }
 
   void set_valid () { m_state = state_type::VALID; }
   void set_unknown () { m_state = state_type::UNKNOWN; }
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr118357.c 
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr118357.c
new file mode 100644
index ..aebb0e3088ab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr118357.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { rv64 } } } */
+/* { dg-options "-march=rv64gc_xtheadvector -mabi=lp64d -O2" } */
+
+#include 
+
+vfloat16m4_t foo (float *ptr, size_t vl)
+{
+  vfloat32m8_t _p = __riscv_vle32_v_f32m8 (ptr, vl);
+  vfloat16m4_t _half = __riscv_vfncvt_f_f_w_f16m4 (_p, vl);
+  return _half;
+}
+
+/* { dg-final { scan-assembler-not {th.vsetvli\tzero,zero} } }*/
-- 
2.25.1



[PATCH] RISC-V: Fix failed tests for regression due to fix ICE patch

2025-02-16 Thread Jin Ma
Ref:
https://github.com/ewlu/gcc-precommit-ci/issues/3096#issue-2854419069

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/bug-9.c: Added new failure check.
* gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-17.c: 
Likewise.
* gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-18.c: 
Likewise.
* gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-19.c: 
Likewise.
* gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-20.c: 
Likewise.
* gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-21.c: 
Likewise.
* gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-22.c: 
Likewise.
* gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-23.c: 
Likewise.
* gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-24.c: 
Likewise.
* gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-25.c: 
Likewise.
* gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-26.c: 
Likewise.
* gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-27.c: 
Likewise.
* gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-28.c: 
Likewise.
* gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-29.c: 
Likewise.
* gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-3.c: 
Likewise.
---
 gcc/testsuite/gcc.target/riscv/rvv/base/bug-9.c  | 1 +
 .../riscv/rvv/base/target_attribute_v_with_intrinsic-17.c| 1 +
 .../riscv/rvv/base/target_attribute_v_with_intrinsic-18.c| 1 +
 .../riscv/rvv/base/target_attribute_v_with_intrinsic-19.c| 1 +
 .../riscv/rvv/base/target_attribute_v_with_intrinsic-20.c| 1 +
 .../riscv/rvv/base/target_attribute_v_with_intrinsic-21.c| 1 +
 .../riscv/rvv/base/target_attribute_v_with_intrinsic-22.c| 1 +
 .../riscv/rvv/base/target_attribute_v_with_intrinsic-23.c| 1 +
 .../riscv/rvv/base/target_attribute_v_with_intrinsic-24.c| 1 +
 .../riscv/rvv/base/target_attribute_v_with_intrinsic-25.c| 1 +
 .../riscv/rvv/base/target_attribute_v_with_intrinsic-26.c| 1 +
 .../riscv/rvv/base/target_attribute_v_with_intrinsic-27.c| 1 +
 .../riscv/rvv/base/target_attribute_v_with_intrinsic-28.c| 1 +
 .../riscv/rvv/base/target_attribute_v_with_intrinsic-29.c| 1 +
 .../riscv/rvv/base/target_attribute_v_with_intrinsic-3.c | 1 +
 15 files changed, 15 insertions(+)

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/bug-9.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-9.c
index 20ae9ebf6f2..8cfe9658875 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/bug-9.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-9.c
@@ -11,3 +11,4 @@ vfloat16m1_t f0 (vfloat16m1_t vs2, vfloat16m1_t vs1, size_t 
vl)
 }
 
 /* { dg-error "return type 'vfloat16m1_t' requires the zvfhmin or zvfh ISA 
extension" "" { target { "riscv*-*-*" } } 0 } */
+/* { dg-error "argument type 'vfloat16m1_t' requires the zvfhmin or zvfh ISA 
extension" "" { target { "riscv*-*-*" } } 0 } */
diff --git 
a/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-17.c
 
b/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-17.c
index a064417169d..ebe31f5c961 100644
--- 
a/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-17.c
+++ 
b/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-17.c
@@ -11,3 +11,4 @@ test_1 (vint64m1_t a, vint64m1_t b, size_t vl)
 }
 
 /* { dg-error "return type 'vint64m1_t' requires the zve64x, zve64f, zve64d or 
v ISA extension" "" { target { "riscv*-*-*" } } 0 } */
+/* { dg-error "argument type 'vint64m1_t' requires the zve64x, zve64f, zve64d 
or v ISA extension" "" { target { "riscv*-*-*" } } 0 } */
diff --git 
a/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-18.c
 
b/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-18.c
index 61d3fb25dc2..7e9a101795d 100644
--- 
a/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-18.c
+++ 
b/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-18.c
@@ -11,3 +11,4 @@ test_1 (vfloat32m1_t a, vfloat32m1_t b, size_t vl)
 }
 
 /* { dg-error "return type 'vfloat32m1_t' requires the zve32f, zve64f, zve64d 
or v ISA extension" "" { target { "riscv*-*-*" } } 0 } */
+/* { dg-error "argument type 'vfloat32m1_t' requires the zve32f, zve64f, 
zve64d or v ISA extension" "" { target { "riscv*-*-*" } } 0 } */
\ No newline at end of file
diff --git 
a/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-19.c
 
b/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-19.c
index bfc26f8210a..b5354f4291f 100644
--- 
a/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-19.c
+++ 
b/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-19.c
@@ -11,

Re: [PATCH] RISC-V: Bugfix ICE for RVV intrinisc when using no-extension parameters

2025-02-16 Thread Jin Ma
On Sat, 15 Feb 2025 20:59:37 -0700, Jeff Law wrote:
> 
> 
> On 2/14/25 12:12 AM, Jin Ma wrote:
> > When using riscv_v_abi, the return and arguments of the function should
> > be adequately checked to avoid ICE.
> > 
> > PR target/118872
> > 
> > gcc/ChangeLog:
> > 
> > * config/riscv/riscv.cc (riscv_fntype_abi): Strengthen the logic
> > of the check to avoid missing the error report.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * gcc.target/riscv/rvv/base/pr118872.c: New test.
> Note this is causing regressions in the pre-commit CI system:
> 
> 
> > https://github.com/ewlu/gcc-precommit-ci/issues/3096#issuecomment-2659969415
> 
> 
> Can you please take care of those regressions.  Thanks.

Patch:
https://gcc.gnu.org/pipermail/gcc-patches/2025-February/675923.html

Resolved-regressions:
https://github.com/ewlu/gcc-precommit-ci/issues/3106

Best regards,
Jin Ma

> jeff



Re: [PATCH 1/2] Add TARGET_COMPUTE_MULTILIB_OS hook to override multi-lib-os result.

2025-02-16 Thread Jin Ma

On Fri, 14 Feb 2025 21:03:46 +0800, Jin Ma wrote:
> Create a new hook to let target could override the multi-lib-os result.
> 
> The motivation for this change arises from the fact that using
> TARGET_COMPUTE_MULTILIB to override the original multilib_dir can lead
> to unexpected behavior with multilib_os_dir.
> 
> In our build scripts, we establish a connection between multilib_os_dir
> and multilib_dir. For example, in gcc/config/riscv/t-linux, we set
> multilib_os_dir to be the parent directory of multilib_dir. However,
> when TARGET_COMPUTE_MULTILIB overrides multilib_dir and returns a reused
> result for multilib_dir, multilib_os_dir ends up being identical to
> multilib_dir. This discrepancy is clearly inconsistent with our
> expectations.
> 
> gcc/ChangeLog:
> 
>   * common/common-target.def (compute_multilib_os): New.
>   * common/common-targhooks.cc (default_compute_multilib_os): New.
>   * common/common-targhooks.h (default_compute_multilib_os): New.
>   * doc/tm.texi (TARGET_COMPUTE_MULTILIB_OS): New.
>   * doc/tm.texi.in: Regen.
>   * gcc.cc (set_multilib_dir): Call targetm_common.compute_multilib_os.
> ---
>  gcc/common/common-target.def   | 14 ++
>  gcc/common/common-targhooks.cc |  9 +
>  gcc/common/common-targhooks.h  |  5 +
>  gcc/doc/tm.texi| 10 ++
>  gcc/doc/tm.texi.in |  1 +
>  gcc/gcc.cc |  4 
>  6 files changed, 43 insertions(+)

Ping :)

Ref:
https://gcc.gnu.org/pipermail/gcc-patches/2025-February/675786.html
https://gcc.gnu.org/pipermail/gcc-patches/2025-February/675787.html

Best regards,
Jin Ma

Re: [PATCH] RISC-V: Bugfix ICE for RVV intrinisc when using no-extension parameters

2025-02-15 Thread Jin Ma
Committed - thanks!

Palmer Dabbelt  于2025年2月15日周六 01:16写道:
>
> On Thu, 13 Feb 2025 23:12:54 PST (-0800), ji...@linux.alibaba.com wrote:
> > When using riscv_v_abi, the return and arguments of the function should
> > be adequately checked to avoid ICE.
> >
> >   PR target/118872
> >
> > gcc/ChangeLog:
> >
> >   * config/riscv/riscv.cc (riscv_fntype_abi): Strengthen the logic
> >   of the check to avoid missing the error report.
> >
> > gcc/testsuite/ChangeLog:
> >
> >   * gcc.target/riscv/rvv/base/pr118872.c: New test.
> > ---
> >  gcc/config/riscv/riscv.cc  | 10 +++---
> >  gcc/testsuite/gcc.target/riscv/rvv/base/pr118872.c | 13 +
> >  2 files changed, 20 insertions(+), 3 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr118872.c
> >
> > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> > index 6e14126e3a4..9bf7713139f 100644
> > --- a/gcc/config/riscv/riscv.cc
> > +++ b/gcc/config/riscv/riscv.cc
> > @@ -6479,9 +6479,13 @@ riscv_fntype_abi (const_tree fntype)
> >/* Implement the vector calling convention.  For more details please
> >   reference the below link.
> >   https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/389  */
> > -  if (riscv_return_value_is_vector_type_p (fntype)
> > -   || riscv_arguments_is_vector_type_p (fntype)
> > -   || riscv_vector_cc_function_p (fntype))
> > +  bool validate_v_abi_p = false;
> > +
> > +  validate_v_abi_p |= riscv_return_value_is_vector_type_p (fntype);
> > +  validate_v_abi_p |= riscv_arguments_is_vector_type_p (fntype);
> > +  validate_v_abi_p |= riscv_vector_cc_function_p (fntype);
>
> There's probably a cleaner way to do this: we're essentially relying on
> the error_at()s in riscv_validate_vector_type() to catch unsupported
> vector sub-types, which means the users have side effects.  That's
> probably going to catch people out again at some point.
>
> That said: this function is the only user of those helpers so I think
> it's correct (IIUC "|=" doesn't short circuit because it's bitwise op,
> not a logical op) and fixes a ICE.  So
>
> Reviewed-by: Palmer Dabbelt 
>
> as we can always find some way to make it easier to understand later.
>
> Thanks!
>
> > +
> > +  if (validate_v_abi_p)
> >  return riscv_v_abi ();
> >
> >return default_function_abi;
> > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr118872.c 
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/pr118872.c
> > new file mode 100644
> > index 000..adb54d648a5
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr118872.c
> > @@ -0,0 +1,13 @@
> > +/* Test that we do not have ice when compile */
> > +/* { dg-do assemble } */
> > +/* { dg-options "-march=rv64gcv -mabi=lp64d -O2"  { target { rv64 } } } */
> > +/* { dg-options "-march=rv32gcv -mabi=ilp32d -O2"  { target { rv32 } } } */
> > +
> > +#include 
> > +
> > +vfloat32m2_t foo (vfloat16m1_t a, size_t vl)
> > +{
> > +  return __riscv_vfwcvt_f_f_v_f32m2(a, vl);
> > +}
> > +
> > +/* { dg-error "argument type 'vfloat16m1_t' requires the zvfhmin or zvfh 
> > ISA extension" "" { target { "riscv*-*-*" } } 0 } */


Re: [PATCH] RISC-V: Bugfix ICE for RVV intrinisc when using no-extension parameters

2025-02-15 Thread Jin Ma
On Sun, 16 Feb 2025 11:59:37 +0800, Jeff Law wrote:
> 
> 
> On 2/14/25 12:12 AM, Jin Ma wrote:
> > When using riscv_v_abi, the return and arguments of the function should
> > be adequately checked to avoid ICE.
> > 
> > PR target/118872
> > 
> > gcc/ChangeLog:
> > 
> > * config/riscv/riscv.cc (riscv_fntype_abi): Strengthen the logic
> > of the check to avoid missing the error report.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * gcc.target/riscv/rvv/base/pr118872.c: New test.
> Note this is causing regressions in the pre-commit CI system:
> 
> 
> > https://github.com/ewlu/gcc-precommit-ci/issues/3096#issuecomment-2659969415
> 
> 
> Can you please take care of those regressions.  Thanks.

I sincerely apologize for the issues caused. I will work on resolving them. 
Before
submitting, I only performed regression tests locally for rv64gc-lp64d and 
rv32gc-ilp32d,
and it seems that was insufficient.

Should I also run regressions for the following?
  rv32gc-ilp32d
  rv32gc_zba_zbb_zbc_zbs-ilp32d
  rv32gcv-ilp32d
  rv32imc_zba_zbb_zbc_zbs-ilp32
  rv64gc-lp64d
  rv64gc_zba_zbb_zbc_zbs-lp64d
  rv64gcv-lp64d

Additionally, I've noticed that when I run regression tests on the master 
branch using
rv64gcv-lp64d or rv32gcv-ilp32d without applying any patches, there are still 
over 300
failures related to RVV. I'm unsure if there is an issue with my testing 
approach.

https://gcc.gnu.org/pipermail/gcc-testresults/2025-February/838574.html

Best regards,
Jin Ma

> jeff



Re: [v5,2/4] RISC-V: Add Zicfilp ISA extension

2025-03-13 Thread Jin Ma
On Fri, 14 Mar 2025 13:30:39 +0800, Monk Chiang wrote:
> Hi Jin Ma,
>   This situation is the same on x86. When using -O0, the lpad instruction
> is merely a redundant instruction and does not affect the execution result.
>   This is the ASM result for x86, and there is also an endbr64 in foo().
>  https://godbolt.org/z/M1fTendE3

As I mentioned earlier, this is architecture-agnostic (regarding the handling of
static functions at -O0). There is a minor concern about whether it is 
reasonable
to insert instructions into static functions. Currently, LLVM does not encounter
the same issue as GCC (LLVM does not handle static functions in the same way).

Regardless, I understand that this will not affect the execution results. 
However,
I believe it would be best to maintain logical consistency with LLVM (whether 
it's
about lpad instructions or static functions in -O0). I'm not entirely certain, 
but I wanted
to bring this up to hear everyone's thoughts on the matter :)

Best regards,
Jin Ma


> On Wed, Mar 12, 2025 at 5:44=E2=80=AFPM Jin Ma  
> wrote:
> 
> > Hi, Monk Chiang
> >
> > I noticed that at -O0, static functions are emitting lpad instructions,
> > whereas
> > they do not at -O2. I'm not sure if this is expected behavior.
> >
> > Upon further investigation, I found that c_node->only_called_directly_p()
> > returns
> > false, which is caused by force_output being set to 1. Tracing back, I
> > encountered
> > the following patch[1] and PR25961[2], which set force_output to 1 for
> > static
> > functions at -O0, while it is 0 at -O2.
> >
> > Do you have any comments on this?
> >
> >
> > Example code:
> >
> > int cc = 333;
> > extern int aa;
> >
> > __attribute__((noinline))
> > static void
> > foo(void)
> > {
> >   cc = aa;
> > }
> > int main(void)
> >
> > {
> >   foo();
> >   return 0;
> > }
> >
> > [1] https://gcc.gnu.org/legacy-ml/gcc-patches/2006-05/msg00315.html
> > [2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24561
> >
> 


Re: [PATCH v2]RISC-V:Add xuantie C908, C910, C920v1 and C920v2 to -mcpu

2025-03-20 Thread Jin Ma
ihintpause
>  */
> +
> +#if !((__riscv_xlen == 64)   \
> +  && !defined(__riscv_32e)   \
> +  && defined(__riscv_mul)\
> +  && defined(__riscv_atomic) \
> +  && (__riscv_flen == 64)\
> +  && defined(__riscv_compressed) \
> +  && defined(__riscv_zihintpause) \
> +  && defined(__riscv_zba) \
> +  && defined(__riscv_zbb) \
> +  && defined(__riscv_zbc) \
> +  && defined(__riscv_zbs) \
> +  && defined(__riscv_zfh) \
> +  && defined(__riscv_xtheadba)   \
> +  && defined(__riscv_xtheadbb)   \
> +  && defined(__riscv_xtheadbs)   \
> +  && defined(__riscv_xtheadcmo)  \
> +  && defined(__riscv_xtheadcondmov)  \
> +  && defined(__riscv_xtheadfmemidx)  \
> +  && defined(__riscv_xtheadmac)  \
> +  && defined(__riscv_xtheadmemidx)   \
> +  && defined(__riscv_xtheadmempair)  \
> +  && defined(__riscv_xtheadsync)) 
> +#error "unexpected arch"
> +#endif
> +
> +int main()
> +{
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/mcpu-xt-c910.c 
> b/gcc/testsuite/gcc.target/riscv/mcpu-xt-c910.c
> new file mode 100644
> index 000..7a813c3071e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/mcpu-xt-c910.c
> @@ -0,0 +1,29 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "-march given" { *-*-* } { "-march=*" } } */
> +/* { dg-options "-mcpu=xt-c910" { target { rv64 } } } */
> +/* XuanTie C910 => 
> rv64imafdc_zfh_xtheadba_xtheadbb_xtheadbs_xtheadcmo_xtheadcondmov_xtheadfmemidx_xtheadint_xtheadmac_xtheadmemidx_xtheadmempair_xtheadsync
>  */
> +
> +#if !((__riscv_xlen == 64)   \
> +  && !defined(__riscv_32e)   \
> +  && defined(__riscv_mul)\
> +  && defined(__riscv_atomic) \
> +  && (__riscv_flen == 64)\
> +  && defined(__riscv_compressed) \
> +  && defined(__riscv_zfh)\
> +  && defined(__riscv_xtheadba)   \
> +  && defined(__riscv_xtheadbb)   \
> +  && defined(__riscv_xtheadbs)   \
> +  && defined(__riscv_xtheadcmo)  \
> +  && defined(__riscv_xtheadcondmov)  \
> +  && defined(__riscv_xtheadfmemidx)  \
> +  && defined(__riscv_xtheadmac)  \
> +  && defined(__riscv_xtheadmemidx)   \
> +  && defined(__riscv_xtheadmempair)  \
> +  && defined(__riscv_xtheadsync)) 
> +#error "unexpected arch"
> +#endif
> +
> +int main()
> +{
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/mcpu-xt-c920v1.c 
> b/gcc/testsuite/gcc.target/riscv/mcpu-xt-c920v1.c
> new file mode 100644
> index 000..f81d6c2e99c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/mcpu-xt-c920v1.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "-march given" { *-*-* } { "-march=*" } } */
> +/* { dg-options "-mcpu=xt-c920v1" { target { rv64 } } } */
> +/* XuanTie c920v1 => 
> rv64imafdc_zfh_xtheadba_xtheadbb_xtheadbs_xtheadcmo_xtheadcondmov_xtheadfmemidx_xtheadint_xtheadmac_xtheadmemidx_xtheadmempair_xtheadsync_xtheadvector
>  */
> +
> +#if !((__riscv_xlen == 64)   \
> +  && !defined(__riscv_32e)   \
> +  && defined(__riscv_mul)\
> +  && defined(__riscv_atomic) \
> +  && (__riscv_flen == 64)\
> +  && defined(__riscv_compressed) \
> +  && defined(__riscv_zfh)\
> +  && defined(__riscv_xtheadba)   \
> +  && defined(__riscv_xtheadbb)   \
> +  && defined(__riscv_xtheadbs)   \
> +  && defined(__riscv_xtheadcmo)  \
> +  && defined(__riscv_xtheadcondmov)  \
> +  && defined(__riscv_xtheadfmemidx)  \
> +  && defined(__riscv_xtheadmac)  \
> +  && defined(__riscv_xtheadmemidx)   \
> +  && defined(__riscv_xtheadmempair)  \
> +  && defined(__riscv_xtheadsync)) \
> +  && defined(__riscv_xtheadvector) 
> +#error "unexpected arch"
> +#endif
> +
> +int main()
> +{
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/mcpu-xt-c920v2.c 
> b/gcc/testsuite/gcc.target/riscv/mcpu-xt-c920v2.c
> new file mode 100644
> index 000..bd3a06aad49
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/mcpu-xt-c920v2.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "-march given" { *-*-* } { "-march=*" } } */
> +/* { dg-options "-mcpu=xt-c906" { target { rv64 } } } */
> +/* XuanTie C920v2 => 
> rv64imafdcv_zfh_xtheadba_xtheadbb_xtheadbs_xtheadcmo_xtheadcondmov_xtheadfmemidx_xtheadint_xtheadmac_xtheadmemidx_xtheadmempair_xtheadsync
>  */
> +
> +#if !((__riscv_xlen == 64)   \
> +  && !defined(__riscv_32e)   \
> +  && defined(__riscv_mul)\
> +  && defined(__riscv_atomic) \
> +  && (__riscv_flen == 64)\
> +  && defined(__riscv_compressed) \
> +  && defined(__riscv_v) \
> +  && defined(__riscv_zfh)\
> +  && defined(__riscv_xtheadba)   \
> +  && defined(__riscv_xtheadbb)   \
> +  && defined(__riscv_xtheadbs)   \
> +  && defined(__riscv_xtheadcmo)  \
> +  && defined(__riscv_xtheadcondmov)  \
> +  && defined(__riscv_xtheadfmemidx)  \
> +  && defined(__riscv_xtheadmac)  \
> +  && defined(__riscv_xtheadmemidx)   \
> +  && defined(__riscv_xtheadmempair)  \
> +  && defined(__riscv_xtheadsync))
> +#error "unexpected arch"
> +#endif
> +
> +int main()
> +{
> +  return 0;
> +}
> -- 
> 2.47.1

Overall, it’s great! You can refer to the relevant manual for more information. 

https://www.xrvm.cn/community/download?id=4224248662731067392

Best regards,
Jin Ma

Re: [PATCH] RISC-V: Fixbug for slli + addw + zext.w into sh[123]add + zext.w

2025-04-05 Thread Jin Ma
On Tue, 1 Apr 2025 22:57:33 -0600, Jeff Law wrote:
> 
> 
> On 4/1/25 12:20 AM, Jin Ma wrote:
> > Assuming we have the following variables:
> > 
> > unsigned long long a0, a1;
> > unsigned int a2;
> > 
> > For the expression:
> > 
> > a0 = (a0 << 50) >> 49;  // slli a0, a0, 50 + srli a0, a0, 49
> > a2 = a1 + a0;   // addw a2, a1, a0 + slli a2, a2, 32 + srli a2, a2, 
> > 32
> > 
> > In the optimization process of ZBA (combine pass), it would be optimized to:
> > 
> > a2 = a0 << 1 + a1;  // sh1add a2, a0, a1 + zext.w a2, a2
> > 
> > This is clearly incorrect, as it overlooks the fact that a0=a0&0x7ffe, 
> > meaning
> > that the bits a0[32:14] are set to zero.
> > 
> > gcc/ChangeLog:
> > 
> > * config/riscv/bitmanip.md: The optimization can only be applied if
> > the high bit of operands[3] is set to 1.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * gcc.target/riscv/zba-shNadd-09.c: New test.
> > * gcc.target/riscv/zba-shNadd-10.c: New test.
> > ---
> >   gcc/config/riscv/bitmanip.md  |  3 ++-
> >   .../gcc.target/riscv/zba-shNadd-09.c  | 12 +++
> >   .../gcc.target/riscv/zba-shNadd-10.c  | 20 +++
> >   3 files changed, 34 insertions(+), 1 deletion(-)
> >   create mode 100644 gcc/testsuite/gcc.target/riscv/zba-shNadd-09.c
> >   create mode 100644 gcc/testsuite/gcc.target/riscv/zba-shNadd-10.c
> > 
> > diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
> > index b29c127bcb8..9091c48b106 100644
> > --- a/gcc/config/riscv/bitmanip.md
> > +++ b/gcc/config/riscv/bitmanip.md
> > @@ -80,7 +80,8 @@ (define_split
> > (match_operand:DI 3 
> > "consecutive_bits_operand")) 0)
> >  (subreg:SI (match_operand:DI 4 
> > "register_operand") 0]
> > "TARGET_64BIT && TARGET_ZBA
> > -   && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL 
> > (operands[3]))"
> > +   && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL 
> > (operands[3]))
> > +   && ((INTVAL (operands[3]) & (1 << 31)) != 0)"
> > [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) 
> > (match_dup 4)))
> >  (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))])
> So I would add a comment to that new condition.  Something like
> /* Ensure the mask includes all the bits in SImode.  */
> 
> We need to be careful with constants like 1 << 31.  Something like
> (HOST_WIDE_INT_1U << 31) would be better from a type safety standpoint 
> (INTVAL returns a HOST_WIDE_INT object).
> 
> > +#include 
> In general, avoid #includes if you can in tests.  Remove the  
> include.
> 
> > +  printf("%llu\n", d);
> Instead of a printf and using dg-output, the standard way we test for 
> correctness is by either aborting or calling exit (0).  So rather than 
> the printf use
> 
>if (d != 3023282)
>  __builtin_abort ();
>__builtin_exit (0);
> 
> And drop the dg-output line.
> 
> 
> With those changes this patch is probably OK.  We'd want to post the V2 
> so that the pre-commit tester can chew on it.

Yes, Very professional advice. I will make the changes and submit V2.

Best regards,
Jin Ma


[PATCH v2] RISC-V: Disable unsupported vsext/vzext patterns for XTheadVector.

2025-04-06 Thread Jin Ma
XThreadVector does not support the vsext/vzext instructions; however,
due to the reuse of RVV optimizations, it may generate these instructions
in certain cases. To prevent the error "Unknown opcode 'th.vsext.vf2',"
we should disable these patterns.

V2:
Change the value of dg-do in the test case from assemble to compile, and
remove the -save-temps option.

gcc/ChangeLog:

* config/riscv/vector.md: Disable vsext/vzext for XTheadVector.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/xtheadvector/vsext.c: New test.
* gcc.target/riscv/rvv/xtheadvector/vzext.c: New test.
---
 gcc/config/riscv/vector.md|  6 ++---
 .../gcc.target/riscv/rvv/xtheadvector/vsext.c | 24 +++
 .../gcc.target/riscv/rvv/xtheadvector/vzext.c | 24 +++
 3 files changed, 51 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vsext.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vzext.c

diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 8ee43cf0ce1..51eb64fb122 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -3939,7 +3939,7 @@ (define_insn "@pred__vf2"
  (any_extend:VWEXTI
(match_operand: 3 "register_operand" "   vr,   vr"))
  (match_operand:VWEXTI 2 "vector_merge_operand" "   vu,
0")))]
-  "TARGET_VECTOR"
+  "TARGET_VECTOR && !TARGET_XTHEADVECTOR"
   "vext.vf2\t%0,%3%p1"
   [(set_attr "type" "vext")
(set_attr "mode" "")])
@@ -3959,7 +3959,7 @@ (define_insn "@pred__vf4"
  (any_extend:VQEXTI
(match_operand: 3 "register_operand" "   vr,   vr"))
  (match_operand:VQEXTI 2 "vector_merge_operand"   "   vu,0")))]
-  "TARGET_VECTOR"
+  "TARGET_VECTOR && !TARGET_XTHEADVECTOR"
   "vext.vf4\t%0,%3%p1"
   [(set_attr "type" "vext")
(set_attr "mode" "")])
@@ -3979,7 +3979,7 @@ (define_insn "@pred__vf8"
  (any_extend:VOEXTI
(match_operand: 3 "register_operand" "   vr,   vr"))
  (match_operand:VOEXTI 2 "vector_merge_operand"  "   vu,0")))]
-  "TARGET_VECTOR"
+  "TARGET_VECTOR && !TARGET_XTHEADVECTOR"
   "vext.vf8\t%0,%3%p1"
   [(set_attr "type" "vext")
(set_attr "mode" "")])
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vsext.c 
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vsext.c
new file mode 100644
index 000..55db28304c7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vsext.c
@@ -0,0 +1,24 @@
+/* { dg-do compile { target { rv64 } } } */
+/* { dg-options "-march=rv64gc_xtheadvector -mabi=lp64d -O3" } */
+
+#include 
+
+struct a
+{
+  int b[];
+} c (vint32m4_t), d;
+
+char e;
+char *f;
+
+void g ()
+{
+  int h;
+  vint32m4_t i;
+  vint8m1_t j = __riscv_vlse8_v_i8m1 (&e, d.b[3], h);
+  vint16m2_t k = __riscv_vwadd_vx_i16m2 (j, 0, h);
+  i = __riscv_vwmacc_vx_i32m4 (i, f[0], k, h);
+  c (i);
+}
+
+/* { dg-final { scan-assembler-not {th\.vsext\.vf2} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vzext.c 
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vzext.c
new file mode 100644
index 000..fcb565991c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vzext.c
@@ -0,0 +1,24 @@
+/* { dg-do compile { target { rv64 } } } */
+/* { dg-options "-march=rv64gc_xtheadvector -mabi=lp64d -O3" } */
+
+#include 
+
+struct a
+{
+  int b[];
+} c (vuint32m4_t), d;
+
+char e;
+char *f;
+
+void g ()
+{
+  int h;
+  vuint32m4_t i;
+  vuint8m1_t j = __riscv_vlse8_v_u8m1 (&e, d.b[3], h);
+  vuint16m2_t k = __riscv_vwaddu_vx_u16m2 (j, 0, h);
+  i = __riscv_vwmaccu_vx_u32m4 (i, f[0], k, h);
+  c (i);
+}
+
+/* { dg-final { scan-assembler-not {th\.vzext\.vf2} } } */
-- 
2.25.1



[PATCH] RISC-V: Fixbug for slli + addw + zext.w into sh[123]add + zext.w

2025-03-31 Thread Jin Ma
Assuming we have the following variables:

unsigned long long a0, a1;
unsigned int a2;

For the expression:

a0 = (a0 << 50) >> 49;  // slli a0, a0, 50 + srli a0, a0, 49
a2 = a1 + a0;   // addw a2, a1, a0 + slli a2, a2, 32 + srli a2, a2, 32

In the optimization process of ZBA (combine pass), it would be optimized to:

a2 = a0 << 1 + a1;  // sh1add a2, a0, a1 + zext.w a2, a2

This is clearly incorrect, as it overlooks the fact that a0=a0&0x7ffe, meaning
that the bits a0[32:14] are set to zero.

gcc/ChangeLog:

* config/riscv/bitmanip.md: The optimization can only be applied if
the high bit of operands[3] is set to 1.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/zba-shNadd-09.c: New test.
* gcc.target/riscv/zba-shNadd-10.c: New test.
---
 gcc/config/riscv/bitmanip.md  |  3 ++-
 .../gcc.target/riscv/zba-shNadd-09.c  | 12 +++
 .../gcc.target/riscv/zba-shNadd-10.c  | 20 +++
 3 files changed, 34 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/zba-shNadd-09.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zba-shNadd-10.c

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index b29c127bcb8..9091c48b106 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -80,7 +80,8 @@ (define_split
(match_operand:DI 3 
"consecutive_bits_operand")) 0)
 (subreg:SI (match_operand:DI 4 
"register_operand") 0]
   "TARGET_64BIT && TARGET_ZBA
-   && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3]))"
+   && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3]))
+   && ((INTVAL (operands[3]) & (1 << 31)) != 0)"
   [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) 
(match_dup 4)))
(set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))])
 
diff --git a/gcc/testsuite/gcc.target/riscv/zba-shNadd-09.c 
b/gcc/testsuite/gcc.target/riscv/zba-shNadd-09.c
new file mode 100644
index 000..303f3cbb863
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zba-shNadd-09.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zba -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+
+long long sub (unsigned long long a, unsigned long long b)
+{
+  b = (b << 50) >> 49;
+  unsigned int x = a + b;
+  return x;
+}
+
+/* { dg-final { scan-assembler-not {\msh1add} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zba-shNadd-10.c 
b/gcc/testsuite/gcc.target/riscv/zba-shNadd-10.c
new file mode 100644
index 000..bec0260d625
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zba-shNadd-10.c
@@ -0,0 +1,20 @@
+/* { dg-do run { target { rv64 } } } */
+/* { dg-options "-march=rv64gc_zba -mabi=lp64d -O2" } */
+
+#include 
+struct {
+  unsigned a : 14;
+  unsigned b : 3;
+} c;
+unsigned long long d;
+void e(unsigned long long *f, long p2) { *f = p2; }
+signed g;
+long i;
+int main() {
+  c.b = 4;
+  i = -(-c.a - (3023282U + c.a + g));
+  e(&d, i);
+  printf("%llu\n", d);
+}
+
+/* { dg-output "3023282\r\n" } */
-- 
2.25.1



[PATCH v2] RISC-V: Fixbug for slli + addw + zext.w into sh[123]add + zext.w

2025-04-02 Thread Jin Ma
Assuming we have the following variables:

unsigned long long a0, a1;
unsigned int a2;

For the expression:

a0 = (a0 << 50) >> 49;  // slli a0, a0, 50 + srli a0, a0, 49
a2 = a1 + a0;   // addw a2, a1, a0 + slli a2, a2, 32 + srli a2, a2, 32

In the optimization process of ZBA (combine pass), it would be optimized to:

a2 = a0 << 1 + a1;  // sh1add a2, a0, a1 + zext.w a2, a2

This is clearly incorrect, as it overlooks the fact that a0=a0&0x7ffe, meaning
that the bits a0[32:14] are set to zero.

gcc/ChangeLog:

* config/riscv/bitmanip.md: The optimization can only be applied if
the high bit of operands[3] is set to 1.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/zba-shNadd-09.c: New test.
* gcc.target/riscv/zba-shNadd-10.c: New test.
---
 gcc/config/riscv/bitmanip.md  |  4 +++-
 .../gcc.target/riscv/zba-shNadd-09.c  | 12 +++
 .../gcc.target/riscv/zba-shNadd-10.c  | 21 +++
 3 files changed, 36 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/zba-shNadd-09.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zba-shNadd-10.c

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index b29c127bcb8..5ed5e18cb36 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -80,7 +80,9 @@ (define_split
(match_operand:DI 3 
"consecutive_bits_operand")) 0)
 (subreg:SI (match_operand:DI 4 
"register_operand") 0]
   "TARGET_64BIT && TARGET_ZBA
-   && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3]))"
+   && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3]))
+   /* Ensure the mask includes all the bits in SImode.  */
+   && ((INTVAL (operands[3]) & (HOST_WIDE_INT_1U << 31)) != 0)"
   [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) 
(match_dup 4)))
(set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))])
 
diff --git a/gcc/testsuite/gcc.target/riscv/zba-shNadd-09.c 
b/gcc/testsuite/gcc.target/riscv/zba-shNadd-09.c
new file mode 100644
index 000..303f3cbb863
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zba-shNadd-09.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zba -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+
+long long sub (unsigned long long a, unsigned long long b)
+{
+  b = (b << 50) >> 49;
+  unsigned int x = a + b;
+  return x;
+}
+
+/* { dg-final { scan-assembler-not {\msh1add} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zba-shNadd-10.c 
b/gcc/testsuite/gcc.target/riscv/zba-shNadd-10.c
new file mode 100644
index 000..883cce271ca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zba-shNadd-10.c
@@ -0,0 +1,21 @@
+/* { dg-do run { target { rv64 } } } */
+/* { dg-options "-march=rv64gc_zba -mabi=lp64d -O2" } */
+
+struct {
+  unsigned a : 14;
+  unsigned b : 3;
+} c;
+
+unsigned long long d;
+void e (unsigned long long *f, long p2) { *f = p2; }
+signed g;
+long i;
+
+int main () {
+  c.b = 4;
+  i = -(-c.a - (3023282U + c.a + g));
+  e (&d, i);
+  if (d != 3023282)
+__builtin_abort ();
+  __builtin_exit (0);
+}
-- 
2.25.1



Re: [PATCH v2] RISC-V: Disable unsupported vsext/vzext patterns for XTheadVector.

2025-04-08 Thread Jin Ma
On Tue, 8 Apr 2025 14:27:16 -0600, Jeff Law wrote:
> 
> 
> On 4/7/25 12:26 AM, Jin Ma wrote:
> > XThreadVector does not support the vsext/vzext instructions; however,
> > due to the reuse of RVV optimizations, it may generate these instructions
> > in certain cases. To prevent the error "Unknown opcode 'th.vsext.vf2',"
> > we should disable these patterns.
> > 
> > V2:
> > Change the value of dg-do in the test case from assemble to compile, and
> > remove the -save-temps option.
> > 
> > gcc/ChangeLog:
> > 
> > * config/riscv/vector.md: Disable vsext/vzext for XTheadVector.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * gcc.target/riscv/rvv/xtheadvector/vsext.c: New test.
> > * gcc.target/riscv/rvv/xtheadvector/vzext.c: New test.
> OK for the trunk.  Thanks!
> 
> Also OK if you wanted to backport to gcc-14.

Thank you very much! After conducting thorough testing locally, I will attempt 
to
cherry-pick them into the gcc-14 branch. By the way, do we have a pre-commit CI
system in place for the gcc-14 branch similar to that of the trunk branch? If 
so,
how can I trigger it and monitor the status of the patches in the CI system?

Best regards,
Jin Ma


Re: [PATCH v2] RISC-V: Fixbug for slli + addw + zext.w into sh[123]add + zext.w

2025-04-11 Thread Jin Ma
On Wed, 2 Apr 2025 13:41:33 -0600, Jeff Law wrote:
> 
> 
> On 4/2/25 1:01 AM, Jin Ma wrote:
> > Assuming we have the following variables:
> > 
> > unsigned long long a0, a1;
> > unsigned int a2;
> > 
> > For the expression:
> > 
> > a0 = (a0 << 50) >> 49;  // slli a0, a0, 50 + srli a0, a0, 49
> > a2 = a1 + a0;   // addw a2, a1, a0 + slli a2, a2, 32 + srli a2, a2, 
> > 32
> > 
> > In the optimization process of ZBA (combine pass), it would be optimized to:
> > 
> > a2 = a0 << 1 + a1;  // sh1add a2, a0, a1 + zext.w a2, a2
> > 
> > This is clearly incorrect, as it overlooks the fact that a0=a0&0x7ffe, 
> > meaning
> > that the bits a0[32:14] are set to zero.
> > 
> > gcc/ChangeLog:
> > 
> > * config/riscv/bitmanip.md: The optimization can only be applied if
> > the high bit of operands[3] is set to 1.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * gcc.target/riscv/zba-shNadd-09.c: New test.
> > * gcc.target/riscv/zba-shNadd-10.c: New test.
> Thanks.
> 
> While there isn't a regression bug in bugzilla, this is almost certainly 
> a 13, 14, 15 regression since the problematic pattern was integrated in 
> late 2022.

Okay, I've backported this GCC patch to the `releases/gcc-13` and 
`releases/gcc-14` branches. Thanks.! :)

Best regards,
Jin Ma

> With that in mind, I went ahead and pushed this to the trunk.
> 
> Thanks again!
> 
> jeff



[PATCH] RISC-V: Implment H modifier for printing the next register name

2025-04-27 Thread Jin Ma
For RV32 inline assembly, when handling 64-bit integer data, it is
often necessary to process the lower and upper 32 bits separately.
Unfortunately, we can only output the current register name
(lower 32 bits) but not the next register name (upper 32 bits).

To address this, the modifier 'H' has been added to allow users
to handle the upper 32 bits of the data. While I believe the
modifier 'N' (representing the next register name) might be more
suitable for this functionality, 'N' is already in use.
Therefore, 'H' (representing the high register) was chosen instead.

Co-Authored-By: Dimitar Dimitrov 

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_print_operand): Add H.
* doc/extend.texi: Document for H.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/modifier-H-error-1.c: New test.
* gcc.target/riscv/modifier-H-error-2.c: New test.
* gcc.target/riscv/modifier-H.c: New test.
---
 gcc/config/riscv/riscv.cc | 22 +++
 gcc/doc/extend.texi   |  1 +
 .../gcc.target/riscv/modifier-H-error-1.c | 13 +++
 .../gcc.target/riscv/modifier-H-error-2.c | 11 ++
 gcc/testsuite/gcc.target/riscv/modifier-H.c   | 22 +++
 5 files changed, 69 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/modifier-H-error-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/modifier-H-error-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/modifier-H.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index bad59e248d0..c5eec7a0136 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -6879,6 +6879,7 @@ riscv_asm_output_opcode (FILE *asm_out_file, const char 
*p)
'T' Print shift-index of inverted single-bit mask OP.
'~' Print w if TARGET_64BIT is true; otherwise not print anything.
'N'  Print register encoding as integer (0-31).
+   'H'  Print the name of the next register for integer.
 
Note please keep this list and the list in riscv.md in sync.  */
 
@@ -7174,6 +7175,27 @@ riscv_print_operand (FILE *file, rtx op, int letter)
asm_fprintf (file, "%u", (regno - offset));
break;
   }
+case 'H':
+  {
+   if (!REG_P (op))
+ {
+   output_operand_lossage ("modifier 'H' require register operand");
+   break;
+ }
+   if (REGNO (op) > 31)
+ {
+   output_operand_lossage ("modifier 'H' is for integer registers 
only");
+   break;
+ }
+   if (REGNO (op) == 31)
+ {
+   output_operand_lossage ("modifier 'H' cannot be applied to R31");
+   break;
+ }
+
+   fputs (reg_names[REGNO (op) + 1], file);
+   break;
+  }
 default:
   switch (code)
{
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 0978c4c41b2..212d2487558 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -12585,6 +12585,7 @@ The list below describes the supported modifiers and 
their effects for RISC-V.
 @item @code{z} @tab Print ''@code{zero}'' instead of 0 if the operand is an 
immediate with a value of zero.
 @item @code{i} @tab Print the character ''@code{i}'' if the operand is an 
immediate.
 @item @code{N} @tab Print the register encoding as integer (0 - 31).
+@item @code{H} @tab Print the name of the next register for integer.
 @end multitable
 
 @anchor{shOperandmodifiers}
diff --git a/gcc/testsuite/gcc.target/riscv/modifier-H-error-1.c 
b/gcc/testsuite/gcc.target/riscv/modifier-H-error-1.c
new file mode 100644
index 000..43ecff6498e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/modifier-H-error-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+/* { dg-options "-march=rv32gc -mabi=ilp32d -O0" } */
+
+float foo ()
+{
+  float ret;
+  asm ("fld\t%H0,(a0)\n\t":"=f"(ret));
+
+  return ret;
+}
+
+/* { dg-error "modifier 'H' is for integer registers only" "" { target { 
"riscv*-*-*" } } 0 } */
diff --git a/gcc/testsuite/gcc.target/riscv/modifier-H-error-2.c 
b/gcc/testsuite/gcc.target/riscv/modifier-H-error-2.c
new file mode 100644
index 000..db478b6ddf6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/modifier-H-error-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+/* { dg-options "-march=rv32gc -mabi=ilp32d -O0 " } */
+
+void foo ()
+{
+  register int x31 __asm__ ("x31");
+  asm ("li\t%H0,1\n\t":"=r"(x31));
+}
+
+/* { dg-error "modifier 'H' cannot be applied to R31" "" { target { 
"riscv*-*-*" } } 0 } */
diff --git a/gcc/testsuite/gcc.target/riscv/modifier-H.c 
b/gcc/testsuite/gcc.target/riscv/modifier-H.c
new file mode 100644
index 000..3571ea966f0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/modifier-H.c
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+/

Re: [RFC] RISC-V: Implment H modifier for printing the next register name

2025-04-26 Thread Jin Ma
On Sat, 26 Apr 2025 09:59:45 +0300, Dimitar Dimitrov wrote:
> On Fri, Apr 25, 2025 at 01:25:50PM +0800, Jin Ma wrote:
> > For RV32 inline assembly, when handling 64-bit integer data, it is
> > often necessary to process the lower and upper 32 bits separately.
> > Unfortunately, we can only output the current register name
> > (lower 32 bits) but not the next register name (upper 32 bits).
> > 
> > To address this, the modifier 'H' has been added to allow users
> > to handle the upper 32 bits of the data. While I believe the
> > modifier 'N' (representing the next register name) might be more
> > suitable for this functionality, 'N' is already in use.
> > Therefore, 'H' (representing the high register) was chosen instead.
> > 
> > Does anyone have any comments on this?
> > 
> > gcc/ChangeLog:
> > 
> > * config/riscv/riscv.cc (riscv_print_operand): Add H.
> > * doc/extend.texi: Document for H.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * gcc.target/riscv/modifier-H.c: New test.
> > ---
> >  gcc/config/riscv/riscv.cc   | 12 +++
> >  gcc/doc/extend.texi |  1 +
> >  gcc/testsuite/gcc.target/riscv/modifier-H.c | 22 +
> >  3 files changed, 35 insertions(+)
> >  create mode 100644 gcc/testsuite/gcc.target/riscv/modifier-H.c
> > 
> > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> > index bad59e248d0..4ef96532f35 100644
> > --- a/gcc/config/riscv/riscv.cc
> > +++ b/gcc/config/riscv/riscv.cc
> > @@ -6879,6 +6879,7 @@ riscv_asm_output_opcode (FILE *asm_out_file, const 
> > char *p)
> > 'T' Print shift-index of inverted single-bit mask OP.
> > '~' Print w if TARGET_64BIT is true; otherwise not print anything.
> > 'N'  Print register encoding as integer (0-31).
> > +   'H'  Print the name of the high register for OP, which is the next 
> > register.
> >  
> > Note please keep this list and the list in riscv.md in sync.  */
> >  
> > @@ -7174,6 +7175,17 @@ riscv_print_operand (FILE *file, rtx op, int letter)
> > asm_fprintf (file, "%u", (regno - offset));
> > break;
> >}
> > +case 'H':
> > +  {
> > +   if (!REG_P (op))
> > + {
> > +   output_operand_lossage ("modifier 'H' require register operand");
> > +   break;
> > + }
> 
> Given the intended usage, does it make sense to limit this modifier only
> to regular integer registers? Example:
> 
>   if (REGNO (op) > 31 )
> {
>   output_operand_lossage ("modifier 'H' is for integer registers only");
>   break;
> }
>   if (REGNO (op) == 31 )
> {
>   output_operand_lossage ("modifier 'H' cannot be applied to R31");
>   break;
> }
> 
> Is it an error to apply H modifier to R0?
> 
> If not, would you consider rejecting the last HW register:
>   if (REGNO (op) >= FIRST_PSEUDO_REGISTER - 1 )
> {
>   output_operand_lossage ("modifier 'H' cannot be applied to last HW 
> register");
>   break;
> }

Thanks. These are excellent review comments, and I will incorporate them into 
the next version.

Does anyone else have additional suggestions?

Best regards,
Jin

  1   2   >