]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PATCH] riscv: add mising masking in lrsc expander (PR118137)
authorAndreas Schwab <schwab@suse.de>
Tue, 7 Jan 2025 19:23:37 +0000 (12:23 -0700)
committerJeff Law <jlaw@ventanamicro.com>
Tue, 7 Jan 2025 19:24:45 +0000 (12:24 -0700)
gcc:
PR target/118137
* config/riscv/sync.md ("lrsc_atomic_exchange<mode>"): Apply mask
to shifted value.

gcc/testsuite:
PR target/118137
* gcc.dg/atomic/pr118137.c: New.

gcc/config/riscv/sync.md
gcc/testsuite/gcc.dg/atomic/pr118137.c [new file with mode: 0644]

index 58f32d253f1b3f073964411b9a0471843aa5d4f4..726800a9662315ef8f1c8c9b5d0e34523a6cf976 100644 (file)
 
   rtx shifted_value = gen_reg_rtx (SImode);
   riscv_lshift_subword (<MODE>mode, value, shift, &shifted_value);
+  emit_move_insn (shifted_value, gen_rtx_AND (SImode, shifted_value, mask));
 
   emit_insn (gen_subword_atomic_exchange_strong (old, aligned_mem,
                                                 shifted_value, model,
diff --git a/gcc/testsuite/gcc.dg/atomic/pr118137.c b/gcc/testsuite/gcc.dg/atomic/pr118137.c
new file mode 100644 (file)
index 0000000..7cdb224
--- /dev/null
@@ -0,0 +1,29 @@
+/* Test that subword atomic operations only affect the subword.  */
+/* { dg-do run } */
+/* { dg-require-effective-target sync_char_short } */
+
+void
+foo (char *x)
+{
+  __sync_fetch_and_or (x, 0xff);
+}
+
+void
+bar (short *y)
+{
+  __atomic_fetch_or (y, 0xffff, 0);
+}
+
+
+int
+main ()
+{
+  char b[4] = {};
+  foo(b);
+
+  short h[2] = {};
+  bar(h);
+
+  if (b[1] || b[2] || b[3] || h[1])
+    __builtin_abort();
+}