Skip to content

Commit 38ae73a

Browse files
Merge branch 'sycl' into enable_spirv_test
2 parents c1f93c0 + fb8d4ab commit 38ae73a

File tree

285 files changed

+3141
-1446
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

285 files changed

+3141
-1446
lines changed

.github/workflows/sycl-linux-precommit.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,42 @@ jobs:
6262
e2e_binaries_artifact: e2e_bin
6363
e2e_binaries_preview_artifact: e2e_bin_preview
6464

65+
# Build and run native cpu e2e tests separately as cannot currently
66+
# build all the e2e tests
67+
build_run_native_cpu_e2e_tests:
68+
if: ${{ always() && !cancelled() && needs.build.outputs.build_conclusion == 'success' }}
69+
runs-on: [Linux, build]
70+
needs: [build]
71+
container:
72+
image: ghcr.io/intel/llvm/sycl_ubuntu2404_nightly:latest
73+
options: -u 1001:1001
74+
steps:
75+
- uses: actions/checkout@v4
76+
with:
77+
sparse-checkout: |
78+
devops/
79+
80+
# download build artefact
81+
- name: Download toolchain
82+
uses: actions/download-artifact@v4
83+
with:
84+
name: sycl_linux_default
85+
- name: Extract SYCL toolchain
86+
shell: bash
87+
run: |
88+
mkdir toolchain
89+
tar -xf llvm_sycl.tar.zst -C toolchain
90+
rm llvm_sycl.tar.zst
91+
- name: Build and run E2E tests
92+
uses: ./devops/actions/run-tests/e2e
93+
with:
94+
ref: ${{ inputs.ref || github.sha }}
95+
testing_mode: full
96+
target_devices: native_cpu:cpu
97+
sycl_compiler: $GITHUB_WORKSPACE/toolchain/bin/clang++
98+
extra_lit_opts: --param sycl_build_targets="native_cpu"
99+
extra_cmake_args: -DSYCL_TEST_E2E_TARGETS="native_cpu:cpu" -DSYCL_TEST_E2E_STANDALONE=ON
100+
65101
# If a PR changes CUDA adapter, run the build on Ubuntu 22.04 as well.
66102
# Ubuntu 22.04 container has CUDA 12.1 installed while Ubuntu 24.0 image
67103
# has CUDA 12.6.1 installed.

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10097,8 +10097,13 @@ void OffloadWrapper::ConstructJob(Compilation &C, const JobAction &JA,
1009710097
// clang-offload-wrapper
1009810098
// -o=<outputfile>.bc
1009910099
// -host=x86_64-pc-linux-gnu -kind=sycl
10100+
#ifndef __INTEL_PREVIEW_BREAKING_CHANGES
1010010101
// -format=spirv <inputfile1>.spv <manifest1>(optional)
1010110102
// -format=spirv <inputfile2>.spv <manifest2>(optional)
10103+
#else
10104+
// -format=spirv <inputfile1>.spv
10105+
// -format=spirv <inputfile2>.spv
10106+
#endif
1010210107
// ...
1010310108
ArgStringList WrapperArgs;
1010410109

@@ -10163,6 +10168,12 @@ void OffloadWrapper::ConstructJob(Compilation &C, const JobAction &JA,
1016310168
WrapperArgs.push_back(
1016410169
C.getArgs().MakeArgString(Twine("-kind=") + Twine(Kind)));
1016510170

10171+
// Enable preview breaking changes in clang-offload-wrapper,
10172+
// in case it needs to introduce any ABI breaking changes.
10173+
// For example, changes in offload binary descriptor format.
10174+
if (C.getArgs().hasArg(options::OPT_fpreview_breaking_changes))
10175+
WrapperArgs.push_back("-fpreview-breaking-changes");
10176+
1016610177
assert((Inputs.size() > 0) && "no inputs for clang-offload-wrapper");
1016710178
assert(((Inputs[0].getType() != types::TY_Tempfiletable) ||
1016810179
(Inputs.size() == 1)) &&
@@ -11580,6 +11591,12 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
1158011591
Args.MakeArgString("--wrapper-jobs=" + Twine(NumThreads)));
1158111592
}
1158211593

11594+
// Enable preview breaking changes in clang-linker-wrapper,
11595+
// in case it needs to introduce any ABI breaking changes.
11596+
// For example, changes in offload binary descriptor format.
11597+
if (Args.hasArg(options::OPT_fpreview_breaking_changes))
11598+
CmdArgs.push_back("-fpreview-breaking-changes");
11599+
1158311600
const char *Exec =
1158411601
Args.MakeArgString(getToolChain().GetProgramPath("clang-linker-wrapper"));
1158511602

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6626,10 +6626,12 @@ class FreeFunctionPrinter {
66266626
raw_ostream &O;
66276627
PrintingPolicy &Policy;
66286628
bool NSInserted = false;
6629+
ASTContext &Context;
66296630

66306631
public:
6631-
FreeFunctionPrinter(raw_ostream &O, PrintingPolicy &PrintPolicy)
6632-
: O(O), Policy(PrintPolicy) {}
6632+
FreeFunctionPrinter(raw_ostream &O, PrintingPolicy &PrintPolicy,
6633+
ASTContext &Context)
6634+
: O(O), Policy(PrintPolicy), Context(Context) {}
66336635

66346636
/// Emits the function declaration of template free function.
66356637
/// \param FTD The function declaration to print.
@@ -6822,22 +6824,46 @@ class FreeFunctionPrinter {
68226824
continue;
68236825
}
68246826

6825-
TemplateName TN = TST->getTemplateName();
6826-
auto SpecArgs = TST->template_arguments();
6827-
auto DeclArgs = CTST->template_arguments();
6828-
6829-
TN.getAsTemplateDecl()->printQualifiedName(ParmListOstream);
6827+
TemplateName CTN = CTST->getTemplateName();
6828+
CTN.getAsTemplateDecl()->printQualifiedName(ParmListOstream);
68306829
ParmListOstream << "<";
68316830

6831+
ArrayRef<TemplateArgument> SpecArgs = TST->template_arguments();
6832+
ArrayRef<TemplateArgument> DeclArgs = CTST->template_arguments();
6833+
6834+
auto TemplateArgPrinter = [&](const TemplateArgument &Arg) {
6835+
if (Arg.getKind() != TemplateArgument::ArgKind::Expression ||
6836+
Arg.isInstantiationDependent()) {
6837+
Arg.print(Policy, ParmListOstream, /* IncludeType = */ false);
6838+
return;
6839+
}
6840+
6841+
Expr *E = Arg.getAsExpr();
6842+
assert(E && "Failed to get an Expr for an Expression template arg?");
6843+
if (E->getType().getTypePtr()->isScopedEnumeralType()) {
6844+
// Scoped enumerations can't be implicitly cast from integers, so
6845+
// we don't need to evaluate them.
6846+
Arg.print(Policy, ParmListOstream, /* IncludeType = */ false);
6847+
return;
6848+
}
6849+
6850+
Expr::EvalResult Res;
6851+
[[maybe_unused]] bool Success =
6852+
Arg.getAsExpr()->EvaluateAsConstantExpr(Res, Context);
6853+
assert(Success && "invalid non-type template argument?");
6854+
assert(!Res.Val.isAbsent() && "couldn't read the evaulation result?");
6855+
Res.Val.printPretty(ParmListOstream, Policy, Arg.getAsExpr()->getType(),
6856+
&Context);
6857+
};
6858+
68326859
for (size_t I = 0, E = std::max(DeclArgs.size(), SpecArgs.size()),
68336860
SE = SpecArgs.size();
68346861
I < E; ++I) {
68356862
if (I != 0)
68366863
ParmListOstream << ", ";
6837-
if (I < SE) // A specialized argument exists, use it
6838-
SpecArgs[I].print(Policy, ParmListOstream, false /* IncludeType */);
6839-
else // Print a canonical form of a default argument
6840-
DeclArgs[I].print(Policy, ParmListOstream, false /* IncludeType */);
6864+
// If we have a specialized argument, use it. Otherwise fallback to a
6865+
// default argument.
6866+
TemplateArgPrinter(I < SE ? SpecArgs[I] : DeclArgs[I]);
68416867
}
68426868

68436869
ParmListOstream << ">";
@@ -7236,7 +7262,7 @@ void SYCLIntegrationHeader::emit(raw_ostream &O) {
72367262
// template arguments that match default template arguments while printing
72377263
// template-ids, even if the source code doesn't reference them.
72387264
Policy.EnforceDefaultTemplateArgs = true;
7239-
FreeFunctionPrinter FFPrinter(O, Policy);
7265+
FreeFunctionPrinter FFPrinter(O, Policy, S.getASTContext());
72407266
if (FTD) {
72417267
FFPrinter.printFreeFunctionDeclaration(FTD);
72427268
if (const auto kind = K.SyclKernel->getTemplateSpecializationKind();
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// RUN: %clang_cc1 -fsycl-is-device -internal-isystem %S/Inputs -triple spir64-unknown-unknown -sycl-std=2020 -fsycl-int-header=%t.h %s
2+
// RUN: FileCheck -input-file=%t.h %s
3+
//
4+
// The purpose of this test is to ensure that forward declarations of free
5+
// function kernels are emitted properly.
6+
// However, this test checks a specific scenario:
7+
// - free function argument is a template which accepts constant expressions as
8+
// arguments
9+
10+
constexpr int A = 2;
11+
constexpr int B = 3;
12+
13+
namespace ns {
14+
15+
constexpr int C = 4;
16+
17+
struct Foo {
18+
static constexpr int D = 5;
19+
};
20+
21+
enum non_class_enum {
22+
VAL_A,
23+
VAL_B
24+
};
25+
26+
enum class class_enum {
27+
VAL_A,
28+
VAL_B
29+
};
30+
31+
enum non_class_enum_typed : int {
32+
VAL_C,
33+
VAL_D
34+
};
35+
36+
enum class class_enum_typed : int {
37+
VAL_C,
38+
VAL_D
39+
};
40+
41+
constexpr int bar(int arg) {
42+
return arg + 42;
43+
}
44+
45+
} // namespace ns
46+
47+
template<int V>
48+
struct Arg {};
49+
50+
template<ns::non_class_enum V>
51+
struct Arg2 {};
52+
53+
template<ns::non_class_enum_typed V>
54+
struct Arg3 {};
55+
56+
template<ns::class_enum V>
57+
struct Arg4 {};
58+
59+
template<ns::class_enum_typed V>
60+
struct Arg5 {};
61+
62+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
63+
void constant(Arg<1>) {}
64+
65+
// CHECK: void constant(Arg<1> );
66+
67+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
68+
void constexpr_v(Arg<A>) {}
69+
70+
// CHECK: void constexpr_v(Arg<2> );
71+
72+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
73+
void constexpr_expr(Arg<A * B>) {}
74+
75+
// CHECK: void constexpr_expr(Arg<6> );
76+
77+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
78+
void constexpr_ns(Arg<ns::C>) {}
79+
80+
// CHECK: void constexpr_ns(Arg<4> );
81+
82+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
83+
void constexpr_ns2(Arg<ns::Foo::D>) {}
84+
85+
// CHECK: void constexpr_ns2(Arg<5> );
86+
87+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
88+
void constexpr_ns2(Arg2<ns::non_class_enum::VAL_A>) {}
89+
90+
// CHECK: void constexpr_ns2(Arg2<ns::VAL_A> );
91+
92+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
93+
void constexpr_ns2(Arg3<ns::non_class_enum_typed::VAL_C>) {}
94+
95+
// CHECK: void constexpr_ns2(Arg3<ns::VAL_C> );
96+
97+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
98+
void constexpr_ns2(Arg4<ns::class_enum::VAL_A>) {}
99+
100+
// CHECK: void constexpr_ns2(Arg4<ns::class_enum::VAL_A> );
101+
102+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
103+
void constexpr_ns2(Arg5<ns::class_enum_typed::VAL_C>) {}
104+
105+
// CHECK: void constexpr_ns2(Arg5<ns::class_enum_typed::VAL_C> );
106+
107+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
108+
void constexpr_call(Arg<ns::bar(B)>) {}
109+
110+
// CHECK: void constexpr_call(Arg<45> );
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// RUN: %clang_cc1 -fsycl-is-device -internal-isystem %S/Inputs -triple spir64-unknown-unknown -sycl-std=2020 -fsycl-int-header=%t.h %s
2+
// RUN: FileCheck -input-file=%t.h %s
3+
//
4+
// The purpose of this test is to ensure that forward declarations of free
5+
// function kernels are emitted properly.
6+
// However, this test checks a specific scenario:
7+
// - free function arguments are type aliases (through using or typedef)
8+
9+
namespace ns {
10+
11+
using IntUsing = int;
12+
typedef int IntTypedef;
13+
14+
template <typename T>
15+
struct Foo {};
16+
17+
using FooIntUsing = Foo<int>;
18+
typedef Foo<int> FooIntTypedef;
19+
20+
template <typename T1, typename T2>
21+
struct Bar {};
22+
23+
template<typename T1>
24+
using BarUsing = Bar<T1, float>;
25+
26+
class Baz {
27+
public:
28+
using type = BarUsing<double>;
29+
};
30+
31+
} // namespace ns
32+
33+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
34+
void int_using(ns::IntUsing Arg) {}
35+
36+
// CHECK: void int_using(int Arg);
37+
38+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
39+
void int_typedef(ns::IntTypedef Arg) {}
40+
41+
// CHECK: void int_typedef(int Arg);
42+
43+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
44+
void foo_using(ns::FooIntUsing Arg) {}
45+
46+
// CHECK: void foo_using(ns::Foo<int> Arg);
47+
48+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
49+
void foo_typedef(ns::FooIntTypedef Arg) {}
50+
51+
// CHECK: void foo_typedef(ns::Foo<int> Arg);
52+
53+
template<typename T>
54+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
55+
void bar_using(ns::BarUsing<T> Arg) {}
56+
template void bar_using(ns::BarUsing<int>);
57+
58+
// CHECK: template <typename T> void bar_using(ns::Bar<T, float>);
59+
60+
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
61+
void baz_type(ns::Baz::type Arg) {}
62+
63+
// CHECK: void baz_type(ns::Bar<double, float> Arg);

0 commit comments

Comments
 (0)