Skip to content

[DXIL] Implement log intrinsic Lowering #86569

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 26, 2024
Merged

Conversation

farzonl
Copy link
Member

@farzonl farzonl commented Mar 25, 2024

Completes #86192
DXIL.td - add log2 to dxilop lowering
DXILIntrinsicExpansion.cpp - add log and log10 to log2 expansions

@llvmbot
Copy link
Member

llvmbot commented Mar 25, 2024

@llvm/pr-subscribers-backend-directx

Author: Farzon Lotfi (farzonl)

Changes

Completes #86192
DXIL.td - add log2 to dxilop lowering
DXILIntrinsicExpansion.cpp - add log and log10 to log2 expansions


Full diff: https://github.com/llvm/llvm-project/pull/86569.diff

6 Files Affected:

  • (modified) llvm/lib/Target/DirectX/DXIL.td (+3)
  • (modified) llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp (+34-2)
  • (added) llvm/test/CodeGen/DirectX/log.ll (+25)
  • (added) llvm/test/CodeGen/DirectX/log10.ll (+25)
  • (added) llvm/test/CodeGen/DirectX/log2.ll (+20)
  • (added) llvm/test/CodeGen/DirectX/log2_error.ll (+10)
diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index f7e69ebae15b6c..fa26d82b9a2a42 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -274,6 +274,9 @@ def Frac : DXILOpMapping<22, unary, int_dx_frac,
                          "Returns a fraction from 0 to 1 that represents the "
                          "decimal part of the input.",
                          [llvm_halforfloat_ty, LLVMMatchType<0>]>;
+def Log2 : DXILOpMapping<23, unary, int_log2,
+                         "Returns the base-2 logarithm of the specified value.",
+                         [llvm_halforfloat_ty, LLVMMatchType<0>]>;
 def RSqrt : DXILOpMapping<25, unary, int_dx_rsqrt,
                          "Returns the reciprocal of the square root of the specified value."
                          "rsqrt(x) = 1 / sqrt(x).",
diff --git a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
index b46564702c7aad..3cc375edabde92 100644
--- a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
+++ b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
@@ -35,6 +35,8 @@ static bool isIntrinsicExpansion(Function &F) {
   switch (F.getIntrinsicID()) {
   case Intrinsic::abs:
   case Intrinsic::exp:
+  case Intrinsic::log:
+  case Intrinsic::log10:
   case Intrinsic::dx_any:
   case Intrinsic::dx_clamp:
   case Intrinsic::dx_uclamp:
@@ -108,8 +110,8 @@ static bool expandExpIntrinsic(CallInst *Orig) {
       Ty->isVectorTy() ? ConstantVector::getSplat(
                              ElementCount::getFixed(
                                  cast<FixedVectorType>(Ty)->getNumElements()),
-                             ConstantFP::get(EltTy, numbers::log2e))
-                       : ConstantFP::get(EltTy, numbers::log2e);
+                             ConstantFP::get(EltTy, numbers::log2ef))
+                       : ConstantFP::get(EltTy, numbers::log2ef);
   Value *NewX = Builder.CreateFMul(Log2eConst, X);
   auto *Exp2Call =
       Builder.CreateIntrinsic(Ty, Intrinsic::exp2, {NewX}, nullptr, "dx.exp2");
@@ -169,6 +171,32 @@ static bool expandLerpIntrinsic(CallInst *Orig) {
   return true;
 }
 
+static bool expandLogIntrinsic(CallInst *Orig,
+                               float LogConstVal = numbers::ln2f) {
+  Value *X = Orig->getOperand(0);
+  IRBuilder<> Builder(Orig->getParent());
+  Builder.SetInsertPoint(Orig);
+  Type *Ty = X->getType();
+  Type *EltTy = Ty->getScalarType();
+  Constant *Ln2Const =
+      Ty->isVectorTy() ? ConstantVector::getSplat(
+                             ElementCount::getFixed(
+                                 cast<FixedVectorType>(Ty)->getNumElements()),
+                             ConstantFP::get(EltTy, LogConstVal))
+                       : ConstantFP::get(EltTy, LogConstVal);
+  auto *Log2Call =
+      Builder.CreateIntrinsic(Ty, Intrinsic::log2, {X}, nullptr, "elt.log2");
+  Log2Call->setTailCall(Orig->isTailCall());
+  Log2Call->setAttributes(Orig->getAttributes());
+  auto *Result = Builder.CreateFMul(Ln2Const, Log2Call);
+  Orig->replaceAllUsesWith(Result);
+  Orig->eraseFromParent();
+  return true;
+}
+static bool expandLog10Intrinsic(CallInst *Orig) {
+  return expandLogIntrinsic(Orig, numbers::ln2f / numbers::ln10f);
+}
+
 static bool expandRcpIntrinsic(CallInst *Orig) {
   Value *X = Orig->getOperand(0);
   IRBuilder<> Builder(Orig->getParent());
@@ -238,6 +266,10 @@ static bool expandIntrinsic(Function &F, CallInst *Orig) {
     return expandAbs(Orig);
   case Intrinsic::exp:
     return expandExpIntrinsic(Orig);
+  case Intrinsic::log:
+    return expandLogIntrinsic(Orig);
+  case Intrinsic::log10:
+    return expandLog10Intrinsic(Orig);
   case Intrinsic::dx_any:
     return expandAnyIntrinsic(Orig);
   case Intrinsic::dx_uclamp:
diff --git a/llvm/test/CodeGen/DirectX/log.ll b/llvm/test/CodeGen/DirectX/log.ll
new file mode 100644
index 00000000000000..172c3bfed3b770
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/log.ll
@@ -0,0 +1,25 @@
+; RUN: opt -S  -dxil-intrinsic-expansion  < %s | FileCheck %s --check-prefixes=CHECK,EXPCHECK
+; RUN: opt -S  -dxil-op-lower  < %s | FileCheck %s --check-prefixes=CHECK,DOPCHECK
+
+; Make sure dxil operation function calls for log are generated.
+
+define noundef float @log_float(float noundef %a) #0 {
+entry:
+; DOPCHECK: call float @dx.op.unary.f32(i32 23, float %{{.*}})
+; EXPCHECK: call float @llvm.log2.f32(float %a)
+; CHECK: fmul float 0x3FE62E4300000000, %{{.*}}
+  %elt.log = call float @llvm.log.f32(float %a)
+  ret float %elt.log
+}
+
+define noundef half @log_half(half noundef %a) #0 {
+entry:
+; DOPCHECK: call half @dx.op.unary.f16(i32 23, half %{{.*}})
+; EXPCHECK: call half @llvm.log2.f16(half %a)
+; CHECK: fmul half 0xH398C, %{{.*}}
+  %elt.log = call half @llvm.log.f16(half %a)
+  ret half %elt.log
+}
+
+declare half @llvm.log.f16(half)
+declare float @llvm.log.f32(float)
diff --git a/llvm/test/CodeGen/DirectX/log10.ll b/llvm/test/CodeGen/DirectX/log10.ll
new file mode 100644
index 00000000000000..d4f827a0d1af83
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/log10.ll
@@ -0,0 +1,25 @@
+; RUN: opt -S  -dxil-intrinsic-expansion  < %s | FileCheck %s --check-prefixes=CHECK,EXPCHECK
+; RUN: opt -S  -dxil-op-lower  < %s | FileCheck %s --check-prefixes=CHECK,DOPCHECK
+
+; Make sure dxil operation function calls for log10 are generated.
+
+define noundef float @log10_float(float noundef %a) #0 {
+entry:
+; DOPCHECK: call float @dx.op.unary.f32(i32 23, float %{{.*}})
+; EXPCHECK: call float @llvm.log2.f32(float %a)
+; CHECK: fmul float 0x3FD3441340000000, %{{.*}}
+  %elt.log10 = call float @llvm.log10.f32(float %a)
+  ret float %elt.log10
+}
+
+define noundef half @log10_half(half noundef %a) #0 {
+entry:
+; DOPCHECK: call half @dx.op.unary.f16(i32 23, half %{{.*}})
+; EXPCHECK: call half @llvm.log2.f16(half %a)
+; CHECK: fmul half 0xH34D1, %{{.*}}
+  %elt.log10 = call half @llvm.log10.f16(half %a)
+  ret half %elt.log10
+}
+
+declare half @llvm.log10.f16(half)
+declare float @llvm.log10.f32(float)
diff --git a/llvm/test/CodeGen/DirectX/log2.ll b/llvm/test/CodeGen/DirectX/log2.ll
new file mode 100644
index 00000000000000..2164d4db9396d1
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/log2.ll
@@ -0,0 +1,20 @@
+; RUN: opt -S -dxil-op-lower < %s | FileCheck %s
+
+; Make sure dxil operation function calls for log2 are generated for float and half.
+
+define noundef float @log2_float(float noundef %a) #0 {
+entry:
+; CHECK:call float @dx.op.unary.f32(i32 23, float %{{.*}})
+  %elt.log2 = call float @llvm.log2.f32(float %a)
+  ret float %elt.log2
+}
+
+define noundef half @log2_half(half noundef %a) #0 {
+entry:
+; CHECK:call half @dx.op.unary.f16(i32 23, half %{{.*}})
+  %elt.log2 = call half @llvm.log2.f16(half %a)
+  ret half %elt.log2
+}
+
+declare half @llvm.log2.f16(half)
+declare float @llvm.log2.f32(float)
diff --git a/llvm/test/CodeGen/DirectX/log2_error.ll b/llvm/test/CodeGen/DirectX/log2_error.ll
new file mode 100644
index 00000000000000..a26f6e8c3117f5
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/log2_error.ll
@@ -0,0 +1,10 @@
+; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s
+
+; DXIL operation log2 does not support double overload type
+; CHECK: LLVM ERROR: Invalid Overload Type
+
+define noundef double @log2_double(double noundef %a) {
+entry:
+  %elt.log2 = call double @llvm.log2.f64(double %a)
+  ret double %elt.log2
+}

@farzonl farzonl linked an issue Mar 25, 2024 that may be closed by this pull request
Copy link

✅ With the latest revision this PR passed the Python code formatter.

Copy link

✅ With the latest revision this PR passed the C/C++ code formatter.

@farzonl farzonl requested a review from bharadwajy March 25, 2024 21:35
farzonl added 2 commits March 25, 2024 23:13
Completes llvm#86192
`DXIL.td` - add log2 to dxilop lowering
`DXILIntrinsicExpansion.cpp` - add log and log10 to log2 expansions
@farzonl farzonl force-pushed the dxil-log-lowering branch from 6b7e184 to bd92b86 Compare March 26, 2024 03:13
Copy link
Contributor

@coopp coopp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I went through all of the tests too. You covered half and float which I assumed would be there. NICE!

@farzonl farzonl merged commit 5cf1e2e into llvm:main Mar 26, 2024
@farzonl farzonl deleted the dxil-log-lowering branch March 26, 2024 16:46
@farzonl farzonl self-assigned this Mar 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

[DXIL] Add log, log2, and log10 intrinsic Lowering
4 participants