I think I must have messed up my previous testing of MIPS16 __sync stuff. This patch fixes one bit of fallout, as seen in ia64-sync-1.c. If the result of sync_lock_test_and_set is unused, the optab helper routine maybe_emit_sync_lock_test_and_set gets called with a "target" of const0_rtx. If the operation expands to a library call, maybe_emit_sync_lock_test_and_set in turn passes const0_rtx down as the required target of the call. We then get an ICE when moving the return register into const0_rtx.
The same problem applies to the atomic_ version. Everywhere else in optabs.c just passes a null call target, so it seemed simplest to do the same here. Tested on mips64-linux-gnu. OK to install? Richard gcc/ * optabs.c (maybe_emit_sync_lock_test_and_set): Pass a null target to emit_library_call_value. (expand_atomic_compare_and_swap): Likewise. Index: gcc/optabs.c =================================================================== --- gcc/optabs.c 2011-12-03 16:19:48.000000000 +0000 +++ gcc/optabs.c 2011-12-04 08:52:12.000000000 +0000 @@ -7400,7 +7400,7 @@ maybe_emit_sync_lock_test_and_set (rtx t rtx addr; addr = convert_memory_address (ptr_mode, XEXP (mem, 0)); - return emit_library_call_value (libfunc, target, LCT_NORMAL, + return emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL, mode, 2, addr, ptr_mode, val, mode); } @@ -7637,7 +7637,7 @@ expand_atomic_compare_and_swap (rtx *pta if (libfunc != NULL) { rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0)); - target_oval = emit_library_call_value (libfunc, target_oval, LCT_NORMAL, + target_oval = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL, mode, 3, addr, ptr_mode, expected, mode, desired, mode);