[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)

2024-03-15 Thread Farzon Lotfi via cfe-commits

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)

2024-03-15 Thread Farzon Lotfi via cfe-commits

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)

2024-03-15 Thread Farzon Lotfi via cfe-commits


@@ -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)

2024-03-15 Thread Cooper Partin via cfe-commits


@@ -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)

2024-03-15 Thread Cooper Partin via cfe-commits

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)

2024-03-15 Thread Cooper Partin via cfe-commits

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)

2024-03-14 Thread Farzon Lotfi via cfe-commits

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)

2024-03-14 Thread Farzon Lotfi via cfe-commits

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)

2024-03-14 Thread Farzon Lotfi via cfe-commits

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)

2024-03-14 Thread Chris B via cfe-commits

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)

2024-03-14 Thread Farzon Lotfi via cfe-commits

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)

2024-03-13 Thread Farzon Lotfi via cfe-commits

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)

2024-03-13 Thread Farzon Lotfi via cfe-commits


@@ -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)

2024-03-13 Thread Justin Bogner via cfe-commits


@@ -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)

2024-03-13 Thread Justin Bogner via cfe-commits

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)

2024-03-13 Thread Justin Bogner via cfe-commits


@@ -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)

2024-03-13 Thread Justin Bogner via cfe-commits

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)

2024-03-13 Thread Farzon Lotfi via cfe-commits

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)

2024-03-13 Thread Farzon Lotfi via cfe-commits


@@ -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)

2024-03-13 Thread Farzon Lotfi via cfe-commits

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)

2024-03-13 Thread Farzon Lotfi via cfe-commits

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)

2024-03-13 Thread Farzon Lotfi via cfe-commits


@@ -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)

2024-03-12 Thread Farzon Lotfi via cfe-commits


@@ -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)

2024-03-12 Thread Farzon Lotfi via cfe-commits

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)

2024-03-12 Thread Farzon Lotfi via cfe-commits


@@ -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)

2024-03-12 Thread Farzon Lotfi via cfe-commits

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)

2024-03-12 Thread Farzon Lotfi via cfe-commits


@@ -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)

2024-03-12 Thread Justin Bogner via cfe-commits


@@ -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)

2024-03-12 Thread Justin Bogner via cfe-commits


@@ -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)

2024-03-12 Thread Justin Bogner via cfe-commits


@@ -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)

2024-03-12 Thread Justin Bogner via cfe-commits


@@ -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)

2024-03-12 Thread Justin Bogner via cfe-commits


@@ -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)

2024-03-12 Thread Justin Bogner via cfe-commits


@@ -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)

2024-03-12 Thread Justin Bogner via cfe-commits


@@ -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)

2024-03-12 Thread Justin Bogner via cfe-commits


@@ -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)

2024-03-12 Thread Justin Bogner via cfe-commits


@@ -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)

2024-03-12 Thread Justin Bogner via cfe-commits


@@ -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)

2024-03-12 Thread Justin Bogner via cfe-commits


@@ -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)

2024-03-12 Thread Farzon Lotfi via cfe-commits

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)

2024-03-12 Thread Farzon Lotfi via cfe-commits

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)

2024-03-11 Thread Farzon Lotfi via cfe-commits

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)

2024-03-11 Thread Farzon Lotfi via cfe-commits

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)

2024-03-11 Thread Farzon Lotfi via cfe-commits

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)

2024-03-11 Thread Farzon Lotfi via cfe-commits

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)

2024-03-08 Thread Farzon Lotfi via cfe-commits

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)

2024-03-08 Thread via cfe-commits

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)

2024-03-08 Thread via cfe-commits

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)

2024-03-08 Thread via cfe-commits

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)

2024-03-08 Thread Farzon Lotfi via cfe-commits

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