-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[DirectX] Add target builtins #134439
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
[DirectX] Add target builtins #134439
Conversation
@llvm/pr-subscribers-hlsl @llvm/pr-subscribers-backend-directx Author: Farzon Lotfi (farzonl) Changes
Full diff: https://github.com/llvm/llvm-project/pull/134439.diff 20 Files Affected:
diff --git a/.github/new-prs-labeler.yml b/.github/new-prs-labeler.yml
index b93cdff8af345..c0c61748010d0 100644
--- a/.github/new-prs-labeler.yml
+++ b/.github/new-prs-labeler.yml
@@ -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.*
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index c7ca607e4b3d2..b2c7ddb43de55 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -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];
diff --git a/clang/include/clang/Basic/BuiltinsDirectX.td b/clang/include/clang/Basic/BuiltinsDirectX.td
new file mode 100644
index 0000000000000..444532ab2874a
--- /dev/null
+++ b/clang/include/clang/Basic/BuiltinsDirectX.td
@@ -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)";
+}
diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt
index 6be6d063c20b4..4d5e1eaa3facb 100644
--- a/clang/include/clang/Basic/CMakeLists.txt
+++ b/clang/include/clang/Basic/CMakeLists.txt
@@ -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)
diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h
index c1ba65064f159..4e490d87ee8d6 100644
--- a/clang/include/clang/Basic/TargetBuiltins.h
+++ b/clang/include/clang/Basic/TargetBuiltins.h
@@ -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 {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6bf1caf6bdd18..30917e7ca0310 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -160,6 +160,7 @@ class SemaAVR;
class SemaBPF;
class SemaCodeCompletion;
class SemaCUDA;
+class SemaDirectX;
class SemaHLSL;
class SemaHexagon;
class SemaLoongArch;
@@ -1074,6 +1075,11 @@ class Sema final : public SemaBase {
return *CUDAPtr;
}
+ SemaDirectX &DirectX() {
+ assert(DirectXPtr);
+ return *DirectXPtr;
+ }
+
SemaHLSL &HLSL() {
assert(HLSLPtr);
return *HLSLPtr;
@@ -1212,6 +1218,7 @@ class Sema final : public SemaBase {
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;
diff --git a/clang/include/clang/Sema/SemaDirectX.h b/clang/include/clang/Sema/SemaDirectX.h
new file mode 100644
index 0000000000000..ae9cd61318714
--- /dev/null
+++ b/clang/include/clang/Sema/SemaDirectX.h
@@ -0,0 +1,29 @@
+//===----- 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
\ No newline at end of file
diff --git a/clang/lib/Basic/Targets/DirectX.cpp b/clang/lib/Basic/Targets/DirectX.cpp
index 0dd27e6e93b33..ff0c062e80947 100644
--- a/clang/lib/Basic/Targets/DirectX.cpp
+++ b/clang/lib/Basic/Targets/DirectX.cpp
@@ -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}};
+}
\ No newline at end of file
diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h
index 6e3ddad626341..0e88a37e32493 100644
--- a/clang/lib/Basic/Targets/DirectX.h
+++ b/clang/lib/Basic/Targets/DirectX.h
@@ -73,9 +73,7 @@ class LLVM_LIBRARY_VISIBILITY DirectXTargetInfo : public TargetInfo {
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 ""; }
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 310addebd50e9..fe55dfffc1cbe 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -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);
diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index 27d1c69439944..99c62808c323d 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -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));
diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt
index ebe2fbd7db295..dc5b2a35583b4 100644
--- a/clang/lib/CodeGen/CMakeLists.txt
+++ b/clang/lib/CodeGen/CMakeLists.txt
@@ -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
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index af9798b30fbcf..34dee6df9dcfc 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4809,6 +4809,7 @@ class CodeGenFunction : public CodeGenTypeCache {
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);
diff --git a/clang/lib/CodeGen/TargetBuiltins/DirectX.cpp b/clang/lib/CodeGen/TargetBuiltins/DirectX.cpp
new file mode 100644
index 0000000000000..202601e257036
--- /dev/null
+++ b/clang/lib/CodeGen/TargetBuiltins/DirectX.cpp
@@ -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;
+}
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
index 3c15f2b38d80f..a8f025b1b5f5f 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
@@ -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
diff --git a/clang/lib/Sema/CMakeLists.txt b/clang/lib/Sema/CMakeLists.txt
index d3fe80f659f69..cc7921fc32254 100644
--- a/clang/lib/Sema/CMakeLists.txt
+++ b/clang/lib/Sema/CMakeLists.txt
@@ -47,6 +47,7 @@ add_clang_library(clangSema
SemaConsumer.cpp
SemaCoroutine.cpp
SemaCUDA.cpp
+ SemaDirectX.cpp
SemaDecl.cpp
SemaDeclAttr.cpp
SemaDeclCXX.cpp
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 64f5633f380ec..32d7744be9229 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.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)),
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 5a4fa97366809..674aa07992785 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -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:
diff --git a/clang/lib/Sema/SemaDirectX.cpp b/clang/lib/Sema/SemaDirectX.cpp
new file mode 100644
index 0000000000000..eaac24cdc710e
--- /dev/null
+++ b/clang/lib/Sema/SemaDirectX.cpp
@@ -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
diff --git a/clang/test/CodeGenDirectX/Builtins/dot2add.c b/clang/test/CodeGenDirectX/Builtins/dot2add.c
new file mode 100644
index 0000000000000..181f61fea1544
--- /dev/null
+++ b/clang/test/CodeGenDirectX/Builtins/dot2add.c
@@ -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); }
|
@llvm/pr-subscribers-backend-x86 Author: Farzon Lotfi (farzonl) Changes
Full diff: https://github.com/llvm/llvm-project/pull/134439.diff 20 Files Affected:
diff --git a/.github/new-prs-labeler.yml b/.github/new-prs-labeler.yml
index b93cdff8af345..c0c61748010d0 100644
--- a/.github/new-prs-labeler.yml
+++ b/.github/new-prs-labeler.yml
@@ -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.*
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index c7ca607e4b3d2..b2c7ddb43de55 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -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];
diff --git a/clang/include/clang/Basic/BuiltinsDirectX.td b/clang/include/clang/Basic/BuiltinsDirectX.td
new file mode 100644
index 0000000000000..444532ab2874a
--- /dev/null
+++ b/clang/include/clang/Basic/BuiltinsDirectX.td
@@ -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)";
+}
diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt
index 6be6d063c20b4..4d5e1eaa3facb 100644
--- a/clang/include/clang/Basic/CMakeLists.txt
+++ b/clang/include/clang/Basic/CMakeLists.txt
@@ -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)
diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h
index c1ba65064f159..4e490d87ee8d6 100644
--- a/clang/include/clang/Basic/TargetBuiltins.h
+++ b/clang/include/clang/Basic/TargetBuiltins.h
@@ -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 {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6bf1caf6bdd18..30917e7ca0310 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -160,6 +160,7 @@ class SemaAVR;
class SemaBPF;
class SemaCodeCompletion;
class SemaCUDA;
+class SemaDirectX;
class SemaHLSL;
class SemaHexagon;
class SemaLoongArch;
@@ -1074,6 +1075,11 @@ class Sema final : public SemaBase {
return *CUDAPtr;
}
+ SemaDirectX &DirectX() {
+ assert(DirectXPtr);
+ return *DirectXPtr;
+ }
+
SemaHLSL &HLSL() {
assert(HLSLPtr);
return *HLSLPtr;
@@ -1212,6 +1218,7 @@ class Sema final : public SemaBase {
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;
diff --git a/clang/include/clang/Sema/SemaDirectX.h b/clang/include/clang/Sema/SemaDirectX.h
new file mode 100644
index 0000000000000..ae9cd61318714
--- /dev/null
+++ b/clang/include/clang/Sema/SemaDirectX.h
@@ -0,0 +1,29 @@
+//===----- 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
\ No newline at end of file
diff --git a/clang/lib/Basic/Targets/DirectX.cpp b/clang/lib/Basic/Targets/DirectX.cpp
index 0dd27e6e93b33..ff0c062e80947 100644
--- a/clang/lib/Basic/Targets/DirectX.cpp
+++ b/clang/lib/Basic/Targets/DirectX.cpp
@@ -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}};
+}
\ No newline at end of file
diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h
index 6e3ddad626341..0e88a37e32493 100644
--- a/clang/lib/Basic/Targets/DirectX.h
+++ b/clang/lib/Basic/Targets/DirectX.h
@@ -73,9 +73,7 @@ class LLVM_LIBRARY_VISIBILITY DirectXTargetInfo : public TargetInfo {
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 ""; }
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 310addebd50e9..fe55dfffc1cbe 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -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);
diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index 27d1c69439944..99c62808c323d 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -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));
diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt
index ebe2fbd7db295..dc5b2a35583b4 100644
--- a/clang/lib/CodeGen/CMakeLists.txt
+++ b/clang/lib/CodeGen/CMakeLists.txt
@@ -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
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index af9798b30fbcf..34dee6df9dcfc 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4809,6 +4809,7 @@ class CodeGenFunction : public CodeGenTypeCache {
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);
diff --git a/clang/lib/CodeGen/TargetBuiltins/DirectX.cpp b/clang/lib/CodeGen/TargetBuiltins/DirectX.cpp
new file mode 100644
index 0000000000000..202601e257036
--- /dev/null
+++ b/clang/lib/CodeGen/TargetBuiltins/DirectX.cpp
@@ -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;
+}
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
index 3c15f2b38d80f..a8f025b1b5f5f 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
@@ -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
diff --git a/clang/lib/Sema/CMakeLists.txt b/clang/lib/Sema/CMakeLists.txt
index d3fe80f659f69..cc7921fc32254 100644
--- a/clang/lib/Sema/CMakeLists.txt
+++ b/clang/lib/Sema/CMakeLists.txt
@@ -47,6 +47,7 @@ add_clang_library(clangSema
SemaConsumer.cpp
SemaCoroutine.cpp
SemaCUDA.cpp
+ SemaDirectX.cpp
SemaDecl.cpp
SemaDeclAttr.cpp
SemaDeclCXX.cpp
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 64f5633f380ec..32d7744be9229 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.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)),
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 5a4fa97366809..674aa07992785 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -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:
diff --git a/clang/lib/Sema/SemaDirectX.cpp b/clang/lib/Sema/SemaDirectX.cpp
new file mode 100644
index 0000000000000..eaac24cdc710e
--- /dev/null
+++ b/clang/lib/Sema/SemaDirectX.cpp
@@ -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
diff --git a/clang/test/CodeGenDirectX/Builtins/dot2add.c b/clang/test/CodeGenDirectX/Builtins/dot2add.c
new file mode 100644
index 0000000000000..181f61fea1544
--- /dev/null
+++ b/clang/test/CodeGenDirectX/Builtins/dot2add.c
@@ -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); }
|
@llvm/pr-subscribers-clang-codegen Author: Farzon Lotfi (farzonl) Changes
Full diff: https://github.com/llvm/llvm-project/pull/134439.diff 20 Files Affected:
diff --git a/.github/new-prs-labeler.yml b/.github/new-prs-labeler.yml
index b93cdff8af345..c0c61748010d0 100644
--- a/.github/new-prs-labeler.yml
+++ b/.github/new-prs-labeler.yml
@@ -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.*
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index c7ca607e4b3d2..b2c7ddb43de55 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -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];
diff --git a/clang/include/clang/Basic/BuiltinsDirectX.td b/clang/include/clang/Basic/BuiltinsDirectX.td
new file mode 100644
index 0000000000000..444532ab2874a
--- /dev/null
+++ b/clang/include/clang/Basic/BuiltinsDirectX.td
@@ -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)";
+}
diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt
index 6be6d063c20b4..4d5e1eaa3facb 100644
--- a/clang/include/clang/Basic/CMakeLists.txt
+++ b/clang/include/clang/Basic/CMakeLists.txt
@@ -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)
diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h
index c1ba65064f159..4e490d87ee8d6 100644
--- a/clang/include/clang/Basic/TargetBuiltins.h
+++ b/clang/include/clang/Basic/TargetBuiltins.h
@@ -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 {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6bf1caf6bdd18..30917e7ca0310 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -160,6 +160,7 @@ class SemaAVR;
class SemaBPF;
class SemaCodeCompletion;
class SemaCUDA;
+class SemaDirectX;
class SemaHLSL;
class SemaHexagon;
class SemaLoongArch;
@@ -1074,6 +1075,11 @@ class Sema final : public SemaBase {
return *CUDAPtr;
}
+ SemaDirectX &DirectX() {
+ assert(DirectXPtr);
+ return *DirectXPtr;
+ }
+
SemaHLSL &HLSL() {
assert(HLSLPtr);
return *HLSLPtr;
@@ -1212,6 +1218,7 @@ class Sema final : public SemaBase {
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;
diff --git a/clang/include/clang/Sema/SemaDirectX.h b/clang/include/clang/Sema/SemaDirectX.h
new file mode 100644
index 0000000000000..ae9cd61318714
--- /dev/null
+++ b/clang/include/clang/Sema/SemaDirectX.h
@@ -0,0 +1,29 @@
+//===----- 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
\ No newline at end of file
diff --git a/clang/lib/Basic/Targets/DirectX.cpp b/clang/lib/Basic/Targets/DirectX.cpp
index 0dd27e6e93b33..ff0c062e80947 100644
--- a/clang/lib/Basic/Targets/DirectX.cpp
+++ b/clang/lib/Basic/Targets/DirectX.cpp
@@ -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}};
+}
\ No newline at end of file
diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h
index 6e3ddad626341..0e88a37e32493 100644
--- a/clang/lib/Basic/Targets/DirectX.h
+++ b/clang/lib/Basic/Targets/DirectX.h
@@ -73,9 +73,7 @@ class LLVM_LIBRARY_VISIBILITY DirectXTargetInfo : public TargetInfo {
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 ""; }
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 310addebd50e9..fe55dfffc1cbe 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -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);
diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index 27d1c69439944..99c62808c323d 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -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));
diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt
index ebe2fbd7db295..dc5b2a35583b4 100644
--- a/clang/lib/CodeGen/CMakeLists.txt
+++ b/clang/lib/CodeGen/CMakeLists.txt
@@ -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
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index af9798b30fbcf..34dee6df9dcfc 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4809,6 +4809,7 @@ class CodeGenFunction : public CodeGenTypeCache {
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);
diff --git a/clang/lib/CodeGen/TargetBuiltins/DirectX.cpp b/clang/lib/CodeGen/TargetBuiltins/DirectX.cpp
new file mode 100644
index 0000000000000..202601e257036
--- /dev/null
+++ b/clang/lib/CodeGen/TargetBuiltins/DirectX.cpp
@@ -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;
+}
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
index 3c15f2b38d80f..a8f025b1b5f5f 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h
@@ -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
diff --git a/clang/lib/Sema/CMakeLists.txt b/clang/lib/Sema/CMakeLists.txt
index d3fe80f659f69..cc7921fc32254 100644
--- a/clang/lib/Sema/CMakeLists.txt
+++ b/clang/lib/Sema/CMakeLists.txt
@@ -47,6 +47,7 @@ add_clang_library(clangSema
SemaConsumer.cpp
SemaCoroutine.cpp
SemaCUDA.cpp
+ SemaDirectX.cpp
SemaDecl.cpp
SemaDeclAttr.cpp
SemaDeclCXX.cpp
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 64f5633f380ec..32d7744be9229 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.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)),
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 5a4fa97366809..674aa07992785 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -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:
diff --git a/clang/lib/Sema/SemaDirectX.cpp b/clang/lib/Sema/SemaDirectX.cpp
new file mode 100644
index 0000000000000..eaac24cdc710e
--- /dev/null
+++ b/clang/lib/Sema/SemaDirectX.cpp
@@ -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
diff --git a/clang/test/CodeGenDirectX/Builtins/dot2add.c b/clang/test/CodeGenDirectX/Builtins/dot2add.c
new file mode 100644
index 0000000000000..181f61fea1544
--- /dev/null
+++ b/clang/test/CodeGenDirectX/Builtins/dot2add.c
@@ -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); }
|
a44ad52
to
a420186
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Just a few comments.
@@ -0,0 +1,23 @@ | |||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The filename should probably be dot2add.hlsl.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No this is a c only test. Since we are exposing the backend api as a target any frontend is technically suppose to be able to access it. This test is to confirm that we aren't gating the directX backend.
//===----- SemaDirectX.h ----- Semantic Analysis for DirectX | ||
// constructs--------===// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this supposed to be on 2 lines?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch. no this should be one line
|
||
bool SemaDirectX::CheckDirectXBuiltinFunctionCall(unsigned BuiltinID, | ||
CallExpr *TheCall) { | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there really no checking needed for the __builtin_dx_dot2add
call? Maybe add an empty switch to make that explicit?
return false; | |
switch (BuiltinID) { | |
case DirectX::BI__builtin_dx_dot2add: | |
return false; | |
} | |
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the Prototype for __builtin_dx_dot2add
defines the types for the arguments and return type the semantic rules are handled via language rules. It felt weird to explicitly return false when that was going to happen any ways. I decided to do nothing because a similar case in __builtin_hlsl_wave_active_all_true
we also did not explicitly handle it. I don't have a strong opinion here and could be convinced to do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case, I think that if we want to add empty switch cases for this then it should be a separate PR to change it for all other the other builtins at once.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The plan right now is that we do target builtins when one of our two targets has an opcode and the other does not. Im not aware of another case right now for directx. The problem i have with removing sema scaffolding when i don’t have another candidate in mind is it feel like we have incomplete support for target builtins if we strip out all the sema changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this change. It helps make implementing builtins more consistent between SPIR-V and DirectX/DXIL
|
||
bool SemaDirectX::CheckDirectXBuiltinFunctionCall(unsigned BuiltinID, | ||
CallExpr *TheCall) { | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case, I think that if we want to add empty switch cases for this then it should be a separate PR to change it for all other the other builtins at once.
Fixes fallback from llvm#134439
clang/lib/CodeGen/TargetBuiltins/DirectX.cpp