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