public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFC] Store_bit_field_1: Use mode of SUBREG instead of REG
@ 2023-07-12  3:19 YunQiang Su
  2023-07-12  7:44 ` Richard Biener
  0 siblings, 1 reply; 3+ messages in thread
From: YunQiang Su @ 2023-07-12  3:19 UTC (permalink / raw)
  To: gcc-patches; +Cc: pinskia, YunQiang Su

PR #104914

When work with
  int val;
  ((unsigned char*)&val)[0] = *buf;
The RTX mode is obtained from REG instead of SUBREG,
which make D<INS> is used instead of <INS>.
Thus something wrong happens on sign-extend default architectures,
like MIPS64.

gcc/ChangeLog:
	PR: 104914.
	* expmed.cc(store_bit_field_1): Get mode from original
	str_rtx instead of op0.
---
 gcc/expmed.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/expmed.cc b/gcc/expmed.cc
index fbd4ce2d42f..37f90912122 100644
--- a/gcc/expmed.cc
+++ b/gcc/expmed.cc
@@ -849,7 +849,7 @@ store_bit_field_1 (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum,
      if we aren't.  This must come after the entire register case above,
      since that case is valid for any mode.  The following cases are only
      valid for integral modes.  */
-  opt_scalar_int_mode op0_mode = int_mode_for_mode (GET_MODE (op0));
+  opt_scalar_int_mode op0_mode = int_mode_for_mode (GET_MODE (str_rtx));
   scalar_int_mode imode;
   if (!op0_mode.exists (&imode) || imode != GET_MODE (op0))
     {
-- 
2.30.2


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [RFC] Store_bit_field_1: Use mode of SUBREG instead of REG
  2023-07-12  3:19 [RFC] Store_bit_field_1: Use mode of SUBREG instead of REG YunQiang Su
@ 2023-07-12  7:44 ` Richard Biener
  2023-07-12 11:22   ` YunQiang Su
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Biener @ 2023-07-12  7:44 UTC (permalink / raw)
  To: YunQiang Su; +Cc: gcc-patches, pinskia

On Wed, Jul 12, 2023 at 5:20 AM YunQiang Su <yunqiang.su@cipunited.com> wrote:
>
> PR #104914
>
> When work with
>   int val;
>   ((unsigned char*)&val)[0] = *buf;
> The RTX mode is obtained from REG instead of SUBREG,
> which make D<INS> is used instead of <INS>.
> Thus something wrong happens on sign-extend default architectures,
> like MIPS64.
>
> gcc/ChangeLog:
>         PR: 104914.
>         * expmed.cc(store_bit_field_1): Get mode from original
>         str_rtx instead of op0.
> ---
>  gcc/expmed.cc | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/gcc/expmed.cc b/gcc/expmed.cc
> index fbd4ce2d42f..37f90912122 100644
> --- a/gcc/expmed.cc
> +++ b/gcc/expmed.cc
> @@ -849,7 +849,7 @@ store_bit_field_1 (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum,
>       if we aren't.  This must come after the entire register case above,
>       since that case is valid for any mode.  The following cases are only
>       valid for integral modes.  */
> -  opt_scalar_int_mode op0_mode = int_mode_for_mode (GET_MODE (op0));
> +  opt_scalar_int_mode op0_mode = int_mode_for_mode (GET_MODE (str_rtx));

I don't think this is correct - op0_mode is used to store into op0, and we are
just requiring that it is an integer mode and equal to the original
mode.  I suppose
your patch makes us go to the fallback code instead, but it's surely
for the wrong
reason.  I also wonder why we don't just check GET_MODE_CLASS
(GET_MODE (op0)) == MODE_CLASS_INT ...

>    scalar_int_mode imode;
>    if (!op0_mode.exists (&imode) || imode != GET_MODE (op0))
>      {
> --
> 2.30.2
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [RFC] Store_bit_field_1: Use mode of SUBREG instead of REG
  2023-07-12  7:44 ` Richard Biener
@ 2023-07-12 11:22   ` YunQiang Su
  0 siblings, 0 replies; 3+ messages in thread
From: YunQiang Su @ 2023-07-12 11:22 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches, pinskia



> 2023年7月12日 15:44,Richard Biener <richard.guenther@gmail.com> 写道:
> 
> On Wed, Jul 12, 2023 at 5:20 AM YunQiang Su <yunqiang.su@cipunited.com> wrote:
>> 
>> PR #104914
>> 
>> When work with
>>  int val;
>>  ((unsigned char*)&val)[0] = *buf;
>> The RTX mode is obtained from REG instead of SUBREG,
>> which make D<INS> is used instead of <INS>.
>> Thus something wrong happens on sign-extend default architectures,
>> like MIPS64.
>> 
>> gcc/ChangeLog:
>>        PR: 104914.
>>        * expmed.cc(store_bit_field_1): Get mode from original
>>        str_rtx instead of op0.
>> ---
>> gcc/expmed.cc | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>> 
>> diff --git a/gcc/expmed.cc b/gcc/expmed.cc
>> index fbd4ce2d42f..37f90912122 100644
>> --- a/gcc/expmed.cc
>> +++ b/gcc/expmed.cc
>> @@ -849,7 +849,7 @@ store_bit_field_1 (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum,
>>      if we aren't.  This must come after the entire register case above,
>>      since that case is valid for any mode.  The following cases are only
>>      valid for integral modes.  */
>> -  opt_scalar_int_mode op0_mode = int_mode_for_mode (GET_MODE (op0));
>> +  opt_scalar_int_mode op0_mode = int_mode_for_mode (GET_MODE (str_rtx));
> 
> I don't think this is correct - op0_mode is used to store into op0, and we are
> just requiring that it is an integer mode and equal to the original
> mode.  I suppose
> your patch makes us go to the fallback code instead, but it's surely
> for the wrong

diff --git a/gcc/expmed.cc b/gcc/expmed.cc
index fbd4ce2d42f..feee8c82f59 100644
--- a/gcc/expmed.cc
+++ b/gcc/expmed.cc
@@ -850,6 +861,7 @@ store_bit_field_1 (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum,
      since that case is valid for any mode.  The following cases are only
      valid for integral modes.  */
   opt_scalar_int_mode op0_mode = int_mode_for_mode (GET_MODE (op0));
+  opt_scalar_int_mode str_mode = int_mode_for_mode (GET_MODE (str_rtx));
   scalar_int_mode imode;
   if (!op0_mode.exists (&imode) || imode != GET_MODE (op0))
     {
@@ -881,8 +893,14 @@ store_bit_field_1 (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum,
 	op0 = gen_lowpart (op0_mode.require (), op0);
     }
 
-  return store_integral_bit_field (op0, op0_mode, ibitsize, ibitnum,
-				   bitregion_start, bitregion_end,
+  bool use_str_mode = false;
+  if (GET_MODE_CLASS(GET_MODE (str_rtx)) == MODE_INT
+      && GET_MODE_CLASS(GET_MODE (op0)) == MODE_INT
+      && known_gt (GET_MODE_SIZE(GET_MODE(op0)), GET_MODE_SIZE(GET_MODE(str_rtx))))
+	use_str_mode = true;
+  return store_integral_bit_field (op0,
+				   use_str_mode ? str_mode : op0_mode,
+				   ibitsize, ibitnum, bitregion_start, bitregion_end,
 				   fieldmode, value, reverse, fallback_p);
 }

> reason.  I also wonder why we don't just check GET_MODE_CLASS
> (GET_MODE (op0)) == MODE_CLASS_INT ...
> 

In fact I have no idea. Maybe there are some other tricky cases.

>>   scalar_int_mode imode;
>>   if (!op0_mode.exists (&imode) || imode != GET_MODE (op0))
>>     {
>> --
>> 2.30.2



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-07-12 11:22 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-12  3:19 [RFC] Store_bit_field_1: Use mode of SUBREG instead of REG YunQiang Su
2023-07-12  7:44 ` Richard Biener
2023-07-12 11:22   ` YunQiang Su

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).