diff mbox

powerpc compare_and_swap fails

Message ID 4EC58988.2060701@redhat.com
State New
Headers show

Commit Message

Richard Henderson Nov. 17, 2011, 10:24 p.m. UTC
On 11/17/2011 10:25 AM, Richard Henderson wrote:
> On 11/17/2011 12:37 AM, Alan Modra wrote:
>> -      oldval = convert_modes (SImode, mode, oldval, 1);
>> +      oldval = gen_reg_rtx (SImode);
>> +      convert_move (oldval, orig, 1);
>>        oldval = expand_simple_binop (SImode, ASHIFT, oldval, shift,
>>  				    oldval, 1, OPTAB_LIB_WIDEN);
> 
> Gah.  From convert_modes, oldval is a subreg, and modifying that
> subreg gets us into all sorts of trouble.  The fix should be as
> simple as 
> 
> - 				    oldval, 1, OPTAB_LIB_WIDEN);
> + 				    NULL_RTX, 1, OPTAB_LIB_WIDEN);
> 
> so that we don't write back into the subreg.

Like so.  Tested on ppc64-linux and committed.


r~
commit 75e213a662f12e22304ecde01e8311b8e3390739
Author: Richard Henderson <rth@twiddle.net>
Date:   Thu Nov 17 14:07:01 2011 -0800

    Fix subreg clobber after convert_modes.
    
    If we've got a (subreg/s/u:QI (reg:DI x)) and we use convert_modes,
    we'll still wind up with (subreg/s/u:SI (reg:DI x)).  Having that
    be the destination of a further expand_binop is incorrect.  Force
    the use of a new pseudo.
    
    * config/rs6000/rs6000.c (rs6000_expand_atomic_compare_and_swap): Get
    new pseudo for target after convert_modes.
    (rs6000_expand_atomic_exchange, rs6000_expand_atomic_op): Likewise.

Comments

Alan Modra Nov. 18, 2011, 1:58 a.m. UTC | #1
On Thu, Nov 17, 2011 at 12:24:08PM -1000, Richard Henderson wrote:
> On 11/17/2011 10:25 AM, Richard Henderson wrote:
> > so that we don't write back into the subreg.
> 
> Like so.  Tested on ppc64-linux and committed.

Thanks!  This, along with my mutex.h rewrite plus adding a
memory_barrier insn gets me down to just one libgomp failure.
Richard Henderson Nov. 18, 2011, 5:41 p.m. UTC | #2
On 11/17/2011 03:58 PM, Alan Modra wrote:
> Thanks!  This, along with my mutex.h rewrite plus adding a
> memory_barrier insn gets me down to just one libgomp failure.

The memory_barrier thing should be fixed now as well...


r~
diff mbox

Patch

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 89c2ea0..f01353b 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -17341,12 +17341,12 @@  rs6000_expand_atomic_compare_and_swap (rtx operands[])
       /* Shift and mask OLDVAL into position with the word.  */
       oldval = convert_modes (SImode, mode, oldval, 1);
       oldval = expand_simple_binop (SImode, ASHIFT, oldval, shift,
-				    oldval, 1, OPTAB_LIB_WIDEN);
+				    NULL_RTX, 1, OPTAB_LIB_WIDEN);
 
       /* Shift and mask NEWVAL into position within the word.  */
       newval = convert_modes (SImode, mode, newval, 1);
       newval = expand_simple_binop (SImode, ASHIFT, newval, shift,
-				    newval, 1, OPTAB_LIB_WIDEN);
+				    NULL_RTX, 1, OPTAB_LIB_WIDEN);
 
       /* Prepare to adjust the return value.  */
       retval = gen_reg_rtx (SImode);
@@ -17434,7 +17434,7 @@  rs6000_expand_atomic_exchange (rtx operands[])
       /* Shift and mask VAL into position with the word.  */
       val = convert_modes (SImode, mode, val, 1);
       val = expand_simple_binop (SImode, ASHIFT, val, shift,
-				 val, 1, OPTAB_LIB_WIDEN);
+				 NULL_RTX, 1, OPTAB_LIB_WIDEN);
 
       /* Prepare to adjust the return value.  */
       retval = gen_reg_rtx (SImode);
@@ -17487,7 +17487,7 @@  rs6000_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
       /* Shift and mask VAL into position with the word.  */
       val = convert_modes (SImode, mode, val, 1);
       val = expand_simple_binop (SImode, ASHIFT, val, shift,
-				 val, 1, OPTAB_LIB_WIDEN);
+				 NULL_RTX, 1, OPTAB_LIB_WIDEN);
 
       switch (code)
 	{