Skip to content

Conversation

@s-perron
Copy link
Contributor

@s-perron s-perron commented Oct 28, 2025

This patch introduces the necessary infrastructure to legalize vector
operations on vectors that are longer than what the SPIR-V target
supports. For instance, shaders only support vectors up to 4 elements.

The legalization is done by splitting the long vectors into smaller
vectors of a legal size.

Specifically, this patch does the following:

  • Introduces vectorElementCountIsGreaterThan and
    vectorElementCountIsLessThanOrEqualTo legality predicates.
  • Adds legalization rules for G_SHUFFLE_VECTOR, G_EXTRACT_VECTOR_ELT,
    G_BUILD_VECTOR, G_CONCAT_VECTORS, G_SPLAT_VECTOR, and
    G_UNMERGE_VALUES.
  • Handles G_BITCAST of long vectors by converting them to
    @llvm.spv.bitcast intrinsics which are then legalized.
  • Updates selectUnmergeValues to handle extraction of both scalars
    and vectors from a larger vector, using OpCompositeExtract and
    OpVectorShuffle respectively.
  • Adds a test case to verify the legalization of a bitcast between
    a <8 x i32> and <4 x f64>, which is a pattern generated by
    HLSL's asuint and asdouble intrinsics.

Fixes #165444

This change sets the hasSideEffects flag to false on type and constant opcodes
so that they can be considered trivially dead if their result is unused. This
means that instruction selection will now be able to remove them.
The spv_bitcast intrinsic is currently replaced by an OpBitcast
during prelegalization. This will cause a problem when we need to
legalize the OpBitcast. The legalizer assumes that instruction
already lowered to a target specific opcode is legal.

We cannot lower it to a G_BITCAST because the bitcasts sometimes
the LLT type will be the same, causing an error in the verifier,
even if the SPIR-V types will be different.

This commit keeps the intrinsic around until instructoin selection.
We can create rules to legalize a G_INTRINISIC* instruction, and
it does not create problem for the verifier.
The previous check for vector bitcasts in `loadVectorFromVector` only
compared the number of elements, which is insufficient when the element
types differ. This can lead to incorrect assumptions about the validity
of the cast.

This commit replaces the element count check with a comparison of the
total size of the vectors in bits. This ensures that the bitcast is
only performed between vectors of the same size, preventing potential
miscompilations.
This commit refactors the SPIRV post-legalizer to use a worklist to process
new instructions. Previously, the post-legalizer would iterate through all
instructions and try to assign types. This could fail if a new instruction
depended on another new instruction that had not been processed yet.

The new implementation adds all new instructions that require a SPIR-V type
to a worklist. It then iteratively processes the worklist until it is empty.
This ensures that all dependencies are met before an instruction is
processed.

This change makes the post-legalizer more robust and fixes potential ordering
issues with newly generated instructions.

Existing tests cover existing functionality. More tests will be added as
the legalizer is modified.

Part of llvm#153091
…tcast-intrinsic' and 'legalize_ptr_cast' into legalize-long-vectors-final
This commit refactors the SPIRV post-legalizer to use a worklist to process
new instructions. Previously, the post-legalizer would iterate through all
instructions and try to assign types. This could fail if a new instruction
depended on another new instruction that had not been processed yet.

The new implementation adds all new instructions that require a SPIR-V type
to a worklist. It then iteratively processes the worklist until it is empty.
This ensures that all dependencies are met before an instruction is
processed.

This change makes the post-legalizer more robust and fixes potential ordering
issues with newly generated instructions.

Existing tests cover existing functionality. More tests will be added as
the legalizer is modified.

Part of llvm#153091
@s-perron s-perron marked this pull request as draft October 28, 2025 17:30
s-perron added a commit to s-perron/llvm-project that referenced this pull request Oct 28, 2025
This patch introduces the necessary infrastructure to legalize vector
operations on vectors that are longer than what the SPIR-V target
supports. For instance, shaders only support vectors up to 4 elements.

The legalization is done by splitting the long vectors into smaller
vectors of a legal size.

Specifically, this patch does the following:
- Introduces `vectorElementCountIsGreaterThan` and
  `vectorElementCountIsLessThanOrEqualTo` legality predicates.
- Adds legalization rules for `G_SHUFFLE_VECTOR`, `G_EXTRACT_VECTOR_ELT`,
  `G_BUILD_VECTOR`, `G_CONCAT_VECTORS`, `G_SPLAT_VECTOR`, and
  `G_UNMERGE_VALUES`.
- Handles `G_BITCAST` of long vectors by converting them to
  `@llvm.spv.bitcast` intrinsics which are then legalized.
- Updates `selectUnmergeValues` to handle extraction of both scalars
  and vectors from a larger vector, using `OpCompositeExtract` and
  `OpVectorShuffle` respectively.
- Adds a test case to verify the legalization of a bitcast between
  a `<8 x i32>` and `<4 x f64>`, which is a pattern generated by
  HLSL's `asuint` and `asdouble` intrinsics.

Fixes: llvm#165444
@s-perron s-perron force-pushed the legalize-long-vectors branch from f50b420 to ed13aeb Compare October 28, 2025 17:32
@s-perron s-perron changed the title legalize long vectors [SPIRV] Add legalization for long vectors Oct 28, 2025
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I need to rename the file.

This patch introduces the necessary infrastructure to legalize vector
operations on vectors that are longer than what the SPIR-V target
supports. For instance, shaders only support vectors up to 4 elements.

The legalization is done by splitting the long vectors into smaller
vectors of a legal size.

Specifically, this patch does the following:
- Introduces `vectorElementCountIsGreaterThan` and
  `vectorElementCountIsLessThanOrEqualTo` legality predicates.
- Adds legalization rules for `G_SHUFFLE_VECTOR`, `G_EXTRACT_VECTOR_ELT`,
  `G_BUILD_VECTOR`, `G_CONCAT_VECTORS`, `G_SPLAT_VECTOR`, and
  `G_UNMERGE_VALUES`.
- Handles `G_BITCAST` of long vectors by converting them to
  `@llvm.spv.bitcast` intrinsics which are then legalized.
- Updates `selectUnmergeValues` to handle extraction of both scalars
  and vectors from a larger vector, using `OpCompositeExtract` and
  `OpVectorShuffle` respectively.
- Adds a test case to verify the legalization of a bitcast between
  a `<8 x i32>` and `<4 x f64>`, which is a pattern generated by
  HLSL's `asuint` and `asdouble` intrinsics.

Fixes: llvm#165444
@s-perron s-perron force-pushed the legalize-long-vectors branch from ed13aeb to 0e00c3a Compare October 29, 2025 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant