Re: [PATCH V4 2/2] rs6000: use li;x?oris to build constant

2023-05-16 Thread guojiufu via Gcc-patches

Hi,

On 2023-05-15 14:53, Kewen.Lin wrote:

Hi Jeff,

on 2022/12/12 09:38, Jiufu Guo wrote:

Hi,

For constant C:
If '(c & 0xULL) == 0x' or say:
32(1) || 1(0) || 15(x) || 16(0), we could use "lis; xoris" to build.

Here N(M) means N continuous bit M, x for M means it is ok for either
1 or 0; '||' means concatenation.

This patch update rs6000_emit_set_long_const to support those 
constants.


Compare with previous version:
https://gcc.gnu.org/pipermail/gcc-patches/2022-December/607618.htm
This patch fix conflicts with trunk.

Bootstrap and regtest pass on ppc64{,le}.

Is this ok for trunk?


OK for trunk, thanks for improving this.

btw, the test case needs to be updated a bit as the function names in 
the
context changed upstream, please ensure it's tested well before 
committing,

thanks!


Yeap! Retested and verified.
Thanks so much for your always insight review and helpful comments!

Committed via r14-923-g5eb7d560626e42.

BR,
Jeff (Jiufu)





BR,
Jeff (Jiufu)


PR target/106708

gcc/ChangeLog:

* config/rs6000/rs6000.cc (rs6000_emit_set_long_const): Add to build
constants through "lis; xoris".


Maybe s/Add to build/Support building/

Yes :)



BR,
Kewen



gcc/testsuite/ChangeLog:

* gcc.target/powerpc/pr106708.c: Add test function.

---
 gcc/config/rs6000/rs6000.cc |  7 +++
 gcc/testsuite/gcc.target/powerpc/pr106708.c | 10 +-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 8c1192a10c8..1138d5e8cd4 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -10251,6 +10251,13 @@ rs6000_emit_set_long_const (rtx dest, 
HOST_WIDE_INT c)

   if (ud1 != 0)
emit_move_insn (dest, gen_rtx_IOR (DImode, temp, GEN_INT (ud1)));
 }
+  else if (ud4 == 0x && ud3 == 0x && !(ud2 & 0x8000) && ud1 
== 0)

+{
+  /* lis; xoris */
+  temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
+  emit_move_insn (temp, GEN_INT (sext_hwi ((ud2 | 0x8000) << 16, 
32)));
+  emit_move_insn (dest, gen_rtx_XOR (DImode, temp, GEN_INT 
(0x8000)));

+}
   else if (ud4 == 0x && ud3 == 0x && (ud1 & 0x8000))
 {
   /* li; xoris */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr106708.c 
b/gcc/testsuite/gcc.target/powerpc/pr106708.c

index dc9ceda8367..a015c71e630 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr106708.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr106708.c
@@ -4,7 +4,7 @@
 /* { dg-require-effective-target has_arch_ppc64 } */

 long long arr[]
-  = {0x7cdeab55LL, 0x98765432LL, 0xabcdLL};
+= {0x7cdeab55LL, 0x98765432LL, 0xabcdLL, 
0x6543LL};


 void __attribute__ ((__noipa__)) lixoris (long long *arg)
 {
@@ -27,6 +27,13 @@ void __attribute__ ((__noipa__)) lisrldicl (long 
long *arg)

 /* { dg-final { scan-assembler-times {\mlis .*,0xabcd\M} 1 } } */
 /* { dg-final { scan-assembler-times {\mrldicl .*,0,32\M} 1 } } */

+void __attribute__ ((__noipa__)) lisxoris (long long *arg)
+{
+  *arg = 0x6543LL;
+}
+/* { dg-final { scan-assembler-times {\mlis .*,0xe543\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxoris .*0x8000\M} 1 } } */
+
 int
 main ()
 {
@@ -35,6 +42,7 @@ main ()
   lixoris (a);
   lioris (a + 1);
   lisrldicl (a + 2);
+  lisxoris (a + 3);
   if (__builtin_memcmp (a, arr, sizeof (arr)) != 0)
 __builtin_abort ();
   return 0;


Re: [PATCH V4 2/2] rs6000: use li;x?oris to build constant

2023-05-14 Thread Kewen.Lin via Gcc-patches
Hi Jeff,

on 2022/12/12 09:38, Jiufu Guo wrote:
> Hi,
> 
> For constant C:
> If '(c & 0xULL) == 0x' or say:
> 32(1) || 1(0) || 15(x) || 16(0), we could use "lis; xoris" to build.
> 
> Here N(M) means N continuous bit M, x for M means it is ok for either
> 1 or 0; '||' means concatenation.
> 
> This patch update rs6000_emit_set_long_const to support those constants.
> 
> Compare with previous version:
> https://gcc.gnu.org/pipermail/gcc-patches/2022-December/607618.htm
> This patch fix conflicts with trunk.
> 
> Bootstrap and regtest pass on ppc64{,le}.
> 
> Is this ok for trunk?

OK for trunk, thanks for improving this.

btw, the test case needs to be updated a bit as the function names in the
context changed upstream, please ensure it's tested well before committing,
thanks!

> 
> BR,
> Jeff (Jiufu)
> 
> 
>   PR target/106708
> 
> gcc/ChangeLog:
> 
>   * config/rs6000/rs6000.cc (rs6000_emit_set_long_const): Add to build
>   constants through "lis; xoris".

Maybe s/Add to build/Support building/

BR,
Kewen

> 
> gcc/testsuite/ChangeLog:
> 
>   * gcc.target/powerpc/pr106708.c: Add test function.
> 
> ---
>  gcc/config/rs6000/rs6000.cc |  7 +++
>  gcc/testsuite/gcc.target/powerpc/pr106708.c | 10 +-
>  2 files changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
> index 8c1192a10c8..1138d5e8cd4 100644
> --- a/gcc/config/rs6000/rs6000.cc
> +++ b/gcc/config/rs6000/rs6000.cc
> @@ -10251,6 +10251,13 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT 
> c)
>if (ud1 != 0)
>   emit_move_insn (dest, gen_rtx_IOR (DImode, temp, GEN_INT (ud1)));
>  }
> +  else if (ud4 == 0x && ud3 == 0x && !(ud2 & 0x8000) && ud1 == 0)
> +{
> +  /* lis; xoris */
> +  temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
> +  emit_move_insn (temp, GEN_INT (sext_hwi ((ud2 | 0x8000) << 16, 32)));
> +  emit_move_insn (dest, gen_rtx_XOR (DImode, temp, GEN_INT 
> (0x8000)));
> +}
>else if (ud4 == 0x && ud3 == 0x && (ud1 & 0x8000))
>  {
>/* li; xoris */
> diff --git a/gcc/testsuite/gcc.target/powerpc/pr106708.c 
> b/gcc/testsuite/gcc.target/powerpc/pr106708.c
> index dc9ceda8367..a015c71e630 100644
> --- a/gcc/testsuite/gcc.target/powerpc/pr106708.c
> +++ b/gcc/testsuite/gcc.target/powerpc/pr106708.c
> @@ -4,7 +4,7 @@
>  /* { dg-require-effective-target has_arch_ppc64 } */
> 
>  long long arr[]
> -  = {0x7cdeab55LL, 0x98765432LL, 0xabcdLL};
> += {0x7cdeab55LL, 0x98765432LL, 0xabcdLL, 0x6543LL};
> 
>  void __attribute__ ((__noipa__)) lixoris (long long *arg)
>  {
> @@ -27,6 +27,13 @@ void __attribute__ ((__noipa__)) lisrldicl (long long *arg)
>  /* { dg-final { scan-assembler-times {\mlis .*,0xabcd\M} 1 } } */
>  /* { dg-final { scan-assembler-times {\mrldicl .*,0,32\M} 1 } } */
> 
> +void __attribute__ ((__noipa__)) lisxoris (long long *arg)
> +{
> +  *arg = 0x6543LL;
> +}
> +/* { dg-final { scan-assembler-times {\mlis .*,0xe543\M} 1 } } */
> +/* { dg-final { scan-assembler-times {\mxoris .*0x8000\M} 1 } } */
> +
>  int
>  main ()
>  {
> @@ -35,6 +42,7 @@ main ()
>lixoris (a);
>lioris (a + 1);
>lisrldicl (a + 2);
> +  lisxoris (a + 3);
>if (__builtin_memcmp (a, arr, sizeof (arr)) != 0)
>  __builtin_abort ();
>return 0;



Ping^^^ [PATCH V4 2/2] rs6000: use li;x?oris to build constant

2023-04-25 Thread Jiufu Guo via Gcc-patches


Hi,

I would like to have a gentle ping for this. 
https://gcc.gnu.org/pipermail/gcc-patches/2022-December/608292.html

BR,
Jeff (Jiufu)

Jiufu Guo via Gcc-patches  writes:

> Hi,
>
> Gentle ping:
> https://gcc.gnu.org/pipermail/gcc-patches/2022-December/608292.html
>
> BR,
> Jeff (Jiufu)
>
>
> Jiufu Guo via Gcc-patches  writes:
>
>> Hi,
>>
>> I would like to have a ping on this patch:
>> https://gcc.gnu.org/pipermail/gcc-patches/2022-December/608292.html
>>
>>
>> BR,
>> Jeff (Jiufu)
>>
>>
>> Jiufu Guo  writes:
>>
>>> Hi,
>>>
>>> For constant C:
>>> If '(c & 0xULL) == 0x' or say:
>>> 32(1) || 1(0) || 15(x) || 16(0), we could use "lis; xoris" to build.
>>>
>>> Here N(M) means N continuous bit M, x for M means it is ok for either
>>> 1 or 0; '||' means concatenation.
>>>
>>> This patch update rs6000_emit_set_long_const to support those constants.
>>>
>>> Compare with previous version:
>>> https://gcc.gnu.org/pipermail/gcc-patches/2022-December/607618.htm
>>> This patch fix conflicts with trunk.
>>>
>>> Bootstrap and regtest pass on ppc64{,le}.
>>>
>>> Is this ok for trunk?
>>>
>>> BR,
>>> Jeff (Jiufu)
>>>
>>>
>>> PR target/106708
>>>
>>> gcc/ChangeLog:
>>>
>>> * config/rs6000/rs6000.cc (rs6000_emit_set_long_const): Add to build
>>> constants through "lis; xoris".
>>>
>>> gcc/testsuite/ChangeLog:
>>>
>>> * gcc.target/powerpc/pr106708.c: Add test function.
>>>
>>> ---
>>>  gcc/config/rs6000/rs6000.cc |  7 +++
>>>  gcc/testsuite/gcc.target/powerpc/pr106708.c | 10 +-
>>>  2 files changed, 16 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
>>> index 8c1192a10c8..1138d5e8cd4 100644
>>> --- a/gcc/config/rs6000/rs6000.cc
>>> +++ b/gcc/config/rs6000/rs6000.cc
>>> @@ -10251,6 +10251,13 @@ rs6000_emit_set_long_const (rtx dest, 
>>> HOST_WIDE_INT c)
>>>if (ud1 != 0)
>>> emit_move_insn (dest, gen_rtx_IOR (DImode, temp, GEN_INT (ud1)));
>>>  }
>>> +  else if (ud4 == 0x && ud3 == 0x && !(ud2 & 0x8000) && ud1 == 0)
>>> +{
>>> +  /* lis; xoris */
>>> +  temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
>>> +  emit_move_insn (temp, GEN_INT (sext_hwi ((ud2 | 0x8000) << 16, 32)));
>>> +  emit_move_insn (dest, gen_rtx_XOR (DImode, temp, GEN_INT 
>>> (0x8000)));
>>> +}
>>>else if (ud4 == 0x && ud3 == 0x && (ud1 & 0x8000))
>>>  {
>>>/* li; xoris */
>>> diff --git a/gcc/testsuite/gcc.target/powerpc/pr106708.c 
>>> b/gcc/testsuite/gcc.target/powerpc/pr106708.c
>>> index dc9ceda8367..a015c71e630 100644
>>> --- a/gcc/testsuite/gcc.target/powerpc/pr106708.c
>>> +++ b/gcc/testsuite/gcc.target/powerpc/pr106708.c
>>> @@ -4,7 +4,7 @@
>>>  /* { dg-require-effective-target has_arch_ppc64 } */
>>>  
>>>  long long arr[]
>>> -  = {0x7cdeab55LL, 0x98765432LL, 0xabcdLL};
>>> += {0x7cdeab55LL, 0x98765432LL, 0xabcdLL, 0x6543LL};
>>>  
>>>  void __attribute__ ((__noipa__)) lixoris (long long *arg)
>>>  {
>>> @@ -27,6 +27,13 @@ void __attribute__ ((__noipa__)) lisrldicl (long long 
>>> *arg)
>>>  /* { dg-final { scan-assembler-times {\mlis .*,0xabcd\M} 1 } } */
>>>  /* { dg-final { scan-assembler-times {\mrldicl .*,0,32\M} 1 } } */
>>>  
>>> +void __attribute__ ((__noipa__)) lisxoris (long long *arg)
>>> +{
>>> +  *arg = 0x6543LL;
>>> +}
>>> +/* { dg-final { scan-assembler-times {\mlis .*,0xe543\M} 1 } } */
>>> +/* { dg-final { scan-assembler-times {\mxoris .*0x8000\M} 1 } } */
>>> +
>>>  int
>>>  main ()
>>>  {
>>> @@ -35,6 +42,7 @@ main ()
>>>lixoris (a);
>>>lioris (a + 1);
>>>lisrldicl (a + 2);
>>> +  lisxoris (a + 3);
>>>if (__builtin_memcmp (a, arr, sizeof (arr)) != 0)
>>>  __builtin_abort ();
>>>return 0;


Ping^^ [PATCH V4 2/2] rs6000: use li;x?oris to build constant

2023-02-20 Thread Jiufu Guo via Gcc-patches
Hi,

Gentle ping:
https://gcc.gnu.org/pipermail/gcc-patches/2022-December/608292.html

BR,
Jeff (Jiufu)


Jiufu Guo via Gcc-patches  writes:

> Hi,
>
> I would like to have a ping on this patch:
> https://gcc.gnu.org/pipermail/gcc-patches/2022-December/608292.html
>
>
> BR,
> Jeff (Jiufu)
>
>
> Jiufu Guo  writes:
>
>> Hi,
>>
>> For constant C:
>> If '(c & 0xULL) == 0x' or say:
>> 32(1) || 1(0) || 15(x) || 16(0), we could use "lis; xoris" to build.
>>
>> Here N(M) means N continuous bit M, x for M means it is ok for either
>> 1 or 0; '||' means concatenation.
>>
>> This patch update rs6000_emit_set_long_const to support those constants.
>>
>> Compare with previous version:
>> https://gcc.gnu.org/pipermail/gcc-patches/2022-December/607618.htm
>> This patch fix conflicts with trunk.
>>
>> Bootstrap and regtest pass on ppc64{,le}.
>>
>> Is this ok for trunk?
>>
>> BR,
>> Jeff (Jiufu)
>>
>>
>>  PR target/106708
>>
>> gcc/ChangeLog:
>>
>>  * config/rs6000/rs6000.cc (rs6000_emit_set_long_const): Add to build
>>  constants through "lis; xoris".
>>
>> gcc/testsuite/ChangeLog:
>>
>>  * gcc.target/powerpc/pr106708.c: Add test function.
>>
>> ---
>>  gcc/config/rs6000/rs6000.cc |  7 +++
>>  gcc/testsuite/gcc.target/powerpc/pr106708.c | 10 +-
>>  2 files changed, 16 insertions(+), 1 deletion(-)
>>
>> diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
>> index 8c1192a10c8..1138d5e8cd4 100644
>> --- a/gcc/config/rs6000/rs6000.cc
>> +++ b/gcc/config/rs6000/rs6000.cc
>> @@ -10251,6 +10251,13 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT 
>> c)
>>if (ud1 != 0)
>>  emit_move_insn (dest, gen_rtx_IOR (DImode, temp, GEN_INT (ud1)));
>>  }
>> +  else if (ud4 == 0x && ud3 == 0x && !(ud2 & 0x8000) && ud1 == 0)
>> +{
>> +  /* lis; xoris */
>> +  temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
>> +  emit_move_insn (temp, GEN_INT (sext_hwi ((ud2 | 0x8000) << 16, 32)));
>> +  emit_move_insn (dest, gen_rtx_XOR (DImode, temp, GEN_INT 
>> (0x8000)));
>> +}
>>else if (ud4 == 0x && ud3 == 0x && (ud1 & 0x8000))
>>  {
>>/* li; xoris */
>> diff --git a/gcc/testsuite/gcc.target/powerpc/pr106708.c 
>> b/gcc/testsuite/gcc.target/powerpc/pr106708.c
>> index dc9ceda8367..a015c71e630 100644
>> --- a/gcc/testsuite/gcc.target/powerpc/pr106708.c
>> +++ b/gcc/testsuite/gcc.target/powerpc/pr106708.c
>> @@ -4,7 +4,7 @@
>>  /* { dg-require-effective-target has_arch_ppc64 } */
>>  
>>  long long arr[]
>> -  = {0x7cdeab55LL, 0x98765432LL, 0xabcdLL};
>> += {0x7cdeab55LL, 0x98765432LL, 0xabcdLL, 0x6543LL};
>>  
>>  void __attribute__ ((__noipa__)) lixoris (long long *arg)
>>  {
>> @@ -27,6 +27,13 @@ void __attribute__ ((__noipa__)) lisrldicl (long long 
>> *arg)
>>  /* { dg-final { scan-assembler-times {\mlis .*,0xabcd\M} 1 } } */
>>  /* { dg-final { scan-assembler-times {\mrldicl .*,0,32\M} 1 } } */
>>  
>> +void __attribute__ ((__noipa__)) lisxoris (long long *arg)
>> +{
>> +  *arg = 0x6543LL;
>> +}
>> +/* { dg-final { scan-assembler-times {\mlis .*,0xe543\M} 1 } } */
>> +/* { dg-final { scan-assembler-times {\mxoris .*0x8000\M} 1 } } */
>> +
>>  int
>>  main ()
>>  {
>> @@ -35,6 +42,7 @@ main ()
>>lixoris (a);
>>lioris (a + 1);
>>lisrldicl (a + 2);
>> +  lisxoris (a + 3);
>>if (__builtin_memcmp (a, arr, sizeof (arr)) != 0)
>>  __builtin_abort ();
>>return 0;


Re: [PATCH V4 2/2] rs6000: use li;x?oris to build constant

2023-01-03 Thread Jiufu Guo via Gcc-patches
Hi,

I would like to have a ping on this patch:
https://gcc.gnu.org/pipermail/gcc-patches/2022-December/608292.html


BR,
Jeff (Jiufu)


Jiufu Guo  writes:

> Hi,
>
> For constant C:
> If '(c & 0xULL) == 0x' or say:
> 32(1) || 1(0) || 15(x) || 16(0), we could use "lis; xoris" to build.
>
> Here N(M) means N continuous bit M, x for M means it is ok for either
> 1 or 0; '||' means concatenation.
>
> This patch update rs6000_emit_set_long_const to support those constants.
>
> Compare with previous version:
> https://gcc.gnu.org/pipermail/gcc-patches/2022-December/607618.htm
> This patch fix conflicts with trunk.
>
> Bootstrap and regtest pass on ppc64{,le}.
>
> Is this ok for trunk?
>
> BR,
> Jeff (Jiufu)
>
>
>   PR target/106708
>
> gcc/ChangeLog:
>
>   * config/rs6000/rs6000.cc (rs6000_emit_set_long_const): Add to build
>   constants through "lis; xoris".
>
> gcc/testsuite/ChangeLog:
>
>   * gcc.target/powerpc/pr106708.c: Add test function.
>
> ---
>  gcc/config/rs6000/rs6000.cc |  7 +++
>  gcc/testsuite/gcc.target/powerpc/pr106708.c | 10 +-
>  2 files changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
> index 8c1192a10c8..1138d5e8cd4 100644
> --- a/gcc/config/rs6000/rs6000.cc
> +++ b/gcc/config/rs6000/rs6000.cc
> @@ -10251,6 +10251,13 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT 
> c)
>if (ud1 != 0)
>   emit_move_insn (dest, gen_rtx_IOR (DImode, temp, GEN_INT (ud1)));
>  }
> +  else if (ud4 == 0x && ud3 == 0x && !(ud2 & 0x8000) && ud1 == 0)
> +{
> +  /* lis; xoris */
> +  temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
> +  emit_move_insn (temp, GEN_INT (sext_hwi ((ud2 | 0x8000) << 16, 32)));
> +  emit_move_insn (dest, gen_rtx_XOR (DImode, temp, GEN_INT 
> (0x8000)));
> +}
>else if (ud4 == 0x && ud3 == 0x && (ud1 & 0x8000))
>  {
>/* li; xoris */
> diff --git a/gcc/testsuite/gcc.target/powerpc/pr106708.c 
> b/gcc/testsuite/gcc.target/powerpc/pr106708.c
> index dc9ceda8367..a015c71e630 100644
> --- a/gcc/testsuite/gcc.target/powerpc/pr106708.c
> +++ b/gcc/testsuite/gcc.target/powerpc/pr106708.c
> @@ -4,7 +4,7 @@
>  /* { dg-require-effective-target has_arch_ppc64 } */
>  
>  long long arr[]
> -  = {0x7cdeab55LL, 0x98765432LL, 0xabcdLL};
> += {0x7cdeab55LL, 0x98765432LL, 0xabcdLL, 0x6543LL};
>  
>  void __attribute__ ((__noipa__)) lixoris (long long *arg)
>  {
> @@ -27,6 +27,13 @@ void __attribute__ ((__noipa__)) lisrldicl (long long *arg)
>  /* { dg-final { scan-assembler-times {\mlis .*,0xabcd\M} 1 } } */
>  /* { dg-final { scan-assembler-times {\mrldicl .*,0,32\M} 1 } } */
>  
> +void __attribute__ ((__noipa__)) lisxoris (long long *arg)
> +{
> +  *arg = 0x6543LL;
> +}
> +/* { dg-final { scan-assembler-times {\mlis .*,0xe543\M} 1 } } */
> +/* { dg-final { scan-assembler-times {\mxoris .*0x8000\M} 1 } } */
> +
>  int
>  main ()
>  {
> @@ -35,6 +42,7 @@ main ()
>lixoris (a);
>lioris (a + 1);
>lisrldicl (a + 2);
> +  lisxoris (a + 3);
>if (__builtin_memcmp (a, arr, sizeof (arr)) != 0)
>  __builtin_abort ();
>return 0;


[PATCH V4 2/2] rs6000: use li;x?oris to build constant

2022-12-11 Thread Jiufu Guo via Gcc-patches
Hi,

For constant C:
If '(c & 0xULL) == 0x' or say:
32(1) || 1(0) || 15(x) || 16(0), we could use "lis; xoris" to build.

Here N(M) means N continuous bit M, x for M means it is ok for either
1 or 0; '||' means concatenation.

This patch update rs6000_emit_set_long_const to support those constants.

Compare with previous version:
https://gcc.gnu.org/pipermail/gcc-patches/2022-December/607618.htm
This patch fix conflicts with trunk.

Bootstrap and regtest pass on ppc64{,le}.

Is this ok for trunk?

BR,
Jeff (Jiufu)


PR target/106708

gcc/ChangeLog:

* config/rs6000/rs6000.cc (rs6000_emit_set_long_const): Add to build
constants through "lis; xoris".

gcc/testsuite/ChangeLog:

* gcc.target/powerpc/pr106708.c: Add test function.

---
 gcc/config/rs6000/rs6000.cc |  7 +++
 gcc/testsuite/gcc.target/powerpc/pr106708.c | 10 +-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 8c1192a10c8..1138d5e8cd4 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -10251,6 +10251,13 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
   if (ud1 != 0)
emit_move_insn (dest, gen_rtx_IOR (DImode, temp, GEN_INT (ud1)));
 }
+  else if (ud4 == 0x && ud3 == 0x && !(ud2 & 0x8000) && ud1 == 0)
+{
+  /* lis; xoris */
+  temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
+  emit_move_insn (temp, GEN_INT (sext_hwi ((ud2 | 0x8000) << 16, 32)));
+  emit_move_insn (dest, gen_rtx_XOR (DImode, temp, GEN_INT (0x8000)));
+}
   else if (ud4 == 0x && ud3 == 0x && (ud1 & 0x8000))
 {
   /* li; xoris */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr106708.c 
b/gcc/testsuite/gcc.target/powerpc/pr106708.c
index dc9ceda8367..a015c71e630 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr106708.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr106708.c
@@ -4,7 +4,7 @@
 /* { dg-require-effective-target has_arch_ppc64 } */
 
 long long arr[]
-  = {0x7cdeab55LL, 0x98765432LL, 0xabcdLL};
+= {0x7cdeab55LL, 0x98765432LL, 0xabcdLL, 0x6543LL};
 
 void __attribute__ ((__noipa__)) lixoris (long long *arg)
 {
@@ -27,6 +27,13 @@ void __attribute__ ((__noipa__)) lisrldicl (long long *arg)
 /* { dg-final { scan-assembler-times {\mlis .*,0xabcd\M} 1 } } */
 /* { dg-final { scan-assembler-times {\mrldicl .*,0,32\M} 1 } } */
 
+void __attribute__ ((__noipa__)) lisxoris (long long *arg)
+{
+  *arg = 0x6543LL;
+}
+/* { dg-final { scan-assembler-times {\mlis .*,0xe543\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxoris .*0x8000\M} 1 } } */
+
 int
 main ()
 {
@@ -35,6 +42,7 @@ main ()
   lixoris (a);
   lioris (a + 1);
   lisrldicl (a + 2);
+  lisxoris (a + 3);
   if (__builtin_memcmp (a, arr, sizeof (arr)) != 0)
 __builtin_abort ();
   return 0;
-- 
2.17.1