When investigating an issue on arm, I discovered a bug that needs fixing.
If there is no atomic_load pattern for data which is larger than the
native word size, we try to issue a compare_and_swap loop. Problem is
there is no check to see if it succeeded or failed. If the compare-swap
loop isn't emitted, we need to leave the __atomic_load_N call rather
than silently generate incorrect code.
Attached patch bootstraps on x86_64-unknown-linux-gnu and fixes the
problem on an arm cross compiler.
No new regressions in the testsuite, and is a harmless change for
working code.
OK to check in? GCC 4.7 is still mainline isn't it?
Andrew
* optabs.c (expand_atomic_load): Do not assume compare_and_swap will
succeed for larger than word integers.
Index: optabs.c
===================================================================
*** optabs.c (revision 183969)
--- optabs.c (working copy)
*************** expand_atomic_load (rtx target, rtx mem,
*** 7665,7673 ****
/* Issue val = compare_and_swap (mem, 0, 0).
This may cause the occasional harmless store of 0 when the value is
already 0, but it seems to be OK according to the standards guys. */
! expand_atomic_compare_and_swap (NULL, &target, mem, const0_rtx,
! const0_rtx, false, model, model);
! return target;
}
/* Otherwise assume loads are atomic, and emit the proper barriers. */
--- 7665,7676 ----
/* Issue val = compare_and_swap (mem, 0, 0).
This may cause the occasional harmless store of 0 when the value is
already 0, but it seems to be OK according to the standards guys. */
! if (expand_atomic_compare_and_swap (NULL, &target, mem, const0_rtx,
! const0_rtx, false, model, model))
! return target;
! else
! /* Otherwise there is no atomic load, leave the library call. */
! return NULL_RTX;
}
/* Otherwise assume loads are atomic, and emit the proper barriers. */