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. */