Skip to content

Commit b331418

Browse files
kito-chengChen Yixuan
authored andcommitted
RISC-V: Fix __atomic_compare_exchange with 32 bit value on RV64
atomic_compare_and_swapsi will use lr.w to do obtain the original value, which sign extends to DI. RV64 only has DI comparisons, so we also need to sign extend the expected value to DI as otherwise the comparison will fail when the expected value has the 32nd bit set. gcc/ChangeLog: PR target/114130 * config/riscv/sync.md (atomic_compare_and_swap<mode>): Sign extend the expected value if needed. gcc/testsuite/ChangeLog: * gcc.target/riscv/pr114130.c: New. Reviewed-by: Palmer Dabbelt <palmer@rivosinc.com>
1 parent f0633ac commit b331418

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

gcc/config/riscv/sync.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,15 @@
353353
(match_operand:SI 7 "const_int_operand" "")] ;; mod_f
354354
"TARGET_ATOMIC"
355355
{
356+
if (word_mode != <MODE>mode && operands[3] != const0_rtx)
357+
{
358+
/* We don't have SI mode compare on RV64, so we need to make sure expected
359+
value is sign-extended. */
360+
rtx tmp0 = gen_reg_rtx (word_mode);
361+
emit_insn (gen_extend_insn (tmp0, operands[3], word_mode, <MODE>mode, 0));
362+
operands[3] = simplify_gen_subreg (<MODE>mode, tmp0, word_mode, 0);
363+
}
364+
356365
emit_insn (gen_atomic_cas_value_strong<mode> (operands[1], operands[2],
357366
operands[3], operands[4],
358367
operands[6], operands[7]));
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-march=rv64gc -mabi=lp64" } */
3+
#include <stdint-gcc.h>
4+
5+
void foo(uint32_t *p) {
6+
uintptr_t x = *(uintptr_t *)p;
7+
uint32_t e = !p ? 0 : (uintptr_t)p >> 1;
8+
uint32_t d = (uintptr_t)x;
9+
__atomic_compare_exchange(p, &e, &d, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
10+
}
11+
12+
/* { dg-final { scan-assembler-bound {sext.w\t} >= 1 } } */

0 commit comments

Comments
 (0)