As noted in the PR, expand_atomic_compare_and_swap can generate wrong code when libcalls are emitted for the sync_compare_and_swap and the result comparison test. This is fixed by emitting a move insn to copy the result rtx of the sync_compare_and_swap libcall to target_oval instead of directly assigning it.
Tested on hppa-unknown-linux-gnu. Okay for trunk and gcc-5? With this change I can enable __sync_compare_and_swap_8 on hppa-linux. Dave -- John David Anglin dave.ang...@bell.net
2015-09-10 John David Anglin <dang...@gcc.gnu.org> PR middle-end/67401 * optabs.c (expand_atomic_compare_and_swap): Move result of emitting sync_compare_and_swap_optab libcall to target_oval. Index: optabs.c =================================================================== --- optabs.c (revision 226978) +++ optabs.c (working copy) @@ -7510,9 +7510,10 @@ if (libfunc != NULL) { rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0)); - target_oval = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL, - mode, 3, addr, ptr_mode, - expected, mode, desired, mode); + rtx target = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL, + mode, 3, addr, ptr_mode, + expected, mode, desired, mode); + emit_move_insn (target_oval, target); /* Compute the boolean return value only if requested. */ if (ptarget_bool)