[2/3] rs6000: NFC use sext_hwi to replace ((v&0xf..f)^0x80..0) - 0x80..0

Message ID 20221201013619.196004-2-guojiufu@linux.ibm.com
State New
Headers
Series [1/3] rs6000: NFC use more readable pattern to clean high 32 bits |

Commit Message

Jiufu Guo Dec. 1, 2022, 1:36 a.m. UTC
  Hi,

This patch just uses sext_hwi to replace the expression like:
((value & 0xf..f) ^ 0x80..0) - 0x80..0 for rs6000.cc and rs6000.md.

Bootstrap & regtest pass on ppc64{,le}.
Is this ok for trunk? 

BR,
Jeff (Jiufu)

gcc/ChangeLog:

	* config/rs6000/rs6000.cc (num_insns_constant_gpr): Use sext_hwi.
	(darwin_rs6000_legitimate_lo_sum_const_p): Likewise.
	(mem_operand_gpr): Likewise.
	(mem_operand_ds_form): Likewise.
	(rs6000_legitimize_address): Likewise.
	(rs6000_emit_set_const): Likewise.
	(rs6000_emit_set_long_const): Likewise.
	(print_operand): Likewise.
	* config/rs6000/rs6000.md: Likewise.

---
 gcc/config/rs6000/rs6000.cc | 30 +++++++++++++-----------------
 gcc/config/rs6000/rs6000.md | 10 +++++-----
 2 files changed, 18 insertions(+), 22 deletions(-)
  

Comments

Kewen.Lin Dec. 1, 2022, 5:17 a.m. UTC | #1
Hi Jeff,

on 2022/12/1 09:36, Jiufu Guo wrote:
> Hi,
> 
> This patch just uses sext_hwi to replace the expression like:
> ((value & 0xf..f) ^ 0x80..0) - 0x80..0 for rs6000.cc and rs6000.md.
> 
> Bootstrap & regtest pass on ppc64{,le}.
> Is this ok for trunk? 

You didn't say it clearly but I guessed you have grepped in the whole
config/rs6000 directory, right?  I noticed there are still two places
using this kind of expression in function constant_generates_xxspltiw,
but I assumed it's intentional as their types are not HOST_WIDE_INT.

gcc/config/rs6000/rs6000.cc:      short sign_h_word = ((h_word & 0xffff) ^ 0x8000) - 0x8000;
gcc/config/rs6000/rs6000.cc:  int sign_word = ((word & 0xffffffff) ^ 0x80000000) - 0x80000000;

If so, could you state it clearly in commit log like "with type
signed/unsigned HOST_WIDE_INT" or similar?

This patch is OK once the above question gets confirmed, thanks!

BR,
Kewen

> 
> BR,
> Jeff (Jiufu)
> 
> gcc/ChangeLog:
> 
> 	* config/rs6000/rs6000.cc (num_insns_constant_gpr): Use sext_hwi.
> 	(darwin_rs6000_legitimate_lo_sum_const_p): Likewise.
> 	(mem_operand_gpr): Likewise.
> 	(mem_operand_ds_form): Likewise.
> 	(rs6000_legitimize_address): Likewise.
> 	(rs6000_emit_set_const): Likewise.
> 	(rs6000_emit_set_long_const): Likewise.
> 	(print_operand): Likewise.
> 	* config/rs6000/rs6000.md: Likewise.
> 
> ---
>  gcc/config/rs6000/rs6000.cc | 30 +++++++++++++-----------------
>  gcc/config/rs6000/rs6000.md | 10 +++++-----
>  2 files changed, 18 insertions(+), 22 deletions(-)
> 
> diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
> index 5efe9b22d8b..718072cc9a1 100644
> --- a/gcc/config/rs6000/rs6000.cc
> +++ b/gcc/config/rs6000/rs6000.cc
> @@ -6021,7 +6021,7 @@ num_insns_constant_gpr (HOST_WIDE_INT value)
> 
>    else if (TARGET_POWERPC64)
>      {
> -      HOST_WIDE_INT low  = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
> +      HOST_WIDE_INT low = sext_hwi (value, 32);
>        HOST_WIDE_INT high = value >> 31;
> 
>        if (high == 0 || high == -1)
> @@ -8456,7 +8456,7 @@ darwin_rs6000_legitimate_lo_sum_const_p (rtx x, machine_mode mode)
>      }
> 
>    /* We only care if the access(es) would cause a change to the high part.  */
> -  offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
> +  offset = sext_hwi (offset, 16);
>    return SIGNED_16BIT_OFFSET_EXTRA_P (offset, extra);
>  }
> 
> @@ -8522,7 +8522,7 @@ mem_operand_gpr (rtx op, machine_mode mode)
>    if (GET_CODE (addr) == LO_SUM)
>      /* For lo_sum addresses, we must allow any offset except one that
>         causes a wrap, so test only the low 16 bits.  */
> -    offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
> +    offset = sext_hwi (offset, 16);
> 
>    return SIGNED_16BIT_OFFSET_EXTRA_P (offset, extra);
>  }
> @@ -8562,7 +8562,7 @@ mem_operand_ds_form (rtx op, machine_mode mode)
>    if (GET_CODE (addr) == LO_SUM)
>      /* For lo_sum addresses, we must allow any offset except one that
>         causes a wrap, so test only the low 16 bits.  */
> -    offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
> +    offset = sext_hwi (offset, 16);
> 
>    return SIGNED_16BIT_OFFSET_EXTRA_P (offset, extra);
>  }
> @@ -9136,7 +9136,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
>      {
>        HOST_WIDE_INT high_int, low_int;
>        rtx sum;
> -      low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
> +      low_int = sext_hwi (INTVAL (XEXP (x, 1)), 16);
>        if (low_int >= 0x8000 - extra)
>  	low_int = 0;
>        high_int = INTVAL (XEXP (x, 1)) - low_int;
> @@ -10203,7 +10203,7 @@ rs6000_emit_set_const (rtx dest, rtx source)
>  	  lo = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
>  				      DImode);
>  	  emit_move_insn (hi, GEN_INT (c >> 32));
> -	  c = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
> +	  c = sext_hwi (c, 32);
>  	  emit_move_insn (lo, GEN_INT (c));
>  	}
>        else
> @@ -10242,7 +10242,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
> 
>    if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
>        || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
> -    emit_move_insn (dest, GEN_INT ((ud1 ^ 0x8000) - 0x8000));
> +    emit_move_insn (dest, GEN_INT (sext_hwi (ud1, 16)));
> 
>    else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
>  	   || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
> @@ -10250,7 +10250,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
>        temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
> 
>        emit_move_insn (ud1 != 0 ? copy_rtx (temp) : dest,
> -		      GEN_INT (((ud2 << 16) ^ 0x80000000) - 0x80000000));
> +		      GEN_INT (sext_hwi (ud2 << 16, 32)));
>        if (ud1 != 0)
>  	emit_move_insn (dest,
>  			gen_rtx_IOR (DImode, copy_rtx (temp),
> @@ -10261,8 +10261,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
>        temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
> 
>        gcc_assert (ud2 & 0x8000);
> -      emit_move_insn (copy_rtx (temp),
> -		      GEN_INT (((ud2 << 16) ^ 0x80000000) - 0x80000000));
> +      emit_move_insn (copy_rtx (temp), GEN_INT (sext_hwi (ud2 << 16, 32)));
>        if (ud1 != 0)
>  	emit_move_insn (copy_rtx (temp),
>  			gen_rtx_IOR (DImode, copy_rtx (temp),
> @@ -10273,7 +10272,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
>      {
>        temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
>        HOST_WIDE_INT num = (ud2 << 16) | ud1;
> -      rs6000_emit_set_long_const (temp, (num ^ 0x80000000) - 0x80000000);
> +      rs6000_emit_set_long_const (temp, sext_hwi (num, 32));
>        rtx one = gen_rtx_AND (DImode, temp, GEN_INT (0xffffffff));
>        rtx two = gen_rtx_ASHIFT (DImode, temp, GEN_INT (32));
>        emit_move_insn (dest, gen_rtx_IOR (DImode, one, two));
> @@ -10283,8 +10282,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
>      {
>        temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
> 
> -      emit_move_insn (copy_rtx (temp),
> -		      GEN_INT (((ud3 << 16) ^ 0x80000000) - 0x80000000));
> +      emit_move_insn (copy_rtx (temp), GEN_INT (sext_hwi (ud3 << 16, 32)));
>        if (ud2 != 0)
>  	emit_move_insn (copy_rtx (temp),
>  			gen_rtx_IOR (DImode, copy_rtx (temp),
> @@ -10336,8 +10334,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
>      {
>        temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
> 
> -      emit_move_insn (copy_rtx (temp),
> -		      GEN_INT (((ud4 << 16) ^ 0x80000000) - 0x80000000));
> +      emit_move_insn (copy_rtx (temp), GEN_INT (sext_hwi (ud4 << 16, 32)));
>        if (ud3 != 0)
>  	emit_move_insn (copy_rtx (temp),
>  			gen_rtx_IOR (DImode, copy_rtx (temp),
> @@ -14167,8 +14164,7 @@ print_operand (FILE *file, rtx x, int code)
>        /* If constant, low-order 16 bits of constant, signed.  Otherwise, write
>  	 normally.  */
>        if (INT_P (x))
> -	fprintf (file, HOST_WIDE_INT_PRINT_DEC,
> -		 ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
> +	fprintf (file, HOST_WIDE_INT_PRINT_DEC, sext_hwi (INTVAL (x), 16));
>        else
>  	print_operand (file, x, 0);
>        return;
> diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
> index 3bae303086b..4bd1dfd3da9 100644
> --- a/gcc/config/rs6000/rs6000.md
> +++ b/gcc/config/rs6000/rs6000.md
> @@ -1787,7 +1787,7 @@ (define_expand "add<mode>3"
>  	}
> 
>        HOST_WIDE_INT val = INTVAL (operands[2]);
> -      HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
> +      HOST_WIDE_INT low = sext_hwi (val, 16);
>        HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
> 
>        if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
> @@ -1930,7 +1930,7 @@ (define_split
>     (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
>  {
>    HOST_WIDE_INT val = INTVAL (operands[2]);
> -  HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
> +  HOST_WIDE_INT low = sext_hwi (val, 16);
>    HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
> 
>    operands[4] = GEN_INT (low);
> @@ -8213,7 +8213,7 @@ (define_split
>    operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
>    operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
>    operands[4] = GEN_INT (value >> 32);
> -  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
> +  operands[1] = GEN_INT (sext_hwi (value, 32));
>  })
> 
>  (define_split
> @@ -9577,7 +9577,7 @@ (define_split
>    operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
>  				       DImode);
>    operands[4] = GEN_INT (value >> 32);
> -  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
> +  operands[1] = GEN_INT (sext_hwi (value, 32));
>  })
> 
>  (define_split
> @@ -12425,7 +12425,7 @@ (define_peephole2
>  					      SImode,
>  					      operands[1], operands[2]);
>    HOST_WIDE_INT c = INTVAL (cnst);
> -  HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
> +  HOST_WIDE_INT sextc = sext_hwi (c, 16);
>    HOST_WIDE_INT xorv = c ^ sextc;
> 
>    operands[9] = GEN_INT (xorv);
  
Kewen.Lin Dec. 1, 2022, 5:30 a.m. UTC | #2
on 2022/12/1 13:17, Kewen.Lin via Gcc-patches wrote:
> Hi Jeff,
> 
> on 2022/12/1 09:36, Jiufu Guo wrote:
>> Hi,
>>
>> This patch just uses sext_hwi to replace the expression like:
>> ((value & 0xf..f) ^ 0x80..0) - 0x80..0 for rs6000.cc and rs6000.md.
>>
>> Bootstrap & regtest pass on ppc64{,le}.
>> Is this ok for trunk? 
> 
> You didn't say it clearly but I guessed you have grepped in the whole
> config/rs6000 directory, right?  I noticed there are still two places
> using this kind of expression in function constant_generates_xxspltiw,
> but I assumed it's intentional as their types are not HOST_WIDE_INT.
> 
> gcc/config/rs6000/rs6000.cc:      short sign_h_word = ((h_word & 0xffff) ^ 0x8000) - 0x8000;
> gcc/config/rs6000/rs6000.cc:  int sign_word = ((word & 0xffffffff) ^ 0x80000000) - 0x80000000;
> 

oh, one place in gcc/config/rs6000/predicates.md got missed.

./predicates.md-756-{
./predicates.md-757-  HOST_WIDE_INT val;
...
./predicates.md-762-  val = const_vector_elt_as_int (op, elt);
./predicates.md:763:  val = ((val & 0xff) ^ 0x80) - 0x80;
./predicates.md-764-  return EASY_VECTOR_15_ADD_SELF (val);
./predicates.md-765-})

Do you mind to have a further check?

Thanks!

Kewen
  
Jiufu Guo Dec. 1, 2022, 5:35 a.m. UTC | #3
Hi Kewen,

Thanks for your quick and insight review!

在 12/1/22 1:17 PM, Kewen.Lin 写道:
> Hi Jeff,
> 
> on 2022/12/1 09:36, Jiufu Guo wrote:
>> Hi,
>>
>> This patch just uses sext_hwi to replace the expression like:
>> ((value & 0xf..f) ^ 0x80..0) - 0x80..0 for rs6000.cc and rs6000.md.
>>
>> Bootstrap & regtest pass on ppc64{,le}.
>> Is this ok for trunk? 
> 
> You didn't say it clearly but I guessed you have grepped in the whole
> config/rs6000 directory, right?  I noticed there are still two places
> using this kind of expression in function constant_generates_xxspltiw,
> but I assumed it's intentional as their types are not HOST_WIDE_INT.
> 
> gcc/config/rs6000/rs6000.cc:      short sign_h_word = ((h_word & 0xffff) ^ 0x8000) - 0x8000;
> gcc/config/rs6000/rs6000.cc:  int sign_word = ((word & 0xffffffff) ^ 0x80000000) - 0x80000000;
> 
> If so, could you state it clearly in commit log like "with type
> signed/unsigned HOST_WIDE_INT" or similar?
> 
Good question!

And as you said sext_hwi is more for "signed/unsigned HOST_WIDE_INT".
For these two places, it seems sext_hwi is not needed actually!
And I did see why these expressions are used, may be just an assignment
is ok.

So, this patch does not cover these two places.

BR,
Jeff (Jiufu)

> This patch is OK once the above question gets confirmed, thanks!
> 
> BR,
> Kewen
> 
>>
>> BR,
>> Jeff (Jiufu)
>>
>> gcc/ChangeLog:
>>
>> 	* config/rs6000/rs6000.cc (num_insns_constant_gpr): Use sext_hwi.
>> 	(darwin_rs6000_legitimate_lo_sum_const_p): Likewise.
>> 	(mem_operand_gpr): Likewise.
>> 	(mem_operand_ds_form): Likewise.
>> 	(rs6000_legitimize_address): Likewise.
>> 	(rs6000_emit_set_const): Likewise.
>> 	(rs6000_emit_set_long_const): Likewise.
>> 	(print_operand): Likewise.
>> 	* config/rs6000/rs6000.md: Likewise.
>>
>> ---
>>  gcc/config/rs6000/rs6000.cc | 30 +++++++++++++-----------------
>>  gcc/config/rs6000/rs6000.md | 10 +++++-----
>>  2 files changed, 18 insertions(+), 22 deletions(-)
>>
>> diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
>> index 5efe9b22d8b..718072cc9a1 100644
>> --- a/gcc/config/rs6000/rs6000.cc
>> +++ b/gcc/config/rs6000/rs6000.cc
>> @@ -6021,7 +6021,7 @@ num_insns_constant_gpr (HOST_WIDE_INT value)
>>
>>    else if (TARGET_POWERPC64)
>>      {
>> -      HOST_WIDE_INT low  = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
>> +      HOST_WIDE_INT low = sext_hwi (value, 32);
>>        HOST_WIDE_INT high = value >> 31;
>>
>>        if (high == 0 || high == -1)
>> @@ -8456,7 +8456,7 @@ darwin_rs6000_legitimate_lo_sum_const_p (rtx x, machine_mode mode)
>>      }
>>
>>    /* We only care if the access(es) would cause a change to the high part.  */
>> -  offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
>> +  offset = sext_hwi (offset, 16);
>>    return SIGNED_16BIT_OFFSET_EXTRA_P (offset, extra);
>>  }
>>
>> @@ -8522,7 +8522,7 @@ mem_operand_gpr (rtx op, machine_mode mode)
>>    if (GET_CODE (addr) == LO_SUM)
>>      /* For lo_sum addresses, we must allow any offset except one that
>>         causes a wrap, so test only the low 16 bits.  */
>> -    offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
>> +    offset = sext_hwi (offset, 16);
>>
>>    return SIGNED_16BIT_OFFSET_EXTRA_P (offset, extra);
>>  }
>> @@ -8562,7 +8562,7 @@ mem_operand_ds_form (rtx op, machine_mode mode)
>>    if (GET_CODE (addr) == LO_SUM)
>>      /* For lo_sum addresses, we must allow any offset except one that
>>         causes a wrap, so test only the low 16 bits.  */
>> -    offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
>> +    offset = sext_hwi (offset, 16);
>>
>>    return SIGNED_16BIT_OFFSET_EXTRA_P (offset, extra);
>>  }
>> @@ -9136,7 +9136,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
>>      {
>>        HOST_WIDE_INT high_int, low_int;
>>        rtx sum;
>> -      low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
>> +      low_int = sext_hwi (INTVAL (XEXP (x, 1)), 16);
>>        if (low_int >= 0x8000 - extra)
>>  	low_int = 0;
>>        high_int = INTVAL (XEXP (x, 1)) - low_int;
>> @@ -10203,7 +10203,7 @@ rs6000_emit_set_const (rtx dest, rtx source)
>>  	  lo = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
>>  				      DImode);
>>  	  emit_move_insn (hi, GEN_INT (c >> 32));
>> -	  c = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
>> +	  c = sext_hwi (c, 32);
>>  	  emit_move_insn (lo, GEN_INT (c));
>>  	}
>>        else
>> @@ -10242,7 +10242,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
>>
>>    if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
>>        || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
>> -    emit_move_insn (dest, GEN_INT ((ud1 ^ 0x8000) - 0x8000));
>> +    emit_move_insn (dest, GEN_INT (sext_hwi (ud1, 16)));
>>
>>    else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
>>  	   || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
>> @@ -10250,7 +10250,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
>>        temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
>>
>>        emit_move_insn (ud1 != 0 ? copy_rtx (temp) : dest,
>> -		      GEN_INT (((ud2 << 16) ^ 0x80000000) - 0x80000000));
>> +		      GEN_INT (sext_hwi (ud2 << 16, 32)));
>>        if (ud1 != 0)
>>  	emit_move_insn (dest,
>>  			gen_rtx_IOR (DImode, copy_rtx (temp),
>> @@ -10261,8 +10261,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
>>        temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
>>
>>        gcc_assert (ud2 & 0x8000);
>> -      emit_move_insn (copy_rtx (temp),
>> -		      GEN_INT (((ud2 << 16) ^ 0x80000000) - 0x80000000));
>> +      emit_move_insn (copy_rtx (temp), GEN_INT (sext_hwi (ud2 << 16, 32)));
>>        if (ud1 != 0)
>>  	emit_move_insn (copy_rtx (temp),
>>  			gen_rtx_IOR (DImode, copy_rtx (temp),
>> @@ -10273,7 +10272,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
>>      {
>>        temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
>>        HOST_WIDE_INT num = (ud2 << 16) | ud1;
>> -      rs6000_emit_set_long_const (temp, (num ^ 0x80000000) - 0x80000000);
>> +      rs6000_emit_set_long_const (temp, sext_hwi (num, 32));
>>        rtx one = gen_rtx_AND (DImode, temp, GEN_INT (0xffffffff));
>>        rtx two = gen_rtx_ASHIFT (DImode, temp, GEN_INT (32));
>>        emit_move_insn (dest, gen_rtx_IOR (DImode, one, two));
>> @@ -10283,8 +10282,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
>>      {
>>        temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
>>
>> -      emit_move_insn (copy_rtx (temp),
>> -		      GEN_INT (((ud3 << 16) ^ 0x80000000) - 0x80000000));
>> +      emit_move_insn (copy_rtx (temp), GEN_INT (sext_hwi (ud3 << 16, 32)));
>>        if (ud2 != 0)
>>  	emit_move_insn (copy_rtx (temp),
>>  			gen_rtx_IOR (DImode, copy_rtx (temp),
>> @@ -10336,8 +10334,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
>>      {
>>        temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
>>
>> -      emit_move_insn (copy_rtx (temp),
>> -		      GEN_INT (((ud4 << 16) ^ 0x80000000) - 0x80000000));
>> +      emit_move_insn (copy_rtx (temp), GEN_INT (sext_hwi (ud4 << 16, 32)));
>>        if (ud3 != 0)
>>  	emit_move_insn (copy_rtx (temp),
>>  			gen_rtx_IOR (DImode, copy_rtx (temp),
>> @@ -14167,8 +14164,7 @@ print_operand (FILE *file, rtx x, int code)
>>        /* If constant, low-order 16 bits of constant, signed.  Otherwise, write
>>  	 normally.  */
>>        if (INT_P (x))
>> -	fprintf (file, HOST_WIDE_INT_PRINT_DEC,
>> -		 ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
>> +	fprintf (file, HOST_WIDE_INT_PRINT_DEC, sext_hwi (INTVAL (x), 16));
>>        else
>>  	print_operand (file, x, 0);
>>        return;
>> diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
>> index 3bae303086b..4bd1dfd3da9 100644
>> --- a/gcc/config/rs6000/rs6000.md
>> +++ b/gcc/config/rs6000/rs6000.md
>> @@ -1787,7 +1787,7 @@ (define_expand "add<mode>3"
>>  	}
>>
>>        HOST_WIDE_INT val = INTVAL (operands[2]);
>> -      HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
>> +      HOST_WIDE_INT low = sext_hwi (val, 16);
>>        HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
>>
>>        if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
>> @@ -1930,7 +1930,7 @@ (define_split
>>     (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
>>  {
>>    HOST_WIDE_INT val = INTVAL (operands[2]);
>> -  HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
>> +  HOST_WIDE_INT low = sext_hwi (val, 16);
>>    HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
>>
>>    operands[4] = GEN_INT (low);
>> @@ -8213,7 +8213,7 @@ (define_split
>>    operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
>>    operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
>>    operands[4] = GEN_INT (value >> 32);
>> -  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
>> +  operands[1] = GEN_INT (sext_hwi (value, 32));
>>  })
>>
>>  (define_split
>> @@ -9577,7 +9577,7 @@ (define_split
>>    operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
>>  				       DImode);
>>    operands[4] = GEN_INT (value >> 32);
>> -  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
>> +  operands[1] = GEN_INT (sext_hwi (value, 32));
>>  })
>>
>>  (define_split
>> @@ -12425,7 +12425,7 @@ (define_peephole2
>>  					      SImode,
>>  					      operands[1], operands[2]);
>>    HOST_WIDE_INT c = INTVAL (cnst);
>> -  HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
>> +  HOST_WIDE_INT sextc = sext_hwi (c, 16);
>>    HOST_WIDE_INT xorv = c ^ sextc;
>>
>>    operands[9] = GEN_INT (xorv);
  
Kewen.Lin Dec. 1, 2022, 6:11 a.m. UTC | #4
on 2022/12/1 13:35, Jiufu Guo wrote:
> Hi Kewen,
> 
> Thanks for your quick and insight review!
> 
> 在 12/1/22 1:17 PM, Kewen.Lin 写道:
>> Hi Jeff,
>>
>> on 2022/12/1 09:36, Jiufu Guo wrote:
>>> Hi,
>>>
>>> This patch just uses sext_hwi to replace the expression like:
>>> ((value & 0xf..f) ^ 0x80..0) - 0x80..0 for rs6000.cc and rs6000.md.
>>>
>>> Bootstrap & regtest pass on ppc64{,le}.
>>> Is this ok for trunk? 
>>
>> You didn't say it clearly but I guessed you have grepped in the whole
>> config/rs6000 directory, right?  I noticed there are still two places
>> using this kind of expression in function constant_generates_xxspltiw,
>> but I assumed it's intentional as their types are not HOST_WIDE_INT.
>>
>> gcc/config/rs6000/rs6000.cc:      short sign_h_word = ((h_word & 0xffff) ^ 0x8000) - 0x8000;
>> gcc/config/rs6000/rs6000.cc:  int sign_word = ((word & 0xffffffff) ^ 0x80000000) - 0x80000000;
>>
>> If so, could you state it clearly in commit log like "with type
>> signed/unsigned HOST_WIDE_INT" or similar?
>>
> Good question!
> 
> And as you said sext_hwi is more for "signed/unsigned HOST_WIDE_INT".
> For these two places, it seems sext_hwi is not needed actually!
> And I did see why these expressions are used, may be just an assignment
> is ok.

ah, I see.  I agree using the assignment is quite enough.  Could you
please also simplify them together?  Since they are with the form 
"((value & 0xf..f) ^ 0x80..0) - 0x80..0" too, and can be refactored
in a better way.  Thanks!

BR,
Kewen
  
Jiufu Guo Dec. 1, 2022, 6:32 a.m. UTC | #5
Hi Kewen,

在 12/1/22 1:30 PM, Kewen.Lin 写道:
> on 2022/12/1 13:17, Kewen.Lin via Gcc-patches wrote:
>> Hi Jeff,
>>
>> on 2022/12/1 09:36, Jiufu Guo wrote:
>>> Hi,
>>>
>>> This patch just uses sext_hwi to replace the expression like:
>>> ((value & 0xf..f) ^ 0x80..0) - 0x80..0 for rs6000.cc and rs6000.md.
>>>
>>> Bootstrap & regtest pass on ppc64{,le}.
>>> Is this ok for trunk? 
>>
>> You didn't say it clearly but I guessed you have grepped in the whole
>> config/rs6000 directory, right?  I noticed there are still two places
>> using this kind of expression in function constant_generates_xxspltiw,
>> but I assumed it's intentional as their types are not HOST_WIDE_INT.
>>
>> gcc/config/rs6000/rs6000.cc:      short sign_h_word = ((h_word & 0xffff) ^ 0x8000) - 0x8000;
>> gcc/config/rs6000/rs6000.cc:  int sign_word = ((word & 0xffffffff) ^ 0x80000000) - 0x80000000;
>>
> 
> oh, one place in gcc/config/rs6000/predicates.md got missed.
> 
> ./predicates.md-756-{
> ./predicates.md-757-  HOST_WIDE_INT val;
> ...
> ./predicates.md-762-  val = const_vector_elt_as_int (op, elt);
> ./predicates.md:763:  val = ((val & 0xff) ^ 0x80) - 0x80;
> ./predicates.md-764-  return EASY_VECTOR_15_ADD_SELF (val);
> ./predicates.md-765-})
> 
> Do you mind to have a further check?

Good catch, thanks!
I will update the patch to cover this one. Bootstrap and testing.

I would be better to check all files under rs6000/. I just rechecked
with grep -r "^.*0x8.*-.*0x8" for rs6000.  No other place is missed.


BR,
Jeff (Jiufu)


Updated patch as attached(add predicates.md).


> 
> Thanks!
> 
> Kewen
From 0059e2175cac5353890965ba782ff58743d2f486 Mon Sep 17 00:00:00 2001
From: Jiufu Guo <guojiufu@linux.ibm.com>
Date: Wed, 30 Nov 2022 13:13:37 +0800
Subject: [PATCH 2/2]rs6000: use sext_hwi to replace ((v&0xf..f)^0x80..0) -
 0x80..0


This patch just uses sext_hwi to replace the expression like:
((value & 0xf..f) ^ 0x80..0) - 0x80..0 for rs6000.cc, rs6000.md and
predicates.md (all occurance under rs6000/).


gcc/ChangeLog:

	* config/rs6000/predicates.md: Use sext_hwi.
	* config/rs6000/rs6000.cc (num_insns_constant_gpr): Use sext_hwi.
	(darwin_rs6000_legitimate_lo_sum_const_p): Likewise.
	(mem_operand_gpr): Likewise.
	(mem_operand_ds_form): Likewise.
	(rs6000_legitimize_address): Likewise.
	(rs6000_emit_set_const): Likewise.
	(rs6000_emit_set_long_const): Likewise.
	(print_operand): Likewise.
	* config/rs6000/rs6000.md: Likewise.

---
 gcc/config/rs6000/predicates.md |  2 +-
 gcc/config/rs6000/rs6000.cc     | 30 +++++++++++++-----------------
 gcc/config/rs6000/rs6000.md     | 10 +++++-----
 3 files changed, 19 insertions(+), 23 deletions(-)

diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index b1fcc69bb60..a1764018545 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -760,7 +760,7 @@ (define_predicate "easy_vector_constant_add_self"
     return 0;
   elt = BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (mode) - 1 : 0;
   val = const_vector_elt_as_int (op, elt);
-  val = ((val & 0xff) ^ 0x80) - 0x80;
+  val = sext_hwi (val, 8);
   return EASY_VECTOR_15_ADD_SELF (val);
 })
 
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 5efe9b22d8b..718072cc9a1 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -6021,7 +6021,7 @@ num_insns_constant_gpr (HOST_WIDE_INT value)
 
   else if (TARGET_POWERPC64)
     {
-      HOST_WIDE_INT low  = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
+      HOST_WIDE_INT low = sext_hwi (value, 32);
       HOST_WIDE_INT high = value >> 31;
 
       if (high == 0 || high == -1)
@@ -8456,7 +8456,7 @@ darwin_rs6000_legitimate_lo_sum_const_p (rtx x, machine_mode mode)
     }
 
   /* We only care if the access(es) would cause a change to the high part.  */
-  offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
+  offset = sext_hwi (offset, 16);
   return SIGNED_16BIT_OFFSET_EXTRA_P (offset, extra);
 }
 
@@ -8522,7 +8522,7 @@ mem_operand_gpr (rtx op, machine_mode mode)
   if (GET_CODE (addr) == LO_SUM)
     /* For lo_sum addresses, we must allow any offset except one that
        causes a wrap, so test only the low 16 bits.  */
-    offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
+    offset = sext_hwi (offset, 16);
 
   return SIGNED_16BIT_OFFSET_EXTRA_P (offset, extra);
 }
@@ -8562,7 +8562,7 @@ mem_operand_ds_form (rtx op, machine_mode mode)
   if (GET_CODE (addr) == LO_SUM)
     /* For lo_sum addresses, we must allow any offset except one that
        causes a wrap, so test only the low 16 bits.  */
-    offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
+    offset = sext_hwi (offset, 16);
 
   return SIGNED_16BIT_OFFSET_EXTRA_P (offset, extra);
 }
@@ -9136,7 +9136,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
     {
       HOST_WIDE_INT high_int, low_int;
       rtx sum;
-      low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
+      low_int = sext_hwi (INTVAL (XEXP (x, 1)), 16);
       if (low_int >= 0x8000 - extra)
 	low_int = 0;
       high_int = INTVAL (XEXP (x, 1)) - low_int;
@@ -10203,7 +10203,7 @@ rs6000_emit_set_const (rtx dest, rtx source)
 	  lo = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
 				      DImode);
 	  emit_move_insn (hi, GEN_INT (c >> 32));
-	  c = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
+	  c = sext_hwi (c, 32);
 	  emit_move_insn (lo, GEN_INT (c));
 	}
       else
@@ -10242,7 +10242,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
 
   if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
       || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
-    emit_move_insn (dest, GEN_INT ((ud1 ^ 0x8000) - 0x8000));
+    emit_move_insn (dest, GEN_INT (sext_hwi (ud1, 16)));
 
   else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
 	   || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
@@ -10250,7 +10250,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
 
       emit_move_insn (ud1 != 0 ? copy_rtx (temp) : dest,
-		      GEN_INT (((ud2 << 16) ^ 0x80000000) - 0x80000000));
+		      GEN_INT (sext_hwi (ud2 << 16, 32)));
       if (ud1 != 0)
 	emit_move_insn (dest,
 			gen_rtx_IOR (DImode, copy_rtx (temp),
@@ -10261,8 +10261,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
 
       gcc_assert (ud2 & 0x8000);
-      emit_move_insn (copy_rtx (temp),
-		      GEN_INT (((ud2 << 16) ^ 0x80000000) - 0x80000000));
+      emit_move_insn (copy_rtx (temp), GEN_INT (sext_hwi (ud2 << 16, 32)));
       if (ud1 != 0)
 	emit_move_insn (copy_rtx (temp),
 			gen_rtx_IOR (DImode, copy_rtx (temp),
@@ -10273,7 +10272,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
       HOST_WIDE_INT num = (ud2 << 16) | ud1;
-      rs6000_emit_set_long_const (temp, (num ^ 0x80000000) - 0x80000000);
+      rs6000_emit_set_long_const (temp, sext_hwi (num, 32));
       rtx one = gen_rtx_AND (DImode, temp, GEN_INT (0xffffffff));
       rtx two = gen_rtx_ASHIFT (DImode, temp, GEN_INT (32));
       emit_move_insn (dest, gen_rtx_IOR (DImode, one, two));
@@ -10283,8 +10282,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
 
-      emit_move_insn (copy_rtx (temp),
-		      GEN_INT (((ud3 << 16) ^ 0x80000000) - 0x80000000));
+      emit_move_insn (copy_rtx (temp), GEN_INT (sext_hwi (ud3 << 16, 32)));
       if (ud2 != 0)
 	emit_move_insn (copy_rtx (temp),
 			gen_rtx_IOR (DImode, copy_rtx (temp),
@@ -10336,8 +10334,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
 
-      emit_move_insn (copy_rtx (temp),
-		      GEN_INT (((ud4 << 16) ^ 0x80000000) - 0x80000000));
+      emit_move_insn (copy_rtx (temp), GEN_INT (sext_hwi (ud4 << 16, 32)));
       if (ud3 != 0)
 	emit_move_insn (copy_rtx (temp),
 			gen_rtx_IOR (DImode, copy_rtx (temp),
@@ -14167,8 +14164,7 @@ print_operand (FILE *file, rtx x, int code)
       /* If constant, low-order 16 bits of constant, signed.  Otherwise, write
 	 normally.  */
       if (INT_P (x))
-	fprintf (file, HOST_WIDE_INT_PRINT_DEC,
-		 ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
+	fprintf (file, HOST_WIDE_INT_PRINT_DEC, sext_hwi (INTVAL (x), 16));
       else
 	print_operand (file, x, 0);
       return;
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 3bae303086b..4bd1dfd3da9 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -1787,7 +1787,7 @@ (define_expand "add<mode>3"
 	}
 
       HOST_WIDE_INT val = INTVAL (operands[2]);
-      HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
+      HOST_WIDE_INT low = sext_hwi (val, 16);
       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
 
       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
@@ -1930,7 +1930,7 @@ (define_split
    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
 {
   HOST_WIDE_INT val = INTVAL (operands[2]);
-  HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
+  HOST_WIDE_INT low = sext_hwi (val, 16);
   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
 
   operands[4] = GEN_INT (low);
@@ -8213,7 +8213,7 @@ (define_split
   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
   operands[4] = GEN_INT (value >> 32);
-  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
+  operands[1] = GEN_INT (sext_hwi (value, 32));
 })
 
 (define_split
@@ -9577,7 +9577,7 @@ (define_split
   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
 				       DImode);
   operands[4] = GEN_INT (value >> 32);
-  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
+  operands[1] = GEN_INT (sext_hwi (value, 32));
 })
 
 (define_split
@@ -12425,7 +12425,7 @@ (define_peephole2
 					      SImode,
 					      operands[1], operands[2]);
   HOST_WIDE_INT c = INTVAL (cnst);
-  HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
+  HOST_WIDE_INT sextc = sext_hwi (c, 16);
   HOST_WIDE_INT xorv = c ^ sextc;
 
   operands[9] = GEN_INT (xorv);
  
Jiufu Guo Dec. 1, 2022, 7:10 a.m. UTC | #6
Hi Kewen,

在 12/1/22 2:11 PM, Kewen.Lin 写道:
> on 2022/12/1 13:35, Jiufu Guo wrote:
>> Hi Kewen,
>>
>> Thanks for your quick and insight review!
>>
>> 在 12/1/22 1:17 PM, Kewen.Lin 写道:
>>> Hi Jeff,
>>>
>>> on 2022/12/1 09:36, Jiufu Guo wrote:
>>>> Hi,
>>>>
>>>> This patch just uses sext_hwi to replace the expression like:
>>>> ((value & 0xf..f) ^ 0x80..0) - 0x80..0 for rs6000.cc and rs6000.md.
>>>>
>>>> Bootstrap & regtest pass on ppc64{,le}.
>>>> Is this ok for trunk? 
>>>
>>> You didn't say it clearly but I guessed you have grepped in the whole
>>> config/rs6000 directory, right?  I noticed there are still two places
>>> using this kind of expression in function constant_generates_xxspltiw,
>>> but I assumed it's intentional as their types are not HOST_WIDE_INT.
>>>
>>> gcc/config/rs6000/rs6000.cc:      short sign_h_word = ((h_word & 0xffff) ^ 0x8000) - 0x8000;
>>> gcc/config/rs6000/rs6000.cc:  int sign_word = ((word & 0xffffffff) ^ 0x80000000) - 0x80000000;
>>>
>>> If so, could you state it clearly in commit log like "with type
>>> signed/unsigned HOST_WIDE_INT" or similar?
>>>
>> Good question!
>>
>> And as you said sext_hwi is more for "signed/unsigned HOST_WIDE_INT".
>> For these two places, it seems sext_hwi is not needed actually!
>> And I did see why these expressions are used, may be just an assignment
>> is ok.
> 
> ah, I see.  I agree using the assignment is quite enough.  Could you
> please also simplify them together?  Since they are with the form 
> "((value & 0xf..f) ^ 0x80..0) - 0x80..0" too, and can be refactored
> in a better way.  Thanks!

Sure, I believe just "short sign_h_word = vsx_const->half_words[0];"
should be correct :-), and included in the updated patch.

Updated patch is attached,  bootstrap&regtest is on going.


BR,
Jeff (Jiufu)

> 
> BR,
> Kewen
>
From 8aa8e1234b6ec34473434951a3a6177253aac770 Mon Sep 17 00:00:00 2001
From: Jiufu Guo <guojiufu@linux.ibm.com>
Date: Wed, 30 Nov 2022 13:13:37 +0800
Subject: [PATCH 2/2]rs6000: update ((v&0xf..f)^0x80..0) - 0x80..0 with code: like sext_hwi

This patch just replaces the expression like: 
((value & 0xf..f) ^ 0x80..0) - 0x80..0 to better code(e.g. sext_hwi) for
rs6000.cc, rs6000.md and predicates.md (files under rs6000/).

gcc/ChangeLog:

	* config/rs6000/predicates.md: Use sext_hwi.
	* config/rs6000/rs6000.cc (num_insns_constant_gpr): Likewise.
	(darwin_rs6000_legitimate_lo_sum_const_p): Likewise.
	(mem_operand_gpr): Likewise.
	(mem_operand_ds_form): Likewise.
	(rs6000_legitimize_address): Likewise.
	(rs6000_emit_set_const): Likewise.
	(rs6000_emit_set_long_const): Likewise.
	(print_operand): Likewise.
	(constant_generates_xxspltiw): Remove unnecessary expressions.
	* config/rs6000/rs6000.md: Use sext_hwi.

---
 gcc/config/rs6000/predicates.md |  2 +-
 gcc/config/rs6000/rs6000.cc     | 36 ++++++++++++++-------------------
 gcc/config/rs6000/rs6000.md     | 10 ++++-----
 3 files changed, 21 insertions(+), 27 deletions(-)

diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index b1fcc69bb60..a1764018545 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -760,7 +760,7 @@ (define_predicate "easy_vector_constant_add_self"
     return 0;
   elt = BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (mode) - 1 : 0;
   val = const_vector_elt_as_int (op, elt);
-  val = ((val & 0xff) ^ 0x80) - 0x80;
+  val = sext_hwi (val, 8);
   return EASY_VECTOR_15_ADD_SELF (val);
 })
 
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 5efe9b22d8b..dff9a0d8835 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -6021,7 +6021,7 @@ num_insns_constant_gpr (HOST_WIDE_INT value)
 
   else if (TARGET_POWERPC64)
     {
-      HOST_WIDE_INT low  = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
+      HOST_WIDE_INT low = sext_hwi (value, 32);
       HOST_WIDE_INT high = value >> 31;
 
       if (high == 0 || high == -1)
@@ -8456,7 +8456,7 @@ darwin_rs6000_legitimate_lo_sum_const_p (rtx x, machine_mode mode)
     }
 
   /* We only care if the access(es) would cause a change to the high part.  */
-  offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
+  offset = sext_hwi (offset, 16);
   return SIGNED_16BIT_OFFSET_EXTRA_P (offset, extra);
 }
 
@@ -8522,7 +8522,7 @@ mem_operand_gpr (rtx op, machine_mode mode)
   if (GET_CODE (addr) == LO_SUM)
     /* For lo_sum addresses, we must allow any offset except one that
        causes a wrap, so test only the low 16 bits.  */
-    offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
+    offset = sext_hwi (offset, 16);
 
   return SIGNED_16BIT_OFFSET_EXTRA_P (offset, extra);
 }
@@ -8562,7 +8562,7 @@ mem_operand_ds_form (rtx op, machine_mode mode)
   if (GET_CODE (addr) == LO_SUM)
     /* For lo_sum addresses, we must allow any offset except one that
        causes a wrap, so test only the low 16 bits.  */
-    offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
+    offset = sext_hwi (offset, 16);
 
   return SIGNED_16BIT_OFFSET_EXTRA_P (offset, extra);
 }
@@ -9136,7 +9136,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
     {
       HOST_WIDE_INT high_int, low_int;
       rtx sum;
-      low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
+      low_int = sext_hwi (INTVAL (XEXP (x, 1)), 16);
       if (low_int >= 0x8000 - extra)
 	low_int = 0;
       high_int = INTVAL (XEXP (x, 1)) - low_int;
@@ -10203,7 +10203,7 @@ rs6000_emit_set_const (rtx dest, rtx source)
 	  lo = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
 				      DImode);
 	  emit_move_insn (hi, GEN_INT (c >> 32));
-	  c = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
+	  c = sext_hwi (c, 32);
 	  emit_move_insn (lo, GEN_INT (c));
 	}
       else
@@ -10242,7 +10242,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
 
   if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
       || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
-    emit_move_insn (dest, GEN_INT ((ud1 ^ 0x8000) - 0x8000));
+    emit_move_insn (dest, GEN_INT (sext_hwi (ud1, 16)));
 
   else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
 	   || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
@@ -10250,7 +10250,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
 
       emit_move_insn (ud1 != 0 ? copy_rtx (temp) : dest,
-		      GEN_INT (((ud2 << 16) ^ 0x80000000) - 0x80000000));
+		      GEN_INT (sext_hwi (ud2 << 16, 32)));
       if (ud1 != 0)
 	emit_move_insn (dest,
 			gen_rtx_IOR (DImode, copy_rtx (temp),
@@ -10261,8 +10261,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
 
       gcc_assert (ud2 & 0x8000);
-      emit_move_insn (copy_rtx (temp),
-		      GEN_INT (((ud2 << 16) ^ 0x80000000) - 0x80000000));
+      emit_move_insn (copy_rtx (temp), GEN_INT (sext_hwi (ud2 << 16, 32)));
       if (ud1 != 0)
 	emit_move_insn (copy_rtx (temp),
 			gen_rtx_IOR (DImode, copy_rtx (temp),
@@ -10273,7 +10272,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
       HOST_WIDE_INT num = (ud2 << 16) | ud1;
-      rs6000_emit_set_long_const (temp, (num ^ 0x80000000) - 0x80000000);
+      rs6000_emit_set_long_const (temp, sext_hwi (num, 32));
       rtx one = gen_rtx_AND (DImode, temp, GEN_INT (0xffffffff));
       rtx two = gen_rtx_ASHIFT (DImode, temp, GEN_INT (32));
       emit_move_insn (dest, gen_rtx_IOR (DImode, one, two));
@@ -10283,8 +10282,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
 
-      emit_move_insn (copy_rtx (temp),
-		      GEN_INT (((ud3 << 16) ^ 0x80000000) - 0x80000000));
+      emit_move_insn (copy_rtx (temp), GEN_INT (sext_hwi (ud3 << 16, 32)));
       if (ud2 != 0)
 	emit_move_insn (copy_rtx (temp),
 			gen_rtx_IOR (DImode, copy_rtx (temp),
@@ -10336,8 +10334,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
 
-      emit_move_insn (copy_rtx (temp),
-		      GEN_INT (((ud4 << 16) ^ 0x80000000) - 0x80000000));
+      emit_move_insn (copy_rtx (temp), GEN_INT (sext_hwi (ud4 << 16, 32)));
       if (ud3 != 0)
 	emit_move_insn (copy_rtx (temp),
 			gen_rtx_IOR (DImode, copy_rtx (temp),
@@ -14167,8 +14164,7 @@ print_operand (FILE *file, rtx x, int code)
       /* If constant, low-order 16 bits of constant, signed.  Otherwise, write
 	 normally.  */
       if (INT_P (x))
-	fprintf (file, HOST_WIDE_INT_PRINT_DEC,
-		 ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
+	fprintf (file, HOST_WIDE_INT_PRINT_DEC, sext_hwi (INTVAL (x), 16));
       else
 	print_operand (file, x, 0);
       return;
@@ -28719,14 +28715,12 @@ constant_generates_xxspltiw (vec_const_128bit_type *vsx_const)
   /* See if we can use VSPLTISH or VSPLTISW.  */
   if (vsx_const->all_half_words_same)
     {
-      unsigned short h_word = vsx_const->half_words[0];
-      short sign_h_word = ((h_word & 0xffff) ^ 0x8000) - 0x8000;
+      short sign_h_word = vsx_const->half_words[0];
       if (EASY_VECTOR_15 (sign_h_word))
 	return 0;
     }
 
-  unsigned int word = vsx_const->words[0];
-  int sign_word = ((word & 0xffffffff) ^ 0x80000000) - 0x80000000;
+  int sign_word = vsx_const->words[0];
   if (EASY_VECTOR_15 (sign_word))
     return 0;
 
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 3bae303086b..4bd1dfd3da9 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -1787,7 +1787,7 @@ (define_expand "add<mode>3"
 	}
 
       HOST_WIDE_INT val = INTVAL (operands[2]);
-      HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
+      HOST_WIDE_INT low = sext_hwi (val, 16);
       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
 
       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
@@ -1930,7 +1930,7 @@ (define_split
    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
 {
   HOST_WIDE_INT val = INTVAL (operands[2]);
-  HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
+  HOST_WIDE_INT low = sext_hwi (val, 16);
   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
 
   operands[4] = GEN_INT (low);
@@ -8213,7 +8213,7 @@ (define_split
   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
   operands[4] = GEN_INT (value >> 32);
-  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
+  operands[1] = GEN_INT (sext_hwi (value, 32));
 })
 
 (define_split
@@ -9577,7 +9577,7 @@ (define_split
   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
 				       DImode);
   operands[4] = GEN_INT (value >> 32);
-  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
+  operands[1] = GEN_INT (sext_hwi (value, 32));
 })
 
 (define_split
@@ -12425,7 +12425,7 @@ (define_peephole2
 					      SImode,
 					      operands[1], operands[2]);
   HOST_WIDE_INT c = INTVAL (cnst);
-  HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
+  HOST_WIDE_INT sextc = sext_hwi (c, 16);
   HOST_WIDE_INT xorv = c ^ sextc;
 
   operands[9] = GEN_INT (xorv);
  
Jiufu Guo Dec. 1, 2022, 12:16 p.m. UTC | #7
On 2022-12-01 15:10, Jiufu Guo via Gcc-patches wrote:
> Hi Kewen,
> 
> 在 12/1/22 2:11 PM, Kewen.Lin 写道:
>> on 2022/12/1 13:35, Jiufu Guo wrote:
>>> Hi Kewen,
>>> 
>>> Thanks for your quick and insight review!
>>> 
>>> 在 12/1/22 1:17 PM, Kewen.Lin 写道:
>>>> Hi Jeff,
>>>> 
>>>> on 2022/12/1 09:36, Jiufu Guo wrote:
>>>>> Hi,
>>>>> 
>>>>> This patch just uses sext_hwi to replace the expression like:
>>>>> ((value & 0xf..f) ^ 0x80..0) - 0x80..0 for rs6000.cc and rs6000.md.
>>>>> 
>>>>> Bootstrap & regtest pass on ppc64{,le}.
>>>>> Is this ok for trunk?
>>>> 
>>>> You didn't say it clearly but I guessed you have grepped in the 
>>>> whole
>>>> config/rs6000 directory, right?  I noticed there are still two 
>>>> places
>>>> using this kind of expression in function 
>>>> constant_generates_xxspltiw,
>>>> but I assumed it's intentional as their types are not HOST_WIDE_INT.
>>>> 
>>>> gcc/config/rs6000/rs6000.cc:      short sign_h_word = ((h_word & 
>>>> 0xffff) ^ 0x8000) - 0x8000;
>>>> gcc/config/rs6000/rs6000.cc:  int sign_word = ((word & 0xffffffff) ^ 
>>>> 0x80000000) - 0x80000000;
>>>> 
>>>> If so, could you state it clearly in commit log like "with type
>>>> signed/unsigned HOST_WIDE_INT" or similar?
>>>> 
>>> Good question!
>>> 
>>> And as you said sext_hwi is more for "signed/unsigned HOST_WIDE_INT".
>>> For these two places, it seems sext_hwi is not needed actually!
>>> And I did see why these expressions are used, may be just an 
>>> assignment
>>> is ok.
>> 
>> ah, I see.  I agree using the assignment is quite enough.  Could you
>> please also simplify them together?  Since they are with the form
>> "((value & 0xf..f) ^ 0x80..0) - 0x80..0" too, and can be refactored
>> in a better way.  Thanks!
> 
> Sure, I believe just "short sign_h_word = vsx_const->half_words[0];"
> should be correct :-), and included in the updated patch.
> 
> Updated patch is attached,  bootstrap&regtest is on going.

Bootstrap and regtest pass on ppc64{,le}.

BR,
Jeff (Jiufu)
> 
> 
> BR,
> Jeff (Jiufu)
> 
>> 
>> BR,
>> Kewen
>>
  
Kewen.Lin Dec. 2, 2022, 8:56 a.m. UTC | #8
on 2022/12/1 20:16, guojiufu wrote:
> On 2022-12-01 15:10, Jiufu Guo via Gcc-patches wrote:
>> Hi Kewen,
>>
>> 在 12/1/22 2:11 PM, Kewen.Lin 写道:
>>> on 2022/12/1 13:35, Jiufu Guo wrote:
>>>> Hi Kewen,
>>>>
>>>> Thanks for your quick and insight review!
>>>>
>>>> 在 12/1/22 1:17 PM, Kewen.Lin 写道:
>>>>> Hi Jeff,
>>>>>
>>>>> on 2022/12/1 09:36, Jiufu Guo wrote:
>>>>>> Hi,
>>>>>>
>>>>>> This patch just uses sext_hwi to replace the expression like:
>>>>>> ((value & 0xf..f) ^ 0x80..0) - 0x80..0 for rs6000.cc and rs6000.md.
>>>>>>
>>>>>> Bootstrap & regtest pass on ppc64{,le}.
>>>>>> Is this ok for trunk?
>>>>>
>>>>> You didn't say it clearly but I guessed you have grepped in the whole
>>>>> config/rs6000 directory, right?  I noticed there are still two places
>>>>> using this kind of expression in function constant_generates_xxspltiw,
>>>>> but I assumed it's intentional as their types are not HOST_WIDE_INT.
>>>>>
>>>>> gcc/config/rs6000/rs6000.cc:      short sign_h_word = ((h_word & 0xffff) ^ 0x8000) - 0x8000;
>>>>> gcc/config/rs6000/rs6000.cc:  int sign_word = ((word & 0xffffffff) ^ 0x80000000) - 0x80000000;
>>>>>
>>>>> If so, could you state it clearly in commit log like "with type
>>>>> signed/unsigned HOST_WIDE_INT" or similar?
>>>>>
>>>> Good question!
>>>>
>>>> And as you said sext_hwi is more for "signed/unsigned HOST_WIDE_INT".
>>>> For these two places, it seems sext_hwi is not needed actually!
>>>> And I did see why these expressions are used, may be just an assignment
>>>> is ok.
>>>
>>> ah, I see.  I agree using the assignment is quite enough.  Could you
>>> please also simplify them together?  Since they are with the form
>>> "((value & 0xf..f) ^ 0x80..0) - 0x80..0" too, and can be refactored
>>> in a better way.  Thanks!
>>
>> Sure, I believe just "short sign_h_word = vsx_const->half_words[0];"
>> should be correct :-), and included in the updated patch.
>>
>> Updated patch is attached,  bootstrap&regtest is on going.
> 

on 2022/12/1 15:10, Jiufu Guo wrote:
> From 8aa8e1234b6ec34473434951a3a6177253aac770 Mon Sep 17 00:00:00 2001
> From: Jiufu Guo <guojiufu@linux.ibm.com>
> Date: Wed, 30 Nov 2022 13:13:37 +0800
> Subject: [PATCH 2/2]rs6000: update ((v&0xf..f)^0x80..0) - 0x80..0 with code: like sext_hwi
> 

May be shorter with "rs6000: Update sign extension computation with sext_hwi"?

> This patch just replaces the expression like: 
> ((value & 0xf..f) ^ 0x80..0) - 0x80..0 to better code(e.g. sext_hwi) for
> rs6000.cc, rs6000.md and predicates.md (files under rs6000/).


> Bootstrap and regtest pass on ppc64{,le}.
> 

Thanks for updating and testing, this patch is OK.

BR,
Kewen
  
Jiufu Guo Dec. 5, 2022, 6:11 a.m. UTC | #9
Hi Kewen,

"Kewen.Lin" <linkw@linux.ibm.com> writes:
> on 2022/12/1 20:16, guojiufu wrote:
>> On 2022-12-01 15:10, Jiufu Guo via Gcc-patches wrote:
>>> Hi Kewen,
>>>
>>> 在 12/1/22 2:11 PM, Kewen.Lin 写道:
>>>> on 2022/12/1 13:35, Jiufu Guo wrote:
>>>>> Hi Kewen,
>>>>>
>>>>> Thanks for your quick and insight review!
>>>>>
>>>>> 在 12/1/22 1:17 PM, Kewen.Lin 写道:
>>>>>> Hi Jeff,
>>>>>>
>>>>>> on 2022/12/1 09:36, Jiufu Guo wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> This patch just uses sext_hwi to replace the expression like:
>>>>>>> ((value & 0xf..f) ^ 0x80..0) - 0x80..0 for rs6000.cc and rs6000.md.
>>>>>>>
>>>>>>> Bootstrap & regtest pass on ppc64{,le}.
>>>>>>> Is this ok for trunk?
>>>>>>
>>>>>> You didn't say it clearly but I guessed you have grepped in the whole
>>>>>> config/rs6000 directory, right?  I noticed there are still two places
>>>>>> using this kind of expression in function constant_generates_xxspltiw,
>>>>>> but I assumed it's intentional as their types are not HOST_WIDE_INT.
>>>>>>
>>>>>> gcc/config/rs6000/rs6000.cc:      short sign_h_word = ((h_word & 0xffff) ^ 0x8000) - 0x8000;
>>>>>> gcc/config/rs6000/rs6000.cc:  int sign_word = ((word & 0xffffffff) ^ 0x80000000) - 0x80000000;
>>>>>>
>>>>>> If so, could you state it clearly in commit log like "with type
>>>>>> signed/unsigned HOST_WIDE_INT" or similar?
>>>>>>
>>>>> Good question!
>>>>>
>>>>> And as you said sext_hwi is more for "signed/unsigned HOST_WIDE_INT".
>>>>> For these two places, it seems sext_hwi is not needed actually!
>>>>> And I did see why these expressions are used, may be just an assignment
>>>>> is ok.
>>>>
>>>> ah, I see.  I agree using the assignment is quite enough.  Could you
>>>> please also simplify them together?  Since they are with the form
>>>> "((value & 0xf..f) ^ 0x80..0) - 0x80..0" too, and can be refactored
>>>> in a better way.  Thanks!
>>>
>>> Sure, I believe just "short sign_h_word = vsx_const->half_words[0];"
>>> should be correct :-), and included in the updated patch.
>>>
>>> Updated patch is attached,  bootstrap&regtest is on going.
>> 
>
> on 2022/12/1 15:10, Jiufu Guo wrote:
>> From 8aa8e1234b6ec34473434951a3a6177253aac770 Mon Sep 17 00:00:00 2001
>> From: Jiufu Guo <guojiufu@linux.ibm.com>
>> Date: Wed, 30 Nov 2022 13:13:37 +0800
>> Subject: [PATCH 2/2]rs6000: update ((v&0xf..f)^0x80..0) - 0x80..0 with code: like sext_hwi
>> 
>
> May be shorter with "rs6000: Update sign extension computation with
> sext_hwi"?
Thanks for your great suggestions!
>
>> This patch just replaces the expression like: 
>> ((value & 0xf..f) ^ 0x80..0) - 0x80..0 to better code(e.g. sext_hwi) for
>> rs6000.cc, rs6000.md and predicates.md (files under rs6000/).
>
>
>> Bootstrap and regtest pass on ppc64{,le}.
>> 
>
> Thanks for updating and testing, this patch is OK.

BR,
Jeff (Jiufu)

>
> BR,
> Kewen
  
Jiufu Guo Dec. 9, 2022, 1:51 a.m. UTC | #10
Hi,

Jiufu Guo via Gcc-patches <gcc-patches@gcc.gnu.org> writes:

> Hi Kewen,
>
> "Kewen.Lin" <linkw@linux.ibm.com> writes:
>> on 2022/12/1 20:16, guojiufu wrote:
>>> On 2022-12-01 15:10, Jiufu Guo via Gcc-patches wrote:
>>>> Hi Kewen,
cut...
>>> From 8aa8e1234b6ec34473434951a3a6177253aac770 Mon Sep 17 00:00:00 2001
>>> From: Jiufu Guo <guojiufu@linux.ibm.com>
>>> Date: Wed, 30 Nov 2022 13:13:37 +0800
>>> Subject: [PATCH 2/2]rs6000: update ((v&0xf..f)^0x80..0) - 0x80..0 with code: like sext_hwi
>>> 
>>
>> May be shorter with "rs6000: Update sign extension computation with
>> sext_hwi"?
> Thanks for your great suggestions!
>>
>>> This patch just replaces the expression like: 
>>> ((value & 0xf..f) ^ 0x80..0) - 0x80..0 to better code(e.g. sext_hwi) for
>>> rs6000.cc, rs6000.md and predicates.md (files under rs6000/).
>>
>>
>>> Bootstrap and regtest pass on ppc64{,le}.
>>> 
>>
>> Thanks for updating and testing, this patch is OK.
Committed via r13-4556.  Thanks again!

BR,
Jeff (Jiufu)
>
> BR,
> Jeff (Jiufu)
>
>>
>> BR,
>> Kewen
  

Patch

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 5efe9b22d8b..718072cc9a1 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -6021,7 +6021,7 @@  num_insns_constant_gpr (HOST_WIDE_INT value)
 
   else if (TARGET_POWERPC64)
     {
-      HOST_WIDE_INT low  = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
+      HOST_WIDE_INT low = sext_hwi (value, 32);
       HOST_WIDE_INT high = value >> 31;
 
       if (high == 0 || high == -1)
@@ -8456,7 +8456,7 @@  darwin_rs6000_legitimate_lo_sum_const_p (rtx x, machine_mode mode)
     }
 
   /* We only care if the access(es) would cause a change to the high part.  */
-  offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
+  offset = sext_hwi (offset, 16);
   return SIGNED_16BIT_OFFSET_EXTRA_P (offset, extra);
 }
 
@@ -8522,7 +8522,7 @@  mem_operand_gpr (rtx op, machine_mode mode)
   if (GET_CODE (addr) == LO_SUM)
     /* For lo_sum addresses, we must allow any offset except one that
        causes a wrap, so test only the low 16 bits.  */
-    offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
+    offset = sext_hwi (offset, 16);
 
   return SIGNED_16BIT_OFFSET_EXTRA_P (offset, extra);
 }
@@ -8562,7 +8562,7 @@  mem_operand_ds_form (rtx op, machine_mode mode)
   if (GET_CODE (addr) == LO_SUM)
     /* For lo_sum addresses, we must allow any offset except one that
        causes a wrap, so test only the low 16 bits.  */
-    offset = ((offset & 0xffff) ^ 0x8000) - 0x8000;
+    offset = sext_hwi (offset, 16);
 
   return SIGNED_16BIT_OFFSET_EXTRA_P (offset, extra);
 }
@@ -9136,7 +9136,7 @@  rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
     {
       HOST_WIDE_INT high_int, low_int;
       rtx sum;
-      low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
+      low_int = sext_hwi (INTVAL (XEXP (x, 1)), 16);
       if (low_int >= 0x8000 - extra)
 	low_int = 0;
       high_int = INTVAL (XEXP (x, 1)) - low_int;
@@ -10203,7 +10203,7 @@  rs6000_emit_set_const (rtx dest, rtx source)
 	  lo = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
 				      DImode);
 	  emit_move_insn (hi, GEN_INT (c >> 32));
-	  c = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
+	  c = sext_hwi (c, 32);
 	  emit_move_insn (lo, GEN_INT (c));
 	}
       else
@@ -10242,7 +10242,7 @@  rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
 
   if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
       || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
-    emit_move_insn (dest, GEN_INT ((ud1 ^ 0x8000) - 0x8000));
+    emit_move_insn (dest, GEN_INT (sext_hwi (ud1, 16)));
 
   else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
 	   || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
@@ -10250,7 +10250,7 @@  rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
 
       emit_move_insn (ud1 != 0 ? copy_rtx (temp) : dest,
-		      GEN_INT (((ud2 << 16) ^ 0x80000000) - 0x80000000));
+		      GEN_INT (sext_hwi (ud2 << 16, 32)));
       if (ud1 != 0)
 	emit_move_insn (dest,
 			gen_rtx_IOR (DImode, copy_rtx (temp),
@@ -10261,8 +10261,7 @@  rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
 
       gcc_assert (ud2 & 0x8000);
-      emit_move_insn (copy_rtx (temp),
-		      GEN_INT (((ud2 << 16) ^ 0x80000000) - 0x80000000));
+      emit_move_insn (copy_rtx (temp), GEN_INT (sext_hwi (ud2 << 16, 32)));
       if (ud1 != 0)
 	emit_move_insn (copy_rtx (temp),
 			gen_rtx_IOR (DImode, copy_rtx (temp),
@@ -10273,7 +10272,7 @@  rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
       HOST_WIDE_INT num = (ud2 << 16) | ud1;
-      rs6000_emit_set_long_const (temp, (num ^ 0x80000000) - 0x80000000);
+      rs6000_emit_set_long_const (temp, sext_hwi (num, 32));
       rtx one = gen_rtx_AND (DImode, temp, GEN_INT (0xffffffff));
       rtx two = gen_rtx_ASHIFT (DImode, temp, GEN_INT (32));
       emit_move_insn (dest, gen_rtx_IOR (DImode, one, two));
@@ -10283,8 +10282,7 @@  rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
 
-      emit_move_insn (copy_rtx (temp),
-		      GEN_INT (((ud3 << 16) ^ 0x80000000) - 0x80000000));
+      emit_move_insn (copy_rtx (temp), GEN_INT (sext_hwi (ud3 << 16, 32)));
       if (ud2 != 0)
 	emit_move_insn (copy_rtx (temp),
 			gen_rtx_IOR (DImode, copy_rtx (temp),
@@ -10336,8 +10334,7 @@  rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
     {
       temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
 
-      emit_move_insn (copy_rtx (temp),
-		      GEN_INT (((ud4 << 16) ^ 0x80000000) - 0x80000000));
+      emit_move_insn (copy_rtx (temp), GEN_INT (sext_hwi (ud4 << 16, 32)));
       if (ud3 != 0)
 	emit_move_insn (copy_rtx (temp),
 			gen_rtx_IOR (DImode, copy_rtx (temp),
@@ -14167,8 +14164,7 @@  print_operand (FILE *file, rtx x, int code)
       /* If constant, low-order 16 bits of constant, signed.  Otherwise, write
 	 normally.  */
       if (INT_P (x))
-	fprintf (file, HOST_WIDE_INT_PRINT_DEC,
-		 ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
+	fprintf (file, HOST_WIDE_INT_PRINT_DEC, sext_hwi (INTVAL (x), 16));
       else
 	print_operand (file, x, 0);
       return;
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 3bae303086b..4bd1dfd3da9 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -1787,7 +1787,7 @@  (define_expand "add<mode>3"
 	}
 
       HOST_WIDE_INT val = INTVAL (operands[2]);
-      HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
+      HOST_WIDE_INT low = sext_hwi (val, 16);
       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
 
       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
@@ -1930,7 +1930,7 @@  (define_split
    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
 {
   HOST_WIDE_INT val = INTVAL (operands[2]);
-  HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
+  HOST_WIDE_INT low = sext_hwi (val, 16);
   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
 
   operands[4] = GEN_INT (low);
@@ -8213,7 +8213,7 @@  (define_split
   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
   operands[4] = GEN_INT (value >> 32);
-  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
+  operands[1] = GEN_INT (sext_hwi (value, 32));
 })
 
 (define_split
@@ -9577,7 +9577,7 @@  (define_split
   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
 				       DImode);
   operands[4] = GEN_INT (value >> 32);
-  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
+  operands[1] = GEN_INT (sext_hwi (value, 32));
 })
 
 (define_split
@@ -12425,7 +12425,7 @@  (define_peephole2
 					      SImode,
 					      operands[1], operands[2]);
   HOST_WIDE_INT c = INTVAL (cnst);
-  HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
+  HOST_WIDE_INT sextc = sext_hwi (c, 16);
   HOST_WIDE_INT xorv = c ^ sextc;
 
   operands[9] = GEN_INT (xorv);