Skip to content

Commit e706e7c

Browse files
author
Melanie Blower
committed
[SYCL] Enable programs that include system headers on Windows
Add Windows-specific predefined type characteristics for wchar, builtin VaListKind, and allow the vectorcall attribute on function declarations. Add Windows support for SPIR target. Signed-off-by: Melanie Blower <[email protected]>
1 parent f78cf5f commit e706e7c

File tree

6 files changed

+159
-8
lines changed

6 files changed

+159
-8
lines changed

clang/lib/Basic/Targets.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,16 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
545545

546546
case llvm::Triple::spir: {
547547
if (Triple.getEnvironment() == llvm::Triple::SYCLDevice) {
548-
switch (os) {
548+
llvm::Triple HT(Opts.HostTriple);
549+
switch (HT.getOS()) {
550+
case llvm::Triple::Win32:
551+
switch (HT.getEnvironment()) {
552+
default: // Assume MSVC for unknown environments
553+
case llvm::Triple::MSVC:
554+
assert(HT.getArch() == llvm::Triple::x86 &&
555+
"Unsupported host architecture");
556+
return new MicrosoftX86_32SPIRTargetInfo(Triple, Opts);
557+
}
549558
case llvm::Triple::Linux:
550559
return new LinuxTargetInfo<SPIR32SYCLDeviceTargetInfo>(Triple, Opts);
551560
default:
@@ -557,7 +566,16 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
557566

558567
case llvm::Triple::spir64: {
559568
if (Triple.getEnvironment() == llvm::Triple::SYCLDevice) {
560-
switch (os) {
569+
llvm::Triple HT(Opts.HostTriple);
570+
switch (HT.getOS()) {
571+
case llvm::Triple::Win32:
572+
switch (HT.getEnvironment()) {
573+
default: // Assume MSVC for unknown environments
574+
case llvm::Triple::MSVC:
575+
assert(HT.getArch() == llvm::Triple::x86_64 &&
576+
"Unsupported host architecture");
577+
return new MicrosoftX86_64_SPIR64TargetInfo(Triple, Opts);
578+
}
561579
case llvm::Triple::Linux:
562580
return new LinuxTargetInfo<SPIR64SYCLDeviceTargetInfo>(Triple, Opts);
563581
default:

clang/lib/Basic/Targets/SPIR.h

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "clang/Basic/TargetOptions.h"
1818
#include "llvm/ADT/Triple.h"
1919
#include "llvm/Support/Compiler.h"
20+
#include "OSTargets.h"
2021

2122
namespace clang {
2223
namespace targets {
@@ -143,6 +144,7 @@ class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo {
143144
PointerWidth = PointerAlign = 64;
144145
SizeType = TargetInfo::UnsignedLong;
145146
PtrDiffType = IntPtrType = TargetInfo::SignedLong;
147+
146148
resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
147149
"v96:128-v192:256-v256:256-v512:512-v1024:1024");
148150
}
@@ -187,6 +189,108 @@ class LLVM_LIBRARY_VISIBILITY SPIR64SYCLDeviceTargetInfo
187189
}
188190
};
189191

192+
// x86-32 SPIR Windows target
193+
class LLVM_LIBRARY_VISIBILITY WindowsX86_32SPIRTargetInfo
194+
: public WindowsTargetInfo<SPIR32SYCLDeviceTargetInfo> {
195+
public:
196+
WindowsX86_32SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
197+
: WindowsTargetInfo<SPIR32SYCLDeviceTargetInfo>(Triple, Opts) {
198+
DoubleAlign = LongLongAlign = 64;
199+
WCharType = UnsignedShort;
200+
bool IsWinCOFF =
201+
getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
202+
resetDataLayout(IsWinCOFF
203+
? "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
204+
: "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32");
205+
}
206+
207+
BuiltinVaListKind getBuiltinVaListKind() const override {
208+
return TargetInfo::CharPtrBuiltinVaList;
209+
}
210+
211+
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
212+
if (CC == CC_X86VectorCall)
213+
// Permit CC_X86VectorCall which is used in Microsoft headers
214+
return CCCR_OK;
215+
return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK
216+
: CCCR_Warning;
217+
}
218+
};
219+
220+
// x86-32 SPIR Windows Visual Studio target
221+
class LLVM_LIBRARY_VISIBILITY MicrosoftX86_32SPIRTargetInfo
222+
: public WindowsX86_32SPIRTargetInfo {
223+
public:
224+
MicrosoftX86_32SPIRTargetInfo(const llvm::Triple &Triple,
225+
const TargetOptions &Opts)
226+
: WindowsX86_32SPIRTargetInfo(Triple, Opts) {
227+
LongDoubleWidth = LongDoubleAlign = 64;
228+
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
229+
}
230+
231+
void getTargetDefines(const LangOptions &Opts,
232+
MacroBuilder &Builder) const override {
233+
WindowsX86_32SPIRTargetInfo::getTargetDefines(Opts, Builder);
234+
// The value of the following reflects processor type.
235+
// 300=386, 400=486, 500=Pentium, 600=Blend (default)
236+
// We lost the original triple, so we use the default.
237+
// TBD should we keep these lines? Copied from X86.h.
238+
Builder.defineMacro("_M_IX86", "600");
239+
}
240+
};
241+
242+
// x86-64 SPIR64 Windows target
243+
class LLVM_LIBRARY_VISIBILITY WindowsX86_64_SPIR64TargetInfo
244+
: public WindowsTargetInfo<SPIR64SYCLDeviceTargetInfo> {
245+
public:
246+
WindowsX86_64_SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
247+
: WindowsTargetInfo<SPIR64SYCLDeviceTargetInfo>(Triple, Opts) {
248+
LongWidth = LongAlign = 32;
249+
DoubleAlign = LongLongAlign = 64;
250+
IntMaxType = SignedLongLong;
251+
Int64Type = SignedLongLong;
252+
SizeType = UnsignedLongLong;
253+
PtrDiffType = SignedLongLong;
254+
IntPtrType = SignedLongLong;
255+
WCharType = UnsignedShort;
256+
bool IsWinCOFF =
257+
getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
258+
resetDataLayout(IsWinCOFF
259+
? "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
260+
: "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32");
261+
}
262+
263+
BuiltinVaListKind getBuiltinVaListKind() const override {
264+
return TargetInfo::CharPtrBuiltinVaList;
265+
}
266+
267+
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
268+
if (CC == CC_X86VectorCall)
269+
// Permit CC_X86VectorCall which is used in Microsoft headers
270+
return CCCR_OK;
271+
return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK
272+
: CCCR_Warning;
273+
}
274+
};
275+
276+
// x86-64 SPIR64 Windows Visual Studio target
277+
class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64_SPIR64TargetInfo
278+
: public WindowsX86_64_SPIR64TargetInfo {
279+
public:
280+
MicrosoftX86_64_SPIR64TargetInfo(const llvm::Triple &Triple,
281+
const TargetOptions &Opts)
282+
: WindowsX86_64_SPIR64TargetInfo(Triple, Opts) {
283+
LongDoubleWidth = LongDoubleAlign = 64;
284+
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
285+
}
286+
287+
void getTargetDefines(const LangOptions &Opts,
288+
MacroBuilder &Builder) const override {
289+
WindowsX86_64_SPIR64TargetInfo::getTargetDefines(Opts, Builder);
290+
Builder.defineMacro("_M_X64", "100");
291+
Builder.defineMacro("_M_AMD64", "100");
292+
}
293+
};
190294
} // namespace targets
191295
} // namespace clang
192296
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3550,14 +3550,30 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
35503550

35513551
if (UseSYCLTriple) {
35523552
// We want to compile sycl kernels.
3553-
if (types::isCXX(Input.getType()))
3554-
CmdArgs.push_back("-std=c++11");
35553553
CmdArgs.push_back("-fsycl-is-device");
35563554
// Pass the triple of host when doing SYCL
3557-
std::string NormalizedTriple =
3558-
llvm::Triple(llvm::sys::getProcessTriple()).normalize();
3555+
auto AuxT = llvm::Triple(llvm::sys::getProcessTriple());
3556+
std::string NormalizedTriple = AuxT.normalize();
35593557
CmdArgs.push_back("-aux-triple");
35603558
CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));
3559+
3560+
bool IsMSVC = AuxT.isWindowsMSVCEnvironment();
3561+
if (types::isCXX(Input.getType()))
3562+
CmdArgs.push_back(IsMSVC ? "-std=c++14" : "-std=c++11");
3563+
if (IsMSVC) {
3564+
CmdArgs.push_back("-fms-extensions");
3565+
VersionTuple MSVT = TC.computeMSVCVersion(&D, Args);
3566+
if (!MSVT.empty())
3567+
CmdArgs.push_back(Args.MakeArgString("-fms-compatibility-version=" +
3568+
MSVT.getAsString()));
3569+
else {
3570+
const char *LowestMSVCSupported =
3571+
"191025017"; // VS2017 v15.0 (initial release)
3572+
CmdArgs.push_back(Args.MakeArgString(
3573+
Twine("-fms-compatibility-version=") + LowestMSVCSupported));
3574+
}
3575+
}
3576+
35613577
CmdArgs.push_back("-disable-llvm-passes");
35623578
if (Args.hasFlag(options::OPT_fsycl_allow_func_ptr,
35633579
options::OPT_fno_sycl_allow_func_ptr, false)) {

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3433,6 +3433,10 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
34333433
if (LangOpts.OpenMPIsDevice)
34343434
Res.getTargetOpts().HostTriple = Res.getFrontendOpts().AuxTriple;
34353435

3436+
// Set the triple of the host for SYCL device compile.
3437+
if (LangOpts.SYCLIsDevice)
3438+
Res.getTargetOpts().HostTriple = Res.getFrontendOpts().AuxTriple;
3439+
34363440
// FIXME: Override value name discarding when asan or msan is used because the
34373441
// backend passes depend on the name of the alloca in order to print out
34383442
// names.

clang/test/SemaSYCL/mangle-kernel.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// RUN: %clang_cc1 -triple spir64-unknown-linux-sycldevice -I %S/Inputs -I %S/../Headers/Inputs/include/ -fsycl-is-device -ast-dump %s | FileCheck %s --check-prefix=CHECK-64
1+
// RUN: %clang_cc1 -triple spir64-unknown-unknown-sycldevice -aux-triple x86_64-pc-windows-msvc -I %S/Inputs -I %S/../Headers/Inputs/include/ -fsycl-is-device -ast-dump %s | FileCheck %s --check-prefix=CHECK-64-WIN
2+
// RUN: %clang_cc1 -triple spir64-unknown-unknown-sycldevice -aux-triple x86_64-unknown-linux-gnu -I %S/Inputs -I %S/../Headers/Inputs/include/ -fsycl-is-device -ast-dump %s | FileCheck %s --check-prefix=CHECK-64-LIN
23
// RUN: %clang_cc1 -triple spir-unknown-linux-sycldevice -I %S/Inputs -I %S/../Headers/Inputs/include/ -fsycl-is-device -ast-dump %s | FileCheck %s --check-prefix=CHECK-32
34
#include <sycl.hpp>
45
#include <stdlib.h>
@@ -25,5 +26,6 @@ int main() {
2526

2627
// CHECK: _ZTS10SimpleVaddIiE
2728
// CHECK: _ZTS10SimpleVaddIdE
28-
// CHECK-64: _ZTS10SimpleVaddImE
29+
// CHECK-64-WIN: _ZTS10SimpleVaddIyE
30+
// CHECK-64-LIN: _ZTS10SimpleVaddImE
2931
// CHECK-32: _ZTS10SimpleVaddIjE

clang/test/SemaSYCL/msvc-fixes.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %clang_cc1 -triple spir64-unknown-windows-sycldevice -fsycl-is-device -aux-triple x86_64-pc-windows-msvc -fsyntax-only -verify %s
2+
// expected-no-diagnostics
3+
4+
void foo(__builtin_va_list bvl) {
5+
char * VaList = bvl;
6+
static_assert(sizeof(wchar_t) == 2, "sizeof wchar is 2 on Windows");
7+
}

0 commit comments

Comments
 (0)