[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