]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[committed][RISC-V][PR target/117595] Fix bogus use of simplify_gen_subreg
authorJeff Law <jlaw@ventanamicro.com>
Mon, 18 Nov 2024 17:55:09 +0000 (10:55 -0700)
committerJeff Law <jlaw@ventanamicro.com>
Mon, 18 Nov 2024 17:55:09 +0000 (10:55 -0700)
And stage3 begins...

Zdenek's fuzzer caught this one.  Essentially using simplify_gen_subreg
directly with an offset of 0 when we just needed a lowpart.

The offset of 0 works for little endian, but for big endian it's simply wrong.
simplify_gen_subreg will return NULL_RTX because the case isn't representable.
We then embed that NULL_RTX into an insn that's later scanned during
mark_jump_label.

Scanning the port I see a couple more instances of this incorrect idiom.   One
is pretty obvious to fix.  The others look a bit goofy and I'll probably need
to sync with Patrick on them.

Anyway tested on riscv64-elf and riscv32-elf with no regressions.  Pushing to
the trunk.

PR target/117595
gcc/
* config/riscv/sync.md (atomic_compare_and_swap<mode>): Use gen_lowpart
rather than simplify_gen_subreg.
* config/riscv/riscv.cc (riscv_legitimize_move): Similarly.

gcc/testsuite/
* gcc.target/riscv/pr117595.c: New test.

gcc/config/riscv/riscv.cc
gcc/config/riscv/sync.md
gcc/testsuite/gcc.target/riscv/pr117595.c [new file with mode: 0644]

index 7694954c4c5c1ec9e785dd9744a0d0e3a568fa8e..03271d893b603a58571f62e3d63173f4139a7e84 100644 (file)
@@ -3646,7 +3646,7 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
       rtx mask = force_reg (word_mode, gen_int_mode (-65536, word_mode));
       rtx temp = gen_reg_rtx (word_mode);
       emit_insn (gen_extend_insn (temp,
-                                 simplify_gen_subreg (HImode, src, mode, 0),
+                                 gen_lowpart (HImode, src),
                                  word_mode, HImode, 1));
       if (word_mode == SImode)
        emit_insn (gen_iorsi3 (temp, mask, temp));
index aa0c20446f4233c294ca0a9d2bb475f9092fdd5f..23c0859e0856af728455a8e176b9f2061a1803f9 100644 (file)
         value is sign-extended.  */
       rtx tmp0 = gen_reg_rtx (word_mode);
       emit_insn (gen_extend_insn (tmp0, operands[3], word_mode, <MODE>mode, 0));
-      operands[3] = simplify_gen_subreg (<MODE>mode, tmp0, word_mode, 0);
+      operands[3] = gen_lowpart (<MODE>mode, tmp0);
     }
 
   if (TARGET_ZACAS)
diff --git a/gcc/testsuite/gcc.target/riscv/pr117595.c b/gcc/testsuite/gcc.target/riscv/pr117595.c
new file mode 100644 (file)
index 0000000..a870df0
--- /dev/null
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-mbig-endian" } */
+
+_Atomic enum { E0 } e;
+void foo() { e++; }