https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116131

--- Comment #2 from Christoph Müllner <cmuellner at gcc dot gnu.org> ---
Thank you for reporting!

A first analysis showed, that adding more extensions does not change anything.
E.g. rv32gc_xtheadmemidx also triggers the error. However, rv64i_xtheadmemidx
is not affected. Also, the optimization level has no impact on the issue.

(In reply to Jeffrey A. Law from comment #1)
> Looks like non-canonical RTL to me.  Inside a MEM that shift should have
> been turned into a multiply.

I agree, but I don't think it is part of the problem, because in
th_memidx_classify_address_index() we expect ASHIFTs.

When looking at the XTheadMemIdx implementation, we have two relevant files:
* gcc/config/riscv/thead.md has the optimization pattern (th_memidx_*)
* gcc/config/riscv/thead.cc processes them (th_memidx_classify_address_index())

In the particular case, th_memidx_I_c creates the optimized INSN:

(insn 18 14 0 2 (set (mem:SI (plus:SI (reg/f:SI 141)
                (ashift:SI (subreg:SI (reg:DI 134 [ a.0_1 ]) 0)
                    (const_int 2 [0x2]))) [0  S4 A32])
        (reg:SI 143 [ b ])) "<source>":4:17 -1
     (nil))

The goal is obviously to generate an th.srw instruction.
The issue here is the subreg, which comes from the following INSN:

(insn 9 7 10 2 (set (reg:SI 139)
        (ashift:SI (subreg:SI (reg:DI 134 [ a.0_1 ]) 0)
            (const_int 2 [0x2])))
"gcc/testsuite/gcc.target/riscv/pr116131.c":12:8 294 {*ashlsi3}
     (expr_list:REG_DEAD (reg:DI 134 [ a.0_1 ])
        (nil)))

An easy fix is to reject subregs (confirmed to work):

diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index a47fe6f28b8..b95959d6827 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -758,6 +758,7 @@ (define_insn_and_split "*th_memidx_I_c"
           (match_operand:X 3 "register_operand" "r")))
         (match_operand:TH_M_ANYI 0 "register_operand" "r"))]
   "TARGET_XTHEADMEMIDX
+   && !SUBREG_P (operands[1])
    && CONST_INT_P (operands[2])
    && pow2p_hwi (INTVAL (operands[2]))
    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)"

A better alternative is to allow this subreg.
I've prepared a patch and will send it once the test are done.

Reply via email to