Skip to content

[SYCL] Enable programs that include system headers on Windows #325

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions clang/lib/Basic/Targets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,16 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,

case llvm::Triple::spir: {
if (Triple.getEnvironment() == llvm::Triple::SYCLDevice) {
switch (os) {
llvm::Triple HT(Opts.HostTriple);
switch (HT.getOS()) {
case llvm::Triple::Win32:
switch (HT.getEnvironment()) {
default: // Assume MSVC for unknown environments
case llvm::Triple::MSVC:
assert(HT.getArch() == llvm::Triple::x86 &&
"Unsupported host architecture");
return new MicrosoftX86_32SPIRTargetInfo(Triple, Opts);
}
case llvm::Triple::Linux:
return new LinuxTargetInfo<SPIR32SYCLDeviceTargetInfo>(Triple, Opts);
default:
Expand All @@ -557,7 +566,16 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,

case llvm::Triple::spir64: {
if (Triple.getEnvironment() == llvm::Triple::SYCLDevice) {
switch (os) {
llvm::Triple HT(Opts.HostTriple);
switch (HT.getOS()) {
case llvm::Triple::Win32:
switch (HT.getEnvironment()) {
default: // Assume MSVC for unknown environments
case llvm::Triple::MSVC:
assert(HT.getArch() == llvm::Triple::x86_64 &&
"Unsupported host architecture");
return new MicrosoftX86_64_SPIR64TargetInfo(Triple, Opts);
}
case llvm::Triple::Linux:
return new LinuxTargetInfo<SPIR64SYCLDeviceTargetInfo>(Triple, Opts);
default:
Expand Down
104 changes: 104 additions & 0 deletions clang/lib/Basic/Targets/SPIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "clang/Basic/TargetOptions.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
#include "OSTargets.h"

namespace clang {
namespace targets {
Expand Down Expand Up @@ -143,6 +144,7 @@ class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo {
PointerWidth = PointerAlign = 64;
SizeType = TargetInfo::UnsignedLong;
PtrDiffType = IntPtrType = TargetInfo::SignedLong;

resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
"v96:128-v192:256-v256:256-v512:512-v1024:1024");
}
Expand Down Expand Up @@ -187,6 +189,108 @@ class LLVM_LIBRARY_VISIBILITY SPIR64SYCLDeviceTargetInfo
}
};

// x86-32 SPIR Windows target
class LLVM_LIBRARY_VISIBILITY WindowsX86_32SPIRTargetInfo
: public WindowsTargetInfo<SPIR32SYCLDeviceTargetInfo> {
public:
WindowsX86_32SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: WindowsTargetInfo<SPIR32SYCLDeviceTargetInfo>(Triple, Opts) {
DoubleAlign = LongLongAlign = 64;
WCharType = UnsignedShort;
bool IsWinCOFF =
getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
resetDataLayout(IsWinCOFF
? "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
: "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32");
}

BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::CharPtrBuiltinVaList;
}

CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
if (CC == CC_X86VectorCall)
// Permit CC_X86VectorCall which is used in Microsoft headers
return CCCR_OK;
return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK
: CCCR_Warning;
}
};

// x86-32 SPIR Windows Visual Studio target
class LLVM_LIBRARY_VISIBILITY MicrosoftX86_32SPIRTargetInfo
: public WindowsX86_32SPIRTargetInfo {
public:
MicrosoftX86_32SPIRTargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts)
: WindowsX86_32SPIRTargetInfo(Triple, Opts) {
LongDoubleWidth = LongDoubleAlign = 64;
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
}

void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override {
WindowsX86_32SPIRTargetInfo::getTargetDefines(Opts, Builder);
// The value of the following reflects processor type.
// 300=386, 400=486, 500=Pentium, 600=Blend (default)
// We lost the original triple, so we use the default.
// TBD should we keep these lines? Copied from X86.h.
Builder.defineMacro("_M_IX86", "600");
}
};

// x86-64 SPIR64 Windows target
class LLVM_LIBRARY_VISIBILITY WindowsX86_64_SPIR64TargetInfo
: public WindowsTargetInfo<SPIR64SYCLDeviceTargetInfo> {
public:
WindowsX86_64_SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: WindowsTargetInfo<SPIR64SYCLDeviceTargetInfo>(Triple, Opts) {
LongWidth = LongAlign = 32;
DoubleAlign = LongLongAlign = 64;
IntMaxType = SignedLongLong;
Int64Type = SignedLongLong;
SizeType = UnsignedLongLong;
PtrDiffType = SignedLongLong;
IntPtrType = SignedLongLong;
WCharType = UnsignedShort;
bool IsWinCOFF =
getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
resetDataLayout(IsWinCOFF
? "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
: "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32");
}

BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::CharPtrBuiltinVaList;
}

CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
if (CC == CC_X86VectorCall)
// Permit CC_X86VectorCall which is used in Microsoft headers
return CCCR_OK;
return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK
: CCCR_Warning;
}
};

// x86-64 SPIR64 Windows Visual Studio target
class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64_SPIR64TargetInfo
: public WindowsX86_64_SPIR64TargetInfo {
public:
MicrosoftX86_64_SPIR64TargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts)
: WindowsX86_64_SPIR64TargetInfo(Triple, Opts) {
LongDoubleWidth = LongDoubleAlign = 64;
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
}

void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override {
WindowsX86_64_SPIR64TargetInfo::getTargetDefines(Opts, Builder);
Builder.defineMacro("_M_X64", "100");
Builder.defineMacro("_M_AMD64", "100");
}
};
} // namespace targets
} // namespace clang
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
24 changes: 20 additions & 4 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3550,14 +3550,30 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,

if (UseSYCLTriple) {
// We want to compile sycl kernels.
if (types::isCXX(Input.getType()))
CmdArgs.push_back("-std=c++11");
CmdArgs.push_back("-fsycl-is-device");
// Pass the triple of host when doing SYCL
std::string NormalizedTriple =
llvm::Triple(llvm::sys::getProcessTriple()).normalize();
auto AuxT = llvm::Triple(llvm::sys::getProcessTriple());
std::string NormalizedTriple = AuxT.normalize();
CmdArgs.push_back("-aux-triple");
CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));

bool IsMSVC = AuxT.isWindowsMSVCEnvironment();
if (types::isCXX(Input.getType()))
CmdArgs.push_back(IsMSVC ? "-std=c++14" : "-std=c++11");
if (IsMSVC) {
CmdArgs.push_back("-fms-extensions");
VersionTuple MSVT = TC.computeMSVCVersion(&D, Args);
if (!MSVT.empty())
CmdArgs.push_back(Args.MakeArgString("-fms-compatibility-version=" +
MSVT.getAsString()));
else {
const char *LowestMSVCSupported =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this 2 lines?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because clang-format

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I mean, why is LowestMSVCSupported a separate variable instead of just being a constant in the line below?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it was nicer this way, self documenting and all

"191025017"; // VS2017 v15.0 (initial release)
CmdArgs.push_back(Args.MakeArgString(
Twine("-fms-compatibility-version=") + LowestMSVCSupported));
}
}

CmdArgs.push_back("-disable-llvm-passes");
if (Args.hasFlag(options::OPT_fsycl_allow_func_ptr,
options::OPT_fno_sycl_allow_func_ptr, false)) {
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3433,6 +3433,10 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
if (LangOpts.OpenMPIsDevice)
Res.getTargetOpts().HostTriple = Res.getFrontendOpts().AuxTriple;

// Set the triple of the host for SYCL device compile.
if (LangOpts.SYCLIsDevice)
Res.getTargetOpts().HostTriple = Res.getFrontendOpts().AuxTriple;

// FIXME: Override value name discarding when asan or msan is used because the
// backend passes depend on the name of the alloca in order to print out
// names.
Expand Down
6 changes: 4 additions & 2 deletions clang/test/SemaSYCL/mangle-kernel.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// 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
// 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
// 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
// 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
#include <sycl.hpp>
#include <stdlib.h>
Expand All @@ -25,5 +26,6 @@ int main() {

// CHECK: _ZTS10SimpleVaddIiE
// CHECK: _ZTS10SimpleVaddIdE
// CHECK-64: _ZTS10SimpleVaddImE
// CHECK-64-WIN: _ZTS10SimpleVaddIyE
// CHECK-64-LIN: _ZTS10SimpleVaddImE
// CHECK-32: _ZTS10SimpleVaddIjE
7 changes: 7 additions & 0 deletions clang/test/SemaSYCL/msvc-fixes.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// RUN: %clang_cc1 -triple spir64-unknown-windows-sycldevice -fsycl-is-device -aux-triple x86_64-pc-windows-msvc -fsyntax-only -verify %s
// expected-no-diagnostics

void foo(__builtin_va_list bvl) {
char * VaList = bvl;
static_assert(sizeof(wchar_t) == 2, "sizeof wchar is 2 on Windows");
}