diff --git a/clang/include/clang/Basic/BuiltinsDirectX.def b/clang/include/clang/Basic/BuiltinsDirectX.def new file mode 100644 --- /dev/null +++ b/clang/include/clang/Basic/BuiltinsDirectX.def @@ -0,0 +1,28 @@ +//===-- BuiltinsDirectX.def - DirectX Builtin function database -*- C++ -*-===// +// +// 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 file defines the DirectX-specific builtin function database. Users of +// this file must define the BUILTIN macro to make use of this information. +// +//===----------------------------------------------------------------------===// + +// The format of this database matches clang/Basic/Builtins.def. + +#if defined(BUILTIN) && !defined(TARGET_BUILTIN) +# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) +#endif + +#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN) +# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS) +#endif + +BUILTIN(__builtin_dx_umax_i32, "UiUiUi", "ne") +BUILTIN(__builtin_dx_umin_i32, "UiUiUi", "ne") + +#undef BUILTIN +#undef TARGET_BUILTIN diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -75,6 +75,16 @@ }; } + /// DirectX builtins + namespace DirectX { + enum { + LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, +#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#include "clang/Basic/BuiltinsDirectX.def" + LastTSBuiltin + }; + } // namespace DirectX + /// PPC builtins namespace PPC { enum { diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h --- a/clang/lib/Basic/Targets/DirectX.h +++ b/clang/lib/Basic/Targets/DirectX.h @@ -44,6 +44,9 @@ }; class LLVM_LIBRARY_VISIBILITY DirectXTargetInfo : public TargetInfo { + + static const Builtin::Info BuiltinInfo[]; + public: DirectXTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { @@ -66,7 +69,7 @@ return Feature == "directx"; } - ArrayRef getTargetBuiltins() const override { return None; } + ArrayRef getTargetBuiltins() const override; const char *getClobbers() const override { return ""; } diff --git a/clang/lib/Basic/Targets/DirectX.cpp b/clang/lib/Basic/Targets/DirectX.cpp --- a/clang/lib/Basic/Targets/DirectX.cpp +++ b/clang/lib/Basic/Targets/DirectX.cpp @@ -12,6 +12,8 @@ #include "DirectX.h" #include "Targets.h" +#include "clang/Basic/Builtins.h" +#include "clang/Basic/TargetBuiltins.h" using namespace clang; using namespace clang::targets; @@ -20,3 +22,16 @@ MacroBuilder &Builder) const { DefineStd(Builder, "DIRECTX", Opts); } + +const Builtin::Info DirectXTargetInfo::BuiltinInfo[] = { +#define BUILTIN(ID, TYPE, ATTRS) \ + {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ + {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, +#include "clang/Basic/BuiltinsDirectX.def" +}; + +ArrayRef DirectXTargetInfo::getTargetBuiltins() const { + return llvm::makeArrayRef(BuiltinInfo, clang::DirectX::LastTSBuiltin - + Builtin::FirstTSBuiltin); +} diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -5524,6 +5524,8 @@ 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); @@ -12088,6 +12090,20 @@ } } +Value *CodeGenFunction::EmitDirectXBuiltinExpr(unsigned BuiltinID, + const CallExpr *E) { + switch (BuiltinID) { + default: + llvm_unreachable("Unexpected DirectX builtin"); + case DirectX::BI__builtin_dx_umax_i32: { + return emitBinaryBuiltin(*this, E, Intrinsic::umax); + } + case DirectX::BI__builtin_dx_umin_i32: { + return emitBinaryBuiltin(*this, E, Intrinsic::umin); + } + } +} + llvm::Value *CodeGenFunction:: BuildVector(ArrayRef Ops) { assert((Ops.size() & (Ops.size() - 1)) == 0 && diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -4239,6 +4239,7 @@ llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E, llvm::Triple::ArchType Arch); llvm::Value *EmitBPFBuiltinExpr(unsigned BuiltinID, const CallExpr *E); + llvm::Value *EmitDirectXBuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *BuildVector(ArrayRef Ops); llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E); diff --git a/clang/test/CodeGenHLSL/umax_umin.hlsl b/clang/test/CodeGenHLSL/umax_umin.hlsl new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenHLSL/umax_umin.hlsl @@ -0,0 +1,13 @@ +// RUN: %clang_dxc -Tlib_6_7 -Fo - %s | FileCheck %s + +// Make sure __builtin_dx_umax/umin_i32 is lowered to llvm.umax/umin.i32. +//CHECK:call i32 @llvm.umax.i32(i32 %{{.*}}, i32 %{{.*}}) +//CHECK:call i32 @llvm.umin.i32(i32 %{{.*}}, i32 %{{.*}}) + +unsigned foo(unsigned a, unsigned b) { + return __builtin_dx_umax_i32(a, b); +} + +unsigned bar(unsigned a, unsigned b) { + return __builtin_dx_umin_i32(a, b); +}