mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-02 13:26:06 +00:00

The SPIR target currently allows for half precision floating point types to be emitted using the LLVM intrinsic functions which convert half types to floats and doubles. However, this is illegal in SPIR as the only intrinsic allowed by SPIR is memcpy, as per section 3 of the SPIR specification. Currently this is leading to an assert being hit in the Clang CodeGen when attempting to emit a constant or literal _Float16 type in a comparison operation on a SPIR or SPIR64 target. This assert stems from the CodeGen attempting to emit a constant half value as an integer because the backend has specified that it is using these half conversion intrinsics (which represents half as i16). This patch prevents SPIR targets from using these intrinsics by overloading the responsible target info method, marks SPIR targets as having a legal half type and provides additional regression testing for the _Float16 type on SPIR targets. Patch by: Stephen McGroarty Differential Revision: https://reviews.llvm.org/D48188 llvm-svn: 335111
133 lines
4.4 KiB
C++
133 lines
4.4 KiB
C++
//===--- SPIR.h - Declare SPIR target feature support -----------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file declares SPIR TargetInfo objects.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
|
|
#define LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
|
|
|
|
#include "clang/Basic/TargetInfo.h"
|
|
#include "clang/Basic/TargetOptions.h"
|
|
#include "llvm/ADT/Triple.h"
|
|
#include "llvm/Support/Compiler.h"
|
|
|
|
namespace clang {
|
|
namespace targets {
|
|
|
|
static const unsigned SPIRAddrSpaceMap[] = {
|
|
0, // Default
|
|
1, // opencl_global
|
|
3, // opencl_local
|
|
2, // opencl_constant
|
|
0, // opencl_private
|
|
4, // opencl_generic
|
|
0, // cuda_device
|
|
0, // cuda_constant
|
|
0 // cuda_shared
|
|
};
|
|
|
|
class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo {
|
|
public:
|
|
SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
|
|
: TargetInfo(Triple) {
|
|
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");
|
|
TLSSupported = false;
|
|
VLASupported = false;
|
|
LongWidth = LongAlign = 64;
|
|
AddrSpaceMap = &SPIRAddrSpaceMap;
|
|
UseAddrSpaceMapMangling = true;
|
|
HasLegalHalfType = true;
|
|
// Define available target features
|
|
// These must be defined in sorted order!
|
|
NoAsmVariants = true;
|
|
}
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
MacroBuilder &Builder) const override;
|
|
|
|
bool hasFeature(StringRef Feature) const override {
|
|
return Feature == "spir";
|
|
}
|
|
|
|
// 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; }
|
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
|
|
|
|
const char *getClobbers() const override { return ""; }
|
|
|
|
ArrayRef<const char *> getGCCRegNames() const override { return None; }
|
|
|
|
bool validateAsmConstraint(const char *&Name,
|
|
TargetInfo::ConstraintInfo &info) const override {
|
|
return true;
|
|
}
|
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
|
|
return None;
|
|
}
|
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
|
return TargetInfo::VoidPtrBuiltinVaList;
|
|
}
|
|
|
|
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
|
|
return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK
|
|
: CCCR_Warning;
|
|
}
|
|
|
|
CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override {
|
|
return CC_SpirFunction;
|
|
}
|
|
|
|
void setSupportedOpenCLOpts() override {
|
|
// Assume all OpenCL extensions and optional core features are supported
|
|
// for SPIR since it is a generic target.
|
|
getSupportedOpenCLOpts().supportAll();
|
|
}
|
|
};
|
|
class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo {
|
|
public:
|
|
SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
|
|
: SPIRTargetInfo(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 SPIR64TargetInfo : public SPIRTargetInfo {
|
|
public:
|
|
SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
|
|
: SPIRTargetInfo(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
|