Skip to content
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

[clang][SPIR-V] Add support for AMDGCN flavoured SPIRV #89796

Merged
merged 37 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
662f160
Add initial support for AMDGCN flavoured SPIRV.
AlexVlx Apr 23, 2024
393ce66
Fix formatting.
AlexVlx Apr 23, 2024
2a10ad0
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx Apr 25, 2024
98db8f7
Use `fillAMDGPUFeatureMap` instead of copy-pasta.
AlexVlx Apr 25, 2024
c359e0a
Add `__has_builtin` test.
AlexVlx Apr 25, 2024
e98f3f5
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx Apr 28, 2024
c41726d
Re-use `AMDGPUTargetInfo`, where feasible, instead of copypasta-ing.
AlexVlx Apr 28, 2024
4698b58
Incorporate review suggestions.
AlexVlx Apr 28, 2024
aa1cd7c
Fix header ordering.
AlexVlx Apr 28, 2024
f9729ef
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx May 8, 2024
8257cb1
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx May 9, 2024
900cd69
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx May 11, 2024
3307f17
Handle `wavefrontsize` (we need both 32 and 64); add more tests.
AlexVlx May 12, 2024
eee6063
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx May 13, 2024
d2f4244
Add an additional test.
AlexVlx May 14, 2024
4cb4026
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx May 14, 2024
84a621d
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx May 14, 2024
1841385
AMDGCN SPIRV should allow both AMDGCN and SPIRV builtins.
AlexVlx May 15, 2024
0ce2da3
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx May 15, 2024
120b73c
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx May 15, 2024
f3942bd
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx May 15, 2024
31ac77d
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx May 15, 2024
0e9b1a1
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx May 16, 2024
83cd5e0
Enable AMDGCN flavoured SPIRV in the experimental SPIRV BE.
AlexVlx May 16, 2024
e9158b0
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx May 16, 2024
05074e7
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx May 19, 2024
e1fb93f
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx May 20, 2024
36c4bf6
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx May 27, 2024
5ffa186
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx May 27, 2024
cf1880c
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx May 29, 2024
4d85a1b
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx Jun 5, 2024
516e14c
Revert spurios testing noise, AMDGCN SPIRV is still SPIRV.
AlexVlx Jun 5, 2024
bdc3eb5
First pass at updating SPIR-V docs to reflect the addition of AMDGCN …
AlexVlx Jun 6, 2024
361d47b
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx Jun 6, 2024
b088c72
Fix erroneous versioning claim.
AlexVlx Jun 6, 2024
e85b557
Remove function pointer tests.
AlexVlx Jun 6, 2024
1d41787
Merge branch 'main' of https://github.com/llvm/llvm-project into amdg…
AlexVlx Jun 6, 2024
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
5 changes: 4 additions & 1 deletion clang/lib/Basic/Targets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -673,8 +673,11 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
}
case llvm::Triple::spirv64: {
if (os != llvm::Triple::UnknownOS ||
Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) {
if (os == llvm::Triple::OSType::AMDHSA)
return std::make_unique<SPIRV64AMDGCNTargetInfo>(Triple, Opts);
return nullptr;
}
return std::make_unique<SPIRV64TargetInfo>(Triple, Opts);
}
case llvm::Triple::wasm32:
Expand Down
75 changes: 75 additions & 0 deletions clang/lib/Basic/Targets/SPIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
//===----------------------------------------------------------------------===//

#include "SPIR.h"
#include "AMDGPU.h"
#include "Targets.h"
#include "llvm/TargetParser/TargetParser.h"

using namespace clang;
using namespace clang::targets;
Expand Down Expand Up @@ -54,3 +56,76 @@ void SPIRV64TargetInfo::getTargetDefines(const LangOptions &Opts,
BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder);
DefineStd(Builder, "SPIRV64", Opts);
}

static const AMDGPUTargetInfo AMDGPUTI(llvm::Triple("amdgcn-amd-amdhsa"), {});

ArrayRef<const char *> SPIRV64AMDGCNTargetInfo::getGCCRegNames() const {
return AMDGPUTI.getGCCRegNames();
}

bool SPIRV64AMDGCNTargetInfo::initFeatureMap(
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef,
const std::vector<std::string> &FeatureVec) const {
llvm::AMDGPU::fillAMDGPUFeatureMap({}, getTriple(), Features);

return TargetInfo::initFeatureMap(Features, Diags, {}, FeatureVec);
}

bool SPIRV64AMDGCNTargetInfo::validateAsmConstraint(
const char *&Name, TargetInfo::ConstraintInfo &Info) const {
return AMDGPUTI.validateAsmConstraint(Name, Info);
}

std::string
SPIRV64AMDGCNTargetInfo::convertConstraint(const char *&Constraint) const {
return AMDGPUTI.convertConstraint(Constraint);
}

ArrayRef<Builtin::Info> SPIRV64AMDGCNTargetInfo::getTargetBuiltins() const {
return AMDGPUTI.getTargetBuiltins();
}

void SPIRV64AMDGCNTargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder);
DefineStd(Builder, "SPIRV64", Opts);

Builder.defineMacro("__AMD__");
Builder.defineMacro("__AMDGPU__");
Builder.defineMacro("__AMDGCN__");
Comment on lines +93 to +95
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these defined on both the host and device? I remember having a quite annoying time with these macros because HIP was defining stuff like __AMDGCN_WAVEFRONT_SIZE on the host.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

__AMDGCN_WAVEFRONT_SIZE is a pretty terrible error, which should never have been defined on host (not in the least because it's non-uniform across targets). These do (should) end up defined on host too, but they are harmless because they are uniform i.e. all potential consumers of spirv64-amd-amdhsa are __AMD__, __AMDGPU__ and __AMDGCN__. They're mostly a necessary nuisance for getting library code to work.

Copy link
Contributor

Choose a reason for hiding this comment

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

I've always thought defining those for both targets was obtuse, since those should act like architecture macros, i.e. (X86). But considering this is how it's done already, I suppose it's a necessary evil.

}

void SPIRV64AMDGCNTargetInfo::setAuxTarget(const TargetInfo *Aux) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is AUX guaranteed non-null here? I know in the NVPTX target we only have an Aux when compiling for CUDA and use that to make sure type widths match up. However, if you have a direct compilation via --target=nvptx64-nvidia-cuda it will be null and not used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As far as I can tell, setAuxTarget is only used when compiling for CUDA / HIP, and wouldn't get invoked otherwise (I could be wrong though); having said that, it probably makes sense to assert that Aux is non-null, thanks for pointing this out.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It is a reasonable assumption. Since HIP/CUDA needs to make sure type consistency between host and device, normal compilation by clang driver always specify aux-target for device compilation.

assert(Aux && "Cannot invoke setAuxTarget without a valid auxiliary target!");

// This is a 1:1 copy of AMDGPUTargetInfo::setAuxTarget()
assert(HalfFormat == Aux->HalfFormat);
assert(FloatFormat == Aux->FloatFormat);
assert(DoubleFormat == Aux->DoubleFormat);

// On x86_64 long double is 80-bit extended precision format, which is
// not supported by AMDGPU. 128-bit floating point format is also not
// supported by AMDGPU. Therefore keep its own format for these two types.
auto SaveLongDoubleFormat = LongDoubleFormat;
auto SaveFloat128Format = Float128Format;
auto SaveLongDoubleWidth = LongDoubleWidth;
auto SaveLongDoubleAlign = LongDoubleAlign;
copyAuxTarget(Aux);
LongDoubleFormat = SaveLongDoubleFormat;
Float128Format = SaveFloat128Format;
LongDoubleWidth = SaveLongDoubleWidth;
LongDoubleAlign = SaveLongDoubleAlign;
// For certain builtin types support on the host target, claim they are
// supported to pass the compilation of the host code during the device-side
// compilation.
// FIXME: As the side effect, we also accept `__float128` uses in the device
// code. To reject these builtin types supported in the host target but not in
// the device target, one approach would support `device_builtin` attribute
// so that we could tell the device builtin types from the host ones. This
// also solves the different representations of the same builtin type, such
// as `size_t` in the MSVC environment.
if (Aux->hasFloat128Type()) {
HasFloat128 = true;
Float128Format = DoubleFormat;
}
}
51 changes: 51 additions & 0 deletions clang/lib/Basic/Targets/SPIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,57 @@ class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public BaseSPIRVTargetInfo {
MacroBuilder &Builder) const override;
};

class LLVM_LIBRARY_VISIBILITY SPIRV64AMDGCNTargetInfo final
: public BaseSPIRVTargetInfo {
public:
SPIRV64AMDGCNTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: BaseSPIRVTargetInfo(Triple, Opts) {
assert(Triple.getArch() == llvm::Triple::spirv64 &&
"Invalid architecture for 64-bit AMDGCN SPIR-V.");
assert(Triple.getVendor() == llvm::Triple::VendorType::AMD &&
"64-bit AMDGCN SPIR-V target must use AMD vendor");
assert(getTriple().getOS() == llvm::Triple::OSType::AMDHSA &&
"64-bit AMDGCN SPIR-V target must use AMDHSA OS");
assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
"64-bit SPIR-V target must use unknown environment type");
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-G1-P4-A0");

BFloat16Width = BFloat16Align = 16;
BFloat16Format = &llvm::APFloat::BFloat();

HasLegalHalfType = true;
HasFloat16 = true;
HalfArgsAndReturns = true;
}

bool hasBFloat16Type() const override { return true; }

ArrayRef<const char *> getGCCRegNames() const override;

bool initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
StringRef,
const std::vector<std::string> &) const override;

bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &Info) const override;

std::string convertConstraint(const char *&Constraint) const override;

ArrayRef<Builtin::Info> getTargetBuiltins() const override;

void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;

void setAuxTarget(const TargetInfo *Aux) override;

bool hasInt128Type() const override { return TargetInfo::hasInt128Type(); }
};

} // namespace targets
} // namespace clang
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
7 changes: 7 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6012,6 +6012,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch());
if (!Prefix.empty()) {
IntrinsicID = Intrinsic::getIntrinsicForClangBuiltin(Prefix.data(), Name);
if (IntrinsicID == Intrinsic::not_intrinsic && Prefix == "spv" &&
getTarget().getTriple().getOS() == llvm::Triple::OSType::AMDHSA)
IntrinsicID = Intrinsic::getIntrinsicForClangBuiltin("amdgcn", Name);
// NOTE we don't need to perform a compatibility flag check here since the
// intrinsics are declared in Builtins*.def via LANGBUILTIN which filter the
// MS builtins via ALL_MS_LANGUAGES and are filtered earlier.
Expand Down Expand Up @@ -6182,6 +6185,10 @@ static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF,
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
return CGF->EmitRISCVBuiltinExpr(BuiltinID, E, ReturnValue);
case llvm::Triple::spirv64:
if (CGF->getTarget().getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
return nullptr;
return CGF->EmitAMDGPUBuiltinExpr(BuiltinID, E);
default:
return nullptr;
}
Expand Down
4 changes: 4 additions & 0 deletions clang/test/CodeGen/target-data.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,3 +268,7 @@
// RUN: %clang_cc1 -triple ve -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=VE
// VE: target datalayout = "e-m:e-i64:64-n32:64-S128-v64:64:64-v128:64:64-v256:64:64-v512:64:64-v1024:64:64-v2048:64:64-v4096:64:64-v8192:64:64-v16384:64:64"

// RUN: %clang_cc1 -triple spirv64-amd -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=SPIR64
// AMDGPUSPIRV64: target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1-P4-A0"
Loading
Loading