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

adding clang codegen #109331

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -4788,6 +4788,12 @@ def HLSLStep: LangBuiltin<"HLSL_LANG"> {
let Prototype = "void(...)";
}

def HLSLAsUintSplitDouble: LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_asuint_splitdouble"];
let Attributes = [NoThrow, Const];
let Prototype = "void(...)";
}

// Builtins for XRay.
def XRayCustomEvent : Builtin {
let Spellings = ["__xray_customevent"];
Expand Down
28 changes: 28 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//

#include "ABIInfo.h"
#include "Address.h"
#include "CGCUDARuntime.h"
#include "CGCXXABI.h"
#include "CGHLSLRuntime.h"
Expand Down Expand Up @@ -18824,6 +18825,33 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
retType, CGM.getHLSLRuntime().getSignIntrinsic(),
ArrayRef<Value *>{Op0}, nullptr, "hlsl.sign");
}
// This should only be called when targeting DXIL
case Builtin::BI__builtin_hlsl_asuint_splitdouble: {

assert((E->getArg(0)->getType()->isDoubleType() &&
E->getArg(1)->getType()->isUnsignedIntegerType() &&
E->getArg(2)->getType()->isUnsignedIntegerType()) &&
"asuint operands types mismatch");

Value *Op0 = EmitScalarExpr(E->getArg(0));
llvm::Type *retType = llvm::StructType::get(Int32Ty, Int32Ty);
if (Op0->getType()->isVectorTy()) {
auto *XVecTy = E->getArg(0)->getType()->getAs<VectorType>();

llvm::VectorType *i32VecTy = llvm::VectorType::get(
Int32Ty, ElementCount::getFixed(XVecTy->getNumElements()));

retType = llvm::StructType::get(i32VecTy, i32VecTy);
}

CallInst *CI =
Builder.CreateIntrinsic(retType, llvm::Intrinsic::dx_asuint_splitdouble,
{Op0}, nullptr, "hlsl.asuint");

Value *arg1 = Builder.CreateExtractValue(CI, 1);
auto addr = EmitPointerWithAlignment(E->getArg(1));
return Builder.CreateStore(arg1, addr);
}
}
return nullptr;
}
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/CodeGen/CGExprScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "llvm/IR/IntrinsicsPowerPC.h"
#include "llvm/IR/MatrixBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TypeSize.h"
#include <cstdarg>
#include <optional>
Expand Down Expand Up @@ -476,6 +477,10 @@ class ScalarExprEmitter
return Visit(E->getSubExpr());
}

Value *VisitHLSLOutArgExpr(HLSLOutArgExpr *E) {
return Visit(E->getArgLValue());
}

// Leaves.
Value *VisitIntegerLiteral(const IntegerLiteral *E) {
return Builder.getInt(E->getValue());
Expand Down
1 change: 0 additions & 1 deletion clang/lib/CodeGen/CGHLSLRuntime.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ class CGHLSLRuntime {
GENERATE_HLSL_INTRINSIC_FUNCTION(SDot, sdot)
GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot)
GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane)

//===----------------------------------------------------------------------===//
// End of reserved area for HLSL intrinsic getters.
//===----------------------------------------------------------------------===//
Expand Down
20 changes: 20 additions & 0 deletions clang/lib/Headers/hlsl/hlsl_intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,26 @@ template <typename T> _HLSL_INLINE uint asuint(T F) {
return __detail::bit_cast<uint, T>(F);
}

//===----------------------------------------------------------------------===//
// asuint splitdouble builtins
//===----------------------------------------------------------------------===//

/// \fn void asuint(double D, out uint lowbits, out int highbits)
/// \brief Split and interprets the lowbits and highbits of double D into uints.
/// \param D The input double.
/// \param lowbits The output lowbits of D.
/// \param highbits The highbits lowbits D.
#if __is_target_arch(dxil)
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_asuint_splitdouble)
void asuint(double, out uint, out uint);
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_asuint_splitdouble)
void asuint(double2, out uint2, out uint2);
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_asuint_splitdouble)
void asuint(double3, out uint3, out uint3);
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_asuint_splitdouble)
void asuint(double4, out uint4, out uint4);
#endif

//===----------------------------------------------------------------------===//
// atan builtins
//===----------------------------------------------------------------------===//
Expand Down
56 changes: 48 additions & 8 deletions clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1467,18 +1467,27 @@ bool CheckVectorElementCallArgs(Sema *S, CallExpr *TheCall) {
return true;
}

bool CheckArgTypeIsCorrect(
Sema *S, Expr *Arg, QualType ExpectedType,
llvm::function_ref<bool(clang::QualType PassedType)> Check) {
QualType PassedType = Arg->getType();
if (Check(PassedType)) {
if (auto *VecTyA = PassedType->getAs<VectorType>())
ExpectedType = S->Context.getVectorType(
ExpectedType, VecTyA->getNumElements(), VecTyA->getVectorKind());
S->Diag(Arg->getBeginLoc(), diag::err_typecheck_convert_incompatible)
<< PassedType << ExpectedType << 1 << 0 << 0;
return true;
}
return false;
}

bool CheckArgsTypesAreCorrect(
Sema *S, CallExpr *TheCall, QualType ExpectedType,
llvm::function_ref<bool(clang::QualType PassedType)> Check) {
for (unsigned i = 0; i < TheCall->getNumArgs(); ++i) {
QualType PassedType = TheCall->getArg(i)->getType();
if (Check(PassedType)) {
if (auto *VecTyA = PassedType->getAs<VectorType>())
ExpectedType = S->Context.getVectorType(
ExpectedType, VecTyA->getNumElements(), VecTyA->getVectorKind());
S->Diag(TheCall->getArg(0)->getBeginLoc(),
diag::err_typecheck_convert_incompatible)
<< PassedType << ExpectedType << 1 << 0 << 0;
Expr *Arg = TheCall->getArg(i);
if (CheckArgTypeIsCorrect(S, Arg, ExpectedType, Check)) {
return true;
}
}
Expand Down Expand Up @@ -1762,6 +1771,37 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
return true;
break;
}
case Builtin::BI__builtin_hlsl_asuint_splitdouble: {
if (SemaRef.checkArgCount(TheCall, 3))
return true;

Expr *Op0 = TheCall->getArg(0);

auto CheckIsNotDouble = [](clang::QualType PassedType) -> bool {
return !PassedType->isDoubleType();
};

if (CheckArgTypeIsCorrect(&SemaRef, Op0, SemaRef.Context.DoubleTy,
CheckIsNotDouble)) {
return true;
}

Expr *Op1 = TheCall->getArg(1);
Expr *Op2 = TheCall->getArg(2);

auto CheckIsNotUint = [](clang::QualType PassedType) -> bool {
return !PassedType->isUnsignedIntegerType();
};

if (CheckArgTypeIsCorrect(&SemaRef, Op1, SemaRef.Context.UnsignedIntTy,
CheckIsNotUint) ||
CheckArgTypeIsCorrect(&SemaRef, Op2, SemaRef.Context.UnsignedIntTy,
CheckIsNotUint)) {
return true;
}

break;
}
case Builtin::BI__builtin_elementwise_acos:
case Builtin::BI__builtin_elementwise_asin:
case Builtin::BI__builtin_elementwise_atan:
Expand Down
9 changes: 9 additions & 0 deletions clang/test/CodeGenHLSL/builtins/asuint-splitdouble.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -O0 -o - | FileCheck %s

// CHECK: define {{.*}}test_scalar{{.*}}(double {{.*}} [[VAL1:%.*]], i32 {{.*}} [[VAL2:%.*]], i32 {{.*}} [[VAL3:%.*]]){{.*}}
// CHECK: [[VALD:%.*]] = load double, ptr [[VAL1]].addr{{.*}}
// CHECK: call { i32, i32 } @llvm.dx.asuint.splitdouble.{{.*}}(double [[VALD]])
uint test_scalar(double d, uint lb, uint hb) {
asuint(d, lb, hb);
return lb;
}
5 changes: 5 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsDirectX.td
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,9 @@ def int_dx_rsqrt : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]
def int_dx_wave_is_first_lane : DefaultAttrsIntrinsic<[llvm_i1_ty], [], [IntrConvergent]>;
def int_dx_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty], [IntrNoMem]>;
def int_dx_step : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, LLVMMatchType<0>], [IntrNoMem]>;

def int_dx_asuint_splitdouble : DefaultAttrsIntrinsic<
[llvm_anyint_ty, LLVMMatchType<0>],
[LLVMScalarOrSameVectorWidth<0, llvm_double_ty>],
[IntrNoMem, IntrWillReturn]>;
}
1 change: 1 addition & 0 deletions llvm/lib/Target/DirectX/DXIL.td
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,7 @@ def FlattenedThreadIdInGroup : DXILOp<96, flattenedThreadIdInGroup> {
let stages = [Stages<DXIL1_0, [compute, mesh, amplification, node]>];
let attributes = [Attributes<DXIL1_0, [ReadNone]>];
}
//

def AnnotateHandle : DXILOp<217, annotateHandle> {
let Doc = "annotate handle with resource properties";
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include "DXILIntrinsicExpansion.h"
#include "DirectX.h"
#include "llvm-c/Core.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/DXILResource.h"
Expand Down Expand Up @@ -346,6 +347,15 @@ static Value *expandStepIntrinsic(CallInst *Orig) {
return Builder.CreateSelect(Cond, Zero, One);
}

// static Value *expandSplitdoubleIntrinsic(CallInst *Orig) {
// Value *X = Orig->getOperand(0);
// Type *Ty = X->getType();
// IRBuilder<> Builder(Orig);

// Builder.CreateIntrinsic()

// }

static Intrinsic::ID getMaxForClamp(Type *ElemTy,
Intrinsic::ID ClampIntrinsic) {
if (ClampIntrinsic == Intrinsic::dx_uclamp)
Expand Down Expand Up @@ -459,6 +469,9 @@ static bool expandIntrinsic(Function &F, CallInst *Orig) {
break;
case Intrinsic::dx_step:
Result = expandStepIntrinsic(Orig);
break;
// case Intrinsic::dx_asuint_splitdouble:
// Result = expandSplitdoubleIntrinsic(Orig);
}
if (Result) {
Orig->replaceAllUsesWith(Result);
Expand Down