This fixes a minor bug that showed up in the CI system, presumably with fuzz testing.

Under the right circumstances, we could end trying to emit a shift-add style sequence where the to-be-shifted operand was not a register. This naturally leads to an unrecognized insn.

The circumstances which triggered this weren't something that should appear in the wild (-ftree-ter, without optimization enabled). So I wasn't planning to backport. Obviously if it shows up in another context we can revisit that decision.

        PR target/115142
gcc/

        * config/riscv/riscv.cc (mem_shadd_or_shadd_rtx_p): Make sure
        shifted argument is a register.

gcc/testsuite

        * gcc.target/riscv/pr115142.c: New test.

I've run this through my rv32gcv and rv64gc tester. Waiting on the CI system before committing.

jeff
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 7a34b4be873..d0c22058b8c 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2465,6 +2465,7 @@ mem_shadd_or_shadd_rtx_p (rtx x)
 {
   return ((GET_CODE (x) == ASHIFT
           || GET_CODE (x) == MULT)
+         && register_operand (XEXP (x, 0), GET_MODE (x))
          && CONST_INT_P (XEXP (x, 1))
          && ((GET_CODE (x) == ASHIFT && IN_RANGE (INTVAL (XEXP (x, 1)), 1, 3))
              || (GET_CODE (x) == MULT
diff --git a/gcc/testsuite/gcc.target/riscv/pr115142.c 
b/gcc/testsuite/gcc.target/riscv/pr115142.c
new file mode 100644
index 00000000000..40ba49dfa20
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr115142.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -ftree-ter" } */
+
+long a;
+char b;
+void e() {
+  char f[8][1];
+  b = f[a][a];
+}
+

Reply via email to