[clang] a10a69f - [SPIR-V] Add SPIR-V triple and clang target info.
Anastasia Stulova via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 8 05:34:25 PST 2021
Author: Anastasia Stulova
Date: 2021-11-08T13:34:10Z
New Revision: a10a69fe9c74bef3630795d9f2f516d7b84e1cd3
URL: https://github.com/llvm/llvm-project/commit/a10a69fe9c74bef3630795d9f2f516d7b84e1cd3
DIFF: https://github.com/llvm/llvm-project/commit/a10a69fe9c74bef3630795d9f2f516d7b84e1cd3.diff
LOG: [SPIR-V] Add SPIR-V triple and clang target info.
Add new triple and target info for ‘spirv32’ and ‘spirv64’ and,
thus, enabling clang (LLVM IR) code emission to SPIR-V target.
The target for SPIR-V is mostly reused from SPIR by derivation
from a common base class since IR output for SPIR-V is mostly
the same as SPIR. Some refactoring are made accordingly.
Added and updated tests for parts that are different between
SPIR and SPIR-V.
Patch by linjamaki (Henry Linjamäki)!
Differential Revision: https://reviews.llvm.org/D109144
Added:
clang/test/CodeGenOpenCL/spirv_target.cl
Modified:
clang/include/clang/Basic/DiagnosticGroups.td
clang/lib/Basic/Targets.cpp
clang/lib/Basic/Targets/SPIR.cpp
clang/lib/Basic/Targets/SPIR.h
clang/lib/CodeGen/TargetInfo.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Frontend/InitPreprocessor.cpp
clang/lib/Headers/opencl-c-base.h
clang/lib/Headers/opencl-c.h
clang/test/Headers/opencl-c-header.cl
clang/test/Preprocessor/predefined-macros.c
llvm/include/llvm/ADT/Triple.h
llvm/lib/Support/Triple.cpp
llvm/unittests/ADT/TripleTest.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 0d8c2cb5b67d..60d417fd5770 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1264,8 +1264,9 @@ def OptionIgnored : DiagGroup<"option-ignored">;
def UnknownArgument : DiagGroup<"unknown-argument">;
// A warning group for warnings about code that clang accepts when
-// compiling OpenCL C/C++ but which is not compatible with the SPIR spec.
+// compiling OpenCL C/C++ but which is not compatible with the SPIR(-V) spec.
def SpirCompat : DiagGroup<"spir-compat">;
+def : DiagGroup<"spirv-compat", [SpirCompat]>; // Alias.
// Warning for the GlobalISel options.
def GlobalISel : DiagGroup<"global-isel">;
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 273eecbd09bf..994a491cddf2 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -606,6 +606,18 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
return nullptr;
return new SPIR64TargetInfo(Triple, Opts);
}
+ case llvm::Triple::spirv32: {
+ if (os != llvm::Triple::UnknownOS ||
+ Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
+ return nullptr;
+ return new SPIRV32TargetInfo(Triple, Opts);
+ }
+ case llvm::Triple::spirv64: {
+ if (os != llvm::Triple::UnknownOS ||
+ Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
+ return nullptr;
+ return new SPIRV64TargetInfo(Triple, Opts);
+ }
case llvm::Triple::wasm32:
if (Triple.getSubArch() != llvm::Triple::NoSubArch ||
Triple.getVendor() != llvm::Triple::UnknownVendor ||
diff --git a/clang/lib/Basic/Targets/SPIR.cpp b/clang/lib/Basic/Targets/SPIR.cpp
index 9b7aab85314a..09d482a8b9ef 100644
--- a/clang/lib/Basic/Targets/SPIR.cpp
+++ b/clang/lib/Basic/Targets/SPIR.cpp
@@ -1,4 +1,4 @@
-//===--- SPIR.cpp - Implement SPIR target feature support -----------------===//
+//===--- SPIR.cpp - Implement SPIR and SPIR-V target feature support ------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements SPIR TargetInfo objects.
+// This file implements SPIR and SPIR-V TargetInfo objects.
//
//===----------------------------------------------------------------------===//
@@ -32,3 +32,20 @@ void SPIR64TargetInfo::getTargetDefines(const LangOptions &Opts,
SPIRTargetInfo::getTargetDefines(Opts, Builder);
DefineStd(Builder, "SPIR64", Opts);
}
+
+void SPIRVTargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ DefineStd(Builder, "SPIRV", Opts);
+}
+
+void SPIRV32TargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ SPIRVTargetInfo::getTargetDefines(Opts, Builder);
+ DefineStd(Builder, "SPIRV32", Opts);
+}
+
+void SPIRV64TargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ SPIRVTargetInfo::getTargetDefines(Opts, Builder);
+ DefineStd(Builder, "SPIRV64", Opts);
+}
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 50f34abd6630..704b1843dfed 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -1,4 +1,4 @@
-//===--- SPIR.h - Declare SPIR target feature support -----------*- C++ -*-===//
+//===--- SPIR.h - Declare SPIR and SPIR-V target feature support *- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file declares SPIR TargetInfo objects.
+// This file declares SPIR and SPIR-V TargetInfo objects.
//
//===----------------------------------------------------------------------===//
@@ -21,6 +21,7 @@
namespace clang {
namespace targets {
+// Used by both the SPIR and SPIR-V targets.
static const unsigned SPIRDefIsPrivMap[] = {
0, // Default
1, // opencl_global
@@ -44,6 +45,7 @@ static const unsigned SPIRDefIsPrivMap[] = {
0 // ptr64
};
+// Used by both the SPIR and SPIR-V targets.
static const unsigned SPIRDefIsGenMap[] = {
4, // Default
// OpenCL address space values for this map are dummy and they can't be used
@@ -67,14 +69,15 @@ static const unsigned SPIRDefIsGenMap[] = {
0 // ptr64
};
-class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo {
-public:
- SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
+// Base class for SPIR and SPIR-V target info.
+class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo {
+protected:
+ BaseSPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
: TargetInfo(Triple) {
assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
- "SPIR target must use unknown OS");
+ "SPIR(-V) target must use unknown OS");
assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
- "SPIR target must use unknown environment type");
+ "SPIR(-V) target must use unknown environment type");
TLSSupported = false;
VLASupported = false;
LongWidth = LongAlign = 64;
@@ -87,13 +90,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo {
NoAsmVariants = true;
}
- void getTargetDefines(const LangOptions &Opts,
- MacroBuilder &Builder) const override;
-
- bool hasFeature(StringRef Feature) const override {
- return Feature == "spir";
- }
-
+public:
// SPIR supports the half type and the only llvm intrinsic allowed in SPIR is
// memcpy as per section 3 of the SPIR spec.
bool useFP16ConversionIntrinsics() const override { return false; }
@@ -149,7 +146,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo {
void setSupportedOpenCLOpts() override {
// Assume all OpenCL extensions and optional core features are supported
- // for SPIR since it is a generic target.
+ // for SPIR and SPIR-V since they are generic targets.
supportAllOpenCLOpts();
}
@@ -158,6 +155,24 @@ class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo {
bool hasInt128Type() const override { return false; }
};
+class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public BaseSPIRTargetInfo {
+public:
+ SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : BaseSPIRTargetInfo(Triple, Opts) {
+ assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
+ "SPIR target must use unknown OS");
+ assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
+ "SPIR target must use unknown environment type");
+ }
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+
+ bool hasFeature(StringRef Feature) const override {
+ return Feature == "spir";
+ }
+};
+
class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo {
public:
SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
@@ -187,6 +202,55 @@ class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo {
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
};
+
+class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRTargetInfo {
+public:
+ SPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : BaseSPIRTargetInfo(Triple, Opts) {
+ assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
+ "SPIR-V target must use unknown OS");
+ assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
+ "SPIR-V target must use unknown environment type");
+ }
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+
+ bool hasFeature(StringRef Feature) const override {
+ return Feature == "spirv";
+ }
+};
+
+class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public SPIRVTargetInfo {
+public:
+ SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : SPIRVTargetInfo(Triple, Opts) {
+ PointerWidth = PointerAlign = 32;
+ SizeType = TargetInfo::UnsignedInt;
+ PtrDiffType = IntPtrType = TargetInfo::SignedInt;
+ resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
+ "v96:128-v192:256-v256:256-v512:512-v1024:1024");
+ }
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public SPIRVTargetInfo {
+public:
+ SPIRV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : SPIRVTargetInfo(Triple, Opts) {
+ 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");
+ }
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+};
+
} // namespace targets
} // namespace clang
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index c76346337dc9..302dc653c46e 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -10169,24 +10169,26 @@ void XCoreTargetCodeGenInfo::emitTargetMetadata(
}
}
}
+
//===----------------------------------------------------------------------===//
-// SPIR ABI Implementation
+// Base ABI and target codegen info implementation common between SPIR and
+// SPIR-V.
//===----------------------------------------------------------------------===//
namespace {
-class SPIRABIInfo : public DefaultABIInfo {
+class CommonSPIRABIInfo : public DefaultABIInfo {
public:
- SPIRABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) { setCCs(); }
+ CommonSPIRABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) { setCCs(); }
private:
void setCCs();
};
} // end anonymous namespace
namespace {
-class SPIRTargetCodeGenInfo : public TargetCodeGenInfo {
+class CommonSPIRTargetCodeGenInfo : public TargetCodeGenInfo {
public:
- SPIRTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)
- : TargetCodeGenInfo(std::make_unique<SPIRABIInfo>(CGT)) {}
+ CommonSPIRTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)
+ : TargetCodeGenInfo(std::make_unique<CommonSPIRABIInfo>(CGT)) {}
LangAS getASTAllocaAddressSpace() const override {
return getLangASFromTargetAS(
@@ -10197,7 +10199,7 @@ class SPIRTargetCodeGenInfo : public TargetCodeGenInfo {
};
} // End anonymous namespace.
-void SPIRABIInfo::setCCs() {
+void CommonSPIRABIInfo::setCCs() {
assert(getRuntimeCC() == llvm::CallingConv::C);
RuntimeCC = llvm::CallingConv::SPIR_FUNC;
}
@@ -10211,7 +10213,7 @@ void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI) {
}
}
-unsigned SPIRTargetCodeGenInfo::getOpenCLKernelCallingConv() const {
+unsigned CommonSPIRTargetCodeGenInfo::getOpenCLKernelCallingConv() const {
return llvm::CallingConv::SPIR_KERNEL;
}
@@ -11280,7 +11282,9 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
return SetCGInfo(new ARCTargetCodeGenInfo(Types));
case llvm::Triple::spir:
case llvm::Triple::spir64:
- return SetCGInfo(new SPIRTargetCodeGenInfo(Types));
+ case llvm::Triple::spirv32:
+ case llvm::Triple::spirv64:
+ return SetCGInfo(new CommonSPIRTargetCodeGenInfo(Types));
case llvm::Triple::ve:
return SetCGInfo(new VETargetCodeGenInfo(Types));
}
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 56fe3ca59988..dc20ae05ed41 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4411,7 +4411,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
TC.addClangWarningOptions(CmdArgs);
// FIXME: Subclass ToolChain for SPIR and move this to addClangWarningOptions.
- if (Triple.isSPIR())
+ if (Triple.isSPIR() || Triple.isSPIRV())
CmdArgs.push_back("-Wspir-compat");
// Select the appropriate action.
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 002456867b0a..fe6503929150 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -1182,7 +1182,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
if (LangOpts.OpenCL) {
InitializeOpenCLFeatureTestMacros(TI, LangOpts, Builder);
- if (TI.getTriple().isSPIR())
+ if (TI.getTriple().isSPIR() || TI.getTriple().isSPIRV())
Builder.defineMacro("__IMAGE_SUPPORT__");
}
diff --git a/clang/lib/Headers/opencl-c-base.h b/clang/lib/Headers/opencl-c-base.h
index a36e657612e5..9c81ddb5e2a7 100644
--- a/clang/lib/Headers/opencl-c-base.h
+++ b/clang/lib/Headers/opencl-c-base.h
@@ -12,8 +12,8 @@
// Define extension macros
#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200)
-// For SPIR all extensions are supported.
-#if defined(__SPIR__)
+// For SPIR and SPIR-V all extensions are supported.
+#if defined(__SPIR__) || defined(__SPIRV__)
#define cl_khr_subgroup_extended_types 1
#define cl_khr_subgroup_non_uniform_vote 1
#define cl_khr_subgroup_ballot 1
@@ -45,7 +45,7 @@
#define __opencl_c_ext_fp32_global_atomic_min_max 1
#define __opencl_c_ext_fp32_local_atomic_min_max 1
-#endif // defined(__SPIR__)
+#endif // defined(__SPIR__) || defined(__SPIRV__)
#endif // (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200)
// Define feature macros for OpenCL C 2.0
@@ -65,8 +65,8 @@
// Define header-only feature macros for OpenCL C 3.0.
#if (__OPENCL_CPP_VERSION__ == 202100 || __OPENCL_C_VERSION__ == 300)
-// For the SPIR target all features are supported.
-#if defined(__SPIR__)
+// For the SPIR and SPIR-V target all features are supported.
+#if defined(__SPIR__) || defined(__SPIRV__)
#define __opencl_c_atomic_scope_all_devices 1
#endif // defined(__SPIR__)
#endif // (__OPENCL_CPP_VERSION__ == 202100 || __OPENCL_C_VERSION__ == 300)
diff --git a/clang/lib/Headers/opencl-c.h b/clang/lib/Headers/opencl-c.h
index f3a9ecdec65c..32af848a94c4 100644
--- a/clang/lib/Headers/opencl-c.h
+++ b/clang/lib/Headers/opencl-c.h
@@ -23,11 +23,14 @@
#endif //cl_khr_3d_image_writes
#endif //__OPENCL_C_VERSION__ < CL_VERSION_2_0
-
-#if (defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_1_2)) && defined(__SPIR__)
+#if (defined(__OPENCL_CPP_VERSION__) || \
+ (__OPENCL_C_VERSION__ >= CL_VERSION_1_2)) && \
+ (defined(__SPIR__) || defined(__SPIRV__))
#pragma OPENCL EXTENSION cl_intel_planar_yuv : begin
#pragma OPENCL EXTENSION cl_intel_planar_yuv : end
-#endif // (defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_1_2)) && defined(__SPIR__)
+#endif // (defined(__OPENCL_CPP_VERSION__) ||
+ // (__OPENCL_C_VERSION__ >= CL_VERSION_1_2)) &&
+ // (defined(__SPIR__) || defined(__SPIRV__))
#define __ovld __attribute__((overloadable))
#define __conv __attribute__((convergent))
diff --git a/clang/test/CodeGenOpenCL/spirv_target.cl b/clang/test/CodeGenOpenCL/spirv_target.cl
new file mode 100644
index 000000000000..07c4bde78a1a
--- /dev/null
+++ b/clang/test/CodeGenOpenCL/spirv_target.cl
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 %s -triple "spirv32-unknown-unknown" -verify -emit-llvm -o - | FileCheck %s -check-prefix=SPIRV32
+// RUN: %clang_cc1 %s -triple "spirv64-unknown-unknown" -verify -emit-llvm -o - | FileCheck %s -check-prefix=SPIRV64
+
+// SPIRV32: target triple = "spirv32-unknown-unknown"
+// SPIRV64: target triple = "spirv64-unknown-unknown"
+
+typedef struct {
+ char c;
+ void *v;
+ void *v2;
+} my_st;
+
+kernel void foo(global long *arg) {
+#if __SPIRV32__ == 1
+ int res1[sizeof(my_st) == 12 ? 1 : -1]; // expected-no-diagnostics
+ int res2[sizeof(void *) == 4 ? 1 : -1]; // expected-no-diagnostics
+ int res3[sizeof(arg) == 4 ? 1 : -1]; // expected-no-diagnostics
+#elif __SPIRV64__ == 1
+ int res1[sizeof(my_st) == 24 ? 1 : -1]; // expected-no-diagnostics
+ int res2[sizeof(void *) == 8 ? 1 : -1]; // expected-no-diagnostics
+ int res3[sizeof(arg) == 8 ? 1 : -1]; // expected-no-diagnostics
+#endif
+ my_st *tmp = 0;
+
+ // SPIRV32: store i64 4, i64 addrspace(1)*
+ // SPIRV64: store i64 8, i64 addrspace(1)*
+ arg[0] = (long)(&tmp->v);
+ // SPIRV32: store i64 8, i64 addrspace(1)*
+ // SPIRV64: store i64 16, i64 addrspace(1)*
+ arg[1] = (long)(&tmp->v2);
+}
diff --git a/clang/test/Headers/opencl-c-header.cl b/clang/test/Headers/opencl-c-header.cl
index bcce9623fafc..be185ff8dcf1 100644
--- a/clang/test/Headers/opencl-c-header.cl
+++ b/clang/test/Headers/opencl-c-header.cl
@@ -5,6 +5,9 @@
// RUN: %clang_cc1 -O0 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -verify -cl-std=CL3.0 | FileCheck %s
// RUN: %clang_cc1 -O0 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -verify -cl-std=clc++2021 | FileCheck %s
+// RUN: %clang_cc1 -O0 -triple spirv32-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -verify | FileCheck %s
+
+
// Test including the default header as a module.
// The module should be compiled only once and loaded from cache afterwards.
// Change the directory mode to read only to make sure no new modules are created.
@@ -91,7 +94,7 @@ global atomic_int z = ATOMIC_VAR_INIT(99);
// Check that extension macros are defined correctly.
// For SPIR all extensions are supported.
-#if defined(__SPIR__)
+#if defined(__SPIR__) || defined(__SPIRV__)
// Verify that cl_intel_planar_yuv extension is defined from OpenCL 1.2 onwards.
#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_1_2)
diff --git a/clang/test/Preprocessor/predefined-macros.c b/clang/test/Preprocessor/predefined-macros.c
index 14b2d9529e9c..46dd76b6fc56 100644
--- a/clang/test/Preprocessor/predefined-macros.c
+++ b/clang/test/Preprocessor/predefined-macros.c
@@ -210,7 +210,21 @@
// CHECK-SPIR64-DAG: #define __SPIR64__ 1
// CHECK-SPIR64-NOT: #define __SPIR32__ 1
-// RUN: %clang_cc1 %s -E -dM -o - -x hip -triple amdgcn-amd-amdhsa \
+// RUN: %clang_cc1 %s -E -dM -o - -x cl -triple spirv32-unknown-unknown \
+// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-SPIRV32
+// CHECK-SPIRV32-DAG: #define __IMAGE_SUPPORT__ 1
+// CHECK-SPIRV32-DAG: #define __SPIRV__ 1
+// CHECK-SPIRV32-DAG: #define __SPIRV32__ 1
+// CHECK-SPIRV32-NOT: #define __SPIRV64__ 1
+
+// RUN: %clang_cc1 %s -E -dM -o - -x cl -triple spirv64-unknown-unknown \
+// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-SPIRV64
+// CHECK-SPIRV64-DAG: #define __IMAGE_SUPPORT__ 1
+// CHECK-SPIRV64-DAG: #define __SPIRV__ 1
+// CHECK-SPIRV64-DAG: #define __SPIRV64__ 1
+// CHECK-SPIRV64-NOT: #define __SPIRV32__ 1
+
+// RUN: %clang_cc1 %s -E -dM -o - -x hip -triple amdgcn-amd-amdhsa \
// RUN: | FileCheck -match-full-lines %s --check-prefix=CHECK-HIP
// CHECK-HIP-NOT: #define __CUDA_ARCH__
// CHECK-HIP: #define __HIPCC__ 1
diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h
index c848314cd9e9..2fd3047acbfd 100644
--- a/llvm/include/llvm/ADT/Triple.h
+++ b/llvm/include/llvm/ADT/Triple.h
@@ -93,6 +93,8 @@ class Triple {
hsail64, // AMD HSAIL with 64-bit pointers
spir, // SPIR: standard portable IR for OpenCL 32-bit version
spir64, // SPIR: standard portable IR for OpenCL 64-bit version
+ spirv32, // SPIR-V with 32-bit pointers
+ spirv64, // SPIR-V with 64-bit pointers
kalimba, // Kalimba: generic kalimba
shave, // SHAVE: Movidius vector VLIW processors
lanai, // Lanai: Lanai 32-bit
@@ -699,6 +701,11 @@ class Triple {
return getArch() == Triple::spir || getArch() == Triple::spir64;
}
+ /// Tests whether the target is SPIR-V (32/64-bit).
+ bool isSPIRV() const {
+ return getArch() == Triple::spirv32 || getArch() == Triple::spirv64;
+ }
+
/// Tests whether the target is NVPTX (32- or 64-bit).
bool isNVPTX() const {
return getArch() == Triple::nvptx || getArch() == Triple::nvptx64;
diff --git a/llvm/lib/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp
index df43ec15eb58..b9a92e280576 100644
--- a/llvm/lib/Support/Triple.cpp
+++ b/llvm/lib/Support/Triple.cpp
@@ -67,6 +67,8 @@ StringRef Triple::getArchTypeName(ArchType Kind) {
case sparcv9: return "sparcv9";
case spir64: return "spir64";
case spir: return "spir";
+ case spirv32: return "spirv32";
+ case spirv64: return "spirv64";
case systemz: return "s390x";
case tce: return "tce";
case tcele: return "tcele";
@@ -147,6 +149,10 @@ StringRef Triple::getArchTypePrefix(ArchType Kind) {
case spir:
case spir64: return "spir";
+
+ case spirv32:
+ case spirv64: return "spirv";
+
case kalimba: return "kalimba";
case lanai: return "lanai";
case shave: return "shave";
@@ -323,6 +329,8 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
.Case("hsail64", hsail64)
.Case("spir", spir)
.Case("spir64", spir64)
+ .Case("spirv32", spirv32)
+ .Case("spirv64", spirv64)
.Case("kalimba", kalimba)
.Case("lanai", lanai)
.Case("shave", shave)
@@ -456,6 +464,8 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Case("hsail64", Triple::hsail64)
.Case("spir", Triple::spir)
.Case("spir64", Triple::spir64)
+ .Case("spirv32", Triple::spirv32)
+ .Case("spirv64", Triple::spirv64)
.StartsWith("kalimba", Triple::kalimba)
.Case("lanai", Triple::lanai)
.Case("renderscript32", Triple::renderscript32)
@@ -759,6 +769,11 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::wasm32:
case Triple::wasm64:
return Triple::Wasm;
+
+ case Triple::spirv32:
+ case Triple::spirv64:
+ // TODO: In future this will be Triple::SPIRV.
+ return Triple::UnknownObjectFormat;
}
llvm_unreachable("unknown architecture");
}
@@ -1328,6 +1343,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::sparc:
case llvm::Triple::sparcel:
case llvm::Triple::spir:
+ case llvm::Triple::spirv32:
case llvm::Triple::tce:
case llvm::Triple::tcele:
case llvm::Triple::thumb:
@@ -1354,6 +1370,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::riscv64:
case llvm::Triple::sparcv9:
case llvm::Triple::spir64:
+ case llvm::Triple::spirv64:
case llvm::Triple::systemz:
case llvm::Triple::ve:
case llvm::Triple::wasm64:
@@ -1413,6 +1430,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::sparc:
case Triple::sparcel:
case Triple::spir:
+ case Triple::spirv32:
case Triple::tce:
case Triple::tcele:
case Triple::thumb:
@@ -1441,6 +1459,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::riscv64: T.setArch(Triple::riscv32); break;
case Triple::sparcv9: T.setArch(Triple::sparc); break;
case Triple::spir64: T.setArch(Triple::spir); break;
+ case Triple::spirv64: T.setArch(Triple::spirv32); break;
case Triple::wasm64: T.setArch(Triple::wasm32); break;
case Triple::x86_64: T.setArch(Triple::x86); break;
}
@@ -1485,6 +1504,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::riscv64:
case Triple::sparcv9:
case Triple::spir64:
+ case Triple::spirv64:
case Triple::systemz:
case Triple::ve:
case Triple::wasm64:
@@ -1511,6 +1531,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::riscv32: T.setArch(Triple::riscv64); break;
case Triple::sparc: T.setArch(Triple::sparcv9); break;
case Triple::spir: T.setArch(Triple::spir64); break;
+ case Triple::spirv32: T.setArch(Triple::spirv64); break;
case Triple::thumb: T.setArch(Triple::aarch64); break;
case Triple::thumbeb: T.setArch(Triple::aarch64_be); break;
case Triple::wasm32: T.setArch(Triple::wasm64); break;
@@ -1547,6 +1568,8 @@ Triple Triple::getBigEndianArchVariant() const {
case Triple::shave:
case Triple::spir64:
case Triple::spir:
+ case Triple::spirv32:
+ case Triple::spirv64:
case Triple::wasm32:
case Triple::wasm64:
case Triple::x86:
@@ -1650,6 +1673,8 @@ bool Triple::isLittleEndian() const {
case Triple::sparcel:
case Triple::spir64:
case Triple::spir:
+ case Triple::spirv32:
+ case Triple::spirv64:
case Triple::tcele:
case Triple::thumb:
case Triple::ve:
diff --git a/llvm/unittests/ADT/TripleTest.cpp b/llvm/unittests/ADT/TripleTest.cpp
index a275732ed6eb..a6a79ed5a39e 100644
--- a/llvm/unittests/ADT/TripleTest.cpp
+++ b/llvm/unittests/ADT/TripleTest.cpp
@@ -224,6 +224,16 @@ TEST(TripleTest, ParsedIDs) {
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::UnknownOS, T.getOS());
+ T = Triple("spirv32-unknown-unknown");
+ EXPECT_EQ(Triple::spirv32, T.getArch());
+ EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+ EXPECT_EQ(Triple::UnknownOS, T.getOS());
+
+ T = Triple("spirv64-unknown-unknown");
+ EXPECT_EQ(Triple::spirv64, T.getArch());
+ EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+ EXPECT_EQ(Triple::UnknownOS, T.getOS());
+
T = Triple("x86_64-unknown-ananas");
EXPECT_EQ(Triple::x86_64, T.getArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
@@ -865,6 +875,16 @@ TEST(TripleTest, BitWidthPredicates) {
EXPECT_FALSE(T.isArch32Bit());
EXPECT_TRUE(T.isArch64Bit());
+ T.setArch(Triple::spirv32);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_TRUE(T.isArch32Bit());
+ EXPECT_FALSE(T.isArch64Bit());
+
+ T.setArch(Triple::spirv64);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_FALSE(T.isArch32Bit());
+ EXPECT_TRUE(T.isArch64Bit());
+
T.setArch(Triple::sparc);
EXPECT_FALSE(T.isArch16Bit());
EXPECT_TRUE(T.isArch32Bit());
@@ -1032,6 +1052,14 @@ TEST(TripleTest, BitWidthArchVariants) {
EXPECT_EQ(Triple::spir, T.get32BitArchVariant().getArch());
EXPECT_EQ(Triple::spir64, T.get64BitArchVariant().getArch());
+ T.setArch(Triple::spirv32);
+ EXPECT_EQ(Triple::spirv32, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::spirv64, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::spirv64);
+ EXPECT_EQ(Triple::spirv32, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::spirv64, T.get64BitArchVariant().getArch());
+
T.setArch(Triple::wasm32);
EXPECT_EQ(Triple::wasm32, T.get32BitArchVariant().getArch());
EXPECT_EQ(Triple::wasm64, T.get64BitArchVariant().getArch());
More information about the cfe-commits
mailing list