[llvm] [SPIR-V] Allow intrinsics with aggregate return type to reach GlobalISel (PR #108893)
Vyacheslav Levytskyy via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 19 02:05:56 PDT 2024
================
@@ -1270,6 +1316,8 @@ Instruction *SPIRVEmitIntrinsics::visitInsertValueInst(InsertValueInst &I) {
}
Instruction *SPIRVEmitIntrinsics::visitExtractValueInst(ExtractValueInst &I) {
+ if (I.getAggregateOperand()->getType()->isAggregateType())
+ return &I;
----------------
VyacheslavLevytskyy wrote:
You are right, it's counterintuitive (unfortunately).
The brief answer is that SPIRV Backend used to get rid of aggregate data types to conform to IRTranslator expectations, and so visitExtractValueInst() as a rule observes non-aggregate operands which are changed to i32 during "prepare-functions". If we saw an aggregate here we can be sure that translation would fail: aggregates are being decomposed to multiple v-regs and this triggers https://github.com/llvm/llvm-project/blob/e762d4dac762a3fc27c6e251086b6645d7543bb2/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp#L2798
So this check means that there's no sense to generate spv_extractv, because the required logic has already been implemented using this PR's way.
A good illustration is when we run smth like `llc -O0 -mtriple=spirv64-unknown-unknown llvm/test/CodeGen/SPIRV/instructions/call-complex-function.ll -o 1 -print-before=prepare-functions -print-after=prepare-functions -print-after=emit-intrinsics -filter-print-funcs=foo` to check info between passes:
```
*** IR Dump Before SPIRV prepare functions (prepare-functions) ***
define i32 @foo({ i32, i16 } %in, i64 %unused) {
%first = extractvalue { i32, i16 } %in, 0
%bar = call i32 @fun(i32 %first)
ret i32 %bar
}
*** IR Dump After SPIRV prepare functions (prepare-functions) ***
define i32 @foo(i32 %in, i64 %unused) {
%first = extractvalue i32 %in, 0
%bar = call i32 @fun(i32 %first)
ret i32 %bar
}
*** IR Dump After SPIRV emit intrinsics (emit-intrinsics) ***
define i32 @foo(i32 %in, i64 %unused) {
%1 = call i32 @llvm.spv.track.constant.i32.i32(i32 0, metadata i32 0)
%2 = call i32 (i32, ...) @llvm.spv.extractv.i32(i32 %in, i32 %1)
call void @llvm.spv.assign.type.i32(i32 %2, metadata i32 poison)
%bar = call i32 @fun(i32 %2)
call void (i32, ...) @llvm.spv.assign.name.i32(i32 %bar, i32 7496034)
call void @llvm.spv.assign.type.i32(i32 %bar, metadata i32 poison)
ret i32 %bar
}
```
https://github.com/llvm/llvm-project/pull/108893
More information about the llvm-commits
mailing list