================
@@ -71,3 +71,106 @@ def LXWU_S_UW : ScaledIndexLoad<0b101, 0b10, 1, 
"lxwu.s.uw">, Sched<[WriteLDW, R
 def LXD_S     : ScaledIndexLoad<0b100, 0b11, 0, "lxd.s">, Sched<[WriteLDD, 
ReadMemBase, ReadMemBase]>;
 def LXD_S_UW  : ScaledIndexLoad<0b101, 0b11, 0, "lxd.s.uw">, Sched<[WriteLDD, 
ReadMemBase, ReadMemBase]>;
 } // Predicates = [HasStdExtZilx, IsRV64]
+
+class AddrRegReg<int N>
+    : ComplexPattern<iPTR, 2, "SelectAddrRegRegFixedScale<"#N#">">;
+class AddrRegZextReg<int N>
+    : ComplexPattern<i64, 2, "SelectAddrRegZextRegFixedScale<"#N#", 32>",
+                     [], [], 10>;
+
+def AddrRegReg0 : AddrRegReg<0>;
+def AddrRegReg1 : AddrRegReg<1>;
+def AddrRegReg2 : AddrRegReg<2>;
+def AddrRegReg3 : AddrRegReg<3>;
+
+def AddrRegZextReg0 : AddrRegZextReg<0>;
+def AddrRegZextReg1 : AddrRegZextReg<1>;
+def AddrRegZextReg2 : AddrRegZextReg<2>;
+def AddrRegZextReg3 : AddrRegZextReg<3>;
+
+let AddedComplexity = 2 in {
----------------
wangpc-pp wrote:

I let AI do the investigation and I checked it is reasonable. The fix is 
https://github.com/llvm/llvm-project/pull/209420/changes/ddc4fe1cd521bff676fcf361ab67acc72ad1671f.

----

## Root Cause: ISel pattern-complexity tie + table order

Evidence was gathered both statically (from the generated `RISCVGenDAGISel.inc`
matcher table: complexity values and entry ordering) and dynamically (`llc`
output plus `-debug-only=isel` traces). The Zilx addressing `ComplexPattern`s
were given a complexity that **tied** with the base load patterns, and the base
patterns appear **earlier** in the matcher table, so they always matched first
and the Zilx instructions were never selected.

There are three overlapping pattern layers that require a strict priority order:

| Pattern | Semantics | Complexity (before) | Outcome |
|---|---|---|---|
| Base `L{B,H,W,D}[U]` (`AddrRegImm`) | reg+imm; treats `add reg,reg` as base+0 
| 13 | matched first |
| Plain Zilx `lx*` / `lx*.s` (`AddrRegReg`) | reg+reg (incl. scaled shift) | 13 
(default `numops*3=6`, no explicit complexity) | lost the tie |
| `.uw` Zilx (`AddrRegZextReg`) | reg + zext(reg) | 17 (had `+10`) | only these 
worked |

This explains the original symptom exactly: only the `.uw` family generated
Zilx instructions, while all plain and scaled forms silently fell back.

## The Fix

`llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td` — two lines. Assign layered,
specificity-based complexity to the two addressing `ComplexPattern`s:

```tablegen
class AddrRegReg<int N>
    : ComplexPattern<iPTR, 2, "SelectAddrRegRegFixedScale<"#N#">",
                     [], [], !add(10, N)>;
class AddrRegZextReg<int N>
    : ComplexPattern<i64, 2, "SelectAddrRegZextRegFixedScale<"#N#", 32>",
                     [], [], !add(20, N)>;
```

This yields a strict priority ordering:

- **Base `L*` (13) < plain Zilx (17–20) < `.uw` Zilx (27–30).**
- `!add(_, N)` also makes the **scaled** form strictly outrank the **unscaled**
  form within a family (e.g. `lxh.s` beats `slli + lxh`), because a larger scale
  is a more specific match.
- The `.uw` forms are the most specific (they also consume the `zext`), so they
  sit above every plain form.

https://github.com/llvm/llvm-project/pull/209420
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to