[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -0,0 +1,186 @@ +//===- DXILIntrinsicExpansion.cpp - Prepare LLVM Module for DXIL encoding--===// +// +// 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 contains DXIL intrinsic expansions for those that don't have +// opcodes in DirectX Intermediate Language (DXIL). +//===--===// + +#include "DXILIntrinsicExpansion.h" +#include "DirectX.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsDirectX.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" +#include "llvm/IR/Type.h" +#include "llvm/Pass.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" + +#define DEBUG_TYPE "dxil-intrinsic-expansion" + +using namespace llvm; + +static bool isIntrinsicExpansion(Function &F) { + switch (F.getIntrinsicID()) { + case Intrinsic::exp: + case Intrinsic::dx_any: + case Intrinsic::dx_lerp: + case Intrinsic::dx_rcp: +return true; + } + return false; +} + +static bool expandExpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + Constant *Log2eConst = + Ty->isVectorTy() ? ConstantVector::getSplat( + ElementCount::getFixed( + cast(Ty)->getNumElements()), + ConstantFP::get(EltTy, numbers::log2e)) + : ConstantFP::get(EltTy, numbers::log2e); + Value *NewX = Builder.CreateFMul(Log2eConst, X); + auto *Exp2Call = + Builder.CreateIntrinsic(Ty, Intrinsic::exp2, {NewX}, nullptr, "dx.exp2"); + Exp2Call->setTailCall(Orig->isTailCall()); + Exp2Call->setAttributes(Orig->getAttributes()); + Orig->replaceAllUsesWith(Exp2Call); + Orig->eraseFromParent(); + return true; +} + +static bool expandAnyIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + + if (!Ty->isVectorTy()) { +Value *Cond = EltTy->isFloatingPointTy() + ? Builder.CreateFCmpUNE(X, ConstantFP::get(EltTy, 0)) + : Builder.CreateICmpNE(X, ConstantInt::get(EltTy, 0)); +Orig->replaceAllUsesWith(Cond); + } else { +auto *XVec = dyn_cast(Ty); +Value *Cond = +EltTy->isFloatingPointTy() +? Builder.CreateFCmpUNE( + X, ConstantVector::getSplat( + ElementCount::getFixed(XVec->getNumElements()), + ConstantFP::get(EltTy, 0))) +: Builder.CreateICmpNE( + X, ConstantVector::getSplat( + ElementCount::getFixed(XVec->getNumElements()), + ConstantInt::get(EltTy, 0))); +Value *Result = Builder.CreateExtractElement(Cond, (uint64_t)0); +for (unsigned I = 1; I < XVec->getNumElements(); I++) { + Value *Elt = Builder.CreateExtractElement(Cond, I); + Result = Builder.CreateOr(Result, Elt); +} +Orig->replaceAllUsesWith(Result); + } + Orig->eraseFromParent(); + return true; +} + +static bool expandLerpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + Value *Y = Orig->getOperand(1); + Value *S = Orig->getOperand(2); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + auto *V = Builder.CreateFSub(Y, X); + V = Builder.CreateFMul(S, V); + auto *Result = Builder.CreateFAdd(X, V, "dx.lerp"); + Orig->replaceAllUsesWith(Result); + Orig->eraseFromParent(); + return true; +} + +static bool expandRcpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + Constant *One = + Ty->isVectorTy() + ? ConstantVector::getSplat( +ElementCount::getFixed( +dyn_cast(Ty)->getNumElements()), +ConstantFP::get(EltTy, 1.0)) + : ConstantFP::get(EltTy, 1.0); + auto *Result = Builder.CreateFDiv(One, X, "dx.rcp"); + Orig->replaceAllUsesWith(Result); + Orig->eraseFromParent(); + return true; +} + +static bool expandIntrinsic(Function &F, CallInst *Orig) { + switch (F.getIntrinsicID()) { + case Intrinsic::exp: +return expandExpIntrinsic(Orig); + case Intrinsic::dx_any: +
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -0,0 +1,186 @@ +//===- DXILIntrinsicExpansion.cpp - Prepare LLVM Module for DXIL encoding--===// +// +// 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 contains DXIL intrinsic expansions for those that don't have +// opcodes in DirectX Intermediate Language (DXIL). +//===--===// + +#include "DXILIntrinsicExpansion.h" +#include "DirectX.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsDirectX.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" +#include "llvm/IR/Type.h" +#include "llvm/Pass.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" + +#define DEBUG_TYPE "dxil-intrinsic-expansion" + +using namespace llvm; + +static bool isIntrinsicExpansion(Function &F) { + switch (F.getIntrinsicID()) { + case Intrinsic::exp: + case Intrinsic::dx_any: + case Intrinsic::dx_lerp: + case Intrinsic::dx_rcp: +return true; + } + return false; +} + +static bool expandExpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + Constant *Log2eConst = + Ty->isVectorTy() ? ConstantVector::getSplat( + ElementCount::getFixed( + cast(Ty)->getNumElements()), + ConstantFP::get(EltTy, numbers::log2e)) + : ConstantFP::get(EltTy, numbers::log2e); + Value *NewX = Builder.CreateFMul(Log2eConst, X); + auto *Exp2Call = + Builder.CreateIntrinsic(Ty, Intrinsic::exp2, {NewX}, nullptr, "dx.exp2"); + Exp2Call->setTailCall(Orig->isTailCall()); + Exp2Call->setAttributes(Orig->getAttributes()); + Orig->replaceAllUsesWith(Exp2Call); + Orig->eraseFromParent(); + return true; +} + +static bool expandAnyIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + + if (!Ty->isVectorTy()) { +Value *Cond = EltTy->isFloatingPointTy() + ? Builder.CreateFCmpUNE(X, ConstantFP::get(EltTy, 0)) + : Builder.CreateICmpNE(X, ConstantInt::get(EltTy, 0)); +Orig->replaceAllUsesWith(Cond); + } else { +auto *XVec = dyn_cast(Ty); +Value *Cond = +EltTy->isFloatingPointTy() +? Builder.CreateFCmpUNE( + X, ConstantVector::getSplat( + ElementCount::getFixed(XVec->getNumElements()), + ConstantFP::get(EltTy, 0))) +: Builder.CreateICmpNE( + X, ConstantVector::getSplat( + ElementCount::getFixed(XVec->getNumElements()), + ConstantInt::get(EltTy, 0))); +Value *Result = Builder.CreateExtractElement(Cond, (uint64_t)0); +for (unsigned I = 1; I < XVec->getNumElements(); I++) { + Value *Elt = Builder.CreateExtractElement(Cond, I); + Result = Builder.CreateOr(Result, Elt); +} +Orig->replaceAllUsesWith(Result); + } + Orig->eraseFromParent(); + return true; +} + +static bool expandLerpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + Value *Y = Orig->getOperand(1); + Value *S = Orig->getOperand(2); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + auto *V = Builder.CreateFSub(Y, X); + V = Builder.CreateFMul(S, V); + auto *Result = Builder.CreateFAdd(X, V, "dx.lerp"); + Orig->replaceAllUsesWith(Result); + Orig->eraseFromParent(); + return true; +} + +static bool expandRcpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + Constant *One = + Ty->isVectorTy() + ? ConstantVector::getSplat( +ElementCount::getFixed( +dyn_cast(Ty)->getNumElements()), +ConstantFP::get(EltTy, 1.0)) + : ConstantFP::get(EltTy, 1.0); + auto *Result = Builder.CreateFDiv(One, X, "dx.rcp"); + Orig->replaceAllUsesWith(Result); + Orig->eraseFromParent(); + return true; +} + +static bool expandIntrinsic(Function &F, CallInst *Orig) { + switch (F.getIntrinsicID()) { + case Intrinsic::exp: +return expandExpIntrinsic(Orig); + case Intrinsic::dx_any: +
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/coopp approved this pull request. Looks good to me for what I can understand. https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/coopp edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl closed https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/84526 >From 3f515637fc87a41db1df4ea7627679c7dd75503a Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 14 Mar 2024 18:53:33 -0400 Subject: [PATCH 1/3] [DXIL] exp, any, lerp, & rcp Intrinsic Lowering This change implements lowering for #70076, #70100, #70072, & #70102 `CGBuiltin.cpp` - - simplify `lerp` intrinsic `IntrinsicsDirectX.td` - simplify `lerp` intrinsic `SemaChecking.cpp` - remove unnecessary check `DXILIntrinsicExpansion.*` - add intrinsic to instruction expansion cases `DXILOpLowering.cpp` - make sure `DXILIntrinsicExpansion` happens first `DirectX.h` - changes to support new pass `DirectXTargetMachine.cpp` - changes to support new pass Why `any`, and `lerp` as instruction expansion just for DXIL? - SPIR-V there is an [OpAny](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpAny) - SPIR-V has a GLSL lerp extension via [Fmix](https://registry.khronos.org/SPIR-V/specs/1.0/GLSL.std.450.html#FMix) Why `exp` instruction expansion? - We have an `exp2` opcode and `exp` reuses that opcode. So instruction expansion is a convenient way to do preprocessing. - Further SPIR-V has a GLSL exp extension via [Exp](https://registry.khronos.org/SPIR-V/specs/1.0/GLSL.std.450.html#Exp) and [Exp2](https://registry.khronos.org/SPIR-V/specs/1.0/GLSL.std.450.html#Exp2) Why `rcp` as instruction expansion? This one is a bit of the odd man out and might have to move to `cgbuiltins` when we better understand SPIRV requirements. However I included it because it seems like [fast math mode has an AllowRecip flag](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#_fp_fast_math_mode) which lets you compute the reciprocal without performing the division. We don't have that in DXIL so thought to include it. --- clang/include/clang/AST/Type.h| 5 + clang/lib/CodeGen/CGBuiltin.cpp | 35 +--- clang/lib/Sema/SemaChecking.cpp | 51 +++-- .../CodeGenHLSL/builtins/lerp-builtin.hlsl| 22 --- clang/test/CodeGenHLSL/builtins/lerp.hlsl | 27 ++- clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl | 17 +- llvm/include/llvm/IR/IntrinsicsDirectX.td | 4 +- llvm/lib/Target/DirectX/CMakeLists.txt| 1 + .../Target/DirectX/DXILIntrinsicExpansion.cpp | 186 ++ .../Target/DirectX/DXILIntrinsicExpansion.h | 33 llvm/lib/Target/DirectX/DXILOpLowering.cpp| 6 +- llvm/lib/Target/DirectX/DirectX.h | 6 + .../Target/DirectX/DirectXTargetMachine.cpp | 2 + llvm/test/CodeGen/DirectX/any.ll | 105 ++ llvm/test/CodeGen/DirectX/exp-vec.ll | 16 ++ llvm/test/CodeGen/DirectX/exp.ll | 29 +++ llvm/test/CodeGen/DirectX/lerp.ll | 53 + llvm/test/CodeGen/DirectX/rcp.ll | 48 + 18 files changed, 557 insertions(+), 89 deletions(-) create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.h create mode 100644 llvm/test/CodeGen/DirectX/any.ll create mode 100644 llvm/test/CodeGen/DirectX/exp-vec.ll create mode 100644 llvm/test/CodeGen/DirectX/exp.ll create mode 100644 llvm/test/CodeGen/DirectX/lerp.ll create mode 100644 llvm/test/CodeGen/DirectX/rcp.ll diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 1942b0e67f65a3..10916053cdfbf5 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2244,6 +2244,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661 + bool isFloat32Type() const; bool isBFloat16Type() const; bool isFloat128Type() const; bool isIbm128Type() const; @@ -7452,6 +7453,10 @@ inline bool Type::isFloat16Type() const { return isSpecificBuiltinType(BuiltinType::Float16); } +inline bool Type::isFloat32Type() const { + return isSpecificBuiltinType(BuiltinType::Float); +} + inline bool Type::isBFloat16Type() const { return isSpecificBuiltinType(BuiltinType::BFloat16); } diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index b9d1a4912385e1..b09bf563622089 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18021,38 +18021,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *S = EmitScalarExpr(E->getArg(2)); -llvm::Type *Xty = X->getType(); -llvm::Type *Yty = Y->getType(); -llvm::Type *Sty = S->getType(); -if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { - if (Xty->isFloatingPointTy()) { -auto V
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/84526 >From 3f515637fc87a41db1df4ea7627679c7dd75503a Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 14 Mar 2024 18:53:33 -0400 Subject: [PATCH 1/2] [DXIL] exp, any, lerp, & rcp Intrinsic Lowering This change implements lowering for #70076, #70100, #70072, & #70102 `CGBuiltin.cpp` - - simplify `lerp` intrinsic `IntrinsicsDirectX.td` - simplify `lerp` intrinsic `SemaChecking.cpp` - remove unnecessary check `DXILIntrinsicExpansion.*` - add intrinsic to instruction expansion cases `DXILOpLowering.cpp` - make sure `DXILIntrinsicExpansion` happens first `DirectX.h` - changes to support new pass `DirectXTargetMachine.cpp` - changes to support new pass Why `any`, and `lerp` as instruction expansion just for DXIL? - SPIR-V there is an [OpAny](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpAny) - SPIR-V has a GLSL lerp extension via [Fmix](https://registry.khronos.org/SPIR-V/specs/1.0/GLSL.std.450.html#FMix) Why `exp` instruction expansion? - We have an `exp2` opcode and `exp` reuses that opcode. So instruction expansion is a convenient way to do preprocessing. - Further SPIR-V has a GLSL exp extension via [Exp](https://registry.khronos.org/SPIR-V/specs/1.0/GLSL.std.450.html#Exp) and [Exp2](https://registry.khronos.org/SPIR-V/specs/1.0/GLSL.std.450.html#Exp2) Why `rcp` as instruction expansion? This one is a bit of the odd man out and might have to move to `cgbuiltins` when we better understand SPIRV requirements. However I included it because it seems like [fast math mode has an AllowRecip flag](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#_fp_fast_math_mode) which lets you compute the reciprocal without performing the division. We don't have that in DXIL so thought to include it. --- clang/include/clang/AST/Type.h| 5 + clang/lib/CodeGen/CGBuiltin.cpp | 35 +--- clang/lib/Sema/SemaChecking.cpp | 51 +++-- .../CodeGenHLSL/builtins/lerp-builtin.hlsl| 22 --- clang/test/CodeGenHLSL/builtins/lerp.hlsl | 27 ++- clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl | 17 +- llvm/include/llvm/IR/IntrinsicsDirectX.td | 4 +- llvm/lib/Target/DirectX/CMakeLists.txt| 1 + .../Target/DirectX/DXILIntrinsicExpansion.cpp | 186 ++ .../Target/DirectX/DXILIntrinsicExpansion.h | 33 llvm/lib/Target/DirectX/DXILOpLowering.cpp| 6 +- llvm/lib/Target/DirectX/DirectX.h | 6 + .../Target/DirectX/DirectXTargetMachine.cpp | 2 + llvm/test/CodeGen/DirectX/any.ll | 105 ++ llvm/test/CodeGen/DirectX/exp-vec.ll | 16 ++ llvm/test/CodeGen/DirectX/exp.ll | 29 +++ llvm/test/CodeGen/DirectX/lerp.ll | 53 + llvm/test/CodeGen/DirectX/rcp.ll | 48 + 18 files changed, 557 insertions(+), 89 deletions(-) create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.h create mode 100644 llvm/test/CodeGen/DirectX/any.ll create mode 100644 llvm/test/CodeGen/DirectX/exp-vec.ll create mode 100644 llvm/test/CodeGen/DirectX/exp.ll create mode 100644 llvm/test/CodeGen/DirectX/lerp.ll create mode 100644 llvm/test/CodeGen/DirectX/rcp.ll diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 1942b0e67f65a3..10916053cdfbf5 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2244,6 +2244,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661 + bool isFloat32Type() const; bool isBFloat16Type() const; bool isFloat128Type() const; bool isIbm128Type() const; @@ -7452,6 +7453,10 @@ inline bool Type::isFloat16Type() const { return isSpecificBuiltinType(BuiltinType::Float16); } +inline bool Type::isFloat32Type() const { + return isSpecificBuiltinType(BuiltinType::Float); +} + inline bool Type::isBFloat16Type() const { return isSpecificBuiltinType(BuiltinType::BFloat16); } diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index b9d1a4912385e1..b09bf563622089 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18021,38 +18021,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *S = EmitScalarExpr(E->getArg(2)); -llvm::Type *Xty = X->getType(); -llvm::Type *Yty = Y->getType(); -llvm::Type *Sty = S->getType(); -if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { - if (Xty->isFloatingPointTy()) { -auto V
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/llvm-beanz approved this pull request. https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -0,0 +1,105 @@ +; RUN: opt -S -dxil-op-lower < %s | FileCheck %s + +; Make sure dxil operation function calls for any are generated for float and half. + +; CHECK:icmp ne i1 %{{.*}}, false farzonl wrote: That was my thinking as well, but all the other tests in this directory lacked the space and I didn't want to go against the the grain. https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -0,0 +1,105 @@ +; RUN: opt -S -dxil-op-lower < %s | FileCheck %s + +; Make sure dxil operation function calls for any are generated for float and half. + +; CHECK:icmp ne i1 %{{.*}}, false bogner wrote: Folks usually put a space between `CHECK:` and the thing being checked (`CHECK: icmp ...`). I find that slightly more readable. https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/bogner approved this pull request. A couple more very minor notes on the tests, then this LGTM https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -0,0 +1,105 @@ +; RUN: opt -S -dxil-op-lower < %s | FileCheck %s + +; Make sure dxil operation function calls for any are generated for float and half. + +; CHECK:icmp ne i1 %{{.*}}, false +define noundef i1 @any_bool(i1 noundef %p0) { bogner wrote: Probably worth adding a `; CHECK-LABEL: define {{.*}} @any_bool` or so to make sure these checks are looking at the right functions and also potentially improve the error message if they fail https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/bogner edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/84526 >From 7dde8faaad046b715027a0f9fb772af90b6ffb30 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 7 Mar 2024 20:48:46 -0500 Subject: [PATCH 1/4] [DXIL] exp, any, lerp, & rcp Intrinsic Lowering This change implements lowering for #70076, #70100, #70072, & #70102 CGBuiltin.cpp - - simplify lerp intrinsic IntrinsicsDirectX.td - simplify lerp intrinsic SemaChecking.cpp - remove unnecessary check DXILIntrinsicExpansion.* - add intrinsic to instruction expansion cases DXILOpLowering.cpp - make sure DXILIntrinsicExpansion happens first DirectX.h - changes to support new pass DirectXTargetMachine.cpp - changes to support new pass --- clang/lib/CodeGen/CGBuiltin.cpp | 35 +--- clang/lib/Sema/SemaChecking.cpp | 2 - clang/test/CodeGenHLSL/builtins/lerp.hlsl | 13 +- llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 +- llvm/lib/Target/DirectX/CMakeLists.txt| 1 + .../Target/DirectX/DXILIntrinsicExpansion.cpp | 187 ++ .../Target/DirectX/DXILIntrinsicExpansion.h | 33 llvm/lib/Target/DirectX/DXILOpLowering.cpp| 6 +- llvm/lib/Target/DirectX/DirectX.h | 6 + .../Target/DirectX/DirectXTargetMachine.cpp | 2 + llvm/test/CodeGen/DirectX/any.ll | 133 + llvm/test/CodeGen/DirectX/exp-vec.ll | 23 +++ llvm/test/CodeGen/DirectX/exp.ll | 38 llvm/test/CodeGen/DirectX/lerp.ll | 64 ++ llvm/test/CodeGen/DirectX/rcp.ll | 63 ++ 15 files changed, 564 insertions(+), 47 deletions(-) create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.h create mode 100644 llvm/test/CodeGen/DirectX/any.ll create mode 100644 llvm/test/CodeGen/DirectX/exp-vec.ll create mode 100644 llvm/test/CodeGen/DirectX/exp.ll create mode 100644 llvm/test/CodeGen/DirectX/lerp.ll create mode 100644 llvm/test/CodeGen/DirectX/rcp.ll diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 93ab465079777b..25e4793c3e22d8 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18015,38 +18015,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *S = EmitScalarExpr(E->getArg(2)); -llvm::Type *Xty = X->getType(); -llvm::Type *Yty = Y->getType(); -llvm::Type *Sty = S->getType(); -if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { - if (Xty->isFloatingPointTy()) { -auto V = Builder.CreateFSub(Y, X); -V = Builder.CreateFMul(S, V); -return Builder.CreateFAdd(X, V, "dx.lerp"); - } - llvm_unreachable("Scalar Lerp is only supported on floats."); -} -// A VectorSplat should have happened -assert(Xty->isVectorTy() && Yty->isVectorTy() && Sty->isVectorTy() && - "Lerp of vector and scalar is not supported."); - -[[maybe_unused]] auto *XVecTy = -E->getArg(0)->getType()->getAs(); -[[maybe_unused]] auto *YVecTy = -E->getArg(1)->getType()->getAs(); -[[maybe_unused]] auto *SVecTy = -E->getArg(2)->getType()->getAs(); -// A HLSLVectorTruncation should have happend -assert(XVecTy->getNumElements() == YVecTy->getNumElements() && - XVecTy->getNumElements() == SVecTy->getNumElements() && - "Lerp requires vectors to be of the same size."); -assert(XVecTy->getElementType()->isRealFloatingType() && - XVecTy->getElementType() == YVecTy->getElementType() && - XVecTy->getElementType() == SVecTy->getElementType() && - "Lerp requires float vectors to be of the same type."); +if (!E->getArg(0)->getType()->hasFloatingRepresentation()) + llvm_unreachable("lerp operand must have a float representation"); return Builder.CreateIntrinsic( -/*ReturnType=*/Xty, Intrinsic::dx_lerp, ArrayRef{X, Y, S}, -nullptr, "dx.lerp"); +/*ReturnType=*/X->getType(), Intrinsic::dx_lerp, +ArrayRef{X, Y, S}, nullptr, "dx.lerp"); } case Builtin::BI__builtin_hlsl_elementwise_frac: { Value *Op0 = EmitScalarExpr(E->getArg(0)); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a5f42b630c3fa2..8a2b7384a0b0d5 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5300,8 +5300,6 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; if (SemaBuiltinElementwiseTernaryMath(TheCall)) return true; -if (CheckAllArgsHaveFloatRepresentation(this, TheCall)) - return true; break; } case Builtin::BI__builtin_hlsl_mad: { diff --git a/clang/test/CodeGenHLSL/builtins/lerp.hlsl b/clang/test/CodeGenHLSL/builtins/le
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -5254,7 +5250,11 @@ bool CheckAllArgsHaveFloatRepresentation(Sema *S, CallExpr *TheCall) { QualType ExpectedType = S->Context.FloatTy; for (unsigned i = 0; i < TheCall->getNumArgs(); ++i) { QualType PassedType = TheCall->getArg(i)->getType(); -if (!PassedType->hasFloatingRepresentation()) { +ExpectedType = PassedType->isHalfType() && S->getLangOpts().NativeHalfType + ? S->Context.HalfTy + : S->Context.FloatTy; +if (PassedType == S->Context.DoubleTy || +!PassedType->hasFloatingRepresentation()) { farzonl wrote: I have a solution I think will make things more clear. https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -18015,38 +18015,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *S = EmitScalarExpr(E->getArg(2)); -llvm::Type *Xty = X->getType(); -llvm::Type *Yty = Y->getType(); -llvm::Type *Sty = S->getType(); -if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { - if (Xty->isFloatingPointTy()) { -auto V = Builder.CreateFSub(Y, X); -V = Builder.CreateFMul(S, V); -return Builder.CreateFAdd(X, V, "dx.lerp"); - } - llvm_unreachable("Scalar Lerp is only supported on floats."); -} -// A VectorSplat should have happened -assert(Xty->isVectorTy() && Yty->isVectorTy() && Sty->isVectorTy() && - "Lerp of vector and scalar is not supported."); - -[[maybe_unused]] auto *XVecTy = -E->getArg(0)->getType()->getAs(); -[[maybe_unused]] auto *YVecTy = -E->getArg(1)->getType()->getAs(); -[[maybe_unused]] auto *SVecTy = -E->getArg(2)->getType()->getAs(); -// A HLSLVectorTruncation should have happend -assert(XVecTy->getNumElements() == YVecTy->getNumElements() && - XVecTy->getNumElements() == SVecTy->getNumElements() && - "Lerp requires vectors to be of the same size."); -assert(XVecTy->getElementType()->isRealFloatingType() && - XVecTy->getElementType() == YVecTy->getElementType() && - XVecTy->getElementType() == SVecTy->getElementType() && - "Lerp requires float vectors to be of the same type."); +if (!E->getArg(0)->getType()->hasFloatingRepresentation()) farzonl wrote: `X->getType()` is a `Type` pointer. `E->getArg(0)->getType()` is a `QualType`. Only QualTypes allow us to use `hasFloatingRepresentation` https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -5254,7 +5250,11 @@ bool CheckAllArgsHaveFloatRepresentation(Sema *S, CallExpr *TheCall) { QualType ExpectedType = S->Context.FloatTy; for (unsigned i = 0; i < TheCall->getNumArgs(); ++i) { QualType PassedType = TheCall->getArg(i)->getType(); -if (!PassedType->hasFloatingRepresentation()) { +ExpectedType = PassedType->isHalfType() && S->getLangOpts().NativeHalfType + ? S->Context.HalfTy + : S->Context.FloatTy; +if (PassedType == S->Context.DoubleTy || +!PassedType->hasFloatingRepresentation()) { farzonl wrote: 1. This was originally just a check to make sure args were floats and I shoehorned in the double case to handle the type promotions caused by `DefaultVariadicArgumentPromotion` when calling the builtin directly. There are no type promotions for BFloat16 or Ibm128 and we don't define those types in hlsl so i'm not able to test for these other floating point types. 2. The name should probably change. 3. I was hoping to avoid triggering the error on api calls of half\vector ie. lerp(half,half,half). There is likely a better way for me to structure this to make it look more correct. 4. It can't be tested I added a test for it on line 91 of `lerp-builtin.hlsl` and the original type is lost by the time we call the builtin. I added a note to explain why it was `float` and not `half`. https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -0,0 +1,187 @@ +//===- DXILIntrinsicExpansion.cpp - Prepare LLVM Module for DXIL encoding--===// +// +// 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 contains DXIL intrinsic expansions for those that don't have +// opcodes in DirectX Intermediate Language (DXIL). +//===--===// + +#include "DXILIntrinsicExpansion.h" +#include "DirectX.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsDirectX.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" +#include "llvm/IR/Type.h" +#include "llvm/Pass.h" +#include "llvm/Support/ErrorHandling.h" + +#define DEBUG_TYPE "dxil-intrinsic-expansion" +#define M_LOG2E_F 1.44269504088896340735992468100189214f + +using namespace llvm; + +static bool isIntrinsicExpansion(Function &F) { + switch (F.getIntrinsicID()) { + case Intrinsic::exp: + case Intrinsic::dx_any: + case Intrinsic::dx_lerp: + case Intrinsic::dx_rcp: +return true; + } + return false; +} + +static bool expandExpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + Constant *Log2eConst = + Ty->isVectorTy() + ? ConstantVector::getSplat( +ElementCount::getFixed( +dyn_cast(Ty)->getNumElements()), +ConstantFP::get(EltTy, M_LOG2E_F)) + : ConstantFP::get(EltTy, M_LOG2E_F); + Value *NewX = Builder.CreateFMul(Log2eConst, X); + auto *Exp2Call = + Builder.CreateIntrinsic(Ty, Intrinsic::exp2, {NewX}, nullptr, "dx.exp2"); + Exp2Call->setTailCall(Orig->isTailCall()); + Exp2Call->setAttributes(Orig->getAttributes()); + Orig->replaceAllUsesWith(Exp2Call); + Orig->eraseFromParent(); + return true; +} + +static bool expandAnyIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + + if (!Ty->isVectorTy()) { +Value *Cond = EltTy->isFloatingPointTy() + ? Builder.CreateFCmpUNE(X, ConstantFP::get(EltTy, 0)) + : Builder.CreateICmpNE(X, ConstantInt::get(EltTy, 0)); +Orig->replaceAllUsesWith(Cond); + } else { +auto *XVec = dyn_cast(Ty); +Value *Cond = +EltTy->isFloatingPointTy() +? Builder.CreateFCmpUNE( + X, ConstantVector::getSplat( + ElementCount::getFixed(XVec->getNumElements()), + ConstantFP::get(EltTy, 0))) +: Builder.CreateICmpNE( + X, ConstantVector::getSplat( + ElementCount::getFixed(XVec->getNumElements()), + ConstantInt::get(EltTy, 0))); +Value *Result = Builder.CreateExtractElement(Cond, (uint64_t)0); +for (unsigned I = 1; I < XVec->getNumElements(); I++) { + Value *Elt = Builder.CreateExtractElement(Cond, I); + Result = Builder.CreateOr(Result, Elt); +} +Orig->replaceAllUsesWith(Result); + } + Orig->eraseFromParent(); + return true; +} + +static bool expandLerpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + Value *Y = Orig->getOperand(1); + Value *S = Orig->getOperand(2); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + auto *V = Builder.CreateFSub(Y, X); + V = Builder.CreateFMul(S, V); + auto *Result = Builder.CreateFAdd(X, V, "dx.lerp"); + Orig->replaceAllUsesWith(Result); + Orig->eraseFromParent(); + return true; +} + +static bool expandReciprocalIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + Constant *One = + Ty->isVectorTy() + ? ConstantVector::getSplat( +ElementCount::getFixed( +dyn_cast(Ty)->getNumElements()), +ConstantFP::get(EltTy, 1.0)) + : ConstantFP::get(EltTy, 1.0); + auto *Result = Builder.CreateFDiv(One, X, "dx.rcp"); + Orig->replaceAllUsesWith(Result); + Orig->eraseFromParent(); + return true; +} + +static bool expandIntrinsic(Function &F, CallInst *Orig) { + switch (F.getIntrinsicID()) { + case Intrinsic::exp: +return expandExpIntrinsic(Orig); + case Intrinsic::dx_any: +return expandAnyIntr
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -0,0 +1,187 @@ +//===- DXILIntrinsicExpansion.cpp - Prepare LLVM Module for DXIL encoding--===// +// +// 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 contains DXIL intrinsic expansions for those that don't have +// opcodes in DirectX Intermediate Language (DXIL). +//===--===// + +#include "DXILIntrinsicExpansion.h" +#include "DirectX.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsDirectX.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" +#include "llvm/IR/Type.h" +#include "llvm/Pass.h" +#include "llvm/Support/ErrorHandling.h" + +#define DEBUG_TYPE "dxil-intrinsic-expansion" +#define M_LOG2E_F 1.44269504088896340735992468100189214f + +using namespace llvm; + +static bool isIntrinsicExpansion(Function &F) { + switch (F.getIntrinsicID()) { + case Intrinsic::exp: + case Intrinsic::dx_any: + case Intrinsic::dx_lerp: + case Intrinsic::dx_rcp: +return true; + } + return false; +} + +static bool expandExpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + Constant *Log2eConst = + Ty->isVectorTy() + ? ConstantVector::getSplat( +ElementCount::getFixed( +dyn_cast(Ty)->getNumElements()), farzonl wrote: I'l change the cast and investigate other vector types. I haven't tested with scalable vectors. I didn't see a generic vector type I could use and I just noticed in lldb the clang vectors had a FixedVector type so went with that. https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -0,0 +1,187 @@ +//===- DXILIntrinsicExpansion.cpp - Prepare LLVM Module for DXIL encoding--===// +// +// 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 contains DXIL intrinsic expansions for those that don't have +// opcodes in DirectX Intermediate Language (DXIL). +//===--===// + +#include "DXILIntrinsicExpansion.h" +#include "DirectX.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsDirectX.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" +#include "llvm/IR/Type.h" +#include "llvm/Pass.h" +#include "llvm/Support/ErrorHandling.h" + +#define DEBUG_TYPE "dxil-intrinsic-expansion" +#define M_LOG2E_F 1.44269504088896340735992468100189214f + +using namespace llvm; + +static bool isIntrinsicExpansion(Function &F) { + switch (F.getIntrinsicID()) { + case Intrinsic::exp: + case Intrinsic::dx_any: + case Intrinsic::dx_lerp: + case Intrinsic::dx_rcp: +return true; + } + return false; +} + +static bool expandExpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + Constant *Log2eConst = + Ty->isVectorTy() + ? ConstantVector::getSplat( +ElementCount::getFixed( +dyn_cast(Ty)->getNumElements()), +ConstantFP::get(EltTy, M_LOG2E_F)) + : ConstantFP::get(EltTy, M_LOG2E_F); + Value *NewX = Builder.CreateFMul(Log2eConst, X); + auto *Exp2Call = + Builder.CreateIntrinsic(Ty, Intrinsic::exp2, {NewX}, nullptr, "dx.exp2"); + Exp2Call->setTailCall(Orig->isTailCall()); + Exp2Call->setAttributes(Orig->getAttributes()); + Orig->replaceAllUsesWith(Exp2Call); + Orig->eraseFromParent(); + return true; +} + +static bool expandAnyIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + + if (!Ty->isVectorTy()) { +Value *Cond = EltTy->isFloatingPointTy() + ? Builder.CreateFCmpUNE(X, ConstantFP::get(EltTy, 0)) + : Builder.CreateICmpNE(X, ConstantInt::get(EltTy, 0)); +Orig->replaceAllUsesWith(Cond); + } else { +auto *XVec = dyn_cast(Ty); +Value *Cond = +EltTy->isFloatingPointTy() +? Builder.CreateFCmpUNE( + X, ConstantVector::getSplat( + ElementCount::getFixed(XVec->getNumElements()), + ConstantFP::get(EltTy, 0))) +: Builder.CreateICmpNE( + X, ConstantVector::getSplat( + ElementCount::getFixed(XVec->getNumElements()), + ConstantInt::get(EltTy, 0))); +Value *Result = Builder.CreateExtractElement(Cond, (uint64_t)0); +for (unsigned I = 1; I < XVec->getNumElements(); I++) { + Value *Elt = Builder.CreateExtractElement(Cond, I); + Result = Builder.CreateOr(Result, Elt); +} +Orig->replaceAllUsesWith(Result); + } + Orig->eraseFromParent(); + return true; +} + +static bool expandLerpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + Value *Y = Orig->getOperand(1); + Value *S = Orig->getOperand(2); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + auto *V = Builder.CreateFSub(Y, X); + V = Builder.CreateFMul(S, V); + auto *Result = Builder.CreateFAdd(X, V, "dx.lerp"); + Orig->replaceAllUsesWith(Result); + Orig->eraseFromParent(); + return true; +} + +static bool expandReciprocalIntrinsic(CallInst *Orig) { bogner wrote: For consistency this should probably just be expandRcpIntrinsic - we didn't spell "Exp" as "Exponential" in the other function above https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -0,0 +1,133 @@ +; RUN: opt -S -dxil-op-lower < %s | FileCheck %s + +; Make sure dxil operation function calls for any are generated for float and half. + + +target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" +target triple = "dxil-pc-shadermodel6.7-library" + + +; CHECK:icmp ne i1 %{{.*}}, false +; Function Attrs: noinline nounwind optnone +define noundef i1 @any_bool(i1 noundef %p0) #0 { bogner wrote: It looks like the `attributes #0 = ...` definition is stripped, but you've left the `#0` on these functions. If we don't need the attributes for the test these can just be stripped. https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -0,0 +1,133 @@ +; RUN: opt -S -dxil-op-lower < %s | FileCheck %s + +; Make sure dxil operation function calls for any are generated for float and half. + + +target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" +target triple = "dxil-pc-shadermodel6.7-library" + + +; CHECK:icmp ne i1 %{{.*}}, false +; Function Attrs: noinline nounwind optnone bogner wrote: Usually best to strip the function attr comments from tests https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -0,0 +1,133 @@ +; RUN: opt -S -dxil-op-lower < %s | FileCheck %s + +; Make sure dxil operation function calls for any are generated for float and half. + + +target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" +target triple = "dxil-pc-shadermodel6.7-library" + + +; CHECK:icmp ne i1 %{{.*}}, false +; Function Attrs: noinline nounwind optnone +define noundef i1 @any_bool(i1 noundef %p0) #0 { +entry: + %p0.addr = alloca i8, align 1 + %frombool = zext i1 %p0 to i8 + store i8 %frombool, ptr %p0.addr, align 1 + %0 = load i8, ptr %p0.addr, align 1 + %tobool = trunc i8 %0 to i1 + %dx.any = call i1 @llvm.dx.any.i1(i1 %tobool) + ret i1 %dx.any +} + +; Function Attrs: nocallback nofree nosync nounwind willreturn +declare i1 @llvm.dx.any.i1(i1) #1 bogner wrote: It doesn't really matter, but I find it a bit tidier to put all of these function declarations together at the end. https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -0,0 +1,187 @@ +//===- DXILIntrinsicExpansion.cpp - Prepare LLVM Module for DXIL encoding--===// +// +// 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 contains DXIL intrinsic expansions for those that don't have +// opcodes in DirectX Intermediate Language (DXIL). +//===--===// + +#include "DXILIntrinsicExpansion.h" +#include "DirectX.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsDirectX.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" +#include "llvm/IR/Type.h" +#include "llvm/Pass.h" +#include "llvm/Support/ErrorHandling.h" + +#define DEBUG_TYPE "dxil-intrinsic-expansion" +#define M_LOG2E_F 1.44269504088896340735992468100189214f bogner wrote: You can get this from `llvm/Support/MathExtras.h` as `numbers::log2e` https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -0,0 +1,133 @@ +; RUN: opt -S -dxil-op-lower < %s | FileCheck %s + +; Make sure dxil operation function calls for any are generated for float and half. + + +target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" +target triple = "dxil-pc-shadermodel6.7-library" bogner wrote: You can probably strip the datalayout from these tests, and maybe even the triple https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -0,0 +1,187 @@ +//===- DXILIntrinsicExpansion.cpp - Prepare LLVM Module for DXIL encoding--===// +// +// 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 contains DXIL intrinsic expansions for those that don't have +// opcodes in DirectX Intermediate Language (DXIL). +//===--===// + +#include "DXILIntrinsicExpansion.h" +#include "DirectX.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsDirectX.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" +#include "llvm/IR/Type.h" +#include "llvm/Pass.h" +#include "llvm/Support/ErrorHandling.h" + +#define DEBUG_TYPE "dxil-intrinsic-expansion" +#define M_LOG2E_F 1.44269504088896340735992468100189214f + +using namespace llvm; + +static bool isIntrinsicExpansion(Function &F) { + switch (F.getIntrinsicID()) { + case Intrinsic::exp: + case Intrinsic::dx_any: + case Intrinsic::dx_lerp: + case Intrinsic::dx_rcp: +return true; + } + return false; +} + +static bool expandExpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + Constant *Log2eConst = + Ty->isVectorTy() + ? ConstantVector::getSplat( +ElementCount::getFixed( +dyn_cast(Ty)->getNumElements()), bogner wrote: If we aren't checking for null this should be `cast` not `dyn_cast`. Does this do something bad if we somehow get here with scalable vectors? https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -0,0 +1,187 @@ +//===- DXILIntrinsicExpansion.cpp - Prepare LLVM Module for DXIL encoding--===// +// +// 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 contains DXIL intrinsic expansions for those that don't have +// opcodes in DirectX Intermediate Language (DXIL). +//===--===// + +#include "DXILIntrinsicExpansion.h" +#include "DirectX.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsDirectX.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" +#include "llvm/IR/Type.h" +#include "llvm/Pass.h" +#include "llvm/Support/ErrorHandling.h" + +#define DEBUG_TYPE "dxil-intrinsic-expansion" +#define M_LOG2E_F 1.44269504088896340735992468100189214f + +using namespace llvm; + +static bool isIntrinsicExpansion(Function &F) { + switch (F.getIntrinsicID()) { + case Intrinsic::exp: + case Intrinsic::dx_any: + case Intrinsic::dx_lerp: + case Intrinsic::dx_rcp: +return true; + } + return false; +} + +static bool expandExpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + Constant *Log2eConst = + Ty->isVectorTy() + ? ConstantVector::getSplat( +ElementCount::getFixed( +dyn_cast(Ty)->getNumElements()), +ConstantFP::get(EltTy, M_LOG2E_F)) + : ConstantFP::get(EltTy, M_LOG2E_F); + Value *NewX = Builder.CreateFMul(Log2eConst, X); + auto *Exp2Call = + Builder.CreateIntrinsic(Ty, Intrinsic::exp2, {NewX}, nullptr, "dx.exp2"); + Exp2Call->setTailCall(Orig->isTailCall()); + Exp2Call->setAttributes(Orig->getAttributes()); + Orig->replaceAllUsesWith(Exp2Call); + Orig->eraseFromParent(); + return true; +} + +static bool expandAnyIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + + if (!Ty->isVectorTy()) { +Value *Cond = EltTy->isFloatingPointTy() + ? Builder.CreateFCmpUNE(X, ConstantFP::get(EltTy, 0)) + : Builder.CreateICmpNE(X, ConstantInt::get(EltTy, 0)); +Orig->replaceAllUsesWith(Cond); + } else { +auto *XVec = dyn_cast(Ty); +Value *Cond = +EltTy->isFloatingPointTy() +? Builder.CreateFCmpUNE( + X, ConstantVector::getSplat( + ElementCount::getFixed(XVec->getNumElements()), + ConstantFP::get(EltTy, 0))) +: Builder.CreateICmpNE( + X, ConstantVector::getSplat( + ElementCount::getFixed(XVec->getNumElements()), + ConstantInt::get(EltTy, 0))); +Value *Result = Builder.CreateExtractElement(Cond, (uint64_t)0); +for (unsigned I = 1; I < XVec->getNumElements(); I++) { + Value *Elt = Builder.CreateExtractElement(Cond, I); + Result = Builder.CreateOr(Result, Elt); +} +Orig->replaceAllUsesWith(Result); + } + Orig->eraseFromParent(); + return true; +} + +static bool expandLerpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + Value *Y = Orig->getOperand(1); + Value *S = Orig->getOperand(2); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + auto *V = Builder.CreateFSub(Y, X); + V = Builder.CreateFMul(S, V); + auto *Result = Builder.CreateFAdd(X, V, "dx.lerp"); + Orig->replaceAllUsesWith(Result); + Orig->eraseFromParent(); + return true; +} + +static bool expandReciprocalIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + Constant *One = + Ty->isVectorTy() + ? ConstantVector::getSplat( +ElementCount::getFixed( +dyn_cast(Ty)->getNumElements()), +ConstantFP::get(EltTy, 1.0)) + : ConstantFP::get(EltTy, 1.0); + auto *Result = Builder.CreateFDiv(One, X, "dx.rcp"); + Orig->replaceAllUsesWith(Result); + Orig->eraseFromParent(); + return true; +} + +static bool expandIntrinsic(Function &F, CallInst *Orig) { + switch (F.getIntrinsicID()) { + case Intrinsic::exp: +return expandExpIntrinsic(Orig); + case Intrinsic::dx_any: +return expandAnyIntr
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -0,0 +1,187 @@ +//===- DXILIntrinsicExpansion.cpp - Prepare LLVM Module for DXIL encoding--===// +// +// 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 contains DXIL intrinsic expansions for those that don't have +// opcodes in DirectX Intermediate Language (DXIL). +//===--===// + +#include "DXILIntrinsicExpansion.h" +#include "DirectX.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsDirectX.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" +#include "llvm/IR/Type.h" +#include "llvm/Pass.h" +#include "llvm/Support/ErrorHandling.h" + +#define DEBUG_TYPE "dxil-intrinsic-expansion" +#define M_LOG2E_F 1.44269504088896340735992468100189214f + +using namespace llvm; + +static bool isIntrinsicExpansion(Function &F) { + switch (F.getIntrinsicID()) { + case Intrinsic::exp: + case Intrinsic::dx_any: + case Intrinsic::dx_lerp: + case Intrinsic::dx_rcp: +return true; + } + return false; +} + +static bool expandExpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + Constant *Log2eConst = + Ty->isVectorTy() + ? ConstantVector::getSplat( +ElementCount::getFixed( +dyn_cast(Ty)->getNumElements()), +ConstantFP::get(EltTy, M_LOG2E_F)) + : ConstantFP::get(EltTy, M_LOG2E_F); + Value *NewX = Builder.CreateFMul(Log2eConst, X); + auto *Exp2Call = + Builder.CreateIntrinsic(Ty, Intrinsic::exp2, {NewX}, nullptr, "dx.exp2"); + Exp2Call->setTailCall(Orig->isTailCall()); + Exp2Call->setAttributes(Orig->getAttributes()); + Orig->replaceAllUsesWith(Exp2Call); + Orig->eraseFromParent(); + return true; +} + +static bool expandAnyIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + + if (!Ty->isVectorTy()) { +Value *Cond = EltTy->isFloatingPointTy() + ? Builder.CreateFCmpUNE(X, ConstantFP::get(EltTy, 0)) + : Builder.CreateICmpNE(X, ConstantInt::get(EltTy, 0)); +Orig->replaceAllUsesWith(Cond); + } else { +auto *XVec = dyn_cast(Ty); +Value *Cond = +EltTy->isFloatingPointTy() +? Builder.CreateFCmpUNE( + X, ConstantVector::getSplat( + ElementCount::getFixed(XVec->getNumElements()), + ConstantFP::get(EltTy, 0))) +: Builder.CreateICmpNE( + X, ConstantVector::getSplat( + ElementCount::getFixed(XVec->getNumElements()), + ConstantInt::get(EltTy, 0))); +Value *Result = Builder.CreateExtractElement(Cond, (uint64_t)0); +for (unsigned I = 1; I < XVec->getNumElements(); I++) { + Value *Elt = Builder.CreateExtractElement(Cond, I); + Result = Builder.CreateOr(Result, Elt); +} +Orig->replaceAllUsesWith(Result); + } + Orig->eraseFromParent(); + return true; +} + +static bool expandLerpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + Value *Y = Orig->getOperand(1); + Value *S = Orig->getOperand(2); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + auto *V = Builder.CreateFSub(Y, X); + V = Builder.CreateFMul(S, V); + auto *Result = Builder.CreateFAdd(X, V, "dx.lerp"); + Orig->replaceAllUsesWith(Result); + Orig->eraseFromParent(); + return true; +} + +static bool expandReciprocalIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + Constant *One = + Ty->isVectorTy() + ? ConstantVector::getSplat( +ElementCount::getFixed( +dyn_cast(Ty)->getNumElements()), +ConstantFP::get(EltTy, 1.0)) + : ConstantFP::get(EltTy, 1.0); + auto *Result = Builder.CreateFDiv(One, X, "dx.rcp"); + Orig->replaceAllUsesWith(Result); + Orig->eraseFromParent(); + return true; +} + +static bool expandIntrinsic(Function &F, CallInst *Orig) { + switch (F.getIntrinsicID()) { + case Intrinsic::exp: +return expandExpIntrinsic(Orig); + case Intrinsic::dx_any: +return expandAnyIntr
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -5254,7 +5250,11 @@ bool CheckAllArgsHaveFloatRepresentation(Sema *S, CallExpr *TheCall) { QualType ExpectedType = S->Context.FloatTy; for (unsigned i = 0; i < TheCall->getNumArgs(); ++i) { QualType PassedType = TheCall->getArg(i)->getType(); -if (!PassedType->hasFloatingRepresentation()) { +ExpectedType = PassedType->isHalfType() && S->getLangOpts().NativeHalfType + ? S->Context.HalfTy + : S->Context.FloatTy; +if (PassedType == S->Context.DoubleTy || +!PassedType->hasFloatingRepresentation()) { bogner wrote: I'm confused about a couple of things here, and it doesn't really look right. 1. hasFloatingRepresentation returns true for any floating point type, but we're explicitly excluding double. Do we really want this to diagnose on double but not for Long Double, BFloat16, or Ibm128? 2. The name of this function is a bit ambiguous - is it supposed to be checking for exactly `float` (as the `ExpectedType` before this change implies) or "any floating point type" (as the use of `hasFloatingRepresentation` implies)? As is it doesn't do either of those things. 3. Why is `ExpectedType` usually `float` but sometimes `half`? 4. I don't think the `half` diagnostic is tested - it should presumably read "passing 'XYZ' to parameter of incompatible type 'half'" https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -18015,38 +18015,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *S = EmitScalarExpr(E->getArg(2)); -llvm::Type *Xty = X->getType(); -llvm::Type *Yty = Y->getType(); -llvm::Type *Sty = S->getType(); -if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { - if (Xty->isFloatingPointTy()) { -auto V = Builder.CreateFSub(Y, X); -V = Builder.CreateFMul(S, V); -return Builder.CreateFAdd(X, V, "dx.lerp"); - } - llvm_unreachable("Scalar Lerp is only supported on floats."); -} -// A VectorSplat should have happened -assert(Xty->isVectorTy() && Yty->isVectorTy() && Sty->isVectorTy() && - "Lerp of vector and scalar is not supported."); - -[[maybe_unused]] auto *XVecTy = -E->getArg(0)->getType()->getAs(); -[[maybe_unused]] auto *YVecTy = -E->getArg(1)->getType()->getAs(); -[[maybe_unused]] auto *SVecTy = -E->getArg(2)->getType()->getAs(); -// A HLSLVectorTruncation should have happend -assert(XVecTy->getNumElements() == YVecTy->getNumElements() && - XVecTy->getNumElements() == SVecTy->getNumElements() && - "Lerp requires vectors to be of the same size."); -assert(XVecTy->getElementType()->isRealFloatingType() && - XVecTy->getElementType() == YVecTy->getElementType() && - XVecTy->getElementType() == SVecTy->getElementType() && - "Lerp requires float vectors to be of the same type."); +if (!E->getArg(0)->getType()->hasFloatingRepresentation()) bogner wrote: Probably clearer to use `X` here rather than repeating `E->getArg(0)` https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/84526 >From 7dde8faaad046b715027a0f9fb772af90b6ffb30 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 7 Mar 2024 20:48:46 -0500 Subject: [PATCH 1/3] [DXIL] exp, any, lerp, & rcp Intrinsic Lowering This change implements lowering for #70076, #70100, #70072, & #70102 CGBuiltin.cpp - - simplify lerp intrinsic IntrinsicsDirectX.td - simplify lerp intrinsic SemaChecking.cpp - remove unnecessary check DXILIntrinsicExpansion.* - add intrinsic to instruction expansion cases DXILOpLowering.cpp - make sure DXILIntrinsicExpansion happens first DirectX.h - changes to support new pass DirectXTargetMachine.cpp - changes to support new pass --- clang/lib/CodeGen/CGBuiltin.cpp | 35 +--- clang/lib/Sema/SemaChecking.cpp | 2 - clang/test/CodeGenHLSL/builtins/lerp.hlsl | 13 +- llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 +- llvm/lib/Target/DirectX/CMakeLists.txt| 1 + .../Target/DirectX/DXILIntrinsicExpansion.cpp | 187 ++ .../Target/DirectX/DXILIntrinsicExpansion.h | 33 llvm/lib/Target/DirectX/DXILOpLowering.cpp| 6 +- llvm/lib/Target/DirectX/DirectX.h | 6 + .../Target/DirectX/DirectXTargetMachine.cpp | 2 + llvm/test/CodeGen/DirectX/any.ll | 133 + llvm/test/CodeGen/DirectX/exp-vec.ll | 23 +++ llvm/test/CodeGen/DirectX/exp.ll | 38 llvm/test/CodeGen/DirectX/lerp.ll | 64 ++ llvm/test/CodeGen/DirectX/rcp.ll | 63 ++ 15 files changed, 564 insertions(+), 47 deletions(-) create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.h create mode 100644 llvm/test/CodeGen/DirectX/any.ll create mode 100644 llvm/test/CodeGen/DirectX/exp-vec.ll create mode 100644 llvm/test/CodeGen/DirectX/exp.ll create mode 100644 llvm/test/CodeGen/DirectX/lerp.ll create mode 100644 llvm/test/CodeGen/DirectX/rcp.ll diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 93ab465079777b..25e4793c3e22d8 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18015,38 +18015,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *S = EmitScalarExpr(E->getArg(2)); -llvm::Type *Xty = X->getType(); -llvm::Type *Yty = Y->getType(); -llvm::Type *Sty = S->getType(); -if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { - if (Xty->isFloatingPointTy()) { -auto V = Builder.CreateFSub(Y, X); -V = Builder.CreateFMul(S, V); -return Builder.CreateFAdd(X, V, "dx.lerp"); - } - llvm_unreachable("Scalar Lerp is only supported on floats."); -} -// A VectorSplat should have happened -assert(Xty->isVectorTy() && Yty->isVectorTy() && Sty->isVectorTy() && - "Lerp of vector and scalar is not supported."); - -[[maybe_unused]] auto *XVecTy = -E->getArg(0)->getType()->getAs(); -[[maybe_unused]] auto *YVecTy = -E->getArg(1)->getType()->getAs(); -[[maybe_unused]] auto *SVecTy = -E->getArg(2)->getType()->getAs(); -// A HLSLVectorTruncation should have happend -assert(XVecTy->getNumElements() == YVecTy->getNumElements() && - XVecTy->getNumElements() == SVecTy->getNumElements() && - "Lerp requires vectors to be of the same size."); -assert(XVecTy->getElementType()->isRealFloatingType() && - XVecTy->getElementType() == YVecTy->getElementType() && - XVecTy->getElementType() == SVecTy->getElementType() && - "Lerp requires float vectors to be of the same type."); +if (!E->getArg(0)->getType()->hasFloatingRepresentation()) + llvm_unreachable("lerp operand must have a float representation"); return Builder.CreateIntrinsic( -/*ReturnType=*/Xty, Intrinsic::dx_lerp, ArrayRef{X, Y, S}, -nullptr, "dx.lerp"); +/*ReturnType=*/X->getType(), Intrinsic::dx_lerp, +ArrayRef{X, Y, S}, nullptr, "dx.lerp"); } case Builtin::BI__builtin_hlsl_elementwise_frac: { Value *Op0 = EmitScalarExpr(E->getArg(0)); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a5f42b630c3fa2..8a2b7384a0b0d5 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5300,8 +5300,6 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; if (SemaBuiltinElementwiseTernaryMath(TheCall)) return true; -if (CheckAllArgsHaveFloatRepresentation(this, TheCall)) - return true; break; } case Builtin::BI__builtin_hlsl_mad: { diff --git a/clang/test/CodeGenHLSL/builtins/lerp.hlsl b/clang/test/CodeGenHLSL/builtins/le
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/84526 >From 7dde8faaad046b715027a0f9fb772af90b6ffb30 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 7 Mar 2024 20:48:46 -0500 Subject: [PATCH 1/3] [DXIL] exp, any, lerp, & rcp Intrinsic Lowering This change implements lowering for #70076, #70100, #70072, & #70102 CGBuiltin.cpp - - simplify lerp intrinsic IntrinsicsDirectX.td - simplify lerp intrinsic SemaChecking.cpp - remove unnecessary check DXILIntrinsicExpansion.* - add intrinsic to instruction expansion cases DXILOpLowering.cpp - make sure DXILIntrinsicExpansion happens first DirectX.h - changes to support new pass DirectXTargetMachine.cpp - changes to support new pass --- clang/lib/CodeGen/CGBuiltin.cpp | 35 +--- clang/lib/Sema/SemaChecking.cpp | 2 - clang/test/CodeGenHLSL/builtins/lerp.hlsl | 13 +- llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 +- llvm/lib/Target/DirectX/CMakeLists.txt| 1 + .../Target/DirectX/DXILIntrinsicExpansion.cpp | 187 ++ .../Target/DirectX/DXILIntrinsicExpansion.h | 33 llvm/lib/Target/DirectX/DXILOpLowering.cpp| 6 +- llvm/lib/Target/DirectX/DirectX.h | 6 + .../Target/DirectX/DirectXTargetMachine.cpp | 2 + llvm/test/CodeGen/DirectX/any.ll | 133 + llvm/test/CodeGen/DirectX/exp-vec.ll | 23 +++ llvm/test/CodeGen/DirectX/exp.ll | 38 llvm/test/CodeGen/DirectX/lerp.ll | 64 ++ llvm/test/CodeGen/DirectX/rcp.ll | 63 ++ 15 files changed, 564 insertions(+), 47 deletions(-) create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.h create mode 100644 llvm/test/CodeGen/DirectX/any.ll create mode 100644 llvm/test/CodeGen/DirectX/exp-vec.ll create mode 100644 llvm/test/CodeGen/DirectX/exp.ll create mode 100644 llvm/test/CodeGen/DirectX/lerp.ll create mode 100644 llvm/test/CodeGen/DirectX/rcp.ll diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 93ab465079777b..25e4793c3e22d8 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18015,38 +18015,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *S = EmitScalarExpr(E->getArg(2)); -llvm::Type *Xty = X->getType(); -llvm::Type *Yty = Y->getType(); -llvm::Type *Sty = S->getType(); -if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { - if (Xty->isFloatingPointTy()) { -auto V = Builder.CreateFSub(Y, X); -V = Builder.CreateFMul(S, V); -return Builder.CreateFAdd(X, V, "dx.lerp"); - } - llvm_unreachable("Scalar Lerp is only supported on floats."); -} -// A VectorSplat should have happened -assert(Xty->isVectorTy() && Yty->isVectorTy() && Sty->isVectorTy() && - "Lerp of vector and scalar is not supported."); - -[[maybe_unused]] auto *XVecTy = -E->getArg(0)->getType()->getAs(); -[[maybe_unused]] auto *YVecTy = -E->getArg(1)->getType()->getAs(); -[[maybe_unused]] auto *SVecTy = -E->getArg(2)->getType()->getAs(); -// A HLSLVectorTruncation should have happend -assert(XVecTy->getNumElements() == YVecTy->getNumElements() && - XVecTy->getNumElements() == SVecTy->getNumElements() && - "Lerp requires vectors to be of the same size."); -assert(XVecTy->getElementType()->isRealFloatingType() && - XVecTy->getElementType() == YVecTy->getElementType() && - XVecTy->getElementType() == SVecTy->getElementType() && - "Lerp requires float vectors to be of the same type."); +if (!E->getArg(0)->getType()->hasFloatingRepresentation()) + llvm_unreachable("lerp operand must have a float representation"); return Builder.CreateIntrinsic( -/*ReturnType=*/Xty, Intrinsic::dx_lerp, ArrayRef{X, Y, S}, -nullptr, "dx.lerp"); +/*ReturnType=*/X->getType(), Intrinsic::dx_lerp, +ArrayRef{X, Y, S}, nullptr, "dx.lerp"); } case Builtin::BI__builtin_hlsl_elementwise_frac: { Value *Op0 = EmitScalarExpr(E->getArg(0)); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a5f42b630c3fa2..8a2b7384a0b0d5 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5300,8 +5300,6 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; if (SemaBuiltinElementwiseTernaryMath(TheCall)) return true; -if (CheckAllArgsHaveFloatRepresentation(this, TheCall)) - return true; break; } case Builtin::BI__builtin_hlsl_mad: { diff --git a/clang/test/CodeGenHLSL/builtins/lerp.hlsl b/clang/test/CodeGenHLSL/builtins/le
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/84526 >From ad83fd46be2e1587a6cb0098467e18dc38612517 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 7 Mar 2024 20:48:46 -0500 Subject: [PATCH 1/2] [DXIL] exp, any, lerp, & rcp Intrinsic Lowering This change implements lowering for #70076, #70100, #70072, & #70102 CGBuiltin.cpp - - simplify lerp intrinsic IntrinsicsDirectX.td - simplify lerp intrinsic SemaChecking.cpp - remove unnecessary check DXILIntrinsicExpansion.* - add intrinsic to instruction expansion cases DXILOpLowering.cpp - make sure DXILIntrinsicExpansion happens first DirectX.h - changes to support new pass DirectXTargetMachine.cpp - changes to support new pass --- clang/lib/CodeGen/CGBuiltin.cpp | 35 +--- clang/lib/Sema/SemaChecking.cpp | 2 - clang/test/CodeGenHLSL/builtins/lerp.hlsl | 13 +- llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 +- llvm/lib/Target/DirectX/CMakeLists.txt| 1 + .../Target/DirectX/DXILIntrinsicExpansion.cpp | 187 ++ .../Target/DirectX/DXILIntrinsicExpansion.h | 33 llvm/lib/Target/DirectX/DXILOpLowering.cpp| 6 +- llvm/lib/Target/DirectX/DirectX.h | 6 + .../Target/DirectX/DirectXTargetMachine.cpp | 2 + llvm/test/CodeGen/DirectX/any.ll | 133 + llvm/test/CodeGen/DirectX/exp-vec.ll | 23 +++ llvm/test/CodeGen/DirectX/exp.ll | 38 llvm/test/CodeGen/DirectX/lerp.ll | 64 ++ llvm/test/CodeGen/DirectX/rcp.ll | 63 ++ 15 files changed, 564 insertions(+), 47 deletions(-) create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.h create mode 100644 llvm/test/CodeGen/DirectX/any.ll create mode 100644 llvm/test/CodeGen/DirectX/exp-vec.ll create mode 100644 llvm/test/CodeGen/DirectX/exp.ll create mode 100644 llvm/test/CodeGen/DirectX/lerp.ll create mode 100644 llvm/test/CodeGen/DirectX/rcp.ll diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 20c35757939152..1d12237fb25e05 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18009,38 +18009,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *S = EmitScalarExpr(E->getArg(2)); -llvm::Type *Xty = X->getType(); -llvm::Type *Yty = Y->getType(); -llvm::Type *Sty = S->getType(); -if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { - if (Xty->isFloatingPointTy()) { -auto V = Builder.CreateFSub(Y, X); -V = Builder.CreateFMul(S, V); -return Builder.CreateFAdd(X, V, "dx.lerp"); - } - llvm_unreachable("Scalar Lerp is only supported on floats."); -} -// A VectorSplat should have happened -assert(Xty->isVectorTy() && Yty->isVectorTy() && Sty->isVectorTy() && - "Lerp of vector and scalar is not supported."); - -[[maybe_unused]] auto *XVecTy = -E->getArg(0)->getType()->getAs(); -[[maybe_unused]] auto *YVecTy = -E->getArg(1)->getType()->getAs(); -[[maybe_unused]] auto *SVecTy = -E->getArg(2)->getType()->getAs(); -// A HLSLVectorTruncation should have happend -assert(XVecTy->getNumElements() == YVecTy->getNumElements() && - XVecTy->getNumElements() == SVecTy->getNumElements() && - "Lerp requires vectors to be of the same size."); -assert(XVecTy->getElementType()->isRealFloatingType() && - XVecTy->getElementType() == YVecTy->getElementType() && - XVecTy->getElementType() == SVecTy->getElementType() && - "Lerp requires float vectors to be of the same type."); +if (!E->getArg(0)->getType()->hasFloatingRepresentation()) + llvm_unreachable("lerp operand must have a float representation"); return Builder.CreateIntrinsic( -/*ReturnType=*/Xty, Intrinsic::dx_lerp, ArrayRef{X, Y, S}, -nullptr, "dx.lerp"); +/*ReturnType=*/X->getType(), Intrinsic::dx_lerp, +ArrayRef{X, Y, S}, nullptr, "dx.lerp"); } case Builtin::BI__builtin_hlsl_elementwise_frac: { Value *Op0 = EmitScalarExpr(E->getArg(0)); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a5f42b630c3fa2..8a2b7384a0b0d5 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5300,8 +5300,6 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; if (SemaBuiltinElementwiseTernaryMath(TheCall)) return true; -if (CheckAllArgsHaveFloatRepresentation(this, TheCall)) - return true; break; } case Builtin::BI__builtin_hlsl_mad: { diff --git a/clang/test/CodeGenHLSL/builtins/lerp.hlsl b/clang/test/CodeGenHLSL/builtins/le
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Farzon Lotfi (farzonl) Changes This change implements lowering for #70076, #70100, #70072, & #70102 `CGBuiltin.cpp` - - simplify `lerp` intrinsic `IntrinsicsDirectX.td` - simplify `lerp` intrinsic `SemaChecking.cpp` - remove unnecessary check `DXILIntrinsicExpansion.*` - add intrinsic to instruction expansion cases `DXILOpLowering.cpp` - make sure `DXILIntrinsicExpansion` happens first `DirectX.h` - changes to support new pass `DirectXTargetMachine.cpp` - changes to support new pass --- Patch is 28.91 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/84526.diff 15 Files Affected: - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+4-31) - (modified) clang/lib/Sema/SemaChecking.cpp (-2) - (modified) clang/test/CodeGenHLSL/builtins/lerp.hlsl (+4-9) - (modified) llvm/include/llvm/IR/IntrinsicsDirectX.td (+1-4) - (modified) llvm/lib/Target/DirectX/CMakeLists.txt (+1) - (added) llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp (+187) - (added) llvm/lib/Target/DirectX/DXILIntrinsicExpansion.h (+33) - (modified) llvm/lib/Target/DirectX/DXILOpLowering.cpp (+5-1) - (modified) llvm/lib/Target/DirectX/DirectX.h (+6) - (modified) llvm/lib/Target/DirectX/DirectXTargetMachine.cpp (+2) - (added) llvm/test/CodeGen/DirectX/any.ll (+133) - (added) llvm/test/CodeGen/DirectX/exp-vec.ll (+23) - (added) llvm/test/CodeGen/DirectX/exp.ll (+38) - (added) llvm/test/CodeGen/DirectX/lerp.ll (+64) - (added) llvm/test/CodeGen/DirectX/rcp.ll (+63) ``diff diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 20c35757939152..1d12237fb25e05 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18009,38 +18009,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *S = EmitScalarExpr(E->getArg(2)); -llvm::Type *Xty = X->getType(); -llvm::Type *Yty = Y->getType(); -llvm::Type *Sty = S->getType(); -if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { - if (Xty->isFloatingPointTy()) { -auto V = Builder.CreateFSub(Y, X); -V = Builder.CreateFMul(S, V); -return Builder.CreateFAdd(X, V, "dx.lerp"); - } - llvm_unreachable("Scalar Lerp is only supported on floats."); -} -// A VectorSplat should have happened -assert(Xty->isVectorTy() && Yty->isVectorTy() && Sty->isVectorTy() && - "Lerp of vector and scalar is not supported."); - -[[maybe_unused]] auto *XVecTy = -E->getArg(0)->getType()->getAs(); -[[maybe_unused]] auto *YVecTy = -E->getArg(1)->getType()->getAs(); -[[maybe_unused]] auto *SVecTy = -E->getArg(2)->getType()->getAs(); -// A HLSLVectorTruncation should have happend -assert(XVecTy->getNumElements() == YVecTy->getNumElements() && - XVecTy->getNumElements() == SVecTy->getNumElements() && - "Lerp requires vectors to be of the same size."); -assert(XVecTy->getElementType()->isRealFloatingType() && - XVecTy->getElementType() == YVecTy->getElementType() && - XVecTy->getElementType() == SVecTy->getElementType() && - "Lerp requires float vectors to be of the same type."); +if (!E->getArg(0)->getType()->hasFloatingRepresentation()) + llvm_unreachable("lerp operand must have a float representation"); return Builder.CreateIntrinsic( -/*ReturnType=*/Xty, Intrinsic::dx_lerp, ArrayRef{X, Y, S}, -nullptr, "dx.lerp"); +/*ReturnType=*/X->getType(), Intrinsic::dx_lerp, +ArrayRef{X, Y, S}, nullptr, "dx.lerp"); } case Builtin::BI__builtin_hlsl_elementwise_frac: { Value *Op0 = EmitScalarExpr(E->getArg(0)); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a5f42b630c3fa2..8a2b7384a0b0d5 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5300,8 +5300,6 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; if (SemaBuiltinElementwiseTernaryMath(TheCall)) return true; -if (CheckAllArgsHaveFloatRepresentation(this, TheCall)) - return true; break; } case Builtin::BI__builtin_hlsl_mad: { diff --git a/clang/test/CodeGenHLSL/builtins/lerp.hlsl b/clang/test/CodeGenHLSL/builtins/lerp.hlsl index a6b3d9643d674c..38a71ed3bcec94 100644 --- a/clang/test/CodeGenHLSL/builtins/lerp.hlsl +++ b/clang/test/CodeGenHLSL/builtins/lerp.hlsl @@ -6,13 +6,10 @@ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF -// NATIVE_HALF: %3 = fsub half %1, %0 -// NATIVE_HALF: %4 = fmul half %2, %3 -// NATIVE_HALF: %dx.lerp = fadd half %0, %4 + +// NATIVE_HALF: %dx.lerp = call half @llvm.dx.lerp.f16(half %0
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
llvmbot wrote: @llvm/pr-subscribers-backend-directx Author: Farzon Lotfi (farzonl) Changes This change implements lowering for #70076, #70100, #70072, & #70102 `CGBuiltin.cpp` - - simplify `lerp` intrinsic `IntrinsicsDirectX.td` - simplify `lerp` intrinsic `SemaChecking.cpp` - remove unnecessary check `DXILIntrinsicExpansion.*` - add intrinsic to instruction expansion cases `DXILOpLowering.cpp` - make sure `DXILIntrinsicExpansion` happens first `DirectX.h` - changes to support new pass `DirectXTargetMachine.cpp` - changes to support new pass --- Patch is 28.91 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/84526.diff 15 Files Affected: - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+4-31) - (modified) clang/lib/Sema/SemaChecking.cpp (-2) - (modified) clang/test/CodeGenHLSL/builtins/lerp.hlsl (+4-9) - (modified) llvm/include/llvm/IR/IntrinsicsDirectX.td (+1-4) - (modified) llvm/lib/Target/DirectX/CMakeLists.txt (+1) - (added) llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp (+187) - (added) llvm/lib/Target/DirectX/DXILIntrinsicExpansion.h (+33) - (modified) llvm/lib/Target/DirectX/DXILOpLowering.cpp (+5-1) - (modified) llvm/lib/Target/DirectX/DirectX.h (+6) - (modified) llvm/lib/Target/DirectX/DirectXTargetMachine.cpp (+2) - (added) llvm/test/CodeGen/DirectX/any.ll (+133) - (added) llvm/test/CodeGen/DirectX/exp-vec.ll (+23) - (added) llvm/test/CodeGen/DirectX/exp.ll (+38) - (added) llvm/test/CodeGen/DirectX/lerp.ll (+64) - (added) llvm/test/CodeGen/DirectX/rcp.ll (+63) ``diff diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 20c35757939152..1d12237fb25e05 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18009,38 +18009,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *S = EmitScalarExpr(E->getArg(2)); -llvm::Type *Xty = X->getType(); -llvm::Type *Yty = Y->getType(); -llvm::Type *Sty = S->getType(); -if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { - if (Xty->isFloatingPointTy()) { -auto V = Builder.CreateFSub(Y, X); -V = Builder.CreateFMul(S, V); -return Builder.CreateFAdd(X, V, "dx.lerp"); - } - llvm_unreachable("Scalar Lerp is only supported on floats."); -} -// A VectorSplat should have happened -assert(Xty->isVectorTy() && Yty->isVectorTy() && Sty->isVectorTy() && - "Lerp of vector and scalar is not supported."); - -[[maybe_unused]] auto *XVecTy = -E->getArg(0)->getType()->getAs(); -[[maybe_unused]] auto *YVecTy = -E->getArg(1)->getType()->getAs(); -[[maybe_unused]] auto *SVecTy = -E->getArg(2)->getType()->getAs(); -// A HLSLVectorTruncation should have happend -assert(XVecTy->getNumElements() == YVecTy->getNumElements() && - XVecTy->getNumElements() == SVecTy->getNumElements() && - "Lerp requires vectors to be of the same size."); -assert(XVecTy->getElementType()->isRealFloatingType() && - XVecTy->getElementType() == YVecTy->getElementType() && - XVecTy->getElementType() == SVecTy->getElementType() && - "Lerp requires float vectors to be of the same type."); +if (!E->getArg(0)->getType()->hasFloatingRepresentation()) + llvm_unreachable("lerp operand must have a float representation"); return Builder.CreateIntrinsic( -/*ReturnType=*/Xty, Intrinsic::dx_lerp, ArrayRef{X, Y, S}, -nullptr, "dx.lerp"); +/*ReturnType=*/X->getType(), Intrinsic::dx_lerp, +ArrayRef{X, Y, S}, nullptr, "dx.lerp"); } case Builtin::BI__builtin_hlsl_elementwise_frac: { Value *Op0 = EmitScalarExpr(E->getArg(0)); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a5f42b630c3fa2..8a2b7384a0b0d5 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5300,8 +5300,6 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; if (SemaBuiltinElementwiseTernaryMath(TheCall)) return true; -if (CheckAllArgsHaveFloatRepresentation(this, TheCall)) - return true; break; } case Builtin::BI__builtin_hlsl_mad: { diff --git a/clang/test/CodeGenHLSL/builtins/lerp.hlsl b/clang/test/CodeGenHLSL/builtins/lerp.hlsl index a6b3d9643d674c..38a71ed3bcec94 100644 --- a/clang/test/CodeGenHLSL/builtins/lerp.hlsl +++ b/clang/test/CodeGenHLSL/builtins/lerp.hlsl @@ -6,13 +6,10 @@ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF -// NATIVE_HALF: %3 = fsub half %1, %0 -// NATIVE_HALF: %4 = fmul half %2, %3 -// NATIVE_HALF: %dx.lerp = fadd half %0, %4 + +// NATIVE_HALF: %dx.lerp = call half @llvm.dx.lerp.f
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
llvmbot wrote: @llvm/pr-subscribers-llvm-ir @llvm/pr-subscribers-hlsl Author: Farzon Lotfi (farzonl) Changes This change implements lowering for #70076, #70100, #70072, & #70102 `CGBuiltin.cpp` - - simplify `lerp` intrinsic `IntrinsicsDirectX.td` - simplify `lerp` intrinsic `SemaChecking.cpp` - remove unnecessary check `DXILIntrinsicExpansion.*` - add intrinsic to instruction expansion cases `DXILOpLowering.cpp` - make sure `DXILIntrinsicExpansion` happens first `DirectX.h` - changes to support new pass `DirectXTargetMachine.cpp` - changes to support new pass --- Patch is 28.91 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/84526.diff 15 Files Affected: - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+4-31) - (modified) clang/lib/Sema/SemaChecking.cpp (-2) - (modified) clang/test/CodeGenHLSL/builtins/lerp.hlsl (+4-9) - (modified) llvm/include/llvm/IR/IntrinsicsDirectX.td (+1-4) - (modified) llvm/lib/Target/DirectX/CMakeLists.txt (+1) - (added) llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp (+187) - (added) llvm/lib/Target/DirectX/DXILIntrinsicExpansion.h (+33) - (modified) llvm/lib/Target/DirectX/DXILOpLowering.cpp (+5-1) - (modified) llvm/lib/Target/DirectX/DirectX.h (+6) - (modified) llvm/lib/Target/DirectX/DirectXTargetMachine.cpp (+2) - (added) llvm/test/CodeGen/DirectX/any.ll (+133) - (added) llvm/test/CodeGen/DirectX/exp-vec.ll (+23) - (added) llvm/test/CodeGen/DirectX/exp.ll (+38) - (added) llvm/test/CodeGen/DirectX/lerp.ll (+64) - (added) llvm/test/CodeGen/DirectX/rcp.ll (+63) ``diff diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 20c35757939152..1d12237fb25e05 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18009,38 +18009,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *S = EmitScalarExpr(E->getArg(2)); -llvm::Type *Xty = X->getType(); -llvm::Type *Yty = Y->getType(); -llvm::Type *Sty = S->getType(); -if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { - if (Xty->isFloatingPointTy()) { -auto V = Builder.CreateFSub(Y, X); -V = Builder.CreateFMul(S, V); -return Builder.CreateFAdd(X, V, "dx.lerp"); - } - llvm_unreachable("Scalar Lerp is only supported on floats."); -} -// A VectorSplat should have happened -assert(Xty->isVectorTy() && Yty->isVectorTy() && Sty->isVectorTy() && - "Lerp of vector and scalar is not supported."); - -[[maybe_unused]] auto *XVecTy = -E->getArg(0)->getType()->getAs(); -[[maybe_unused]] auto *YVecTy = -E->getArg(1)->getType()->getAs(); -[[maybe_unused]] auto *SVecTy = -E->getArg(2)->getType()->getAs(); -// A HLSLVectorTruncation should have happend -assert(XVecTy->getNumElements() == YVecTy->getNumElements() && - XVecTy->getNumElements() == SVecTy->getNumElements() && - "Lerp requires vectors to be of the same size."); -assert(XVecTy->getElementType()->isRealFloatingType() && - XVecTy->getElementType() == YVecTy->getElementType() && - XVecTy->getElementType() == SVecTy->getElementType() && - "Lerp requires float vectors to be of the same type."); +if (!E->getArg(0)->getType()->hasFloatingRepresentation()) + llvm_unreachable("lerp operand must have a float representation"); return Builder.CreateIntrinsic( -/*ReturnType=*/Xty, Intrinsic::dx_lerp, ArrayRef{X, Y, S}, -nullptr, "dx.lerp"); +/*ReturnType=*/X->getType(), Intrinsic::dx_lerp, +ArrayRef{X, Y, S}, nullptr, "dx.lerp"); } case Builtin::BI__builtin_hlsl_elementwise_frac: { Value *Op0 = EmitScalarExpr(E->getArg(0)); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a5f42b630c3fa2..8a2b7384a0b0d5 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5300,8 +5300,6 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; if (SemaBuiltinElementwiseTernaryMath(TheCall)) return true; -if (CheckAllArgsHaveFloatRepresentation(this, TheCall)) - return true; break; } case Builtin::BI__builtin_hlsl_mad: { diff --git a/clang/test/CodeGenHLSL/builtins/lerp.hlsl b/clang/test/CodeGenHLSL/builtins/lerp.hlsl index a6b3d9643d674c..38a71ed3bcec94 100644 --- a/clang/test/CodeGenHLSL/builtins/lerp.hlsl +++ b/clang/test/CodeGenHLSL/builtins/lerp.hlsl @@ -6,13 +6,10 @@ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF -// NATIVE_HALF: %3 = fsub half %1, %0 -// NATIVE_HALF: %4 = fmul half %2, %3 -// NATIVE_HALF: %dx.lerp = fadd half %0, %4 + +// NATIVE_HALF: %dx.lerp = call ha
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl created https://github.com/llvm/llvm-project/pull/84526 This change implements lowering for #70076, #70100, #70072, & #70102 `CGBuiltin.cpp` - - simplify `lerp` intrinsic `IntrinsicsDirectX.td` - simplify `lerp` intrinsic `SemaChecking.cpp` - remove unnecessary check `DXILIntrinsicExpansion.*` - add intrinsic to instruction expansion cases `DXILOpLowering.cpp` - make sure `DXILIntrinsicExpansion` happens first `DirectX.h` - changes to support new pass `DirectXTargetMachine.cpp` - changes to support new pass >From ad83fd46be2e1587a6cb0098467e18dc38612517 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 7 Mar 2024 20:48:46 -0500 Subject: [PATCH] [DXIL] exp, any, lerp, & rcp Intrinsic Lowering This change implements lowering for #70076, #70100, #70072, & #70102 CGBuiltin.cpp - - simplify lerp intrinsic IntrinsicsDirectX.td - simplify lerp intrinsic SemaChecking.cpp - remove unnecessary check DXILIntrinsicExpansion.* - add intrinsic to instruction expansion cases DXILOpLowering.cpp - make sure DXILIntrinsicExpansion happens first DirectX.h - changes to support new pass DirectXTargetMachine.cpp - changes to support new pass --- clang/lib/CodeGen/CGBuiltin.cpp | 35 +--- clang/lib/Sema/SemaChecking.cpp | 2 - clang/test/CodeGenHLSL/builtins/lerp.hlsl | 13 +- llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 +- llvm/lib/Target/DirectX/CMakeLists.txt| 1 + .../Target/DirectX/DXILIntrinsicExpansion.cpp | 187 ++ .../Target/DirectX/DXILIntrinsicExpansion.h | 33 llvm/lib/Target/DirectX/DXILOpLowering.cpp| 6 +- llvm/lib/Target/DirectX/DirectX.h | 6 + .../Target/DirectX/DirectXTargetMachine.cpp | 2 + llvm/test/CodeGen/DirectX/any.ll | 133 + llvm/test/CodeGen/DirectX/exp-vec.ll | 23 +++ llvm/test/CodeGen/DirectX/exp.ll | 38 llvm/test/CodeGen/DirectX/lerp.ll | 64 ++ llvm/test/CodeGen/DirectX/rcp.ll | 63 ++ 15 files changed, 564 insertions(+), 47 deletions(-) create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.h create mode 100644 llvm/test/CodeGen/DirectX/any.ll create mode 100644 llvm/test/CodeGen/DirectX/exp-vec.ll create mode 100644 llvm/test/CodeGen/DirectX/exp.ll create mode 100644 llvm/test/CodeGen/DirectX/lerp.ll create mode 100644 llvm/test/CodeGen/DirectX/rcp.ll diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 20c35757939152..1d12237fb25e05 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18009,38 +18009,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *S = EmitScalarExpr(E->getArg(2)); -llvm::Type *Xty = X->getType(); -llvm::Type *Yty = Y->getType(); -llvm::Type *Sty = S->getType(); -if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { - if (Xty->isFloatingPointTy()) { -auto V = Builder.CreateFSub(Y, X); -V = Builder.CreateFMul(S, V); -return Builder.CreateFAdd(X, V, "dx.lerp"); - } - llvm_unreachable("Scalar Lerp is only supported on floats."); -} -// A VectorSplat should have happened -assert(Xty->isVectorTy() && Yty->isVectorTy() && Sty->isVectorTy() && - "Lerp of vector and scalar is not supported."); - -[[maybe_unused]] auto *XVecTy = -E->getArg(0)->getType()->getAs(); -[[maybe_unused]] auto *YVecTy = -E->getArg(1)->getType()->getAs(); -[[maybe_unused]] auto *SVecTy = -E->getArg(2)->getType()->getAs(); -// A HLSLVectorTruncation should have happend -assert(XVecTy->getNumElements() == YVecTy->getNumElements() && - XVecTy->getNumElements() == SVecTy->getNumElements() && - "Lerp requires vectors to be of the same size."); -assert(XVecTy->getElementType()->isRealFloatingType() && - XVecTy->getElementType() == YVecTy->getElementType() && - XVecTy->getElementType() == SVecTy->getElementType() && - "Lerp requires float vectors to be of the same type."); +if (!E->getArg(0)->getType()->hasFloatingRepresentation()) + llvm_unreachable("lerp operand must have a float representation"); return Builder.CreateIntrinsic( -/*ReturnType=*/Xty, Intrinsic::dx_lerp, ArrayRef{X, Y, S}, -nullptr, "dx.lerp"); +/*ReturnType=*/X->getType(), Intrinsic::dx_lerp, +ArrayRef{X, Y, S}, nullptr, "dx.lerp"); } case Builtin::BI__builtin_hlsl_elementwise_frac: { Value *Op0 = EmitScalarExpr(E->getArg(0)); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a5f42b630c3fa2..8a2b7384a0b0d5 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/cl