You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[SPIR-V] Address the case when optimization uses GEP operator and GenCode creates G_PTR_ADD to convey the semantics (#107880)
When running SPIR-V Backend with optimization levels higher than 0, we
observe GEP Operator's as a new factor, massively used to convey the
semantics of the original LLVM IR. Previously, an issue related to GEP
Operator was mentioned and fixed on the consumer side of toolchains
(see, for example, Khronos Trandslator Issue
KhronosGroup/SPIRV-LLVM-Translator#2486 and PR
KhronosGroup/SPIRV-LLVM-Translator#2487).
However, there is a case when GenCode creates G_PTR_ADD to convey the
original semantics under optimization levels higher than 0 where it's
SPIR-V Backend that fails to translate source LLVM IR correctly.
Consider the following reproducer:
```
%struct = type { i32, [257 x i8], [257 x i8], [129 x i8], i32, i64, i64, i64, i64, i64, i64 }
@mem = linkonce_odr dso_local addrspace(1) global %struct zeroinitializer, align 8
define weak dso_local spir_func void @__devicelib_assert_fail(ptr addrspace(4) noundef %expr, i32 noundef %line, i1 %fl) {
entry:
%cmp = icmp eq i32 %line, 0
br i1 %cmp, label %lbl, label %exit
lbl:
store i32 %line, ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) @mem, i64 648), align 8
br i1 %fl, label %lbl, label %exit
exit:
ret void
}
```
converted to the following machine instructions by SPIR-V Backend:
```
%4:type(s64) = OpTypeInt 32, 0
%22:type(s64) = OpTypePointer 5, %4:type(s64)
%2:type(s64) = OpTypeInt 8, 0
%28:type(s64) = OpTypePointer 5, %2:type(s64)
%10:pid(p1) = G_GLOBAL_VALUE @mem
%36:type(s64) = OpTypeStruct %4:type(s64), %32:type(s64), %32:type(s64), %34:type(s64), %4:type(s64), %35:type(s64), %35:type(s64), %35:type(s64), %35:type(s64), %35:type(s64), %35:type(s64)
%37:iid(s32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.spv.const.composite)
%8:iid(s32) = ASSIGN_TYPE %37:iid(s32), %36:type(s64)
G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.spv.init.global), %10:pid(p1), %8:iid(s32)
%29:pid(p1) = nuw G_PTR_ADD %10:pid, %16:iid(s64)
%15:pid(p1) = nuw ASSIGN_TYPE %29:pid(p1), %28:type(s64)
%27:pid(p2) = G_BITCAST %15:pid(p1)
%17:pid(p2) = ASSIGN_TYPE %27:pid(p2), %22:type(s64)
G_STORE %1:iid(s32), %17:pid(p2) :: (store (s32) into %ir.3, align 8, addrspace 1)
```
On the next stage of instruction selection this `G_PTR_ADD`-related
pattern would be interpreted as an initialization of a global variable
and converted to an invalid constant GEP pattern that, in its turn,
would fail to be verified by LLVM during back translation from SPIR-V to
LLVM IR.
This PR introduces a fix for the problem by adding one more case of
`G_PTR_ADD` translation, when we use a non-const GEP to convey the
meaning. The reproducer is attached as a new test case.
0 commit comments