Skip to content

Commit 55ebb76

Browse files
VyacheslavLevytskyyjsji
authored andcommitted
Fix incorrect translation of calls to a builtin that returns a structure (#2722)
Fix issue #2721: Incorrect translation of calls to a builtin that returns a structure: create just one load, and account for a special case when Translator prepared a well-known pattern (store/load) for itself. Original commit: KhronosGroup/SPIRV-LLVM-Translator@dc1221cd83e67ef
1 parent 25f613c commit 55ebb76

File tree

2 files changed

+62
-4
lines changed

2 files changed

+62
-4
lines changed

llvm-spirv/lib/SPIRV/SPIRVUtil.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2229,8 +2229,9 @@ bool postProcessBuiltinReturningStruct(Function *F) {
22292229
Builder.SetInsertPoint(CI);
22302230
SmallVector<User *> Users(CI->users());
22312231
Value *A = nullptr;
2232+
StoreInst *SI = nullptr;
22322233
for (auto *U : Users) {
2233-
if (auto *SI = dyn_cast<StoreInst>(U)) {
2234+
if ((SI = dyn_cast<StoreInst>(U)) != nullptr) {
22342235
A = SI->getPointerOperand();
22352236
InstToRemove.push_back(SI);
22362237
break;
@@ -2253,9 +2254,14 @@ bool postProcessBuiltinReturningStruct(Function *F) {
22532254
CallInst *NewCI = Builder.CreateCall(NewF, Args, CI->getName());
22542255
NewCI->addParamAttr(0, SretAttr);
22552256
NewCI->setCallingConv(CI->getCallingConv());
2256-
SmallVector<User *> CIUsers(CI->users());
2257-
for (auto *CIUser : CIUsers) {
2258-
CIUser->replaceUsesOfWith(CI, A);
2257+
SmallVector<User *, 32> UsersToReplace;
2258+
for (auto *U : Users)
2259+
if (U != SI)
2260+
UsersToReplace.push_back(U);
2261+
if (UsersToReplace.size() > 0) {
2262+
auto *LI = Builder.CreateLoad(F->getReturnType(), A);
2263+
for (auto *U : UsersToReplace)
2264+
U->replaceUsesOfWith(CI, LI);
22592265
}
22602266
InstToRemove.push_back(CI);
22612267
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
; REQUIRES: spirv-as
2+
; RUN: spirv-as --target-env spv1.0 -o %t.spv %s
3+
; RUN: spirv-val %t.spv
4+
; RUN: llvm-spirv -r -o - %t.spv | llvm-dis | FileCheck %s
5+
6+
OpCapability Kernel
7+
OpCapability Addresses
8+
OpCapability Int8
9+
OpCapability GenericPointer
10+
OpCapability Linkage
11+
%1 = OpExtInstImport "OpenCL.std"
12+
OpMemoryModel Physical64 OpenCL
13+
OpSource OpenCL_CPP 100000
14+
OpName %a "a"
15+
OpName %p "p"
16+
OpName %foo "foo"
17+
OpName %e "e"
18+
OpName %math "math"
19+
OpName %ov "ov"
20+
OpDecorate %foo LinkageAttributes "foo" Export
21+
%uint = OpTypeInt 32 0
22+
%uchar = OpTypeInt 8 0
23+
%_ptr_Generic_uchar = OpTypePointer Generic %uchar
24+
%5 = OpTypeFunction %uint %uint %_ptr_Generic_uchar
25+
%bool = OpTypeBool
26+
%_struct_7 = OpTypeStruct %uint %uint
27+
%uint_1 = OpConstant %uint 1
28+
%uchar_42 = OpConstant %uchar 42
29+
%10 = OpConstantNull %uint
30+
%foo = OpFunction %uint None %5
31+
%a = OpFunctionParameter %uint
32+
%p = OpFunctionParameter %_ptr_Generic_uchar
33+
%19 = OpLabel
34+
OpBranch %20
35+
%20 = OpLabel
36+
%e = OpPhi %uint %a %19 %math %21
37+
%16 = OpIAddCarry %_struct_7 %e %uint_1
38+
%math = OpCompositeExtract %uint %16 0
39+
%17 = OpCompositeExtract %uint %16 1
40+
%ov = OpINotEqual %bool %17 %10
41+
OpBranchConditional %ov %22 %21
42+
%21 = OpLabel
43+
OpStore %p %uchar_42 Aligned 1
44+
OpBranch %20
45+
%22 = OpLabel
46+
OpReturnValue %math
47+
OpFunctionEnd
48+
49+
; CHECK: %[[#Var:]] = alloca %structtype, align 8
50+
; CHECK: call spir_func void @_Z17__spirv_IAddCarryii(ptr sret(%structtype) %[[#Var:]]
51+
; CHECK: %[[#Load:]] = load %structtype, ptr %[[#Var]], align 4
52+
; CHECK-2: extractvalue %structtype %[[#Load:]]

0 commit comments

Comments
 (0)