[libc] Use a syscall wrapper for setsid (#240331)
This PR move setsid behind the centralized syscall wrappers, following
libc/docs/dev/syscall_wrapper_refactor.md.
[libc] Use a syscall wrapper for pwrite (#240330)
This PR move pwrite behind the centralized syscall wrappers, following
libc/docs/dev/syscall_wrapper_refactor.md.
[libc] Use a syscall wrapper for pread (#240329)
This PR move pread behind the centralized syscall wrappers, following
libc/docs/dev/syscall_wrapper_refactor.md.
[libc] Use a syscall wrapper for pipe (#240328)
This PR move pipe behind the centralized syscall wrappers, following
libc/docs/dev/syscall_wrapper_refactor.md.
[mlir][ODS] Add DefaultValuedEnumProp
Giving an enum property a default currently means subclassing EnumProp
and spelling the default as `Enum.cppType # "::Case"`, or wrapping it in
DefaultValuedProp with the same hand-written string. DefaultValuedEnumProp
takes the EnumInfo and one of its EnumCase defs, mirroring
DefaultValuedEnumAttr, and asserts at TableGen time that the case belongs
to the enum. GEPNoWrapFlagsProp and the test dialect's default-valued enum
props switch to it.
Assisted-by: Claude Code (Claude Fable 5.1).
[SLSR] Sign-extend or truncate stride for +/-1 IndexDelta (#240262)
In StraightLineStrengthReduce::emitBump, a GEP candidate's Index (and
IndexDelta) has the pointer index type, whereas Stride may have a
narrower integer type from the GEP index operand.
While emitBump already converts C.Stride to DeltaType via
CreateSExtOrTrunc for the general CreateMul(ExtendedStride, C.Delta)
case, the early-return fast paths for IndexDelta == 1 and IndexDelta ==
-1 returned C.Stride and Builder.CreateNeg(C.Stride) in C.Stride's
original type.
For GEP candidates, this passes an offset narrower than the pointer
index type to IRBuilder::CreatePtrAdd, triggering the assertion added in
#239262 ("Offset must match index type"), and for IndexDelta == -1 it
also negated the narrow stride prior to sign-extension.
Compute ExtendedStride before handling the 1 and -1 special cases.
[libc] Use RAII and DirScanResult in scandir (#240107)
When building LLVM libc in full-build mode, dir_scan_impl_test fails
with Scudo due to unaligned buffer casts and raw allocations in the test
mock. In production code, scan_impl relied on manual error jumps to free
partially accumulated entries and close the directory descriptor,
leaving callers vulnerable to leaks if intermediate failures occurred.
Modernise scan_impl and Dir::scan to manage the directory lifecycle and
accumulated entries using RAII (unique_ptr, ScannedEntries, and
AllocChecker), eliminating leak hazards on error paths at zero overhead
to the happy path. Return an ErrorOr<DirScanResult> pair rather than
mutating an indirect out-pointer, decouple dir.h from the scanning
template via dir_scan_result.h, and update unit tests with aligned
buffers and span-based loops.
Assisted-by: Automated tooling, human reviewed.
linux: Allow connect() with destination port 0
Linux allows connect() with destination port 0, but FreeBSD returns
EADDRNOTAVAIL in in_pcbconnect() and in6_pcbladdr(). Some Linux programs
(e.g. the new Android CLI tool) rely on this for routability checks,
however.
Add an SV_CONN_PORT0 flag to sv_flags which is set in the Linux sysvecs,
allowing the port 0 guard in the connect paths to be bypassed.
Reviewed by: glebius, kib
Differential Revision: https://reviews.freebsd.org/D60659
[GlobalISel] Simplify demanded bits through G_TRUNC, G_XOR and G_SELECT
Extend CombinerHelper's demanded-bits simplification to G_TRUNC, G_XOR
and G_SELECT, following SelectionDAG's SimplifyDemandedBits, and make
them roots of the simplify_demanded_bits rule (used by the AArch64 and
AMDGPU post-legalizer combiners).
- G_TRUNC demands the low bits of its source, bypasses multi-use
logical ops, and turns trunc (lshr X, C) into lshr (trunc X), C when
no shifted-in bits are demanded.
- G_XOR drops an operand whose demanded bits are known zero, narrows to
a type with free trunc/zext, becomes G_OR when no demanded bit can be
set on both sides (disjoint only if that holds for all bits), becomes
G_AND or NOT based on known bits, and commutes with a logical shift
when the target allows it. Unlike SelectionDAG it does not shrink the
XOR constant: without a targetShrinkDemandedConstant equivalent that
can make an encodable immediate unencodable.
simplifyMultipleUseDemandedBits also bypasses G_XOR.
- G_SELECT propagates demand to both value operands and intersects
[11 lines not shown]
[GlobalISel] Use known bits to bypass multi-use AND/OR for demanded bits
simplifyMultipleUseDemandedBits only looked through a G_AND/G_OR whose
other operand is a constant. Like SelectionDAG's
SimplifyMultipleUseDemandedBits, also return an operand when known bits
show that the logic op does not change any demanded bit, treating
constants as fully known even at the analysis depth limit.
When a root G_AND/G_OR/shift cannot simplify an operand in place, route
that use to the value returned by simplifyMultipleUseDemandedBits instead
of giving up, leaving other users of the operand untouched.
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
[AArch64][GlobalISel] Look through G_UBFX when folding into TB(N)Z
Testing bit b of (G_UBFX x, lsb, width) with b < width is testing bit
lsb + b of x. Walk through the extract in getTestBitReg so that
and (ubfx x, lsb, width), (1 << b) feeding a branch still selects a single
TB(N)Z on x, as SelectionDAG does.
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
[TargetLowering] Decouple isDesirableToCommuteXorWithShift from SDNode (NFC)
Pass the shift direction, XOR mask, shift amount and vector-ness instead
of the XOR node, so that GlobalISel can ask the same question. The
AArch64 and ARM overrides keep accepting only scalar masks that cover
exactly the bits the shift preserves.
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
[mlir][ODS] Add so-called "Natural Sharding" to ops
Prior to this PR, ODS had one mechanism for sharding which equally split a `<Dialect>Ops.cpp.inc` file into `n` many, as requested on the command line (using preprocessor defines for selective enablement).
The motivation for doing so is that this can speed up compile time by splitting class definition compilation to multiple translation units.
However, this approach has one large disadvantage: Since only the `<Dialect>Ops.cpp.inc` is split, the correpsonding `<Dialect>Ops.h.inc` is still included in each translation unit. For a large dialect like NVVM or LLVM this leads to **much higher** concurrent memory usage while compiling as every compilation process contains an in-memory copy of the header plus can lead to slower compilation time overall if too many shards are being used as overall work goes up (`n` header parses instead of 1).
This PR tries to address these issues by introducing a new kind of sharding called "natural sharding". The idea is that we split `<Dialect>Ops.cpp.inc` and `<Dialect>Ops.h.inc` along so called partitions. A new header can be created for every partition and every translation unit only contains the code from its partition. This means a TU no longer needs to include the entire dialect header but only the header from its partition.
One can think of these as effectively being sub-dialects from the perspective of the required boilerplate.
We call it "Natural Sharding", as the partitions are defined by the dialect authors and are meant to be categories that naturally categorizes a dialects operations (e.g., Memory ops, control flow ops, arithmetic ops, intrinsic ops, etc. in the LLVM Dialect). The new `-op-partition` then filters output generation to just a given partition.
This PR introduces the mechanism and for testing, already exercises it on the test dialect. Users of `TestOps.h` were further changed to just include a given partition if deemed useful.
Overall this yielded the following build gains vs the existing sharding, measured on a 16 thread machine (Release + assertions, 16 parallel jobs, median of 3 runs). "Users of `MLIRTestDialect`" are other TUs (unittests mainly) that include `MLIRTestDialect` headers. Total memory is the sum of the max RSS of every TU:
| TUs | Compiler | Wall time (s) | CPU time (s) | Total memory used during compilation (GiB) |
|----------------------------|----------|---------------------|--------------------|--------------------------------------------|
| `MLIRTestDialect` | clang | 49.9 -> 35.2 (-29%) | 710 -> 365 (-49%) | 23.3 -> 11.1 (-52%) |
| `MLIRTestDialect` | clang -g | 57.8 -> 43.1 (-25%) | 791 -> 427 (-46%) | 25.0 -> 12.5 (-50%) |
[8 lines not shown]
[LifetimeSafety] Don't treat assignment to a temporary as a use of its pointee (#240175)
`handleAssignment` stripped the LHS with `IgnoreParenImpCasts()`, which
also skips `MaterializeTemporaryExpr`. For `View{v} = View()`,
`handleAccess()` then saw the prvalue `View{v}` instead of the
materialized temporary, so it checked the loans of the view's value
(`v`'s pointee) instead of the temporary's storage.
```cpp
View v;
{
MyObj s;
v = s;
}
v = View(); // no warning
View{v} = View(); // warning (false positive)
```