JIT: Cleanup and harden lowering#130837
Conversation
Drop unconsumed JITDUMP arguments (including a null-deref of splitPoint) and correct the [%06u} closing brace to a bracket in the containment diagnostics. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Guard the child shift/NOT containment path with IsInvariantInRange to match its sibling paths, remove the redundant OperIs sub-condition already guaranteed by the enclosing block, and drop dead stores to oper in LowerHWIntrinsic. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Pass &userIsScalar instead of clobbering the outer isScalar, drop the no-op node->Op(1) reassignment and the tautological TYP_STRUCT assert, and simplify the dead + (0 * elemSize) offset arithmetic. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Update the DPPD immediate to 0x33, reword the integer compare-less-than swap comment, refer to X86Base.BlendVariable, and fix assorted typos (so so, don't both, storeInder, ouutIndirOpSource, hsa). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Azure Pipelines: Successfully started running 5 pipeline(s). 10 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
There was a problem hiding this comment.
Pull request overview
This PR does a small set of cleanup and hardening changes in CoreCLR JIT lowering, primarily removing dead/debug-only hazards and correcting internal comments/diagnostics.
Changes:
- Fix debug-only
JITDUMPissues in lowering diagnostics (format typos, unused varargs, and a null-deref in a verbose-only path). - Harden ARMArch shift containment under NOT/*_NOT by adding the same
IsInvariantInRangeguard used by adjacent containment paths; remove deadoperstores in ARM HWIntrinsic lowering. - Remove no-op/dead code in xarch HWIntrinsic lowering, fix a latent
isScalarout-param clobber, and update various comments/typos to match current behavior.
Show a summary per file
| File | Description |
|---|---|
| src/coreclr/jit/lower.cpp | Corrects debug-only containment/split-arg diagnostics (format/args) and removes a verbose-only null-deref hazard. |
| src/coreclr/jit/lowerarmarch.cpp | Adds an IsInvariantInRange containment guard for shift+NOT cases and removes dead stores in HWIntrinsic lowering. |
| src/coreclr/jit/lowerxarch.cpp | Removes no-op/dead assertions/assignments, fixes GetOperForHWIntrinsicId out-param usage, and updates comments/typos for clarity and correctness. |
Copilot's findings
- Files reviewed: 3/3 changed files
- Comments generated: 0
|
Azure Pipelines: Successfully started running 5 pipeline(s). 10 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Workflow state for the Holistic Review Orchestrator. {
"version": 5,
"last_dispatched_commit": "87528676b346b660386e93b9c1bb55cdf2f617f9",
"last_dispatched_base_ref": "main",
"last_dispatched_base_sha": "f2281d59e62aa6a75e53055b8f842bac108b9887",
"last_reviewed_commit": "87528676b346b660386e93b9c1bb55cdf2f617f9",
"last_reviewed_base_ref": "main",
"last_reviewed_base_sha": "f2281d59e62aa6a75e53055b8f842bac108b9887",
"last_recorded_worker_run_id": "29684894810",
"review_attempt_commit": "",
"review_attempt_base_ref": "",
"review_attempt_count": 0,
"max_review_attempts": 5,
"review_history_format": "holistic-review-disclosure-v1",
"review_history": [
{
"commit": "87528676b346b660386e93b9c1bb55cdf2f617f9",
"review_id": 4730669898
}
]
} |
There was a problem hiding this comment.
Holistic Review
Motivation: A batch of low-risk cleanup and hardening in JIT lowering, uncovered during a lowering deep-dive. The goal is to remove dead code, fix latent footguns, correct misleading diagnostics, and align inconsistent containment logic—none of which is runtime-observable, so no regression tests accompany the change.
Approach: The PR groups focused edits across three lowering files. In lower.cpp it removes unconsumed JITDUMP arguments (including a verbose-only null-deref of splitPoint->GetOffset() on the splitPoint == nullptr branch) and fixes two [%06u} → [%06u] format typos. In lowerarmarch.cpp it adds a missing IsInvariantInRange guard to the shift/NOT containment path in IsContainableUnaryOrBinaryOp (mirroring the sibling GT_ADD/GT_SUB/... and GT_CMP/GT_OR/... blocks), drops an OperIs(GT_LSH, GT_RSH, GT_RSZ) sub-condition already guaranteed by the enclosing if, and removes dead stores to oper in LowerHWIntrinsic. In lowerxarch.cpp it fixes GetOperForHWIntrinsicId(&isScalar) → &userIsScalar (the outer isScalar was being clobbered), removes a no-op node->Op(1) = op1;, a tautological assert(!src->TypeIs(TYP_STRUCT)), dead + (0 * elemSize) arithmetic, and assorted comment/typo fixes.
Summary: I reviewed the full base-to-head range and confirmed each change. The removed oper assignments in the ARM LowerHWIntrinsic occur after the last read of oper (lines reading it at the GT_AND/GT_OR checks still see the value set at the top of the function), so the removal is safe. The new IsInvariantInRange guard is a verbatim structural mirror of the adjacent containment blocks in the same function and is strictly more conservative, so it cannot introduce a miscompile; the retained assert(shiftAmountNode->isContained()) matches the siblings. The &userIsScalar fix targets a genuinely misdirected out-parameter and does not change behavior today because the outer isScalar is not subsequently consumed in a way that depended on the clobbered value. The removed node->Op(1) = op1; is a no-op since op1 was just read from node->Op(1) with no intervening reassignment. All remaining edits are diagnostics, comments, and dead arithmetic with no functional effect. The changes are self-consistent, improve robustness, and carry negligible risk.
Verdict: LGTM. No actionable findings.
Note
This review was generated by this repository's Holistic Review agentic workflow to complement the built-in Copilot review.
Generated by Holistic Review · 66.6 AIC · ⌖ 10.6 AIC · ⊞ 10K
|
CC. @dotnet/jit-contrib, @EgorBo. Trivial cleanup of some comments, JITDUMP, and a simplification to a code path |
Follow-up to #130837. Several `JITDUMP` calls pass a trailing argument to a format string that has no corresponding `%` specifier, so the argument is silently ignored. This removes those leftover args. All are `DEBUG`-only and behavior is unchanged. - `lower.cpp` -- `JITDUMP("Argument is a local\n", numRegs, stackSeg.Size)` (the one called out in #130837) - `importercalls.cpp` -- `arrayElemSize` - `importervectorization.cpp` -- `str` - `inductionvariableopts.cpp` -- `dspTreeID(...)` (redundant; the following `DISPTREE` already dumps the tree) and `lclNum` - `optimizer.cpp` -- `lclNum` - `rangecheck.cpp` -- `expr` (two sites) Found by scanning every `.cpp` under `src/coreclr/jit` for literal format strings with no conversion but a trailing argument; these were the only hits. > [!NOTE] > This PR description and the changes were drafted with GitHub Copilot. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
A batch of low-risk cleanup and hardening in JIT lowering, found during a lowering deep-dive. None of these are runtime-observable, so there are no regression tests. Grouped into focused commits.
lower.cpp-- debug-only diagnosticsSplitArgumentBetweenRegistersAndStackhad aJITDUMPthat evaluatedsplitPoint->GetOffset()on the branch wheresplitPoint == nullptr-- a verbose-only null-deref, and the format string didn't even consume it. Dropped that and the other unconsumednumRegs, stackSeg.Sizeargs on the FIELD_LIST/BLK/reuse/spill dumps. Also fixed two[%06u}->[%06u]typos in the containment diagnostics.lowerarmarch.cpp-- shift/NOT containment hardening + dead storesThe child shift/NOT containment path in
IsContainableUnaryOrBinaryOpdidn't callIsInvariantInRangebefore allowing containment, unlike its siblings just above it. This isn't a live bug today (the operand is the immediate LIR predecessor by construction), but it's fragile and inconsistent, so this adds the matching guard and drops a redundantOperIssub-condition already guaranteed by the enclosing block. Also removes dead stores tooperinLowerHWIntrinsic.lowerxarch.cpp-- dead code + comment/typo fixesGetOperForHWIntrinsicId(&isScalar)clobbered the outerisScalar; the adjacent localuserIsScalarwas the intended target. Latent footgun, not a behavior change today.node->Op(1) = op1;, a tautologicalassert(!src->TypeIs(TYP_STRUCT));, and dead+ (0 * elemSize)arithmetic.0x31->0x33to match the code, reworded the integer compare-less-than swap comment,Sse41.BlendVariable->X86Base.BlendVariable, and assorted typos.Verified: baseline
build.cmd clr -rc checkedsucceeds,jitformat.pyis clean, and the x64 JIT rebuilds with no warnings/errors. Thelowerarmarch.cppchange is a verbatim structural mirror of adjacent compiling code in the same function.Note
This PR description was drafted by GitHub Copilot.