Skip to content

Commit 2ca1252

Browse files
pkwasnie-intelpszymich
authored andcommitted
fix select instruction handling in ScalarArgAsPointer pass
Fixes select instruction handling in ScalarArgAsPointer pass. (cherry picked from commit 71a219b)
1 parent bb3ec0e commit 2ca1252

File tree

5 files changed

+146
-23
lines changed

5 files changed

+146
-23
lines changed

IGC/Compiler/Optimizer/OpenCLPasses/ScalarArgAsPointer/ScalarArgAsPointer.cpp

+49-22
Original file line numberDiff line numberDiff line change
@@ -151,44 +151,71 @@ ScalarArgAsPointerAnalysis::findArgs(llvm::Instruction* inst)
151151
if (!findStoredArgs(*LI, *result))
152152
return nullptr; // (1) Found indirect access, fail search
153153
}
154+
else if (SelectInst* SI = dyn_cast<SelectInst>(inst))
155+
{
156+
auto args1 = analyzeOperand(inst->getOperand(1));
157+
auto args2 = analyzeOperand(inst->getOperand(2));
158+
159+
if (!args1 && !args2)
160+
return nullptr; // propagate fail only if both paths fails
161+
162+
if (args1)
163+
result->insert(args1->begin(), args1->end());
164+
165+
if (args2)
166+
result->insert(args2->begin(), args2->end());
167+
}
154168
else
155169
{
156170
// For any other type of instruction trace back operands.
157171
unsigned int numOperands = isa<GetElementPtrInst>(inst) ? 1 : inst->getNumOperands();
158172

159173
for (unsigned int i = 0; i < numOperands; ++i)
160174
{
161-
Value* op = inst->getOperand(i);
175+
auto args = analyzeOperand(inst->getOperand(i));
162176

163-
if (Argument* arg = dyn_cast<Argument>(op))
164-
{
165-
// Consider only integer arguments
166-
if (arg->getType()->getScalarType()->isIntegerTy())
167-
{
168-
result->insert(arg);
169-
}
170-
else
171-
{
172-
// (2) Found non-compatible argument, fail
173-
return nullptr;
174-
}
175-
}
176-
else if (Instruction* opInst = dyn_cast<Instruction>(op))
177-
{
178-
auto args = findArgs(opInst);
179-
180-
if (!args)
181-
return nullptr; // propagate fail
177+
if (!args)
178+
return nullptr; // propagate fail
182179

183-
result->insert(args->begin(), args->end());
184-
}
180+
result->insert(args->begin(), args->end());
185181
}
186182
}
187183

188184
m_visitedInst[inst] = result;
189185
return result;
190186
}
191187

188+
const std::shared_ptr<ScalarArgAsPointerAnalysis::ArgSet>
189+
ScalarArgAsPointerAnalysis::analyzeOperand(llvm::Value* op)
190+
{
191+
auto result = std::make_shared<ScalarArgAsPointerAnalysis::ArgSet>();
192+
193+
if (Argument* arg = dyn_cast<Argument>(op))
194+
{
195+
// Consider only integer arguments
196+
if (arg->getType()->getScalarType()->isIntegerTy())
197+
{
198+
result->insert(arg);
199+
}
200+
else
201+
{
202+
// (2) Found non-compatible argument, fail
203+
return nullptr;
204+
}
205+
}
206+
else if (Instruction* opInst = dyn_cast<Instruction>(op))
207+
{
208+
auto args = findArgs(opInst);
209+
210+
if (!args)
211+
return nullptr; // propagate fail
212+
213+
result->insert(args->begin(), args->end());
214+
}
215+
216+
return result;
217+
}
218+
192219
void ScalarArgAsPointerAnalysis::analyzeStoredArg(llvm::StoreInst& SI)
193220
{
194221
// Only track stores of kernel arguments.

IGC/Compiler/Optimizer/OpenCLPasses/ScalarArgAsPointer/ScalarArgAsPointer.hpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*========================== begin_copyright_notice ============================
22
3-
Copyright (C) 2022 Intel Corporation
3+
Copyright (C) 2022-2023 Intel Corporation
44
55
SPDX-License-Identifier: MIT
66
@@ -87,6 +87,13 @@ namespace IGC
8787
/// @returns Set of matching kernel arguments.
8888
const std::shared_ptr<ArgSet> findArgs(llvm::Instruction* I);
8989

90+
/// @brief Called by findArgs to analyzes instruction's operands. Returns null if load/store:
91+
/// (1) is indirect, or
92+
/// (2) uses pointer kernel argument
93+
/// @param op operand to trace back.
94+
/// @returns Set of matching kernel arguments.
95+
const std::shared_ptr<ArgSet> analyzeOperand(llvm::Value* op);
96+
9097
/// @brief Checks if instruction stores kernel argument, and if true, traces back to
9198
/// alloca instruction (with offset). This is required for decomposed structs
9299
/// that are copied into private memory.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
;=========================== begin_copyright_notice ============================
2+
;
3+
; Copyright (C) 2023 Intel Corporation
4+
;
5+
; SPDX-License-Identifier: MIT
6+
;
7+
;============================ end_copyright_notice =============================
8+
9+
; RUN: igc_opt --igc-scalar-arg-as-pointer-analysis --serialize-igc-metadata -S %s | FileCheck %s
10+
;
11+
; Tests "select" instruction, when first path leads to scalar as pointer.
12+
;
13+
; CHECK-NOT: !{!"m_OpenCLArgScalarAsPointersSet{{[[][0-9][]]}}", i32 0}
14+
; CHECK: !{!"m_OpenCLArgScalarAsPointersSet{{[[][0-9][]]}}", i32 1}
15+
; CHECK-NOT: !{!"m_OpenCLArgScalarAsPointersSet{{[[][0-9][]]}}", i32 2}
16+
17+
define spir_kernel void @test(i1 %s, i64 %a, i32 addrspace(1)* %b) #0 {
18+
entry:
19+
%0 = inttoptr i64 %a to i32 addrspace(1)*
20+
%1 = select i1 %s, i32 addrspace(1)* %0, i32 addrspace(1)* %b
21+
%add.ptr = getelementptr inbounds i32, i32 addrspace(1)* %1, i64 0
22+
store i32 39, i32 addrspace(1)* %add.ptr, align 4
23+
ret void
24+
}
25+
26+
!igc.functions = !{!0}
27+
28+
!0 = !{void (i1, i64, i32 addrspace(1)*)* @test, !1}
29+
!1 = !{!2}
30+
!2 = !{!"function_type", i32 0}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
;=========================== begin_copyright_notice ============================
2+
;
3+
; Copyright (C) 2023 Intel Corporation
4+
;
5+
; SPDX-License-Identifier: MIT
6+
;
7+
;============================ end_copyright_notice =============================
8+
9+
; RUN: igc_opt --igc-scalar-arg-as-pointer-analysis --serialize-igc-metadata -S %s | FileCheck %s
10+
;
11+
; Tests "select" instruction, when second path leads to scalar as pointer.
12+
;
13+
; CHECK-NOT: !{!"m_OpenCLArgScalarAsPointersSet{{[[][0-9][]]}}", i32 0}
14+
; CHECK-NOT: !{!"m_OpenCLArgScalarAsPointersSet{{[[][0-9][]]}}", i32 1}
15+
; CHECK: !{!"m_OpenCLArgScalarAsPointersSet{{[[][0-9][]]}}", i32 2}
16+
17+
define spir_kernel void @test(i1 %s, i32 addrspace(1)* %a, i64 %b) #0 {
18+
entry:
19+
%0 = inttoptr i64 %b to i32 addrspace(1)*
20+
%1 = select i1 %s, i32 addrspace(1)* %a, i32 addrspace(1)* %0
21+
%add.ptr = getelementptr inbounds i32, i32 addrspace(1)* %1, i64 0
22+
store i32 39, i32 addrspace(1)* %add.ptr, align 4
23+
ret void
24+
}
25+
26+
!igc.functions = !{!0}
27+
28+
!0 = !{void (i1, i32 addrspace(1)*, i64)* @test, !1}
29+
!1 = !{!2}
30+
!2 = !{!"function_type", i32 0}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
;=========================== begin_copyright_notice ============================
2+
;
3+
; Copyright (C) 2023 Intel Corporation
4+
;
5+
; SPDX-License-Identifier: MIT
6+
;
7+
;============================ end_copyright_notice =============================
8+
9+
; RUN: igc_opt --igc-scalar-arg-as-pointer-analysis --serialize-igc-metadata -S %s | FileCheck %s
10+
;
11+
; Tests "select" instruction, when no path leads to scalar as pointer.
12+
;
13+
; CHECK-NOT: !{!"m_OpenCLArgScalarAsPointersSet{{[[][0-9][]]}}", i32 0}
14+
; CHECK-NOT: !{!"m_OpenCLArgScalarAsPointersSet{{[[][0-9][]]}}", i32 1}
15+
; CHECK-NOT !{!"m_OpenCLArgScalarAsPointersSet{{[[][0-9][]]}}", i32 2}
16+
17+
define spir_kernel void @test(i1 %s, i32 addrspace(1)* %a, i32 addrspace(1)* %b) #0 {
18+
entry:
19+
%0 = select i1 %s, i32 addrspace(1)* %a, i32 addrspace(1)* %b
20+
%add.ptr = getelementptr inbounds i32, i32 addrspace(1)* %0, i64 0
21+
store i32 39, i32 addrspace(1)* %add.ptr, align 4
22+
ret void
23+
}
24+
25+
!igc.functions = !{!0}
26+
27+
!0 = !{void (i1, i32 addrspace(1)*, i32 addrspace(1)*)* @test, !1}
28+
!1 = !{!2}
29+
!2 = !{!"function_type", i32 0}

0 commit comments

Comments
 (0)