Skip to content

Move CHECK_IR before morph global#127352

Closed
AndyAyersMS wants to merge 1 commit intodotnet:mainfrom
AndyAyersMS:check-ir-before-morph-global
Closed

Move CHECK_IR before morph global#127352
AndyAyersMS wants to merge 1 commit intodotnet:mainfrom
AndyAyersMS:check-ir-before-morph-global

Conversation

@AndyAyersMS
Copy link
Copy Markdown
Member

Not sold on the need for these size updates, or (if needed) the way they're implemented

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 23, 2026 22:14
@github-actions github-actions Bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Apr 23, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates CoreCLR JIT behavior in two areas: (1) it enables CHECK_IR phase checks before PHASE_MORPH_GLOBAL so post-phase IR validation runs after global morph, and (2) it adds logic to re-derive Vector<T> sizing/ISA markers from the runtime-reported Vector<T> struct size (via getClassSize) during intrinsic lookup and struct normalization.

Changes:

  • Enable PhaseChecks::CHECK_IR prior to global morph so fgDebugCheckLinks() runs on morphed IR.
  • Infer Vector<T> width (128/256/512) from Vector<T>’s class size and adjust VectorT ISA markers accordingly.
  • Add instruction set flag normalization (Set64BitInstructionSetVariants + EnsureInstructionSetFlagsAreValid) in compSetProcessor.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
src/coreclr/jit/importercalls.cpp Adjusts Vector<T> intrinsic lookup sizing based on class size and updates VectorT ISA markers.
src/coreclr/jit/importer.cpp Updates struct normalization to detect System.Numerics.Vector<T> and adjust VectorT ISA markers based on its size.
src/coreclr/jit/compiler.cpp Tweaks ISA initialization/validation and moves CHECK_IR enabling ahead of global morph.

Comment on lines +10844 to +10873
opts.compSupportsISA.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISA.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISA.RemoveInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT512);

switch (classSize)
{
case 16:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT128);
size = 16;
break;

case 32:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT256);
size = 32;
break;

case 64:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT512);
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid mutating opts.compSupportsISAReported / opts.compSupportsISAExactly here. Those sets are intended to be managed by compExactlyDependsOn (which calls notifyInstructionSetUsage and then updates *Reported/Exactly); pre-populating them here can suppress VM notification for VectorT dependencies and make R2R/ISA tracking incorrect. Consider only adjusting opts.compSupportsISA (if absolutely necessary) and let compExactlyDependsOn report usage, or compute size from classSize without changing global ISA tracking state.

Suggested change
opts.compSupportsISA.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISA.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISA.RemoveInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT512);
switch (classSize)
{
case 16:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT128);
size = 16;
break;
case 32:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT256);
size = 32;
break;
case 64:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT512);
switch (classSize)
{
case 16:
size = 16;
break;
case 32:
size = 32;
break;
case 64:

Copilot uses AI. Check for mistakes.
Comment on lines +10854 to +10860
switch (classSize)
{
case 16:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT128);
size = 16;
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This switch has no default/assert, but the code has already cleared all VectorT* flags above. If classSize is ever not 16/32/64 (e.g., unexpected layout), the compiler will silently proceed with no VectorT ISA set, leaving compilation state inconsistent. Consider guarding the flag update so it only happens for the expected sizes, and otherwise keep the existing VectorT* flags (or assert/unreached).

Copilot uses AI. Check for mistakes.
Comment on lines +1202 to +1226
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT512);

switch (originalSize)
{
case 16:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT128);
break;

case 32:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT256);
break;

case 64:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT512);
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid mutating opts.compSupportsISAReported / opts.compSupportsISAExactly in impNormStructType. These sets are used to track which ISAs were actually reported to the VM (see compExactlyDependsOn); manually adding VectorT* here can prevent notifyInstructionSetUsage from running later and can corrupt dependency tracking. If you need Vector sizing to follow the struct size, prefer deriving a local size value (or adjusting only compSupportsISA during option setup) and leave *Reported/*Exactly to compExactlyDependsOn.

Suggested change
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT512);
switch (originalSize)
{
case 16:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT128);
break;
case 32:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT256);
break;
case 64:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT512);
switch (originalSize)
{
case 16:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT128);
break;
case 32:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT256);
break;
case 64:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT512);

Copilot uses AI. Check for mistakes.
Comment on lines +1199 to +1227
opts.compSupportsISA.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISA.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISA.RemoveInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT512);

switch (originalSize)
{
case 16:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT128);
break;

case 32:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT256);
break;

case 64:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT512);
break;
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This switch clears all VectorT* flags first, but does nothing for unexpected originalSize values. If originalSize is not 16/32/64, the method will silently leave VectorT sizing unset for the rest of the compilation. Consider validating originalSize and either preserving the existing VectorT* flags or asserting to avoid silently changing global ISA state.

Suggested change
opts.compSupportsISA.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISA.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISA.RemoveInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT512);
switch (originalSize)
{
case 16:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT128);
break;
case 32:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT256);
break;
case 64:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT512);
break;
const bool isValidVectorTSize = (originalSize == 16) || (originalSize == 32) || (originalSize == 64);
assert(isValidVectorTSize);
if (isValidVectorTSize)
{
opts.compSupportsISA.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISA.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISA.RemoveInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAReported.RemoveInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAExactly.RemoveInstructionSet(InstructionSet_VectorT512);
switch (originalSize)
{
case 16:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT128);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT128);
break;
case 32:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT256);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT256);
break;
case 64:
opts.compSupportsISA.AddInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAReported.AddInstructionSet(InstructionSet_VectorT512);
opts.compSupportsISAExactly.AddInstructionSet(InstructionSet_VectorT512);
break;
}

Copilot uses AI. Check for mistakes.
@AndyAyersMS
Copy link
Copy Markdown
Member Author

Just wanted to share this with Tanner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants