-
Notifications
You must be signed in to change notification settings - Fork 14.5k
[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
Conversation
@llvm/pr-subscribers-backend-directx Author: Farzon Lotfi (farzonl) ChangesCompletes #86192 Full diff: https://github.com/llvm/llvm-project/pull/86569.diff 6 Files Affected:
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
+}
|
✅ With the latest revision this PR passed the Python code formatter. |
✅ With the latest revision this PR passed the C/C++ code formatter. |
Completes llvm#86192 `DXIL.td` - add log2 to dxilop lowering `DXILIntrinsicExpansion.cpp` - add log and log10 to log2 expansions
6b7e184
to
bd92b86
Compare
There was a problem hiding this 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!
Completes #86192
DXIL.td
- add log2 to dxilop loweringDXILIntrinsicExpansion.cpp
- add log and log10 to log2 expansions