mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-21 19:36:45 +00:00
[DirectX] Add target builtins (#134439)
- fixes #132303 - Moves dot2add from a language builtin to a target builtin. - Sets the scaffolding for Sema checks for DX builtins - Setup DirectX backend as able to have target builtins - Adds a DX TargetBuiltins emitter in `clang/lib/CodeGen/TargetBuiltins/DirectX.cpp`
This commit is contained in:
parent
7fe6e70e7c
commit
16c84c4475
.github
clang
include/clang
lib
Basic/Targets
CodeGen
Headers/hlsl
Sema
test/CodeGenDirectX/Builtins
6
.github/new-prs-labeler.yml
vendored
6
.github/new-prs-labeler.yml
vendored
@ -660,6 +660,12 @@ backend:DirectX:
|
||||
- '**/*dxil*/**'
|
||||
- '**/*DXContainer*'
|
||||
- '**/*DXContainer*/**'
|
||||
- clang/lib/Sema/SemaDirectX.cpp
|
||||
- clang/include/clang/Sema/SemaDirectX.h
|
||||
- clang/include/clang/Basic/BuiltinsDirectX.td
|
||||
- clang/lib/CodeGen/TargetBuiltins/DirectX.cpp
|
||||
- clang/test/CodeGenDirectX/**
|
||||
- clang/test/SemaDirectX/**
|
||||
|
||||
backend:SPIR-V:
|
||||
- clang/lib/Driver/ToolChains/SPIRV.*
|
||||
|
@ -4891,12 +4891,6 @@ def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
|
||||
let Prototype = "void(...)";
|
||||
}
|
||||
|
||||
def HLSLDot2Add : LangBuiltin<"HLSL_LANG"> {
|
||||
let Spellings = ["__builtin_hlsl_dot2add"];
|
||||
let Attributes = [NoThrow, Const];
|
||||
let Prototype = "float(_ExtVector<2, _Float16>, _ExtVector<2, _Float16>, float)";
|
||||
}
|
||||
|
||||
def HLSLDot4AddI8Packed : LangBuiltin<"HLSL_LANG"> {
|
||||
let Spellings = ["__builtin_hlsl_dot4add_i8packed"];
|
||||
let Attributes = [NoThrow, Const];
|
||||
|
15
clang/include/clang/Basic/BuiltinsDirectX.td
Normal file
15
clang/include/clang/Basic/BuiltinsDirectX.td
Normal file
@ -0,0 +1,15 @@
|
||||
//===--- BuiltinsDirectX.td - DirectX Builtin function database -----------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
include "clang/Basic/BuiltinsBase.td"
|
||||
|
||||
def DxDot2Add : Builtin {
|
||||
let Spellings = ["__builtin_dx_dot2add"];
|
||||
let Attributes = [NoThrow, Const];
|
||||
let Prototype = "float(_ExtVector<2, _Float16>, _ExtVector<2, _Float16>, float)";
|
||||
}
|
@ -82,6 +82,10 @@ clang_tablegen(BuiltinsBPF.inc -gen-clang-builtins
|
||||
SOURCE BuiltinsBPF.td
|
||||
TARGET ClangBuiltinsBPF)
|
||||
|
||||
clang_tablegen(BuiltinsDirectX.inc -gen-clang-builtins
|
||||
SOURCE BuiltinsDirectX.td
|
||||
TARGET ClangBuiltinsDirectX)
|
||||
|
||||
clang_tablegen(BuiltinsHexagon.inc -gen-clang-builtins
|
||||
SOURCE BuiltinsHexagon.td
|
||||
TARGET ClangBuiltinsHexagon)
|
||||
|
@ -141,6 +141,17 @@ namespace clang {
|
||||
};
|
||||
}
|
||||
|
||||
/// DirectX builtins
|
||||
namespace DirectX {
|
||||
enum {
|
||||
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
|
||||
#define GET_BUILTIN_ENUMERATORS
|
||||
#include "clang/Basic/BuiltinsDirectX.inc"
|
||||
#undef GET_BUILTIN_ENUMERATORS
|
||||
LastTSBuiltin
|
||||
};
|
||||
} // namespace DirectX
|
||||
|
||||
/// SPIRV builtins
|
||||
namespace SPIRV {
|
||||
enum {
|
||||
|
@ -160,6 +160,7 @@ class SemaAVR;
|
||||
class SemaBPF;
|
||||
class SemaCodeCompletion;
|
||||
class SemaCUDA;
|
||||
class SemaDirectX;
|
||||
class SemaHLSL;
|
||||
class SemaHexagon;
|
||||
class SemaLoongArch;
|
||||
@ -1074,6 +1075,11 @@ public:
|
||||
return *CUDAPtr;
|
||||
}
|
||||
|
||||
SemaDirectX &DirectX() {
|
||||
assert(DirectXPtr);
|
||||
return *DirectXPtr;
|
||||
}
|
||||
|
||||
SemaHLSL &HLSL() {
|
||||
assert(HLSLPtr);
|
||||
return *HLSLPtr;
|
||||
@ -1212,6 +1218,7 @@ private:
|
||||
std::unique_ptr<SemaBPF> BPFPtr;
|
||||
std::unique_ptr<SemaCodeCompletion> CodeCompletionPtr;
|
||||
std::unique_ptr<SemaCUDA> CUDAPtr;
|
||||
std::unique_ptr<SemaDirectX> DirectXPtr;
|
||||
std::unique_ptr<SemaHLSL> HLSLPtr;
|
||||
std::unique_ptr<SemaHexagon> HexagonPtr;
|
||||
std::unique_ptr<SemaLoongArch> LoongArchPtr;
|
||||
|
28
clang/include/clang/Sema/SemaDirectX.h
Normal file
28
clang/include/clang/Sema/SemaDirectX.h
Normal file
@ -0,0 +1,28 @@
|
||||
//===----- SemaDirectX.h ----- Semantic Analysis for DirectX constructs----===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// \file
|
||||
/// This file declares semantic analysis for DirectX constructs.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_SEMA_SEMADIRECTX_H
|
||||
#define LLVM_CLANG_SEMA_SEMADIRECTX_H
|
||||
|
||||
#include "clang/AST/ASTFwd.h"
|
||||
#include "clang/Sema/SemaBase.h"
|
||||
|
||||
namespace clang {
|
||||
class SemaDirectX : public SemaBase {
|
||||
public:
|
||||
SemaDirectX(Sema &S);
|
||||
|
||||
bool CheckDirectXBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
|
||||
};
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_SEMA_SEMADIRECTX_H
|
@ -12,11 +12,31 @@
|
||||
|
||||
#include "DirectX.h"
|
||||
#include "Targets.h"
|
||||
#include "clang/Basic/TargetBuiltins.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace clang::targets;
|
||||
|
||||
static constexpr int NumBuiltins =
|
||||
clang::DirectX::LastTSBuiltin - Builtin::FirstTSBuiltin;
|
||||
|
||||
#define GET_BUILTIN_STR_TABLE
|
||||
#include "clang/Basic/BuiltinsDirectX.inc"
|
||||
#undef GET_BUILTIN_STR_TABLE
|
||||
|
||||
static constexpr Builtin::Info BuiltinInfos[] = {
|
||||
#define GET_BUILTIN_INFOS
|
||||
#include "clang/Basic/BuiltinsDirectX.inc"
|
||||
#undef GET_BUILTIN_INFOS
|
||||
};
|
||||
static_assert(std::size(BuiltinInfos) == NumBuiltins);
|
||||
|
||||
void DirectXTargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const {
|
||||
DefineStd(Builder, "DIRECTX", Opts);
|
||||
}
|
||||
|
||||
llvm::SmallVector<Builtin::InfosShard>
|
||||
DirectXTargetInfo::getTargetBuiltins() const {
|
||||
return {{&BuiltinStrings, BuiltinInfos}};
|
||||
}
|
||||
|
@ -73,9 +73,7 @@ public:
|
||||
return Feature == "directx";
|
||||
}
|
||||
|
||||
llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override {
|
||||
return {};
|
||||
}
|
||||
llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;
|
||||
|
||||
std::string_view getClobbers() const override { return ""; }
|
||||
|
||||
|
@ -70,6 +70,8 @@ static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF,
|
||||
case llvm::Triple::bpfeb:
|
||||
case llvm::Triple::bpfel:
|
||||
return CGF->EmitBPFBuiltinExpr(BuiltinID, E);
|
||||
case llvm::Triple::dxil:
|
||||
return CGF->EmitDirectXBuiltinExpr(BuiltinID, E);
|
||||
case llvm::Triple::x86:
|
||||
case llvm::Triple::x86_64:
|
||||
return CGF->EmitX86BuiltinExpr(BuiltinID, E);
|
||||
|
@ -380,18 +380,6 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
|
||||
getDotProductIntrinsic(CGM.getHLSLRuntime(), VecTy0->getElementType()),
|
||||
ArrayRef<Value *>{Op0, Op1}, nullptr, "hlsl.dot");
|
||||
}
|
||||
case Builtin::BI__builtin_hlsl_dot2add: {
|
||||
assert(CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil &&
|
||||
"Intrinsic dot2add is only allowed for dxil architecture");
|
||||
Value *A = EmitScalarExpr(E->getArg(0));
|
||||
Value *B = EmitScalarExpr(E->getArg(1));
|
||||
Value *C = EmitScalarExpr(E->getArg(2));
|
||||
|
||||
Intrinsic::ID ID = llvm ::Intrinsic::dx_dot2add;
|
||||
return Builder.CreateIntrinsic(
|
||||
/*ReturnType=*/C->getType(), ID, ArrayRef<Value *>{A, B, C}, nullptr,
|
||||
"dx.dot2add");
|
||||
}
|
||||
case Builtin::BI__builtin_hlsl_dot4add_i8packed: {
|
||||
Value *A = EmitScalarExpr(E->getArg(0));
|
||||
Value *B = EmitScalarExpr(E->getArg(1));
|
||||
|
@ -118,6 +118,7 @@ add_clang_library(clangCodeGen
|
||||
SwiftCallingConv.cpp
|
||||
TargetBuiltins/ARM.cpp
|
||||
TargetBuiltins/AMDGPU.cpp
|
||||
TargetBuiltins/DirectX.cpp
|
||||
TargetBuiltins/Hexagon.cpp
|
||||
TargetBuiltins/NVPTX.cpp
|
||||
TargetBuiltins/PPC.cpp
|
||||
|
@ -4809,6 +4809,7 @@ public:
|
||||
llvm::Value *EmitAMDGPUBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
|
||||
llvm::Value *EmitHLSLBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
|
||||
ReturnValueSlot ReturnValue);
|
||||
llvm::Value *EmitDirectXBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
|
||||
llvm::Value *EmitSPIRVBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
|
||||
llvm::Value *EmitScalarOrConstFoldImmArg(unsigned ICEArguments, unsigned Idx,
|
||||
const CallExpr *E);
|
||||
|
37
clang/lib/CodeGen/TargetBuiltins/DirectX.cpp
Normal file
37
clang/lib/CodeGen/TargetBuiltins/DirectX.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
//===--------- DirectX.cpp - Emit LLVM Code for builtins ------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This contains code to emit Builtin calls as LLVM code.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "CGHLSLRuntime.h"
|
||||
#include "CodeGenFunction.h"
|
||||
#include "clang/Basic/TargetBuiltins.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace CodeGen;
|
||||
using namespace llvm;
|
||||
|
||||
Value *CodeGenFunction::EmitDirectXBuiltinExpr(unsigned BuiltinID,
|
||||
const CallExpr *E) {
|
||||
switch (BuiltinID) {
|
||||
case DirectX::BI__builtin_dx_dot2add: {
|
||||
Value *A = EmitScalarExpr(E->getArg(0));
|
||||
Value *B = EmitScalarExpr(E->getArg(1));
|
||||
Value *C = EmitScalarExpr(E->getArg(2));
|
||||
|
||||
Intrinsic::ID ID = llvm ::Intrinsic::dx_dot2add;
|
||||
return Builder.CreateIntrinsic(
|
||||
/*ReturnType=*/C->getType(), ID, ArrayRef<Value *>{A, B, C}, nullptr,
|
||||
"dx.dot2add");
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
@ -46,8 +46,8 @@ distance_vec_impl(vector<T, N> X, vector<T, N> Y) {
|
||||
}
|
||||
|
||||
constexpr float dot2add_impl(half2 a, half2 b, float c) {
|
||||
#if defined(__DIRECTX__)
|
||||
return __builtin_hlsl_dot2add(a, b, c);
|
||||
#if (__has_builtin(__builtin_dx_dot2add))
|
||||
return __builtin_dx_dot2add(a, b, c);
|
||||
#else
|
||||
return dot(a, b) + c;
|
||||
#endif
|
||||
|
@ -47,6 +47,7 @@ add_clang_library(clangSema
|
||||
SemaConsumer.cpp
|
||||
SemaCoroutine.cpp
|
||||
SemaCUDA.cpp
|
||||
SemaDirectX.cpp
|
||||
SemaDecl.cpp
|
||||
SemaDeclAttr.cpp
|
||||
SemaDeclCXX.cpp
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "clang/Sema/SemaCUDA.h"
|
||||
#include "clang/Sema/SemaCodeCompletion.h"
|
||||
#include "clang/Sema/SemaConsumer.h"
|
||||
#include "clang/Sema/SemaDirectX.h"
|
||||
#include "clang/Sema/SemaHLSL.h"
|
||||
#include "clang/Sema/SemaHexagon.h"
|
||||
#include "clang/Sema/SemaLoongArch.h"
|
||||
@ -226,6 +227,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
|
||||
CodeCompletionPtr(
|
||||
std::make_unique<SemaCodeCompletion>(*this, CodeCompleter)),
|
||||
CUDAPtr(std::make_unique<SemaCUDA>(*this)),
|
||||
DirectXPtr(std::make_unique<SemaDirectX>(*this)),
|
||||
HLSLPtr(std::make_unique<SemaHLSL>(*this)),
|
||||
HexagonPtr(std::make_unique<SemaHexagon>(*this)),
|
||||
LoongArchPtr(std::make_unique<SemaLoongArch>(*this)),
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "clang/Sema/SemaAMDGPU.h"
|
||||
#include "clang/Sema/SemaARM.h"
|
||||
#include "clang/Sema/SemaBPF.h"
|
||||
#include "clang/Sema/SemaDirectX.h"
|
||||
#include "clang/Sema/SemaHLSL.h"
|
||||
#include "clang/Sema/SemaHexagon.h"
|
||||
#include "clang/Sema/SemaLoongArch.h"
|
||||
@ -1930,6 +1931,8 @@ bool Sema::CheckTSBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
|
||||
case llvm::Triple::bpfeb:
|
||||
case llvm::Triple::bpfel:
|
||||
return BPF().CheckBPFBuiltinFunctionCall(BuiltinID, TheCall);
|
||||
case llvm::Triple::dxil:
|
||||
return DirectX().CheckDirectXBuiltinFunctionCall(BuiltinID, TheCall);
|
||||
case llvm::Triple::hexagon:
|
||||
return Hexagon().CheckHexagonBuiltinFunctionCall(BuiltinID, TheCall);
|
||||
case llvm::Triple::mips:
|
||||
|
23
clang/lib/Sema/SemaDirectX.cpp
Normal file
23
clang/lib/Sema/SemaDirectX.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
//===- SemaDirectX.cpp - Semantic Analysis for DirectX constructs----------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
// This implements Semantic Analysis for DirectX constructs.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Sema/SemaDirectX.h"
|
||||
#include "clang/Basic/TargetBuiltins.h"
|
||||
#include "clang/Sema/Sema.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
SemaDirectX::SemaDirectX(Sema &S) : SemaBase(S) {}
|
||||
|
||||
bool SemaDirectX::CheckDirectXBuiltinFunctionCall(unsigned BuiltinID,
|
||||
CallExpr *TheCall) {
|
||||
return false;
|
||||
}
|
||||
} // namespace clang
|
23
clang/test/CodeGenDirectX/Builtins/dot2add.c
Normal file
23
clang/test/CodeGenDirectX/Builtins/dot2add.c
Normal file
@ -0,0 +1,23 @@
|
||||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
|
||||
|
||||
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -o - | FileCheck %s
|
||||
|
||||
typedef _Float16 half;
|
||||
typedef half half2 __attribute__((ext_vector_type(2)));
|
||||
|
||||
// CHECK-LABEL: define float @test_dot2add(
|
||||
// CHECK-SAME: <2 x half> noundef [[X:%.*]], <2 x half> noundef [[Y:%.*]], float noundef [[Z:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||
// CHECK-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-NEXT: [[X_ADDR:%.*]] = alloca <2 x half>, align 4
|
||||
// CHECK-NEXT: [[Y_ADDR:%.*]] = alloca <2 x half>, align 4
|
||||
// CHECK-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4
|
||||
// CHECK-NEXT: store <2 x half> [[X]], ptr [[X_ADDR]], align 4
|
||||
// CHECK-NEXT: store <2 x half> [[Y]], ptr [[Y_ADDR]], align 4
|
||||
// CHECK-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load <2 x half>, ptr [[X_ADDR]], align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load <2 x half>, ptr [[Y_ADDR]], align 4
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[Z_ADDR]], align 4
|
||||
// CHECK-NEXT: [[DX_DOT2ADD:%.*]] = call float @llvm.dx.dot2add.v2f16(<2 x half> [[TMP0]], <2 x half> [[TMP1]], float [[TMP2]])
|
||||
// CHECK-NEXT: ret float [[DX_DOT2ADD]]
|
||||
//
|
||||
float test_dot2add(half2 X, half2 Y, float Z) { return __builtin_dx_dot2add(X, Y, Z); }
|
Loading…
x
Reference in New Issue
Block a user