Skip to content

Commit bf97252

Browse files
jzcAlexeySachkovmaarquitos14
authored
[SYCL] Propagate explicitly declared aspects even if excluded (#10650)
This PR changes `SYCLPropagateAspectsPass` to propagate aspects that come from `sycl_declared_aspects` even if they are excluded. The reason for this change is because a test like `no-fp64-optimization-declared-aspects.cpp` added in this PR would failed before with higher optimization level because - on the first aspect propagation pass, `fp64` is not propagated (to allow for trivial uses of `float x = 1.5` to optimized out) - the call to the function marked with `device_has(fp64)` is inlined on higher optimizations - that function does not actually use `double` in its body which means no usage of double ends up in the optimized function, leading the second aspect propagation pass to not attach `fp64` to its used aspects metadata. --------- Co-authored-by: Alexey Sachkov <[email protected]> Co-authored-by: Marcos Maronas <[email protected]>
1 parent 0119790 commit bf97252

File tree

3 files changed

+67
-24
lines changed

3 files changed

+67
-24
lines changed

llvm/lib/SYCLLowerIR/SYCLPropagateAspectsUsage.cpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -316,11 +316,10 @@ getAspectUsageChain(const Function *F, const FunctionToAspectsMapTy &AspectsMap,
316316
}
317317

318318
void createUsedAspectsMetadataForFunctions(
319-
FunctionToAspectsMapTy &Map, const AspectsSetTy &ExcludeAspectVals) {
320-
for (auto &[F, Aspects] : Map) {
321-
if (Aspects.empty())
322-
continue;
323-
319+
FunctionToAspectsMapTy &FunctionToUsedAspects,
320+
FunctionToAspectsMapTy &FunctionToDeclaredAspects,
321+
const AspectsSetTy &ExcludeAspectVals) {
322+
for (auto &[F, Aspects] : FunctionToUsedAspects) {
324323
LLVMContext &C = F->getContext();
325324

326325
// Create a set of unique aspects. First we add the ones from the found
@@ -330,6 +329,11 @@ void createUsedAspectsMetadataForFunctions(
330329
if (!ExcludeAspectVals.contains(A))
331330
UniqueAspects.insert(A);
332331

332+
// The aspects that were propagated via declared aspects are always
333+
// added to the metadata.
334+
for (const int &A : FunctionToDeclaredAspects[F])
335+
UniqueAspects.insert(A);
336+
333337
// If there are no new aspects, we can just keep the old metadata.
334338
if (UniqueAspects.empty())
335339
continue;
@@ -547,7 +551,7 @@ void setSyclFixedTargetsMD(const std::vector<Function *> &EntryPoints,
547551
}
548552

549553
/// Returns a map of functions with corresponding used aspects.
550-
FunctionToAspectsMapTy
554+
std::pair<FunctionToAspectsMapTy, FunctionToAspectsMapTy>
551555
buildFunctionsToAspectsMap(Module &M, TypeToAspectsMapTy &TypesWithAspects,
552556
const AspectValueToNameMapTy &AspectValues,
553557
const std::vector<Function *> &EntryPoints,
@@ -575,10 +579,9 @@ buildFunctionsToAspectsMap(Module &M, TypeToAspectsMapTy &TypesWithAspects,
575579
Visited.clear();
576580
for (Function *F : EntryPoints)
577581
propagateAspectsThroughCG(F, CG, FunctionToDeclaredAspects, Visited);
578-
for (const auto &It : FunctionToDeclaredAspects)
579-
FunctionToUsedAspects[It.first].insert(It.second.begin(), It.second.end());
580582

581-
return FunctionToUsedAspects;
583+
return {std::move(FunctionToUsedAspects),
584+
std::move(FunctionToDeclaredAspects)};
582585
}
583586

584587
} // anonymous namespace
@@ -617,8 +620,9 @@ SYCLPropagateAspectsUsagePass::run(Module &M, ModuleAnalysisManager &MAM) {
617620

618621
propagateAspectsToOtherTypesInModule(M, TypesWithAspects, AspectValues);
619622

620-
FunctionToAspectsMapTy FunctionToUsedAspects = buildFunctionsToAspectsMap(
621-
M, TypesWithAspects, AspectValues, EntryPoints, ValidateAspectUsage);
623+
auto [FunctionToUsedAspects, FunctionToDeclaredAspects] =
624+
buildFunctionsToAspectsMap(M, TypesWithAspects, AspectValues, EntryPoints,
625+
ValidateAspectUsage);
622626

623627
// Create a set of excluded aspect values.
624628
AspectsSetTy ExcludedAspectVals;
@@ -629,8 +633,8 @@ SYCLPropagateAspectsUsagePass::run(Module &M, ModuleAnalysisManager &MAM) {
629633
ExcludedAspectVals.insert(AspectValIter->second);
630634
}
631635

632-
createUsedAspectsMetadataForFunctions(FunctionToUsedAspects,
633-
ExcludedAspectVals);
636+
createUsedAspectsMetadataForFunctions(
637+
FunctionToUsedAspects, FunctionToDeclaredAspects, ExcludedAspectVals);
634638

635639
setSyclFixedTargetsMD(EntryPoints, TargetFixedAspects, AspectValues);
636640

llvm/test/SYCLLowerIR/PropagateAspectsUsage/exclude-aspect.ll

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,34 +47,38 @@ define spir_kernel void @kernel1() {
4747
ret void
4848
}
4949

50-
; funcE should get none of its explicitly declared aspects in its
50+
; funcE should get its explicitly declared aspects even if excluded
5151
; sycl_used_aspects
52-
; CHECK: define spir_func void @funcE() !sycl_declared_aspects ![[#DA1:]] {
52+
; CHECK: define spir_func void @funcE() !sycl_declared_aspects ![[#DA1:]]
53+
; CHECK-SAME: !sycl_used_aspects ![[#DA1]] {
5354
define spir_func void @funcE() !sycl_declared_aspects !10 {
5455
ret void
5556
}
5657

5758
; funcF should have the same aspects as funcE
58-
; CHECK-NOT: define spir_func void @funcF() {{.*}} !sycl_used_aspects
59+
; CHECK: define spir_func void @funcF() !sycl_used_aspects ![[#DA1]] {
5960
define spir_func void @funcF() {
6061
call spir_func void @funcE()
6162
ret void
6263
}
6364

64-
; funcG only keeps one aspect, the rest are excluded
65-
; CHECK: define spir_func void @funcG() !sycl_declared_aspects ![[#DA2:]] !sycl_used_aspects ![[#ID3:]]
65+
; aspect1 is used but excluded, aspect2 and aspect4 are declared, so
66+
; attached metadata is aspect2 and aspect4
67+
; CHECK: define spir_func void @funcG() !sycl_declared_aspects ![[#DA2:]]
68+
; CHECK-SAME: !sycl_used_aspects ![[#DA2]] {
6669
define spir_func void @funcG() !sycl_declared_aspects !11 {
70+
%tmp = alloca %B
6771
ret void
6872
}
6973

7074
; funcH should have the same aspects as funcG
71-
; CHECK: define spir_func void @funcH() !sycl_used_aspects ![[#ID3]]
75+
; CHECK: define spir_func void @funcH() !sycl_used_aspects ![[#DA2]]
7276
define spir_func void @funcH() {
7377
call spir_func void @funcG()
7478
ret void
7579
}
7680

77-
; CHECK: define spir_kernel void @kernel2() !sycl_used_aspects ![[#ID3]]
81+
; CHECK: define spir_kernel void @kernel2() !sycl_used_aspects ![[#ID5:]]
7882
define spir_kernel void @kernel2() {
7983
call spir_func void @funcF()
8084
call spir_func void @funcH()
@@ -100,7 +104,7 @@ define spir_func void @funcK() !sycl_used_aspects !11 {
100104
ret void
101105
}
102106

103-
; CHECK: define spir_func void @funcL() !sycl_used_aspects ![[#ID3]]
107+
; CHECK: define spir_func void @funcL() !sycl_used_aspects ![[#ID3:]]
104108
define spir_func void @funcL() {
105109
call spir_func void @funcK()
106110
ret void
@@ -128,12 +132,12 @@ define spir_kernel void @kernel3() {
128132
!9 = !{!"fp64", i32 5}
129133

130134
!10 = !{i32 1}
131-
!11 = !{i32 4, i32 2, i32 1}
135+
!11 = !{i32 4, i32 2}
132136
; CHECK-DAG: ![[#DA1]] = !{i32 1}
133-
; CHECK-DAG: ![[#DA2]] = !{i32 4, i32 2, i32 1}
137+
; CHECK-DAG: ![[#DA2]] = !{i32 4, i32 2}
134138

135139
; CHECK-DAG: ![[#ID0]] = !{i32 0}
136140
; CHECK-DAG: ![[#ID1]] = !{i32 2, i32 0}
137141
; CHECK-DAG: ![[#ID2]] = !{i32 0, i32 2, i32 3}
138142
; CHECK-DAG: ![[#ID3]] = !{i32 2}
139-
; CHECK-DAG: ![[#ID4]] = !{i32 2, i32 4, i32 1}
143+
; CHECK-DAG: ![[#ID4]] = !{i32 2, i32 4}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// UNSUPPORTED: aspect-fp64
2+
// RUN: %{build} -o %t.out -O3
3+
// RUN: %{run} %t.out
4+
5+
#include <sycl/sycl.hpp>
6+
7+
using namespace sycl;
8+
9+
template <aspect asp, typename T>
10+
[[sycl::device_has(asp)]] void dummy_function_decorated(const T &acc) {
11+
acc[0] = true;
12+
}
13+
14+
int main() {
15+
queue q;
16+
bool b = false;
17+
assert(!q.get_device().has(aspect::fp64));
18+
19+
buffer<bool, 1> buf(&b, 1);
20+
try {
21+
q.submit([&](handler &cgh) {
22+
accessor acc(buf, cgh);
23+
cgh.single_task([=]() { dummy_function_decorated<aspect::fp64>(acc); });
24+
});
25+
std::cout << "Exception should have been thrown!\n";
26+
return 1;
27+
} catch (const sycl::exception &e) {
28+
if (e.code() != errc::kernel_not_supported) {
29+
std::cout << "Exception caught, but wrong error code!\n";
30+
throw;
31+
}
32+
std::cout << "pass\n";
33+
return 0;
34+
}
35+
}

0 commit comments

Comments
 (0)