From: Jeff Law Date: Sun, 8 Feb 2026 15:23:07 +0000 (-0700) Subject: [PR target/123911][RISC-V] Fix infinite recursion in riscv_legitimize_move X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2f84ad4ddc2a2dc93584d87da347c444a77f429c;p=thirdparty%2Fgcc.git [PR target/123911][RISC-V] Fix infinite recursion in riscv_legitimize_move I kept hoping I'd see a better solution, perhaps one where chunks of this routine just go away, but that hasn't materialized. So... This patch avoids infinite recursion through riscv_legitimize_move. Essentially we end up calling it recursively with arguments that are a nop-move and those particular arguments trigger infinite recursion. So this patch just recognizes and elides the nop move. Bootstrapped on riscv64-linux-gnu and regression tested on riscv{32,64}-elf with no regressions. Pushing to the trunk. PR target/123911 gcc/ * config/riscv/riscv.cc (riscv_legitimize_move): Elide nop moves to avoid infinite recursion. gcc/testsuite/ * gcc.target/riscv/pr123911.c: New test. --- diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 25749af1436..3baf0a936b5 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -3912,9 +3912,16 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src) } } + /* If we are extracting a single element out of a vector and do + not need an intermediate register, then the extraction will + occur directly into RESULT. RESULT is the same as DEST and + INT_REG. So we end up with a nop move. That is not a major + problem, except in this case it'll send us right back into + this code and we recurse. Given we put the value in RESULT + already we can just elide the nop move here and be done. */ if (need_int_reg_p) emit_move_insn (dest, gen_lowpart (GET_MODE (dest), int_reg)); - else + else if (!rtx_equal_p (dest, int_reg)) emit_move_insn (dest, int_reg); return true; } diff --git a/gcc/testsuite/gcc.target/riscv/pr123911.c b/gcc/testsuite/gcc.target/riscv/pr123911.c new file mode 100644 index 00000000000..30abe7ac76d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr123911.c @@ -0,0 +1,15 @@ +/* { dg-do compile */ +/* { dg-options "-march=rv64gv -mabi=lp64d" { target { rv64 } } } */ +/* { dg-options "-march=rv32gv -mabi=ilp32" { target { rv32 } } } */ + +typedef __attribute__((__vector_size__(8))) char W; +typedef __attribute__((__vector_size__(64))) short V; + +V +foo(V v, W w) +{ + __builtin_memmove(30 + (char *)&v, &w, 1); + __builtin_memmove(&v, &w, 8); + return v; +} +