diff options
author | Farzon Lotfi <1802579+farzonl@users.noreply.github.com> | 2024-02-29 10:01:36 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-29 07:01:36 -0800 |
commit | e60ebbd0001f2e66cb9f76874ddd69290e2086c1 (patch) | |
tree | 38e0f8fa751e831117b65d1e562c298ccf6f4aac /clang/lib/Sema/SemaChecking.cpp | |
parent | 99824cf7967922bdd9ac895c949f330bb8d6b85a (diff) | |
download | llvm-e60ebbd0001f2e66cb9f76874ddd69290e2086c1.zip llvm-e60ebbd0001f2e66cb9f76874ddd69290e2086c1.tar.gz llvm-e60ebbd0001f2e66cb9f76874ddd69290e2086c1.tar.bz2 |
[HLSL] implementation of lerp intrinsic (#83077)
This is the start of implementing the lerp intrinsic
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-lerp
Builtins.td - defines the builtin
hlsl_intrinsics.h - defines the lerp api
DiagnosticSemaKinds.td - needed a new error to be inclusive for more
than two operands.
CGBuiltin.cpp - add the lerp intrinsic lowering
SemaChecking.cpp - type checks for lerp builtin
IntrinsicsDirectX.td - define the lerp intrinsic
this change implements the first half of #70102
Co-authored-by: Xiang Li <python3kgae@outlook.com>
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 69 |
1 files changed, 42 insertions, 27 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 35d453e..016e983 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5197,43 +5197,49 @@ bool Sema::CheckPPCMMAType(QualType Type, SourceLocation TypeLoc) { bool CheckVectorElementCallArgs(Sema *S, CallExpr *TheCall) { assert(TheCall->getNumArgs() > 1); ExprResult A = TheCall->getArg(0); - ExprResult B = TheCall->getArg(1); + QualType ArgTyA = A.get()->getType(); - QualType ArgTyB = B.get()->getType(); + auto *VecTyA = ArgTyA->getAs<VectorType>(); - auto *VecTyB = ArgTyB->getAs<VectorType>(); SourceLocation BuiltinLoc = TheCall->getBeginLoc(); - if (VecTyA == nullptr && VecTyB == nullptr) - return false; - if (VecTyA && VecTyB) { - bool retValue = false; - if (VecTyA->getElementType() != VecTyB->getElementType()) { - // Note: type promotion is intended to be handeled via the intrinsics - // and not the builtin itself. - S->Diag(TheCall->getBeginLoc(), diag::err_vec_builtin_incompatible_vector) - << TheCall->getDirectCallee() - << SourceRange(A.get()->getBeginLoc(), B.get()->getEndLoc()); - retValue = true; - } - if (VecTyA->getNumElements() != VecTyB->getNumElements()) { - // if we get here a HLSLVectorTruncation is needed. - S->Diag(BuiltinLoc, diag::err_vec_builtin_incompatible_vector) - << TheCall->getDirectCallee() - << SourceRange(TheCall->getArg(0)->getBeginLoc(), - TheCall->getArg(1)->getEndLoc()); - retValue = true; - } + for (unsigned i = 1; i < TheCall->getNumArgs(); ++i) { + ExprResult B = TheCall->getArg(i); + QualType ArgTyB = B.get()->getType(); + auto *VecTyB = ArgTyB->getAs<VectorType>(); + if (VecTyA == nullptr && VecTyB == nullptr) + return false; + + if (VecTyA && VecTyB) { + bool retValue = false; + if (VecTyA->getElementType() != VecTyB->getElementType()) { + // Note: type promotion is intended to be handeled via the intrinsics + // and not the builtin itself. + S->Diag(TheCall->getBeginLoc(), + diag::err_vec_builtin_incompatible_vector_all) + << TheCall->getDirectCallee() + << SourceRange(A.get()->getBeginLoc(), B.get()->getEndLoc()); + retValue = true; + } + if (VecTyA->getNumElements() != VecTyB->getNumElements()) { + // if we get here a HLSLVectorTruncation is needed. + S->Diag(BuiltinLoc, diag::err_vec_builtin_incompatible_vector_all) + << TheCall->getDirectCallee() + << SourceRange(TheCall->getArg(0)->getBeginLoc(), + TheCall->getArg(1)->getEndLoc()); + retValue = true; + } - if (retValue) - TheCall->setType(VecTyA->getElementType()); + if (!retValue) + TheCall->setType(VecTyA->getElementType()); - return retValue; + return retValue; + } } // Note: if we get here one of the args is a scalar which // requires a VectorSplat on Arg0 or Arg1 - S->Diag(BuiltinLoc, diag::err_vec_builtin_non_vector) + S->Diag(BuiltinLoc, diag::err_vec_builtin_non_vector_all) << TheCall->getDirectCallee() << SourceRange(TheCall->getArg(0)->getBeginLoc(), TheCall->getArg(1)->getEndLoc()); @@ -5253,6 +5259,15 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; break; } + case Builtin::BI__builtin_hlsl_lerp: { + if (checkArgCount(*this, TheCall, 3)) + return true; + if (CheckVectorElementCallArgs(this, TheCall)) + return true; + if (SemaBuiltinElementwiseTernaryMath(TheCall)) + return true; + break; + } } return false; } |