Skip to content

Commit 21edac2

Browse files
authored
[SPIRV] Add Target Builtins using Distance ext as an example (#121598)
- Update pr labeler so new SPIRV files get properly labeled. - Add distance target builtin to BuiltinsSPIRV.td. - Update TargetBuiltins.h to account for spirv builtins. - Update clang basic CMakeLists.txt to build spirv builtin tablegen. - Hook up sema for SPIRV in Sema.h|cpp, SemaSPIRV.h|cpp, and SemaChecking.cpp. - Hookup sprv target builtins to SPIR.h|SPIR.cpp target. - Update GBuiltin.cpp to emit spirv intrinsics when we get the expected spirv target builtin. Consensus was reach in this RFC to add both target builtins and pattern matching: https://discourse.llvm.org/t/rfc-add-targetbuiltins-for-spirv-to-support-hlsl/83329. pattern matching will come in a separate pr this one just sets up the groundwork to do target builtins for spirv. partially resolves [#99107](#99107)
1 parent ca603d2 commit 21edac2

File tree

21 files changed

+294
-1
lines changed

21 files changed

+294
-1
lines changed

.github/new-prs-labeler.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,11 @@ backend:DirectX:
661661

662662
backend:SPIR-V:
663663
- clang/lib/Driver/ToolChains/SPIRV.*
664+
- clang/lib/Sema/SemaSPIRV.cpp
665+
- clang/include/clang/Sema/SemaSPIRV.h
666+
- clang/include/clang/Basic/BuiltinsSPIRV.td
667+
- clang/test/CodeGenSPIRV/**
668+
- clang/test/SemaSPIRV/**
664669
- llvm/lib/Target/SPIRV/**
665670
- llvm/test/CodeGen/SPIRV/**
666671
- llvm/test/Frontend/HLSL/**
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//===--- BuiltinsSPIRV.td - SPIRV Builtin function database ---------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
include "clang/Basic/BuiltinsBase.td"
10+
11+
def HLSLDistance : Builtin {
12+
let Spellings = ["__builtin_spirv_distance"];
13+
let Attributes = [NoThrow, Const];
14+
let Prototype = "void(...)";
15+
}

clang/include/clang/Basic/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ clang_tablegen(BuiltinsRISCV.inc -gen-clang-builtins
6060
SOURCE BuiltinsRISCV.td
6161
TARGET ClangBuiltinsRISCV)
6262

63+
clang_tablegen(BuiltinsSPIRV.inc -gen-clang-builtins
64+
SOURCE BuiltinsSPIRV.td
65+
TARGET ClangBuiltinsSPIRV)
66+
6367
clang_tablegen(BuiltinsX86.inc -gen-clang-builtins
6468
SOURCE BuiltinsX86.td
6569
TARGET ClangBuiltinsX86)

clang/include/clang/Basic/TargetBuiltins.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,16 @@ namespace clang {
119119
};
120120
}
121121

122+
/// SPIRV builtins
123+
namespace SPIRV {
124+
enum {
125+
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
126+
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
127+
#include "clang/Basic/BuiltinsSPIRV.inc"
128+
LastTSBuiltin
129+
};
130+
} // namespace SPIRV
131+
122132
/// X86 builtins
123133
namespace X86 {
124134
enum {

clang/include/clang/Sema/Sema.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ class SemaOpenMP;
173173
class SemaPPC;
174174
class SemaPseudoObject;
175175
class SemaRISCV;
176+
class SemaSPIRV;
176177
class SemaSYCL;
177178
class SemaSwift;
178179
class SemaSystemZ;
@@ -1142,6 +1143,11 @@ class Sema final : public SemaBase {
11421143
return *RISCVPtr;
11431144
}
11441145

1146+
SemaSPIRV &SPIRV() {
1147+
assert(SPIRVPtr);
1148+
return *SPIRVPtr;
1149+
}
1150+
11451151
SemaSYCL &SYCL() {
11461152
assert(SYCLPtr);
11471153
return *SYCLPtr;
@@ -1219,6 +1225,7 @@ class Sema final : public SemaBase {
12191225
std::unique_ptr<SemaPPC> PPCPtr;
12201226
std::unique_ptr<SemaPseudoObject> PseudoObjectPtr;
12211227
std::unique_ptr<SemaRISCV> RISCVPtr;
1228+
std::unique_ptr<SemaSPIRV> SPIRVPtr;
12221229
std::unique_ptr<SemaSYCL> SYCLPtr;
12231230
std::unique_ptr<SemaSwift> SwiftPtr;
12241231
std::unique_ptr<SemaSystemZ> SystemZPtr;

clang/include/clang/Sema/SemaSPIRV.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===----- SemaSPIRV.h ----- Semantic Analysis for SPIRV constructs--------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
/// \file
9+
/// This file declares semantic analysis for SPIRV constructs.
10+
///
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_CLANG_SEMA_SEMASPIRV_H
14+
#define LLVM_CLANG_SEMA_SEMASPIRV_H
15+
16+
#include "clang/AST/ASTFwd.h"
17+
#include "clang/Sema/SemaBase.h"
18+
19+
namespace clang {
20+
class SemaSPIRV : public SemaBase {
21+
public:
22+
SemaSPIRV(Sema &S);
23+
24+
bool CheckSPIRVBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
25+
};
26+
} // namespace clang
27+
28+
#endif // LLVM_CLANG_SEMA_SEMASPIRV_H

clang/lib/Basic/Targets/SPIR.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,24 @@
1313
#include "SPIR.h"
1414
#include "AMDGPU.h"
1515
#include "Targets.h"
16+
#include "clang/Basic/MacroBuilder.h"
17+
#include "clang/Basic/TargetBuiltins.h"
1618
#include "llvm/TargetParser/TargetParser.h"
1719

1820
using namespace clang;
1921
using namespace clang::targets;
2022

23+
static constexpr Builtin::Info BuiltinInfo[] = {
24+
#define BUILTIN(ID, TYPE, ATTRS) \
25+
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
26+
#include "clang/Basic/BuiltinsSPIRV.inc"
27+
};
28+
29+
ArrayRef<Builtin::Info> SPIRVTargetInfo::getTargetBuiltins() const {
30+
return llvm::ArrayRef(BuiltinInfo,
31+
clang::SPIRV::LastTSBuiltin - Builtin::FirstTSBuiltin);
32+
}
33+
2134
void SPIRTargetInfo::getTargetDefines(const LangOptions &Opts,
2235
MacroBuilder &Builder) const {
2336
DefineStd(Builder, "SPIR", Opts);

clang/lib/Basic/Targets/SPIR.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo {
313313
resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-"
314314
"v256:256-v512:512-v1024:1024-n8:16:32:64-G1");
315315
}
316-
316+
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
317317
void getTargetDefines(const LangOptions &Opts,
318318
MacroBuilder &Builder) const override;
319319
};

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6797,6 +6797,8 @@ static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF,
67976797
case llvm::Triple::riscv32:
67986798
case llvm::Triple::riscv64:
67996799
return CGF->EmitRISCVBuiltinExpr(BuiltinID, E, ReturnValue);
6800+
case llvm::Triple::spirv:
6801+
return CGF->EmitSPIRVBuiltinExpr(BuiltinID, E);
68006802
case llvm::Triple::spirv64:
68016803
if (CGF->getTarget().getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
68026804
return nullptr;
@@ -20480,6 +20482,26 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
2048020482
}
2048120483
}
2048220484

20485+
Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned BuiltinID,
20486+
const CallExpr *E) {
20487+
switch (BuiltinID) {
20488+
case SPIRV::BI__builtin_spirv_distance: {
20489+
Value *X = EmitScalarExpr(E->getArg(0));
20490+
Value *Y = EmitScalarExpr(E->getArg(1));
20491+
assert(E->getArg(0)->getType()->hasFloatingRepresentation() &&
20492+
E->getArg(1)->getType()->hasFloatingRepresentation() &&
20493+
"Distance operands must have a float representation");
20494+
assert(E->getArg(0)->getType()->isVectorType() &&
20495+
E->getArg(1)->getType()->isVectorType() &&
20496+
"Distance operands must be a vector");
20497+
return Builder.CreateIntrinsic(
20498+
/*ReturnType=*/X->getType()->getScalarType(), Intrinsic::spv_distance,
20499+
ArrayRef<Value *>{X, Y}, nullptr, "spv.distance");
20500+
}
20501+
}
20502+
return nullptr;
20503+
}
20504+
2048320505
/// Handle a SystemZ function in which the final argument is a pointer
2048420506
/// to an int that receives the post-instruction CC value. At the LLVM level
2048520507
/// this is represented as a function that returns a {result, cc} pair.

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4756,6 +4756,7 @@ class CodeGenFunction : public CodeGenTypeCache {
47564756
llvm::Value *EmitAMDGPUBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
47574757
llvm::Value *EmitHLSLBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
47584758
ReturnValueSlot ReturnValue);
4759+
llvm::Value *EmitSPIRVBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
47594760
llvm::Value *EmitScalarOrConstFoldImmArg(unsigned ICEArguments, unsigned Idx,
47604761
const CallExpr *E);
47614762
llvm::Value *EmitSystemZBuiltinExpr(unsigned BuiltinID, const CallExpr *E);

0 commit comments

Comments
 (0)