[Mips] Use a proper boolean for the select condition in lowerShift*Parts (#241685)
lowerShiftLeftParts and lowerShiftRightParts used (and Shamt, VT.bits)
directly as the condition of ISD::SELECT. That value is 0 or VT.bits
(32, or 64 for i128 on MIPS64), not 0/1. Since MIPS uses
ZeroOrOneBooleanContent, DAG combines may treat the condition as a 0/1
value, e.g. folding select(c, 0, 1) into xor c, 1, which miscompiles
when the condition is 32. For example 0x1FFFFFFFF >> (b & 32) returned
0x2100000001 instead of 1 for b = 32 on MIPS32.
Compare the masked shift amount against zero with setcc ne to form the
select condition. The DOUBLE_SELECT_I/DOUBLE_SELECT_I64 path used for
pre-MIPS4/MIPS32 in lowerShiftRightParts branches on the value being
non-zero, so it keeps using the masked shift amount directly.
Fixes #235261
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
[GlobalISel] Ignore debug uses in direct single-use combines (#237643)
Debug uses can block the lshr/trunc and insert-vector chain combines in
`CombinerHelper`, making ordinary Machine IR depend on debug
information.
This patch counts only non-debug uses and uses a non-debug iterator when
retrieving the insert-vector user. The regression tests cover both
combines and fail without the change.
These direct `MRI.hasOneUse()` checks are not covered by #237070, which
changes the `m_OneUse` matcher.
This issue was found through a source audit. AI assisted with the
analysis and development of the fix.
[SPIR-V] Legalize G_PHI of a vector of pointers (#241166)
With `SPV_INTEL_masked_gather_scatter`, vectors of pointers are legal
types and `G_IMPLICIT_DEF`/`G_FREEZE` already accept them, but `G_PHI`
did not, so a PHI of `<N x ptr>` failed with "unable to legalize
instruction". The SLP vectorizer forms such PHIs from vectorized address
computations. This adds the same pointer-vector rule to `G_PHI`.
Assisted-by: Claude Opus 5.5
[GVN] Fold equivalent `bitextract` and `bitinsert` (#242716)
GVN gives each instruction a value number, and replaces an instruction
with an earlier one that has the same number. An instruction gets a
number from its opcode, type and operands only if GVN knows the opcode.
Any other opcode gets a fresh number, so GVN never merges it.
`bitextract` and `bitinsert` were missing from that list.
Replaces #237785, which was closed by mistake during a restack.
[dsymutil] Undo prefix mapping before resolving paths for ODR uniquing
The classic linker resolves the declaration file of a type with
realpath() to tell apart types with the same name, line and size. For
paths remapped by compilation caching, which don't exist on disk,
realpath() fails and only the file name is left, so different types
declared in headers with the same name in different directories were
merged. Undo the prefix mapping from compilation-prefix-map.json first.
[Support] Add vfs::findFileInParentDirectories()
Several tools look for a file in a directory and its parent
directories, for example clang-format for .clang-format and clang-tidy
for .clang-tidy, and each has its own loop for that. Add a function for
it, which dsymutil will use to find the compilation-prefix-map.json
files that compilation caching writes.
[dsymutil] Support compilation-prefix-map.json from compilation caching
Compilation caching can prefix map the paths that the compiler sees, so
that cache keys don't depend on where the build happens, for example
/path/to/project becomes /^src. The build system records the mapping in
a compilation-prefix-map.json file in a parent directory of the object
files, as a JSON object from each remapped prefix to the original one.
dsymutil didn't support it, so it used the remapped paths from the
debug info as is: it failed to copy the Swift interfaces that the debug
info refers to, didn't recognize interfaces from the SDK or the
toolchain that it should skip, and wrote the remapped paths into the
dSYM.
Load the compilation-prefix-map.json closest to each object file, and
use it to find Swift interfaces and Clang modules, and to restore the
original paths in the path attributes and line tables of the linked
debug info. Clang modules use the map of the object file that refers to
them. -object-prefix-map still only applies to looking up Clang
[6 lines not shown]
[VPlan] Remove dead hasScalarVFOnly check in handleFindLastRed (NFC). (#242714)
handleFindLastReductions runs before the VFs are added to the plan, so
Plan.hasScalarVFOnly() is always false there. Scalar VFs with
interleaving are supported since 03c34bb59eb9 (#184099), so remove the
check instead of making it effective.
[Support] Address PrefixMapper review feedback
Match a mapping whose Old ends with a separator, such as "/=/new" or
"/old/=/new", against paths below it; it used to match only the exact
path. Append the rest of the path with its leading separator intact, so
Windows paths keep their separators: "C:/old/a" now maps to "C:/new/a"
instead of "C:/new\a".
Make the map functions const, document how separators are matched and
joined, test separators, sort() and addInverseRange(), and drop the
unused StringSaver references.
[VPlan] Keep NaN exit when using active-lane-mask for control flow. (#241543)
handleMaxMinNumReductions exits the vector loop early if any lane is
NaN, OR'ing the check with the latch exit check. With active-lane-mask
control flow, addVPLaneMaskPhiAndUpdateExitBranch replaced the whole
latch terminator by a branch on the negated mask without checking the
terminator, dropping the NaN exit.
Only replace the latch exit check by the negated mask and keep the other
exit conditions.
PR: https://github.com/llvm/llvm-project/pull/241543