mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 12:26:52 +08:00
[DXIL] Implement pow lowering (#86733)
closes #86179 - `DXILIntrinsicExpansion.cpp` - add the pow expansion to exp2(y*log2(x))
This commit is contained in:
@@ -37,6 +37,7 @@ static bool isIntrinsicExpansion(Function &F) {
|
||||
case Intrinsic::exp:
|
||||
case Intrinsic::log:
|
||||
case Intrinsic::log10:
|
||||
case Intrinsic::pow:
|
||||
case Intrinsic::dx_any:
|
||||
case Intrinsic::dx_clamp:
|
||||
case Intrinsic::dx_uclamp:
|
||||
@@ -197,6 +198,26 @@ static bool expandLog10Intrinsic(CallInst *Orig) {
|
||||
return expandLogIntrinsic(Orig, numbers::ln2f / numbers::ln10f);
|
||||
}
|
||||
|
||||
static bool expandPowIntrinsic(CallInst *Orig) {
|
||||
|
||||
Value *X = Orig->getOperand(0);
|
||||
Value *Y = Orig->getOperand(1);
|
||||
Type *Ty = X->getType();
|
||||
IRBuilder<> Builder(Orig->getParent());
|
||||
Builder.SetInsertPoint(Orig);
|
||||
|
||||
auto *Log2Call =
|
||||
Builder.CreateIntrinsic(Ty, Intrinsic::log2, {X}, nullptr, "elt.log2");
|
||||
auto *Mul = Builder.CreateFMul(Log2Call, Y);
|
||||
auto *Exp2Call =
|
||||
Builder.CreateIntrinsic(Ty, Intrinsic::exp2, {Mul}, nullptr, "elt.exp2");
|
||||
Exp2Call->setTailCall(Orig->isTailCall());
|
||||
Exp2Call->setAttributes(Orig->getAttributes());
|
||||
Orig->replaceAllUsesWith(Exp2Call);
|
||||
Orig->eraseFromParent();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool expandRcpIntrinsic(CallInst *Orig) {
|
||||
Value *X = Orig->getOperand(0);
|
||||
IRBuilder<> Builder(Orig->getParent());
|
||||
@@ -270,6 +291,8 @@ static bool expandIntrinsic(Function &F, CallInst *Orig) {
|
||||
return expandLogIntrinsic(Orig);
|
||||
case Intrinsic::log10:
|
||||
return expandLog10Intrinsic(Orig);
|
||||
case Intrinsic::pow:
|
||||
return expandPowIntrinsic(Orig);
|
||||
case Intrinsic::dx_any:
|
||||
return expandAnyIntrinsic(Orig);
|
||||
case Intrinsic::dx_uclamp:
|
||||
|
||||
15
llvm/test/CodeGen/DirectX/pow-vec.ll
Normal file
15
llvm/test/CodeGen/DirectX/pow-vec.ll
Normal file
@@ -0,0 +1,15 @@
|
||||
; RUN: opt -S -dxil-intrinsic-expansion < %s | FileCheck %s
|
||||
|
||||
; Make sure dxil operation function calls for pow are generated for float and half.
|
||||
|
||||
; CHECK-LABEL: pow_float4
|
||||
; CHECK: call <4 x float> @llvm.log2.v4f32(<4 x float> %a)
|
||||
; CHECK: fmul <4 x float> %{{.*}}, %b
|
||||
; CHECK: call <4 x float> @llvm.exp2.v4f32(<4 x float> %{{.*}})
|
||||
define noundef <4 x float> @pow_float4(<4 x float> noundef %a, <4 x float> noundef %b) {
|
||||
entry:
|
||||
%elt.pow = call <4 x float> @llvm.pow.v4f32(<4 x float> %a, <4 x float> %b)
|
||||
ret <4 x float> %elt.pow
|
||||
}
|
||||
|
||||
declare <4 x float> @llvm.pow.v4f32(<4 x float>,<4 x float>)
|
||||
29
llvm/test/CodeGen/DirectX/pow.ll
Normal file
29
llvm/test/CodeGen/DirectX/pow.ll
Normal file
@@ -0,0 +1,29 @@
|
||||
; 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 pow are generated.
|
||||
|
||||
define noundef float @pow_float(float noundef %a, float noundef %b) {
|
||||
entry:
|
||||
; DOPCHECK: call float @dx.op.unary.f32(i32 23, float %a)
|
||||
; EXPCHECK: call float @llvm.log2.f32(float %a)
|
||||
; CHECK: fmul float %{{.*}}, %b
|
||||
; DOPCHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}})
|
||||
; EXPCHECK: call float @llvm.exp2.f32(float %{{.*}})
|
||||
%elt.pow = call float @llvm.pow.f32(float %a, float %b)
|
||||
ret float %elt.pow
|
||||
}
|
||||
|
||||
define noundef half @pow_half(half noundef %a, half noundef %b) {
|
||||
entry:
|
||||
; DOPCHECK: call half @dx.op.unary.f16(i32 23, half %a)
|
||||
; EXPCHECK: call half @llvm.log2.f16(half %a)
|
||||
; CHECK: fmul half %{{.*}}, %b
|
||||
; DOPCHECK: call half @dx.op.unary.f16(i32 21, half %{{.*}})
|
||||
; EXPCHECK: call half @llvm.exp2.f16(half %{{.*}})
|
||||
%elt.pow = call half @llvm.pow.f16(half %a, half %b)
|
||||
ret half %elt.pow
|
||||
}
|
||||
|
||||
declare half @llvm.pow.f16(half,half)
|
||||
declare float @llvm.pow.f32(float,float)
|
||||
Reference in New Issue
Block a user