This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
powerpc compare_and_swap fails
- From: Alan Modra <amodra at gmail dot com>
- To: gcc at gcc dot gnu dot org
- Cc: Richard Henderson <rth at redhat dot com>
- Date: Thu, 17 Nov 2011 21:07:49 +1030
- Subject: powerpc compare_and_swap fails
I'm seeing a lot of testsuite failures on powerpc-linux, some of
which are locking related. For example:
WARNING: Program timed out.
FAIL: libgomp.c/atomic-10.c execution test
This one fails in f3() here:
#pragma omp atomic
z4 *= 3;
z4 is an unsigned char, so we hit the QImode case in
rs6000_expand_atomic_compare_and_swap. operands[3] is modified.
The rather horrible piece of code below corresponds with z4 *= 3;
At 10000c60 you can see operands[3], oldval, being shifted. At
10000c90 and 10000c94, the newly loaded value from the z4 word is
shifted to the low byte position and masked. Then in 10000c98 this is
compared against oldval. The comparison never succeeds, because r9
has the value 00yy0000 (the shift happens to be 16 for z4) while r8
has 000000yy.
10000c34: 57 c6 1e f8 rlwinm r6,r30,3,27,28
10000c38: 38 a0 00 ff li r5,255
10000c3c: 89 39 13 d1 lbz r9,5073(r25)
10000c40: 68 c6 00 18 xori r6,r6,24
10000c44: 57 de 00 3a rlwinm r30,r30,0,0,29
10000c48: 7c a5 30 30 slw r5,r5,r6
10000c4c: 48 00 00 08 b 10000c54 <f3+0x22c>
10000c50: 7d 09 43 78 mr r9,r8
10000c54: 7c 00 04 ac sync
10000c58: 55 2a 08 3c rlwinm r10,r9,1,0,30
10000c5c: 7d 4a 4a 14 add r10,r10,r9
10000c60: 7d 29 30 30 slw r9,r9,r6
10000c64: 55 4a 06 3e clrlwi r10,r10,24
10000c68: 7d 4a 30 30 slw r10,r10,r6
10000c6c: 7d 00 f0 28 lwarx r8,0,r30
10000c70: 7d 07 28 38 and r7,r8,r5
10000c74: 7f 87 48 00 cmpw cr7,r7,r9
10000c78: 7d 07 28 78 andc r7,r8,r5
10000c7c: 7c e7 53 78 or r7,r7,r10
10000c80: 40 9e 00 0c bne- cr7,10000c8c <f3+0x264>
10000c84: 7c e0 f1 2d stwcx. r7,0,r30
10000c88: 40 a2 ff e4 bne- 10000c6c <f3+0x244>
10000c8c: 4c 00 01 2c isync
10000c90: 7d 08 34 30 srw r8,r8,r6
10000c94: 55 08 06 3e clrlwi r8,r8,24
10000c98: 7f 89 40 00 cmpw cr7,r9,r8
10000c9c: 40 9e ff b4 bne+ cr7,10000c50 <f3+0x228>
I suspect the fix to this problem doesn't belong in rs6000.c,
but the following does seem to cure this failure.
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 181400)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -17334,10 +17366,13 @@ rs6000_expand_atomic_compare_and_swap (r
mask = shift = NULL_RTX;
if (mode == QImode || mode == HImode)
{
+ rtx orig = oldval;
+
mem = rs6000_adjust_atomic_subword (mem, &shift, &mask);
/* Shift and mask OLDVAL into position with the word. */
- 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);
--
Alan Modra
Australia Development Lab, IBM