Repository navigation
[aarch64] Fix several instructions being lifted with the wrong semantics - #8699
Merged
Merged
Conversation
zznop
requested changes
Oct 29, 2026
bdash
force-pushed
the
test_aarch64_misc_lifting_fixes
branch
from
October 29, 2026 21:42
ec6b9e3 to
73aaec6
Compare
zznop
approved these changes
Oct 30, 2026
A 32-bit `LDP` or `LDNP` such as `ldp w2, w4, [x2]` computed the second address from the value the first load had just written. The check for this case compared `w2` with `x2`, so it never matched. It now compares a W destination as its X register. The temporary holding the second address is now read back at 8 bytes. It was read at the load size, which truncated the address for `LDPSW`. `LDPSW` also now sign-extends each word it loads.
`FMOV` from a general register to an FP register copies the bits, but was lifted as `INT_TO_FLOAT`, so `fmov s1, w21` with `w21` holding 3 produced 3.0. It is now a register copy. The half-precision forms copy the low 16 bits. `FMOV <Vd>.D[1], <Xn>` now reads `Xn` as 64 bits rather than 128.
An ACLE intrinsic whose result went to WZR or XZR, such as `fcvtas wzr, s20`, listed the zero register as its output. MLIL turned that into a variable named `:0`. The result now goes to a temporary, which discards it. This matches what `IntrinsicToRegisters` already does for the plugin's own intrinsics.
…gned `FCVTZU`, `FCVTMU`, `FCVTNU` and `FCVTPU` writing a general register were lifted as signed `FLOAT_TO_INT`. LLIL has no float to unsigned integer conversion. A W destination now takes the low half of a 64-bit `FLOAT_TO_INT`, which holds every in-range unsigned 32-bit result. An X destination lifts as the ACLE intrinsic. ACLE has no intrinsic for `FCVTZU <Xd>, <Sn>, #<fbits>`, and the one for `FCVTZU <Xd>, <Hn>, #<fbits>` takes at most 16 fraction bits. Those forms widen the source to double and use the double-precision intrinsic. Widening and scaling by a power of two are exact, so the result is the same.
…tions The vector forms of `ADD`, `SUB`, `UMULL`, `SMULL`, `CLZ` and `CLS` fell through to the scalar lifting, which treated each vector register as one 128-bit integer. Carries crossed lanes and counts spanned the whole register. The SME forms of `ADD` and `SUB` and the SVE forms of `CLZ` and `CLS` fell through the same way. The NEON forms now lift as ACLE intrinsics, like vector `MUL`. When intrinsics are not preferred, vector `ADD` and `SUB` lift lane by lane and the other NEON forms lift as unimplemented. The SME and SVE forms lift as unimplemented, like the existing SVE forms of `ADD` and `SUB`.
`ORR` with an immediate wrote the immediate into each lane as if it were `MOVI`, so `orr v0.4s, #1` set every lane to 1. `BIC` with an immediate was one 128-bit AND with the immediate in lane 0 only, so `bic v0.4s, #1` cleared only bit 0 of lane 0. It also set flags, which vector `BIC` does not. Both now apply the shifted immediate to each lane of `Vd`.
When intrinsics are not preferred, vector `FSUB` is lifted lane by lane. That lifting read `Vd` and `Vn` instead of `Vn` and `Vm`, so `fsub v0.4s, v1.4s, v2.4s` computed `v0 - v1`. It now computes `Vn - Vm`.
bdash
force-pushed
the
test_aarch64_misc_lifting_fixes
branch
from
October 30, 2026 18:51
73aaec6 to
68ff5f5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
LDP/LDNPof W registers read through a base the first load had overwritten.LDPSWdidn't sign-extend.FMOVfrom a general register was lifted as an int-to-float conversion.FCVT*Uto a general register was lifted as signed.ADD,SUB,UMULL,SMULL,CLZandCLSwere lifted as 128-bit scalar operations.ORR/BICwith an immediate didn't apply the immediate to each lane.FSUBlift subtracted the wrong registers.