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

@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
s-perron added a commit to s-perron/llvm-project that referenced this pull request Oct 29, 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 ed13aeb to 0e00c3a Compare October 29, 2025 13:46
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
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.
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 0e00c3a to 2bdaa1c Compare November 5, 2025 14:35
@github-actions
Copy link

github-actions bot commented Nov 5, 2025

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff origin/main HEAD --extensions h,cpp -- llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h llvm/lib/CodeGen/GlobalISel/LegalityPredicates.cpp llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.h llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp --diff_from_common_commit

⚠️
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing origin/main to the base branch/commit you want to compare against.
⚠️

View the diff from clang-format here.
diff --git a/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
index 7bd68dfd2..6ae73a11e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
@@ -108,8 +108,8 @@ static SPIRVType *deduceTypeFromSingleOperand(MachineInstr *I,
       Register ResVReg = I->getOperand(0).getReg();
       const LLT &ResLLT = MIB.getMRI()->getType(ResVReg);
       if (ResLLT.isVector())
-        return GR->getOrCreateSPIRVVectorType(
-            CompType, ResLLT.getNumElements(), MIB, false);
+        return GR->getOrCreateSPIRVVectorType(CompType, ResLLT.getNumElements(),
+                                              MIB, false);
       return CompType;
     }
   }

@s-perron s-perron closed this Nov 26, 2025
s-perron added a commit to s-perron/llvm-project that referenced this pull request Nov 26, 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.

Fixes: llvm#165444
s-perron added a commit to s-perron/llvm-project that referenced this pull request Nov 27, 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.

Fixes: llvm#165444
s-perron added a commit that referenced this pull request Dec 1, 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.

Fixes #165444
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Dec 1, 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.

Fixes llvm/llvm-project#165444
augusto2112 pushed a commit to augusto2112/llvm-project that referenced this pull request Dec 3, 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.

Fixes llvm#165444
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