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)

Reply via email to