Skip to content

Commit 8f21239

Browse files
adding clang codegen
1 parent 1335a11 commit 8f21239

File tree

9 files changed

+137
-10
lines changed

9 files changed

+137
-10
lines changed

clang/include/clang/Basic/Builtins.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4788,6 +4788,12 @@ def HLSLStep: LangBuiltin<"HLSL_LANG"> {
47884788
let Prototype = "void(...)";
47894789
}
47904790

4791+
def HLSLAsUintSplitDouble: LangBuiltin<"HLSL_LANG"> {
4792+
let Spellings = ["__builtin_hlsl_asuint_splitdouble"];
4793+
let Attributes = [NoThrow, Const];
4794+
let Prototype = "void(...)";
4795+
}
4796+
47914797
// Builtins for XRay.
47924798
def XRayCustomEvent : Builtin {
47934799
let Spellings = ["__xray_customevent"];

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18824,6 +18824,40 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
1882418824
retType, CGM.getHLSLRuntime().getSignIntrinsic(),
1882518825
ArrayRef<Value *>{Op0}, nullptr, "hlsl.sign");
1882618826
}
18827+
// This should only be called when targeting DXIL
18828+
case Builtin::BI__builtin_hlsl_asuint_splitdouble: {
18829+
18830+
assert((E->getArg(0)->getType()->isDoubleType() ||
18831+
E->getArg(1)->getType()->isUnsignedIntegerType() ||
18832+
E->getArg(2)->getType()->isUnsignedIntegerType()) &&
18833+
"asuint operands types mismatch");
18834+
18835+
Value *Op0 = EmitScalarExpr(E->getArg(0));
18836+
18837+
llvm::Type *retType = llvm::StructType::get(Int32Ty, Int32Ty);
18838+
if (Op0->getType()->isVectorTy()) {
18839+
auto *XVecTy = E->getArg(0)->getType()->getAs<VectorType>();
18840+
18841+
llvm::VectorType *i32VecTy = llvm::VectorType::get(
18842+
Int32Ty, ElementCount::getFixed(XVecTy->getNumElements()));
18843+
18844+
retType = llvm::StructType::get(i32VecTy, i32VecTy);
18845+
}
18846+
18847+
auto ptr = CreateMemTemp(E->getArg(1)->getType());
18848+
EmitAnyExprToMem(E->getArg(1), ptr, Qualifiers(), /*init*/ true);
18849+
Address x = EmitPointerWithAlignment(E->getArg(1));
18850+
18851+
CallInst *CI =
18852+
Builder.CreateIntrinsic(retType, llvm::Intrinsic::dx_asuint_splitdouble,
18853+
{Op0}, nullptr, "hlsl.asuint");
18854+
18855+
// Value* arg1 = Builder.CreateExtractValue(CI, 1);
18856+
18857+
// Address y = EmitPointerWithAlignment(E->getArg(2));
18858+
// Builder.CreateLoad(ptr);
18859+
// return Builder.CreateStore(arg1, ptr);
18860+
}
1882718861
}
1882818862
return nullptr;
1882918863
}
@@ -22398,4 +22432,4 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
2239822432

2239922433
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
2240022434
return Builder.CreateCall(F, Ops, "");
22401-
}
22435+
}

clang/lib/CodeGen/CGHLSLRuntime.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ class CGHLSLRuntime {
8787
GENERATE_HLSL_INTRINSIC_FUNCTION(SDot, sdot)
8888
GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot)
8989
GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane)
90-
9190
//===----------------------------------------------------------------------===//
9291
// End of reserved area for HLSL intrinsic getters.
9392
//===----------------------------------------------------------------------===//

clang/lib/Headers/hlsl/hlsl_intrinsics.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,26 @@ template <typename T> _HLSL_INLINE uint asuint(T F) {
423423
return __detail::bit_cast<uint, T>(F);
424424
}
425425

426+
//===----------------------------------------------------------------------===//
427+
// asuint splitdouble builtins
428+
//===----------------------------------------------------------------------===//
429+
430+
/// \fn void asuint(double D, out uint lowbits, out int highbits)
431+
/// \brief Split and interprets the lowbits and highbits of double D into uints.
432+
/// \param D The input double.
433+
/// \param lowbits The output lowbits of D.
434+
/// \param highbits The highbits lowbits D.
435+
#if __is_target_arch(dxil)
436+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_asuint_splitdouble)
437+
void asuint(double, out uint, out uint);
438+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_asuint_splitdouble)
439+
void asuint(double2, out uint2, out uint2);
440+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_asuint_splitdouble)
441+
void asuint(double3, out uint3, out uint3);
442+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_asuint_splitdouble)
443+
void asuint(double4, out uint4, out uint4);
444+
#endif
445+
426446
//===----------------------------------------------------------------------===//
427447
// atan builtins
428448
//===----------------------------------------------------------------------===//

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1467,18 +1467,27 @@ bool CheckVectorElementCallArgs(Sema *S, CallExpr *TheCall) {
14671467
return true;
14681468
}
14691469

1470+
bool CheckArgTypeIsCorrect(
1471+
Sema *S, Expr *Arg, QualType ExpectedType,
1472+
llvm::function_ref<bool(clang::QualType PassedType)> Check) {
1473+
QualType PassedType = Arg->getType();
1474+
if (Check(PassedType)) {
1475+
if (auto *VecTyA = PassedType->getAs<VectorType>())
1476+
ExpectedType = S->Context.getVectorType(
1477+
ExpectedType, VecTyA->getNumElements(), VecTyA->getVectorKind());
1478+
S->Diag(Arg->getBeginLoc(), diag::err_typecheck_convert_incompatible)
1479+
<< PassedType << ExpectedType << 1 << 0 << 0;
1480+
return true;
1481+
}
1482+
return false;
1483+
}
1484+
14701485
bool CheckArgsTypesAreCorrect(
14711486
Sema *S, CallExpr *TheCall, QualType ExpectedType,
14721487
llvm::function_ref<bool(clang::QualType PassedType)> Check) {
14731488
for (unsigned i = 0; i < TheCall->getNumArgs(); ++i) {
1474-
QualType PassedType = TheCall->getArg(i)->getType();
1475-
if (Check(PassedType)) {
1476-
if (auto *VecTyA = PassedType->getAs<VectorType>())
1477-
ExpectedType = S->Context.getVectorType(
1478-
ExpectedType, VecTyA->getNumElements(), VecTyA->getVectorKind());
1479-
S->Diag(TheCall->getArg(0)->getBeginLoc(),
1480-
diag::err_typecheck_convert_incompatible)
1481-
<< PassedType << ExpectedType << 1 << 0 << 0;
1489+
Expr *Arg = TheCall->getArg(i);
1490+
if (CheckArgTypeIsCorrect(S, Arg, ExpectedType, Check)) {
14821491
return true;
14831492
}
14841493
}
@@ -1762,6 +1771,37 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
17621771
return true;
17631772
break;
17641773
}
1774+
case Builtin::BI__builtin_hlsl_asuint_splitdouble: {
1775+
if (SemaRef.checkArgCount(TheCall, 3))
1776+
return true;
1777+
1778+
Expr *Op0 = TheCall->getArg(0);
1779+
1780+
auto CheckIsNotDouble = [](clang::QualType PassedType) -> bool {
1781+
return !PassedType->isDoubleType();
1782+
};
1783+
1784+
if (CheckArgTypeIsCorrect(&SemaRef, Op0, SemaRef.Context.DoubleTy,
1785+
CheckIsNotDouble)) {
1786+
return true;
1787+
}
1788+
1789+
Expr *Op1 = TheCall->getArg(1);
1790+
Expr *Op2 = TheCall->getArg(2);
1791+
1792+
auto CheckIsNotUint = [](clang::QualType PassedType) -> bool {
1793+
return !PassedType->isUnsignedIntegerType();
1794+
};
1795+
1796+
if (CheckArgTypeIsCorrect(&SemaRef, Op1, SemaRef.Context.UnsignedIntTy,
1797+
CheckIsNotUint) ||
1798+
CheckArgTypeIsCorrect(&SemaRef, Op2, SemaRef.Context.UnsignedIntTy,
1799+
CheckIsNotUint)) {
1800+
return true;
1801+
}
1802+
1803+
break;
1804+
}
17651805
case Builtin::BI__builtin_elementwise_acos:
17661806
case Builtin::BI__builtin_elementwise_asin:
17671807
case Builtin::BI__builtin_elementwise_atan:
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -O0 -o - | FileCheck %s
2+
3+
// CHECK: define {{.*}}test_scalar{{.*}}(double {{.*}} [[VAL1:%.*]], i32 {{.*}} [[VAL2:%.*]], i32 {{.*}} [[VAL3:%.*]]){{.*}}
4+
// CHECK: [[VALD:%.*]] = load double, ptr [[VAL1]].addr{{.*}}
5+
// CHECK: call { i32, i32 } @llvm.dx.asuint.splitdouble.{{.*}}(double [[VALD]])
6+
uint test_scalar(double d, uint lb, uint hb) {
7+
asuint(d, lb, hb);
8+
return lb;
9+
}

llvm/include/llvm/IR/IntrinsicsDirectX.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,9 @@ def int_dx_rsqrt : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]
8888
def int_dx_wave_is_first_lane : DefaultAttrsIntrinsic<[llvm_i1_ty], [], [IntrConvergent]>;
8989
def int_dx_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty], [IntrNoMem]>;
9090
def int_dx_step : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, LLVMMatchType<0>], [IntrNoMem]>;
91+
92+
def int_dx_asuint_splitdouble : DefaultAttrsIntrinsic<
93+
[llvm_anyint_ty, LLVMMatchType<0>],
94+
[LLVMScalarOrSameVectorWidth<0, llvm_double_ty>],
95+
[IntrNoMem, IntrWillReturn]>;
9196
}

llvm/lib/Target/DirectX/DXIL.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,7 @@ def FlattenedThreadIdInGroup : DXILOp<96, flattenedThreadIdInGroup> {
778778
let stages = [Stages<DXIL1_0, [compute, mesh, amplification, node]>];
779779
let attributes = [Attributes<DXIL1_0, [ReadNone]>];
780780
}
781+
//
781782

782783
def AnnotateHandle : DXILOp<217, annotateHandle> {
783784
let Doc = "annotate handle with resource properties";

llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "DXILIntrinsicExpansion.h"
1414
#include "DirectX.h"
15+
#include "llvm-c/Core.h"
1516
#include "llvm/ADT/STLExtras.h"
1617
#include "llvm/ADT/SmallVector.h"
1718
#include "llvm/Analysis/DXILResource.h"
@@ -346,6 +347,15 @@ static Value *expandStepIntrinsic(CallInst *Orig) {
346347
return Builder.CreateSelect(Cond, Zero, One);
347348
}
348349

350+
// static Value *expandSplitdoubleIntrinsic(CallInst *Orig) {
351+
// Value *X = Orig->getOperand(0);
352+
// Type *Ty = X->getType();
353+
// IRBuilder<> Builder(Orig);
354+
355+
// Builder.CreateIntrinsic()
356+
357+
// }
358+
349359
static Intrinsic::ID getMaxForClamp(Type *ElemTy,
350360
Intrinsic::ID ClampIntrinsic) {
351361
if (ClampIntrinsic == Intrinsic::dx_uclamp)
@@ -459,6 +469,9 @@ static bool expandIntrinsic(Function &F, CallInst *Orig) {
459469
break;
460470
case Intrinsic::dx_step:
461471
Result = expandStepIntrinsic(Orig);
472+
break;
473+
// case Intrinsic::dx_asuint_splitdouble:
474+
// Result = expandSplitdoubleIntrinsic(Orig);
462475
}
463476
if (Result) {
464477
Orig->replaceAllUsesWith(Result);

0 commit comments

Comments
 (0)