x64: lower isub by a constant to lea - #14015
Conversation
8888063 to
39c2a52
Compare
|
Pushed a fixup: refreshed the 12 |
Subscribe to Label ActionDetailsThis issue or pull request has been labeled: "cranelift", "cranelift:area:x64", "isle"Thus the following users have been cc'd because of the following labels:
To subscribe or unsubscribe from this label, edit the |
|
Hi @darmie -- are you aware of the add-vs-lea performance discussion thread we had recently (#13325)? I ask because at the very least, we should benchmark this change with the full Sightglass suite. I am also pretty leery in general of introducing more uses of LEA given the performance variability that we've seen on different systems. I'm not surprised that you saw a speedup on one particular benchmark since LEA is "non-destructive" (doesn't clobber the source) but I'd be curious to know how this looks overall. Thanks! |
|
Hi @cfallin! Actually I am not aware of that thread, I should have searched first. Yes I saw a performance improvement on my alderlake x86_64 box, but it's only ~6.9% so far. I'll read through the thread now. |
`iadd` of a value and a constant already lowers to `lea`, folding the constant into the address displacement and avoiding a register copy when the result lands in a different register than the input. `isub` by a constant did not: it fell to the two-operand `sub`, which forces a `mov`+`sub` pair whenever the destination differs from the source. Lower `x - C` to `lea -C(x)` for 32- and 64-bit types, mirroring the `iadd` path. The rule fires only when the negated constant fits in an `Offset32` (i.e. `C` is not `i32::MIN`); register/register `isub` is unchanged.
- Precise-output filetest asserting `x - C` lowers to a single `lea`, and that register/register `isub` still lowers to `sub`. - Runtest exercising the result on the interpreter and every native target. - Refresh the `load-store/x64` disas goldens: the in-place bounds-check `sub $C` now lowers via `lea` to `add $-C`, identical to how `iadd` by a constant already lowers (same instruction count).
39c2a52 to
10bdb3b
Compare
iaddof a value and a 32/64-bit constant already lowers tolea, foldingthe constant into the address displacement and computing the result in a
different register than the input without a separate
mov.isubby aconstant did not have a matching rule: it fell through to the two-operand
sub, which forces amov+subpair whenever the destination registerdiffers from the source.
This adds a rule that lowers
x - C(for a 32- or 64-bit integer constantC) tolea -C(x), mirroring the existingiaddpath. The rule fires onlywhen the negated constant fits in an
Offset32(i.e.Cis noti32::MIN);register/register
isubis unchanged.Example
Before:
After:
One instruction instead of two, and no flags clobbered.
Testing
isub-const-lea.clif) asserting thelealowering for i64 and i32, and that register/register
isubstill lowersto
sub.x - C(including a negative constant) on theinterpreter and every native target.
isa/x64filetests pass unchanged.I found this while profiling a call/arithmetic-heavy workload where every
argument setup was an
x - C; folding themovaway was a measurable win.