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 r...@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.
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)
{