aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorHongyu Wang <hongyu.wang@intel.com>2021-11-18 14:45:23 +0800
committerHongyu Wang <hongyu.wang@intel.com>2021-11-18 16:29:19 +0800
commit15f5e70cbb33b40c97325ef9d55557747a148d39 (patch)
tree1df1020b51e959c0aa2de8fea18561d3a6161780 /gcc
parent17da2c7425ea1f5bf417b954f444dbe1f1618a1c (diff)
downloadgcc-15f5e70cbb33b40c97325ef9d55557747a148d39.zip
gcc-15f5e70cbb33b40c97325ef9d55557747a148d39.tar.gz
gcc-15f5e70cbb33b40c97325ef9d55557747a148d39.tar.bz2
i386: Fix wrong codegen for -mrelax-cmpxchg-loop
For -mrelax-cmpxchg-loop introduced by PR 103069/r12-5265, it would produce infinite loop. The correct code should be .L84: movl (%rdi), %ecx movl %eax, %edx orl %esi, %edx cmpl %eax, %ecx jne .L82 lock cmpxchgl %edx, (%rdi) jne .L84 movl %r8d, %eax <<< retval is missing in previous impl ret .L82: rep nop jmp .L84 Adjust corresponding expander to fix such issue, and fix runtime test so the problem would be exposed. gcc/ChangeLog: * config/i386/i386-expand.c (ix86_expand_atomic_fetch_op_loop): Adjust generated cfg to avoid infinite loop. gcc/testsuite/ChangeLog: * gcc.target/i386/pr103069-2.c: Adjust.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/i386/i386-expand.c7
-rw-r--r--gcc/testsuite/gcc.target/i386/pr103069-2.c11
2 files changed, 12 insertions, 6 deletions
diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index 3e4de64..0d5d1a0 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -23143,13 +23143,14 @@ void ix86_expand_atomic_fetch_op_loop (rtx target, rtx mem, rtx val,
bool doubleword)
{
rtx old_reg, new_reg, old_mem, success, oldval, new_mem;
- rtx_code_label *loop_label, *pause_label;
+ rtx_code_label *loop_label, *pause_label, *done_label;
machine_mode mode = GET_MODE (target);
old_reg = gen_reg_rtx (mode);
new_reg = old_reg;
loop_label = gen_label_rtx ();
pause_label = gen_label_rtx ();
+ done_label = gen_label_rtx ();
old_mem = copy_to_reg (mem);
emit_label (loop_label);
emit_move_insn (old_reg, old_mem);
@@ -23207,11 +23208,15 @@ void ix86_expand_atomic_fetch_op_loop (rtx target, rtx mem, rtx val,
GET_MODE (success), 1, loop_label,
profile_probability::guessed_never ());
+ emit_jump_insn (gen_jump (done_label));
+ emit_barrier ();
+
/* If mem is not expected, pause and loop back. */
emit_label (pause_label);
emit_insn (gen_pause ());
emit_jump_insn (gen_jump (loop_label));
emit_barrier ();
+ emit_label (done_label);
}
#include "gt-i386-expand.h"
diff --git a/gcc/testsuite/gcc.target/i386/pr103069-2.c b/gcc/testsuite/gcc.target/i386/pr103069-2.c
index 8ac824c..b3f2235 100644
--- a/gcc/testsuite/gcc.target/i386/pr103069-2.c
+++ b/gcc/testsuite/gcc.target/i386/pr103069-2.c
@@ -1,5 +1,5 @@
-/* PR target/103068 */
-/* { dg-do compile } */
+/* PR target/103069 */
+/* { dg-do run } */
/* { dg-additional-options "-O2 -march=x86-64 -mtune=generic" } */
#include <stdlib.h>
@@ -37,13 +37,14 @@ FUNC_ATOMIC_RELAX (char, xor)
#define TEST_ATOMIC_FETCH_LOGIC(TYPE, OP) \
{ \
TYPE a = 11, b = 101, res, exp; \
+ TYPE c = 11, d = 101; \
res = relax_##TYPE##_##OP##_fetch (&a, b); \
- exp = f_##TYPE##_##OP##_fetch (&a, b); \
+ exp = f_##TYPE##_##OP##_fetch (&c, d); \
if (res != exp) \
abort (); \
- a = 21, b = 92; \
+ a = c = 21, b = d = 92; \
res = relax_##TYPE##_fetch_##OP (&a, b); \
- exp = f_##TYPE##_fetch_##OP (&a, b); \
+ exp = f_##TYPE##_fetch_##OP (&c, d); \
if (res != exp) \
abort (); \
}