On Wed, Apr 2, 2025 at 5:35 AM Jeff Law <jeffreya...@gmail.com> wrote: > > > Segher -- there's a combine question near the end...
I've created PR119587 to keep track of this issue. BR Christoph > > > 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. > > --- > > gcc/config/riscv/thead.md | 21 +++++++++++++++++++ > > .../gcc.target/riscv/xtheadmemidx-bug.c | 13 ++++++++++++ > > 2 files changed, 34 insertions(+) > > create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx-bug.c > > > > diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md > > index d816f3b86dd..20e82e68df2 100644 > > --- a/gcc/config/riscv/thead.md > > +++ b/gcc/config/riscv/thead.md > > @@ -458,6 +458,27 @@ (define_insn "*th_mempair_load_zero_extendsidi2" > > > > ;; XTheadMemIdx > > > > +;; Help reload to add a displacement for the base register. > > +;; In the case `zext(*(uN*))(base+((rN<<1)&0x1fffffffe))` LRA splits > > +;; off two new instructions: a) `new_base = base + disp`, and > > +;; b) `index = (rN<<1)&0x1fffffffe`. The index calculation has no > > +;; corresponding instruction pattern and needs this insn_and_split > > +;; to recover. > > + > > +(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" > So this is a nasty little problem and touches on a deeper issue. > > The core problem is that combine doesn't know anything about > constraints. It works with predicates and conditions. So combine has > no idea if it's creating an ASM with operands that can't be handled. As > a result combine has to be careful with ASMs. > > In can_combine_p we have: > > > > /* Can't merge an ASM_OPERANDS. */ > > || GET_CODE (src) == ASM_OPERANDS > > Which is part of a large conditional indicating when we can't combine > two insns together. So I would have expected it to reject this insn for > combining: > > > (insn 12 11 0 2 (set (mem/f:DI (reg/v/f:DI 138 [ e ]) [2 *e_6+0 S8 A64]) > > (asm_operands:DI ("") ("=A") 0 [ > > (mem/f:DI (reg/v/f:DI 138 [ e ]) [2 *e_6+0 S8 A64]) > > ] > > [ > > (asm_input:DI ("A") j.c:8) > > ] > > [] j.c:8)) "j.c":8:3 -1 > > (expr_list:REG_DEAD (reg/v/f:DI 138 [ e ]) > > (nil))) > > So the natural question is why did insn 12 participate in combination at > all: > > > Trying 11 -> 12: > > 11: r138:DI=r145:DI+r144:DI > > REG_DEAD r145:DI > > REG_DEAD r144:DI > > 12: [r138:DI]=asm_operands > > REG_DEAD r138:DI > > Failed to match this instruction: > > (set (mem/f:DI (plus:DI (reg/f:DI 145 [ b ]) > > (reg:DI 144 [ _4 ])) [2 *e_6+0 S8 A64]) > > (asm_operands:DI ("") ("=A") 0 [ > > (mem/f:DI (plus:DI (reg/f:DI 145 [ b ]) > > (reg:DI 144 [ _4 ])) [2 *e_6+0 S8 A64]) > > ] > > [ > > (asm_input:DI ("A") j.c:8) > > ] > > [] j.c:8)) > > allowing combination of insns 11 and 12 > > original costs 4 + 36 = 40 > > replacement cost 36 > > deferring deletion of insn with uid = 11. > > modifying insn i3 12: [r145:DI+r144:DI]=asm_operands > > REG_DEAD r144:DI > > REG_DEAD r145:DI > > deferring rescan insn with uid = 12. > > So without a deep dive, my question is should this have been rejected > for combination before we even got here? I just don't see how combine > can do anything with asms other than replacing one pseudo with another > since combine doesn't have any notion of constraints. > > Segher, comments? > > jeff > >