aboutsummaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>2015-10-26 10:28:12 +0000
committerktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>2015-10-26 10:28:12 +0000
commit5da065098ec237aa7e4883ba06b20cb8f0ff2cf4 (patch)
tree426eb71f12eed0495b4e17dcb79040d32e2822f5 /gcc/optabs.c
parent44d567c8dc10de1abf5118ebf0f16dba1dc25fbe (diff)
[optabs.c] Fix PR 67989: Handle const0_rtx target in expand_atomic_compare_and_swap
PR middle-end/67989 * optabs.c (expand_atomic_compare_and_swap): Handle case when ptarget_oval or ptarget_bool are const0_rtx. * g++.dg/pr67989.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@229317 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r--gcc/optabs.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c
index e1ac0b85e5e..4e93d3c7451 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -5810,9 +5810,9 @@ expand_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
*PTARGET_BOOL is an optional place to store the boolean success/failure.
*PTARGET_OVAL is an optional place to store the old value from memory.
- Both target parameters may be NULL to indicate that we do not care about
- that return value. Both target parameters are updated on success to
- the actual location of the corresponding result.
+ Both target parameters may be NULL or const0_rtx to indicate that we do
+ not care about that return value. Both target parameters are updated on
+ success to the actual location of the corresponding result.
MEMMODEL is the memory model variant to use.
@@ -5837,6 +5837,9 @@ expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
/* Make sure we always have some place to put the return oldval.
Further, make sure that place is distinct from the input expected,
just in case we need that path down below. */
+ if (ptarget_oval && *ptarget_oval == const0_rtx)
+ ptarget_oval = NULL;
+
if (ptarget_oval == NULL
|| (target_oval = *ptarget_oval) == NULL
|| reg_overlap_mentioned_p (expected, target_oval))
@@ -5847,6 +5850,9 @@ expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
{
machine_mode bool_mode = insn_data[icode].operand[0].mode;
+ if (ptarget_bool && *ptarget_bool == const0_rtx)
+ ptarget_bool = NULL;
+
/* Make sure we always have a place for the bool operand. */
if (ptarget_bool == NULL
|| (target_bool = *ptarget_bool) == NULL