diff mbox

Fix -mcpu=power8 atomic expansion (PR target/69644)

Message ID 20160203222801.GH3017@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Feb. 3, 2016, 10:28 p.m. UTC
Hi!

rs6000_expand_atomic_compare_and_swap uses oldval directly in
a comparison instruction, but oldval might be a CONST_INT not suitable
for the instruction (such as in the testcase below in SImode comparison
0x8000 constant).  We need to force those into register if they don't
satisfy the predicate.

Bootstrapped/regtested on powerpc64{,le}-linux, ok for trunk?

2016-02-03  Jakub Jelinek  <jakub@redhat.com>

	PR target/69644
	* config/rs6000/rs6000.c (rs6000_expand_atomic_compare_and_swap):
	Force oldval into register if it does not satisfy reg_or_short_operand
	predicate.  Fix up formatting.

	* gcc.dg/pr69644.c: New test.


	Jakub

Comments

David Edelsohn Feb. 3, 2016, 10:34 p.m. UTC | #1
On Wed, Feb 3, 2016 at 5:28 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> rs6000_expand_atomic_compare_and_swap uses oldval directly in
> a comparison instruction, but oldval might be a CONST_INT not suitable
> for the instruction (such as in the testcase below in SImode comparison
> 0x8000 constant).  We need to force those into register if they don't
> satisfy the predicate.
>
> Bootstrapped/regtested on powerpc64{,le}-linux, ok for trunk?
>
> 2016-02-03  Jakub Jelinek  <jakub@redhat.com>
>
>         PR target/69644
>         * config/rs6000/rs6000.c (rs6000_expand_atomic_compare_and_swap):
>         Force oldval into register if it does not satisfy reg_or_short_operand
>         predicate.  Fix up formatting.
>
>         * gcc.dg/pr69644.c: New test.

Okay.

Thanks, David
Alan Modra Feb. 4, 2016, 11:33 a.m. UTC | #2
On Wed, Feb 03, 2016 at 05:34:17PM -0500, David Edelsohn wrote:
> On Wed, Feb 3, 2016 at 5:28 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> > Hi!
> >
> > rs6000_expand_atomic_compare_and_swap uses oldval directly in
> > a comparison instruction, but oldval might be a CONST_INT not suitable
> > for the instruction (such as in the testcase below in SImode comparison
> > 0x8000 constant).  We need to force those into register if they don't
> > satisfy the predicate.
> >
> > Bootstrapped/regtested on powerpc64{,le}-linux, ok for trunk?
> >
> > 2016-02-03  Jakub Jelinek  <jakub@redhat.com>
> >
> >         PR target/69644
> >         * config/rs6000/rs6000.c (rs6000_expand_atomic_compare_and_swap):
> >         Force oldval into register if it does not satisfy reg_or_short_operand
> >         predicate.  Fix up formatting.
> >
> >         * gcc.dg/pr69644.c: New test.
> 
> Okay.

This needs to go on gcc-5 and gcc-4.9 branches too, where it fixes
pr69146.  pr69146 and pr69644 are dups.  OK to apply to the branches?
David Edelsohn Feb. 4, 2016, 1:40 p.m. UTC | #3
On Thu, Feb 4, 2016 at 6:33 AM, Alan Modra <amodra@gmail.com> wrote:
> On Wed, Feb 03, 2016 at 05:34:17PM -0500, David Edelsohn wrote:
>> On Wed, Feb 3, 2016 at 5:28 PM, Jakub Jelinek <jakub@redhat.com> wrote:
>> > Hi!
>> >
>> > rs6000_expand_atomic_compare_and_swap uses oldval directly in
>> > a comparison instruction, but oldval might be a CONST_INT not suitable
>> > for the instruction (such as in the testcase below in SImode comparison
>> > 0x8000 constant).  We need to force those into register if they don't
>> > satisfy the predicate.
>> >
>> > Bootstrapped/regtested on powerpc64{,le}-linux, ok for trunk?
>> >
>> > 2016-02-03  Jakub Jelinek  <jakub@redhat.com>
>> >
>> >         PR target/69644
>> >         * config/rs6000/rs6000.c (rs6000_expand_atomic_compare_and_swap):
>> >         Force oldval into register if it does not satisfy reg_or_short_operand
>> >         predicate.  Fix up formatting.
>> >
>> >         * gcc.dg/pr69644.c: New test.
>>
>> Okay.
>
> This needs to go on gcc-5 and gcc-4.9 branches too, where it fixes
> pr69146.  pr69146 and pr69644 are dups.  OK to apply to the branches?

Okay with me, but coordinate with Jakub.

Thanks, David
Jakub Jelinek Feb. 4, 2016, 1:42 p.m. UTC | #4
On Thu, Feb 04, 2016 at 08:40:22AM -0500, David Edelsohn wrote:
> On Thu, Feb 4, 2016 at 6:33 AM, Alan Modra <amodra@gmail.com> wrote:
> > On Wed, Feb 03, 2016 at 05:34:17PM -0500, David Edelsohn wrote:
> >> On Wed, Feb 3, 2016 at 5:28 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> >> > Hi!
> >> >
> >> > rs6000_expand_atomic_compare_and_swap uses oldval directly in
> >> > a comparison instruction, but oldval might be a CONST_INT not suitable
> >> > for the instruction (such as in the testcase below in SImode comparison
> >> > 0x8000 constant).  We need to force those into register if they don't
> >> > satisfy the predicate.
> >> >
> >> > Bootstrapped/regtested on powerpc64{,le}-linux, ok for trunk?
> >> >
> >> > 2016-02-03  Jakub Jelinek  <jakub@redhat.com>
> >> >
> >> >         PR target/69644
> >> >         * config/rs6000/rs6000.c (rs6000_expand_atomic_compare_and_swap):
> >> >         Force oldval into register if it does not satisfy reg_or_short_operand
> >> >         predicate.  Fix up formatting.
> >> >
> >> >         * gcc.dg/pr69644.c: New test.
> >>
> >> Okay.
> >
> > This needs to go on gcc-5 and gcc-4.9 branches too, where it fixes
> > pr69146.  pr69146 and pr69644 are dups.  OK to apply to the branches?
> 
> Okay with me, but coordinate with Jakub.

Ok with me to, just don't have spare cycles now to bootstrap/regtest it.
So, Alan, if you could do that, it would be greatly appreciated.

	Jakub
Alan Modra Feb. 4, 2016, 1:53 p.m. UTC | #5
On Thu, Feb 04, 2016 at 02:42:38PM +0100, Jakub Jelinek wrote:
> On Thu, Feb 04, 2016 at 08:40:22AM -0500, David Edelsohn wrote:
> > On Thu, Feb 4, 2016 at 6:33 AM, Alan Modra <amodra@gmail.com> wrote:
> > > On Wed, Feb 03, 2016 at 05:34:17PM -0500, David Edelsohn wrote:
> > >> On Wed, Feb 3, 2016 at 5:28 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> > >> > Hi!
> > >> >
> > >> > rs6000_expand_atomic_compare_and_swap uses oldval directly in
> > >> > a comparison instruction, but oldval might be a CONST_INT not suitable
> > >> > for the instruction (such as in the testcase below in SImode comparison
> > >> > 0x8000 constant).  We need to force those into register if they don't
> > >> > satisfy the predicate.
> > >> >
> > >> > Bootstrapped/regtested on powerpc64{,le}-linux, ok for trunk?
> > >> >
> > >> > 2016-02-03  Jakub Jelinek  <jakub@redhat.com>
> > >> >
> > >> >         PR target/69644
> > >> >         * config/rs6000/rs6000.c (rs6000_expand_atomic_compare_and_swap):
> > >> >         Force oldval into register if it does not satisfy reg_or_short_operand
> > >> >         predicate.  Fix up formatting.
> > >> >
> > >> >         * gcc.dg/pr69644.c: New test.
> > >>
> > >> Okay.
> > >
> > > This needs to go on gcc-5 and gcc-4.9 branches too, where it fixes
> > > pr69146.  pr69146 and pr69644 are dups.  OK to apply to the branches?
> > 
> > Okay with me, but coordinate with Jakub.
> 
> Ok with me to, just don't have spare cycles now to bootstrap/regtest it.
> So, Alan, if you could do that, it would be greatly appreciated.

I've regression tested powerpc64le-linux gcc-5 and gcc-4.9, all langs.
diff mbox

Patch

--- gcc/config/rs6000/rs6000.c.jj	2016-02-02 20:42:01.000000000 +0100
+++ gcc/config/rs6000/rs6000.c	2016-02-03 08:45:31.345521112 +0100
@@ -22275,6 +22275,9 @@  rs6000_expand_atomic_compare_and_swap (r
   else if (reg_overlap_mentioned_p (retval, oldval))
     oldval = copy_to_reg (oldval);
 
+  if (mode != TImode && !reg_or_short_operand (oldval, mode))
+    oldval = copy_to_mode_reg (mode, oldval);
+
   mem = rs6000_pre_atomic_barrier (mem, mod_s);
 
   label1 = NULL_RTX;
@@ -22289,10 +22292,8 @@  rs6000_expand_atomic_compare_and_swap (r
 
   x = retval;
   if (mask)
-    {
-      x = expand_simple_binop (SImode, AND, retval, mask,
-			       NULL_RTX, 1, OPTAB_LIB_WIDEN);
-    }
+    x = expand_simple_binop (SImode, AND, retval, mask,
+			     NULL_RTX, 1, OPTAB_LIB_WIDEN);
 
   cond = gen_reg_rtx (CCmode);
   /* If we have TImode, synthesize a comparison.  */
--- gcc/testsuite/gcc.dg/pr69644.c.jj	2016-02-03 08:42:20.827165549 +0100
+++ gcc/testsuite/gcc.dg/pr69644.c	2016-02-03 08:41:51.000000000 +0100
@@ -0,0 +1,11 @@ 
+/* PR target/69644 */
+/* { dg-do compile } */
+
+int
+main ()
+{
+  unsigned short x = 0x8000;
+  if (!__sync_bool_compare_and_swap (&x, 0x8000, 0) || x)
+    __builtin_abort ();
+  return 0;
+}