On 3/23/25 8:43 PM, Bohan Lei wrote:
The combine pass can generate an index like (and:DI (mult:DI (reg:DI)
(const_int scale)) (const_int mask)) when XTheadMemIdx is available.
LRA may pull it out, and thus a splitter is needed when Zba is not
available.

A similar splitter were introduced when XTheadMemIdx support was added,
but removed in commit 31c3c5d.  The new splitter in this new patch is
based on the removed one.

gcc/ChangeLog:

         * config/riscv/thead.md (*th_memidx_operand): New splitter.

gcc/testsuite/ChangeLog:

         * gcc.target/riscv/xtheadmemidx-bug.c: New test.
Sorry, this doesn't look correct to me.



+(define_insn_and_split "*th_memidx_operand"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
+                          (match_operand:QI 2 "imm123_operand" "Ds3"))
+               (match_operand 3 "const_int_operand" "n")))]
+  "TARGET_64BIT && TARGET_XTHEADMEMIDX && (lra_in_progress || reload_completed)
+   && (INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff"
+  "#"
+  "&& !TARGET_ZBA && reload_completed"
+  [(set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 1) 0)))
+   (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
The RTL pattern matches a DImode register. But the split code zeros out the upper 32 bits. ie, there is a semantic mismatch between the behavior of the original RTL pattern and the split RTL code.

That can't be correct and is a strong indicator that the real problem is elsewhere.

Jeff

Reply via email to