Skip to content

Commit 36b8643

Browse files
authored
[DXIL] Implement pow lowering (#86733)
closes #86179 - `DXILIntrinsicExpansion.cpp` - add the pow expansion to exp2(y*log2(x))
1 parent 0f61051 commit 36b8643

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ static bool isIntrinsicExpansion(Function &F) {
3737
case Intrinsic::exp:
3838
case Intrinsic::log:
3939
case Intrinsic::log10:
40+
case Intrinsic::pow:
4041
case Intrinsic::dx_any:
4142
case Intrinsic::dx_clamp:
4243
case Intrinsic::dx_uclamp:
@@ -197,6 +198,26 @@ static bool expandLog10Intrinsic(CallInst *Orig) {
197198
return expandLogIntrinsic(Orig, numbers::ln2f / numbers::ln10f);
198199
}
199200

201+
static bool expandPowIntrinsic(CallInst *Orig) {
202+
203+
Value *X = Orig->getOperand(0);
204+
Value *Y = Orig->getOperand(1);
205+
Type *Ty = X->getType();
206+
IRBuilder<> Builder(Orig->getParent());
207+
Builder.SetInsertPoint(Orig);
208+
209+
auto *Log2Call =
210+
Builder.CreateIntrinsic(Ty, Intrinsic::log2, {X}, nullptr, "elt.log2");
211+
auto *Mul = Builder.CreateFMul(Log2Call, Y);
212+
auto *Exp2Call =
213+
Builder.CreateIntrinsic(Ty, Intrinsic::exp2, {Mul}, nullptr, "elt.exp2");
214+
Exp2Call->setTailCall(Orig->isTailCall());
215+
Exp2Call->setAttributes(Orig->getAttributes());
216+
Orig->replaceAllUsesWith(Exp2Call);
217+
Orig->eraseFromParent();
218+
return true;
219+
}
220+
200221
static bool expandRcpIntrinsic(CallInst *Orig) {
201222
Value *X = Orig->getOperand(0);
202223
IRBuilder<> Builder(Orig->getParent());
@@ -270,6 +291,8 @@ static bool expandIntrinsic(Function &F, CallInst *Orig) {
270291
return expandLogIntrinsic(Orig);
271292
case Intrinsic::log10:
272293
return expandLog10Intrinsic(Orig);
294+
case Intrinsic::pow:
295+
return expandPowIntrinsic(Orig);
273296
case Intrinsic::dx_any:
274297
return expandAnyIntrinsic(Orig);
275298
case Intrinsic::dx_uclamp:

llvm/test/CodeGen/DirectX/pow-vec.ll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
; RUN: opt -S -dxil-intrinsic-expansion < %s | FileCheck %s
2+
3+
; Make sure dxil operation function calls for pow are generated for float and half.
4+
5+
; CHECK-LABEL: pow_float4
6+
; CHECK: call <4 x float> @llvm.log2.v4f32(<4 x float> %a)
7+
; CHECK: fmul <4 x float> %{{.*}}, %b
8+
; CHECK: call <4 x float> @llvm.exp2.v4f32(<4 x float> %{{.*}})
9+
define noundef <4 x float> @pow_float4(<4 x float> noundef %a, <4 x float> noundef %b) {
10+
entry:
11+
%elt.pow = call <4 x float> @llvm.pow.v4f32(<4 x float> %a, <4 x float> %b)
12+
ret <4 x float> %elt.pow
13+
}
14+
15+
declare <4 x float> @llvm.pow.v4f32(<4 x float>,<4 x float>)

llvm/test/CodeGen/DirectX/pow.ll

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
; RUN: opt -S -dxil-intrinsic-expansion < %s | FileCheck %s --check-prefixes=CHECK,EXPCHECK
2+
; RUN: opt -S -dxil-op-lower < %s | FileCheck %s --check-prefixes=CHECK,DOPCHECK
3+
4+
; Make sure dxil operation function calls for pow are generated.
5+
6+
define noundef float @pow_float(float noundef %a, float noundef %b) {
7+
entry:
8+
; DOPCHECK: call float @dx.op.unary.f32(i32 23, float %a)
9+
; EXPCHECK: call float @llvm.log2.f32(float %a)
10+
; CHECK: fmul float %{{.*}}, %b
11+
; DOPCHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}})
12+
; EXPCHECK: call float @llvm.exp2.f32(float %{{.*}})
13+
%elt.pow = call float @llvm.pow.f32(float %a, float %b)
14+
ret float %elt.pow
15+
}
16+
17+
define noundef half @pow_half(half noundef %a, half noundef %b) {
18+
entry:
19+
; DOPCHECK: call half @dx.op.unary.f16(i32 23, half %a)
20+
; EXPCHECK: call half @llvm.log2.f16(half %a)
21+
; CHECK: fmul half %{{.*}}, %b
22+
; DOPCHECK: call half @dx.op.unary.f16(i32 21, half %{{.*}})
23+
; EXPCHECK: call half @llvm.exp2.f16(half %{{.*}})
24+
%elt.pow = call half @llvm.pow.f16(half %a, half %b)
25+
ret half %elt.pow
26+
}
27+
28+
declare half @llvm.pow.f16(half,half)
29+
declare float @llvm.pow.f32(float,float)

0 commit comments

Comments
 (0)