[all-commits] [llvm/llvm-project] e16c73: [SPIRV] Expand aggregate instructions with mutated...
Nick Sarnie via All-commits
all-commits at lists.llvm.org
Tue Jul 7 07:11:14 PDT 2026
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: e16c737a52fa9c5144299282f4da519e898af2a5
https://github.com/llvm/llvm-project/commit/e16c737a52fa9c5144299282f4da519e898af2a5
Author: Nick Sarnie <nick.sarnie at intel.com>
Date: 2026-07-07 (Tue, 07 Jul 2026)
Changed paths:
M llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
A llvm/test/CodeGen/SPIRV/instructions/phi-aggregate-call.ll
A llvm/test/CodeGen/SPIRV/instructions/phi-aggregate-with-overflow-zeroinitializer.ll
A llvm/test/CodeGen/SPIRV/instructions/phi-aggregate-with-overflow.ll
A llvm/test/CodeGen/SPIRV/instructions/select-freeze-aggregate-with-overflow.ll
Log Message:
-----------
[SPIRV] Expand aggregate instructions with mutated-type uses (#206835)
This is a workaround for the problem in GH issue
https://github.com/llvm/llvm-project/issues/203586.
The problem is that we need to mutate aggregate-typed PHI nodes to
`i32`, however that means all incoming values need to have a matching
type, but we can't always easily mutate the incoming types to i32, as in
the case in the GH issue with a math intrinsic that returns a struct
by-value.
We do the same mutation for some other cases like `freeze`, the
workaround is the same.
The workaround is to expand the incoming values to a form that will also
be mutated to i32 so the types match. An example transformation is
below:
Before
```
...
bb1: ; preds = %entry
%0 = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %a, i64 %b)
br label %epilog
...
%2 = phi { i64, i1 } [ %1, %bb0 ], [ %0, %bb1 ]
```
After
```
...
bb1: ; preds = %entry
%0 = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %a, i64 %b)
%1 = extractvalue { i64, i1 } %0, 0
%2 = insertvalue { i64, i1 } poison, i64 %1, 0
%3 = extractvalue { i64, i1 } %0, 1
%4 = insertvalue { i64, i1 } %2, i1 %3, 1
br label %epilog
...
%10 = phi { i64, i1 } [ %9, %bb0 ], [ %4, %bb1 ]
```
`insertvalue` get replaced with a SPIR-V intrinsic later in the pass
which is also type-mutated, so the IR is correct:
```
...
bb1: ; preds = %entry
%0 = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %a, i64 %b)
call void @llvm.spv.value.md(metadata !0)
call void (...) @llvm.fake.use({ i64, i1 } %0)
%1 = extractvalue { i64, i1 } %0, 0
call void @llvm.spv.assign.type.i64(i64 %1, metadata i64 poison)
call void @llvm.spv.assign.type.i32(i32 undef, metadata { i64, i1 } poison)
%2 = call i32 (i32, i64, ...) @llvm.spv.insertv.i64(i32 undef, i64 %1, i32 0)
call void @llvm.spv.assign.type.i32(i32 %2, metadata { i64, i1 } poison)
%3 = extractvalue { i64, i1 } %0, 1
call void @llvm.spv.assign.type.i1(i1 %3, metadata i1 poison)
%4 = call i32 (i32, i1, ...) @llvm.spv.insertv.i1(i32 %2, i1 %3, i32 1)
call void @llvm.spv.assign.type.i32(i32 %4, metadata { i64, i1 } poison)
br label %epilog
...
%10 = phi i32 [ %9, %bb0 ], [ %4, %bb1 ]
```
This is the simplest change I could come up with, my other ideas were
much more complicated and/or risky.
This fix is important for us because this pattern comes up in libc's
implementation on FMA, so this is blocking SPIR-V libc support.
Fixes: https://github.com/llvm/llvm-project/issues/203586
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply at anthropic.com>
Signed-off-by: Nick Sarnie <nick.sarnie at intel.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply at anthropic.com>
To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications
More information about the All-commits
mailing list