[llvm] 31fb1d8 - [AMDGPU] Fix pow with a negative base (#222248)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 9 07:17:02 PDT 2026
Author: Arseniy Obolenskiy
Date: 2026-09-09T16:16:50+02:00
New Revision: 31fb1d84516bb48b6f6d1e34b50d069458a64f09
URL: https://github.com/llvm/llvm-project/commit/31fb1d84516bb48b6f6d1e34b50d069458a64f09
DIFF: https://github.com/llvm/llvm-project/commit/31fb1d84516bb48b6f6d1e34b50d069458a64f09.diff
LOG: [AMDGPU] Fix pow with a negative base (#222248)
v_log_f32 of a negative value is NaN, so the old expansion returned NaN
for every negative base
Take the log of `|x|` and fix up the sign
Added:
llvm/test/CodeGen/AMDGPU/GlobalISel/fma-mix-true16.ll
Modified:
llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h
llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.h
llvm/lib/Target/AMDGPU/R600ISelLowering.cpp
llvm/lib/Target/AMDGPU/SIInstructions.td
llvm/test/CodeGen/AMDGPU/GlobalISel/fpow.ll
llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-fpow.mir
llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-fpowi.mir
llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.powi.ll
llvm/test/CodeGen/AMDGPU/fpow.ll
llvm/test/CodeGen/AMDGPU/llvm.powi.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 63535f3070cd3..b01799a8194e0 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -413,9 +413,9 @@ AMDGPUTargetLowering::AMDGPUTargetLowering(const TargetMachine &TM,
// Library functions. These default to Expand, but we have instructions
// for them.
- setOperationAction({ISD::FCEIL, ISD::FPOW, ISD::FABS, ISD::FFLOOR,
- ISD::FROUNDEVEN, ISD::FTRUNC},
- {MVT::f16, MVT::f32}, Legal);
+ setOperationAction(
+ {ISD::FCEIL, ISD::FABS, ISD::FFLOOR, ISD::FROUNDEVEN, ISD::FTRUNC},
+ {MVT::f16, MVT::f32}, Legal);
setOperationAction({ISD::FMINNUM, ISD::FMAXNUM}, MVT::f32, Legal);
setOperationAction(ISD::FLOG2, MVT::f32, Custom);
@@ -424,8 +424,8 @@ AMDGPUTargetLowering::AMDGPUTargetLowering(const TargetMachine &TM,
{MVT::f16, MVT::f32, MVT::f64}, Expand);
setOperationAction(
- {ISD::FLOG, ISD::FLOG10, ISD::FEXP, ISD::FEXP2, ISD::FEXP10}, MVT::f32,
- Custom);
+ {ISD::FLOG, ISD::FLOG10, ISD::FEXP, ISD::FEXP2, ISD::FEXP10, ISD::FPOW},
+ MVT::f32, Custom);
setOperationAction({ISD::FEXP, ISD::FEXP2, ISD::FEXP10}, MVT::f64, Custom);
setOperationAction(ISD::FNEARBYINT, {MVT::f16, MVT::f32, MVT::f64}, Custom);
@@ -1462,6 +1462,8 @@ SDValue AMDGPUTargetLowering::LowerOperation(SDValue Op,
return lowerFEXP(Op, DAG);
case ISD::FEXP2:
return lowerFEXP2(Op, DAG);
+ case ISD::FPOW:
+ return lowerFPOW(Op, DAG);
case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG);
case ISD::UINT_TO_FP: return LowerUINT_TO_FP(Op, DAG);
case ISD::FP_TO_FP16: return LowerFP_TO_FP16(Op, DAG);
@@ -3315,6 +3317,77 @@ SDValue AMDGPUTargetLowering::lowerFEXP(SDValue Op, SelectionDAG &DAG) const {
return R;
}
+// No pow instruction or libcall to fall back on. fmul_legacy returns 0 for a
+// zero operand even against an infinity or a NaN, so pow(x, 0) and pow(1, y)
+// fall out as exp2(0) = 1.
+SDValue AMDGPUTargetLowering::lowerFPOW(SDValue Op, SelectionDAG &DAG) const {
+ EVT VT = Op.getValueType();
+ assert(VT == MVT::f32);
+
+ SDLoc SL(Op);
+ SDValue X = Op.getOperand(0);
+ SDValue Y = Op.getOperand(1);
+ SDNodeFlags Flags = Op->getFlags();
+
+ // log2(0) is -inf, which exp2 turns back into a finite result, so the core
+ // goes infinite for inputs a ninf fpow still asserts about, like pow(0, 2).
+ SDNodeFlags CoreFlags = Flags;
+ CoreFlags.setNoInfs(false);
+
+ // Fast expansion: ignores denormals, NaN for a negative base.
+ if (allowApproxFunc(DAG, Flags)) {
+ SDValue Log = DAG.getNode(AMDGPUISD::LOG, SL, VT, X, CoreFlags);
+ SDValue Mul =
+ DAG.getNode(AMDGPUISD::FMUL_LEGACY, SL, VT, Y, Log, CoreFlags);
+ return DAG.getNode(AMDGPUISD::EXP, SL, VT, Mul, CoreFlags);
+ }
+
+ SDValue Abs = DAG.getNode(ISD::FABS, SL, VT, X, Flags);
+ SDValue Log = DAG.getNode(ISD::FLOG2, SL, VT, Abs, CoreFlags);
+ SDValue Mul = DAG.getNode(AMDGPUISD::FMUL_LEGACY, SL, VT, Y, Log, CoreFlags);
+ SDValue R = DAG.getNode(ISD::FEXP2, SL, VT, Mul, CoreFlags);
+
+ // A base that is never negative needs neither the sign fixup nor the NaN.
+ if (DAG.computeKnownFPClass(X, fcNegative).signBitIsZeroOrNaN())
+ return R;
+
+ EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
+
+ // Infinities count as integers, and every f32 >= 2^24 in magnitude is even.
+ SDValue YTrunc = DAG.getNode(ISD::FTRUNC, SL, VT, Y);
+ SDValue YIsInt = DAG.getSetCC(SL, SetCCVT, YTrunc, Y, ISD::SETOEQ);
+ SDValue YHalf =
+ DAG.getNode(ISD::FMUL, SL, VT, Y, DAG.getConstantFP(0.5, SL, VT));
+ SDValue YHalfTrunc = DAG.getNode(ISD::FTRUNC, SL, VT, YHalf);
+ SDValue YIsOdd =
+ DAG.getNode(ISD::AND, SL, SetCCVT, YIsInt,
+ DAG.getSetCC(SL, SetCCVT, YHalfTrunc, YHalf, ISD::SETONE));
+
+ // pow(-x, odd y) = -pow(x, y). Selecting the copysign lets even y fold it.
+ R = DAG.getNode(ISD::SELECT, SL, VT, YIsOdd,
+ DAG.getNode(ISD::FCOPYSIGN, SL, VT, R, X), R);
+
+ if (Flags.hasNoNaNs())
+ return R;
+
+ // A negative finite base to a non-integral power is NaN. -inf is excluded:
+ // the core already gives pow(+inf, y). So are subnormals when flushed.
+ FPClassTest NegFiniteMask = fcNegNormal;
+ if (!DAG.getMachineFunction()
+ .getDenormalMode(APFloat::IEEEsingle())
+ .inputsAreZero())
+ NegFiniteMask |= fcNegSubnormal;
+ SDValue XNegFinite =
+ DAG.getNode(ISD::IS_FPCLASS, SL, SetCCVT, X,
+ DAG.getTargetConstant(NegFiniteMask, SL, MVT::i32));
+ // Not a SETONE compare: pow(-1, NaN) needs the NaN-true behavior of !SETOEQ.
+ SDValue NegNonInt = DAG.getNode(ISD::AND, SL, SetCCVT, XNegFinite,
+ DAG.getNOT(SL, YIsInt, SetCCVT));
+ SDValue NaN =
+ DAG.getConstantFP(APFloat::getQNaN(VT.getFltSemantics()), SL, VT);
+ return DAG.getNode(ISD::SELECT, SL, VT, NegNonInt, NaN, R);
+}
+
static bool isCtlzOpc(unsigned Opc) {
return Opc == ISD::CTLZ || Opc == ISD::CTLZ_ZERO_POISON;
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h
index 33ca92d5b7a51..9316f83fac06e 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h
@@ -87,6 +87,7 @@ class AMDGPUTargetLowering : public TargetLowering {
SDNodeFlags Flags) const;
SDValue lowerFEXP(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerFEXPF64(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerFPOW(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerCTLZResults(SDValue Op, SelectionDAG &DAG) const;
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
index 04b23a55e9fa6..e4111ba265a7c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
@@ -7129,7 +7129,7 @@ AMDGPUInstructionSelector::selectVOP3PMadMixModsImpl(MachineOperand &Root,
unsigned Mods;
std::tie(Src, Mods) = selectVOP3ModsImpl(Root.getReg());
- if (mi_match(Src, *MRI, m_GFPExt(m_Reg(Src)))) {
+ if (!STI.useRealTrue16Insts() && mi_match(Src, *MRI, m_GFPExt(m_Reg(Src)))) {
assert(MRI->getType(Src) == LLT::scalar(16));
// Only change Src if src modifier could be gained. In such cases new Src
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
index 6d722311d6d5d..d0091a8295d04 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
@@ -730,7 +730,6 @@ AMDGPULegalizerInfo::AMDGPULegalizerInfo(const GCNSubtarget &ST_,
const std::initializer_list<LLT> FPTypesPK16_64 = {F32, F64, F16, V2F16,
V2F64};
- const LLT MinExtendedFPTy = ST.has16BitInsts() ? F16 : F32;
const LLT I1 = LLT::integer(1);
const LLT I16 = LLT::integer(16);
const LLT I32 = LLT::integer(32);
@@ -1356,17 +1355,12 @@ AMDGPULegalizerInfo::AMDGPULegalizerInfo(const GCNSubtarget &ST_,
FCmpBuilder.widenScalarToNextPow2(1).minScalar(1, F32).scalarize(0);
- // FIXME: fpow has a selection pattern that should move to custom lowering.
- auto &ExpOps = getActionDefinitionsBuilder(G_FPOW);
- if (ST.has16BitInsts())
- ExpOps.customFor({{F32}, {F16}});
- else
- ExpOps.customFor({F32});
- ExpOps.clampScalar(0, MinExtendedFPTy, F32).scalarize(0);
+ getActionDefinitionsBuilder(G_FPOW)
+ .customFor({F32})
+ .clampScalar(0, F32, F32)
+ .scalarize(0);
- getActionDefinitionsBuilder(G_FPOWI)
- .clampScalar(0, MinExtendedFPTy, F32)
- .lower();
+ getActionDefinitionsBuilder(G_FPOWI).clampScalar(0, F32, F32).lower();
getActionDefinitionsBuilder(G_FLOG2)
.legalFor(ST.has16BitInsts(), {F16})
@@ -2390,7 +2384,7 @@ bool AMDGPULegalizerInfo::legalizeCustom(
case TargetOpcode::G_FEXP10:
return legalizeFExp(MI, B);
case TargetOpcode::G_FPOW:
- return legalizeFPow(MI, B);
+ return legalizeFPow(Helper, MI);
case TargetOpcode::G_FFLOOR:
return legalizeFFloor(MI, MRI, B);
case TargetOpcode::G_BUILD_VECTOR:
@@ -4315,37 +4309,78 @@ bool AMDGPULegalizerInfo::legalizeFExp(MachineInstr &MI,
return true;
}
-bool AMDGPULegalizerInfo::legalizeFPow(MachineInstr &MI,
- MachineIRBuilder &B) const {
+// Keep in sync with AMDGPUTargetLowering::lowerFPOW, which documents this.
+bool AMDGPULegalizerInfo::legalizeFPow(LegalizerHelper &Helper,
+ MachineInstr &MI) const {
+ MachineIRBuilder &B = Helper.MIRBuilder;
Register Dst = MI.getOperand(0).getReg();
- Register Src0 = MI.getOperand(1).getReg();
- Register Src1 = MI.getOperand(2).getReg();
+ Register X = MI.getOperand(1).getReg();
+ Register Y = MI.getOperand(2).getReg();
unsigned Flags = MI.getFlags();
- LLT Ty = B.getMRI()->getType(Dst);
+ assert(B.getMRI()->getType(Dst) == F32);
- if (Ty == F32) {
- auto Log = B.buildFLog2(F32, Src0, Flags);
+ // log2(0) is -inf, which exp2 turns back into a finite result, so the core
+ // goes infinite for inputs a ninf fpow still asserts about, like pow(0, 2).
+ unsigned CoreFlags = Flags & ~MachineInstr::FmNoInfs;
+
+ // Fast expansion: ignores denormals, NaN for a negative base.
+ if (allowApproxFunc(B.getMF(), Flags)) {
+ auto Log = B.buildIntrinsic(Intrinsic::amdgcn_log, {F32})
+ .addUse(X)
+ .setMIFlags(CoreFlags);
auto Mul = B.buildIntrinsic(Intrinsic::amdgcn_fmul_legacy, {F32})
+ .addUse(Y)
.addUse(Log.getReg(0))
- .addUse(Src1)
- .setMIFlags(Flags);
- B.buildFExp2(Dst, Mul, Flags);
- } else if (Ty == F16) {
- // There's no f16 fmul_legacy, so we need to convert for it.
- auto Log = B.buildFLog2(F16, Src0, Flags);
- auto Ext0 = B.buildFPExt(F32, Log, Flags);
- auto Ext1 = B.buildFPExt(F32, Src1, Flags);
- auto Mul = B.buildIntrinsic(Intrinsic::amdgcn_fmul_legacy, {F32})
- .addUse(Ext0.getReg(0))
- .addUse(Ext1.getReg(0))
- .setMIFlags(Flags);
- // The f32 product is finite whenever the original fpow was, but it can
- // still be outside the f16 range. Drop ninf from the truncation and from
- // the exp2, since neither can assume a finite value here.
- unsigned FlagsNoNInf = Flags & ~MachineInstr::FmNoInfs;
- B.buildFExp2(Dst, B.buildFPTrunc(F16, Mul, FlagsNoNInf), FlagsNoNInf);
- } else
- return false;
+ .setMIFlags(CoreFlags);
+ buildExp(B, Dst, Mul.getReg(0), CoreFlags);
+ MI.eraseFromParent();
+ return true;
+ }
+
+ auto Abs = B.buildFAbs(F32, X, Flags);
+ auto Log = B.buildFLog2(F32, Abs, CoreFlags);
+ auto Mul = B.buildIntrinsic(Intrinsic::amdgcn_fmul_legacy, {F32})
+ .addUse(Y)
+ .addUse(Log.getReg(0))
+ .setMIFlags(CoreFlags);
+
+ // A base that is never negative needs neither the sign fixup nor the NaN.
+ if (Helper.getValueTracking()
+ ->computeKnownFPClass(X, Flags, fcNegative, 0)
+ .signBitIsZeroOrNaN()) {
+ B.buildFExp2(Dst, Mul, CoreFlags);
+ MI.eraseFromParent();
+ return true;
+ }
+
+ Register R = B.buildFExp2(F32, Mul, CoreFlags).getReg(0);
+
+ auto YTrunc = B.buildIntrinsicTrunc(F32, Y);
+ auto YIsInt = B.buildFCmp(CmpInst::FCMP_OEQ, S1, YTrunc, Y);
+ auto YHalf = B.buildFMul(F32, Y, B.buildFConstant(F32, 0.5));
+ auto YHalfTrunc = B.buildIntrinsicTrunc(F32, YHalf);
+ auto YIsOdd = B.buildAnd(
+ S1, YIsInt, B.buildFCmp(CmpInst::FCMP_ONE, S1, YHalfTrunc, YHalf));
+
+ // pow(-x, odd y) = -pow(x, y). Selecting the copysign lets even y fold it.
+ auto Neg = B.buildFCopysign(F32, R, X);
+ if (Flags & MachineInstr::FmNoNans) {
+ B.buildSelect(Dst, YIsOdd, Neg, R);
+ MI.eraseFromParent();
+ return true;
+ }
+ R = B.buildSelect(F32, YIsOdd, Neg, R).getReg(0);
+
+ // A negative finite base to a non-integral power is NaN. -inf is excluded:
+ // the core already gives pow(+inf, y). So are subnormals when flushed.
+ FPClassTest NegFiniteMask = fcNegNormal;
+ if (!B.getMF().getDenormalMode(APFloat::IEEEsingle()).inputsAreZero())
+ NegFiniteMask |= fcNegSubnormal;
+ auto XNegFinite = B.buildIsFPClass(S1, X, NegFiniteMask);
+ // Not an ONE compare: pow(-1, NaN) needs the NaN-true behavior of !OEQ.
+ auto NegNonInt = B.buildAnd(S1, XNegFinite, B.buildNot(S1, YIsInt));
+ auto NaN = B.buildFConstant(F32, APFloat::getQNaN(APFloat::IEEEsingle()));
+ B.buildSelect(Dst, NegNonInt, NaN, R);
MI.eraseFromParent();
return true;
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.h b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.h
index 30fd16930e6ae..b2f1df909f06e 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.h
@@ -103,7 +103,7 @@ class AMDGPULegalizerInfo final : public LegalizerInfo {
bool legalizeFEXPF64(MachineInstr &MI, MachineIRBuilder &B) const;
bool legalizeFExp(MachineInstr &MI, MachineIRBuilder &B) const;
- bool legalizeFPow(MachineInstr &MI, MachineIRBuilder &B) const;
+ bool legalizeFPow(LegalizerHelper &Helper, MachineInstr &MI) const;
bool legalizeFFloor(MachineInstr &MI, MachineRegisterInfo &MRI,
MachineIRBuilder &B) const;
diff --git a/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp b/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp
index ad088c81335ef..7595f285b5eea 100644
--- a/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp
@@ -110,6 +110,8 @@ R600TargetLowering::R600TargetLowering(const TargetMachine &TM,
setOperationAction({ISD::FCEIL, ISD::FTRUNC, ISD::FROUNDEVEN, ISD::FFLOOR},
MVT::f64, Custom);
+ setOperationAction(ISD::FPOW, MVT::f32, Legal);
+
setOperationAction(ISD::SELECT_CC, {MVT::f32, MVT::i32}, Custom);
setOperationAction(ISD::SETCC, {MVT::i32, MVT::f32}, Expand);
diff --git a/llvm/lib/Target/AMDGPU/SIInstructions.td b/llvm/lib/Target/AMDGPU/SIInstructions.td
index af08bf0861215..fbe3c9f5ac20b 100644
--- a/llvm/lib/Target/AMDGPU/SIInstructions.td
+++ b/llvm/lib/Target/AMDGPU/SIInstructions.td
@@ -2757,11 +2757,6 @@ def : GCNPat <(i1 imm:$imm),
/********** Intrinsic Patterns **********/
/********** ================== **********/
-def : GCNPat <
- (f32 (fpow (VOP3Mods f32:$src0, i32:$src0_mods), (VOP3Mods f32:$src1, i32:$src1_mods))),
- (V_EXP_F32_e64 SRCMODS.NONE, (V_MUL_LEGACY_F32_e64 $src1_mods, $src1, SRCMODS.NONE, (V_LOG_F32_e64 $src0_mods, $src0), 0, 0))
->;
-
def : GCNPat <
(i32 (sext i1:$src0)),
(V_CNDMASK_B32_e64 /*src0mod*/(i32 0), /*src0*/(i32 0),
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/fma-mix-true16.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/fma-mix-true16.ll
new file mode 100644
index 0000000000000..be15af54b0429
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/fma-mix-true16.ll
@@ -0,0 +1,74 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -global-isel -mtriple=amdgpu11.00 -mattr=+real-true16 < %s | FileCheck -check-prefixes=GFX11-TRUE16 %s
+; RUN: llc -global-isel -mtriple=amdgpu11.00 -mattr=-real-true16 < %s | FileCheck -check-prefixes=GFX11-FAKE16 %s
+
+; With real true16 instructions s16 values live in 16-bit register classes,
+; and folding an fpext into a mix instruction's 32-bit source operand leaves
+; an unselectable 16-bit def. Check that the fold is skipped instead of
+; crashing the selector.
+
+define float @v_mul_f32_fpext_f16(half %x, half %y) {
+; GFX11-TRUE16-LABEL: v_mul_f32_fpext_f16:
+; GFX11-TRUE16: ; %bb.0:
+; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.l
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v1.l
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_mul_f32_e32 v0, v0, v1
+; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-FAKE16-LABEL: v_mul_f32_fpext_f16:
+; GFX11-FAKE16: ; %bb.0:
+; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v0, v0, v1, neg(0) op_sel_hi:[1,1,0]
+; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
+ %ex = fpext half %x to float
+ %ey = fpext half %y to float
+ %mul = fmul float %ex, %ey
+ ret float %mul
+}
+
+define float @v_fma_f32_fpext_f16(half %x, half %y, float %z) {
+; GFX11-TRUE16-LABEL: v_fma_f32_fpext_f16:
+; GFX11-TRUE16: ; %bb.0:
+; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.l
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v1.l
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_fma_f32 v0, v0, v1, v2
+; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-FAKE16-LABEL: v_fma_f32_fpext_f16:
+; GFX11-FAKE16: ; %bb.0:
+; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v0, v0, v1, v2 op_sel_hi:[1,1,0]
+; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
+ %ex = fpext half %x to float
+ %ey = fpext half %y to float
+ %fma = call float @llvm.fma.f32(float %ex, float %ey, float %z)
+ ret float %fma
+}
+
+define float @v_fma_f32_fpext_fneg_f16(half %x, half %y, float %z) {
+; GFX11-TRUE16-LABEL: v_fma_f32_fpext_fneg_f16:
+; GFX11-TRUE16: ; %bb.0:
+; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e64 v0, -v0.l
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v1.l
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_fma_f32 v0, v0, v1, v2
+; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-FAKE16-LABEL: v_fma_f32_fpext_fneg_f16:
+; GFX11-FAKE16: ; %bb.0:
+; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v0, -v0, v1, v2 op_sel_hi:[1,1,0]
+; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
+ %neg.x = fneg half %x
+ %ex = fpext half %neg.x to float
+ %ey = fpext half %y to float
+ %fma = call float @llvm.fma.f32(float %ex, float %ey, float %z)
+ ret float %fma
+}
+
+declare float @llvm.fma.f32(float, float, float)
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/fpow.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/fpow.ll
index b84ec70d3e35d..c62344f055d7a 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/fpow.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/fpow.ll
@@ -11,116 +11,190 @@ define float @v_pow_f32(float %x, float %y) {
; GFX6: ; %bb.0:
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX6-NEXT: v_mov_b32_e32 v2, 0x800000
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v2
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
; GFX6-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
; GFX6-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v2
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_mov_b32_e32 v2, 0x42000000
-; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
-; GFX6-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX6-NEXT: v_mov_b32_e32 v2, 0x42800000
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
-; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
-; GFX6-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
-; GFX6-NEXT: v_not_b32_e32 v1, 63
-; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v1
+; GFX6-NEXT: v_ldexp_f32_e64 v2, |v0|, v2
+; GFX6-NEXT: v_log_f32_e32 v2, v2
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX6-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX6-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX6-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_exp_f32_e32 v2, v2
+; GFX6-NEXT: v_not_b32_e32 v3, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: v_ldexp_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_trunc_f32_e32 v3, v1
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v3, v1
+; GFX6-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX6-NEXT: v_trunc_f32_e32 v3, v1
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v3, v1
+; GFX6-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX6-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX6-NEXT: v_or_b32_e32 v1, v1, v3
+; GFX6-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX6-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX6-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX6-NEXT: s_setpc_b64 s[30:31]
;
; GFX8-LABEL: v_pow_f32:
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX8-NEXT: v_mov_b32_e32 v2, 0x800000
-; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v0, v2
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
; GFX8-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX8-NEXT: v_ldexp_f32 v0, v0, v2
-; GFX8-NEXT: v_log_f32_e32 v0, v0
-; GFX8-NEXT: v_mov_b32_e32 v2, 0x42000000
-; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
-; GFX8-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX8-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX8-NEXT: v_mov_b32_e32 v2, 0x42800000
-; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
-; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
-; GFX8-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX8-NEXT: v_exp_f32_e32 v0, v0
-; GFX8-NEXT: v_not_b32_e32 v1, 63
-; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX8-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX8-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX8-NEXT: v_log_f32_e32 v2, v2
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX8-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX8-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX8-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_exp_f32_e32 v2, v2
+; GFX8-NEXT: v_not_b32_e32 v3, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX8-NEXT: v_trunc_f32_e32 v3, v1
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v3, v1
+; GFX8-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v3, v1
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v3, v1
+; GFX8-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX8-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX8-NEXT: v_or_b32_e32 v1, v1, v3
+; GFX8-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX8-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX8-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: v_pow_f32:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_mov_b32_e32 v2, 0x800000
-; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v0, v2
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
; GFX9-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
; GFX9-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX9-NEXT: v_ldexp_f32 v0, v0, v2
-; GFX9-NEXT: v_log_f32_e32 v0, v0
-; GFX9-NEXT: v_mov_b32_e32 v2, 0x42000000
-; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
-; GFX9-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX9-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX9-NEXT: v_mov_b32_e32 v2, 0x42800000
-; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
-; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
-; GFX9-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX9-NEXT: v_exp_f32_e32 v0, v0
-; GFX9-NEXT: v_not_b32_e32 v1, 63
-; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX9-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX9-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX9-NEXT: v_log_f32_e32 v2, v2
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX9-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX9-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX9-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX9-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX9-NEXT: v_exp_f32_e32 v2, v2
+; GFX9-NEXT: v_not_b32_e32 v3, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX9-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX9-NEXT: v_trunc_f32_e32 v3, v1
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v3, v1
+; GFX9-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX9-NEXT: v_trunc_f32_e32 v3, v1
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v3, v1
+; GFX9-NEXT: v_bfrev_b32_e32 v1, -2
+; GFX9-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX9-NEXT: v_and_or_b32 v1, v2, v1, v3
+; GFX9-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX9-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX9-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX9-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_f32:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0x800000, v0
-; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc_lo
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v0|
+; GFX10-NEXT: v_trunc_f32_e32 v5, v1
+; GFX10-NEXT: v_cmp_class_f32_e64 s6, v0, 24
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 1, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s4
; GFX10-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX10-NEXT: v_ldexp_f32 v0, v0, v2
-; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, vcc_lo
-; GFX10-NEXT: v_log_f32_e32 v0, v0
-; GFX10-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
-; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
-; GFX10-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, vcc_lo
-; GFX10-NEXT: v_exp_f32_e32 v0, v0
-; GFX10-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX10-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX10-NEXT: v_log_f32_e32 v2, v2
+; GFX10-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX10-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_cmp_eq_f32_e32 vcc_lo, v5, v1
+; GFX10-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX10-NEXT: v_mul_f32_e32 v3, 0.5, v1
+; GFX10-NEXT: v_exp_f32_e32 v2, v2
+; GFX10-NEXT: v_trunc_f32_e32 v6, v3
+; GFX10-NEXT: v_cmp_lg_f32_e64 s4, v6, v3
+; GFX10-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX10-NEXT: v_and_b32_e32 v4, 0x80000000, v0
+; GFX10-NEXT: s_and_b32 s4, vcc_lo, s4
+; GFX10-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v4
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v2, v1, s4
+; GFX10-NEXT: s_xor_b32 s4, vcc_lo, exec_lo
+; GFX10-NEXT: s_and_b32 s4, s6, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s4
; GFX10-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: v_pow_f32:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0x800000, v0
-; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc_lo
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-NEXT: v_trunc_f32_e32 v5, v1
+; GFX11-NEXT: v_cmp_class_f32_e64 s2, v0, 24
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 1, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s0
; GFX11-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX11-NEXT: v_ldexp_f32 v0, v0, v2
-; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, vcc_lo
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_1)
-; GFX11-NEXT: v_log_f32_e32 v0, v0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX11-NEXT: v_log_f32_e32 v2, v2
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, v0, v1
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
-; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
-; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
-; GFX11-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, vcc_lo
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2)
-; GFX11-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v2, v1, v2
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: v_cmp_eq_f32_e32 vcc_lo, v5, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_dual_add_f32 v2, v2, v3 :: v_dual_mul_f32 v3, 0.5, v1
+; GFX11-NEXT: v_exp_f32_e32 v2, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_trunc_f32_e32 v6, v3
+; GFX11-NEXT: v_cmp_lg_f32_e64 s0, v6, v3
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX11-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX11-NEXT: v_and_b32_e32 v4, 0x80000000, v0
+; GFX11-NEXT: s_and_b32 s0, vcc_lo, s0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v4
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v2, v1, s0
+; GFX11-NEXT: s_xor_b32 s0, vcc_lo, exec_lo
+; GFX11-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
+; GFX11-NEXT: s_and_b32 s0, s2, s0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
%pow = call float @llvm.pow.f32(float %x, float %y)
ret float %pow
@@ -131,189 +205,328 @@ define <2 x float> @v_pow_v2f32(<2 x float> %x, <2 x float> %y) {
; GFX6: ; %bb.0:
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX6-NEXT: v_mov_b32_e32 v4, 0x800000
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v4
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v4
; GFX6-NEXT: v_cndmask_b32_e64 v5, 0, 1, vcc
-; GFX6-NEXT: v_cmp_lt_f32_e64 s[4:5], v1, v4
; GFX6-NEXT: v_lshlrev_b32_e32 v5, 5, v5
-; GFX6-NEXT: v_cndmask_b32_e64 v4, 0, 1, s[4:5]
-; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v5
-; GFX6-NEXT: v_lshlrev_b32_e32 v4, 5, v4
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_ldexp_f32_e32 v1, v1, v4
-; GFX6-NEXT: v_log_f32_e32 v1, v1
-; GFX6-NEXT: v_mov_b32_e32 v5, 0x42000000
-; GFX6-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
-; GFX6-NEXT: v_sub_f32_e32 v0, v0, v6
-; GFX6-NEXT: v_cndmask_b32_e64 v5, 0, v5, s[4:5]
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v0, v2
-; GFX6-NEXT: v_mov_b32_e32 v2, 0xc2fc0000
-; GFX6-NEXT: v_sub_f32_e32 v1, v1, v5
-; GFX6-NEXT: v_mov_b32_e32 v6, 0x42800000
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v2
-; GFX6-NEXT: v_mul_legacy_f32_e32 v1, v1, v3
+; GFX6-NEXT: v_ldexp_f32_e64 v5, |v0|, v5
+; GFX6-NEXT: v_log_f32_e32 v5, v5
+; GFX6-NEXT: v_mov_b32_e32 v6, 0x42000000
; GFX6-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
-; GFX6-NEXT: v_cmp_lt_f32_e64 s[4:5], v1, v2
-; GFX6-NEXT: v_add_f32_e32 v0, v0, v7
-; GFX6-NEXT: v_cndmask_b32_e64 v2, 0, v6, s[4:5]
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
-; GFX6-NEXT: v_add_f32_e32 v1, v1, v2
-; GFX6-NEXT: v_exp_f32_e32 v1, v1
-; GFX6-NEXT: v_not_b32_e32 v4, 63
-; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v4, vcc
-; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v2
-; GFX6-NEXT: v_cndmask_b32_e64 v2, 0, v4, s[4:5]
-; GFX6-NEXT: v_ldexp_f32_e32 v1, v1, v2
+; GFX6-NEXT: v_mov_b32_e32 v8, 0x42800000
+; GFX6-NEXT: v_sub_f32_e32 v5, v5, v7
+; GFX6-NEXT: v_mul_legacy_f32_e32 v5, v2, v5
+; GFX6-NEXT: v_mov_b32_e32 v7, 0xc2fc0000
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v5, v7
+; GFX6-NEXT: v_cndmask_b32_e32 v9, 0, v8, vcc
+; GFX6-NEXT: v_add_f32_e32 v5, v5, v9
+; GFX6-NEXT: v_exp_f32_e32 v5, v5
+; GFX6-NEXT: v_not_b32_e32 v9, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v10, 0, v9, vcc
+; GFX6-NEXT: v_cmp_class_f32_e64 s[8:9], v0, 24
+; GFX6-NEXT: v_ldexp_f32_e32 v5, v5, v10
+; GFX6-NEXT: v_trunc_f32_e32 v10, v2
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v10, v2
+; GFX6-NEXT: v_mul_f32_e32 v2, 0.5, v2
+; GFX6-NEXT: v_trunc_f32_e32 v10, v2
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v10, v2
+; GFX6-NEXT: v_and_b32_e32 v2, 0x7fffffff, v5
+; GFX6-NEXT: v_and_b32_e32 v10, 0x80000000, v0
+; GFX6-NEXT: v_or_b32_e32 v2, v2, v10
+; GFX6-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e64 v2, v5, v2, s[4:5]
+; GFX6-NEXT: v_cmp_lt_f32_e64 s[4:5], |v1|, v4
+; GFX6-NEXT: v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX6-NEXT: v_lshlrev_b32_e32 v0, 5, v0
+; GFX6-NEXT: v_ldexp_f32_e64 v0, |v1|, v0
+; GFX6-NEXT: v_log_f32_e32 v0, v0
+; GFX6-NEXT: v_cndmask_b32_e64 v5, 0, v6, s[4:5]
+; GFX6-NEXT: s_xor_b64 s[10:11], vcc, exec
+; GFX6-NEXT: v_mov_b32_e32 v4, 0x7fc00000
+; GFX6-NEXT: v_sub_f32_e32 v0, v0, v5
+; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v3, v0
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v7
+; GFX6-NEXT: v_cndmask_b32_e32 v5, 0, v8, vcc
+; GFX6-NEXT: v_add_f32_e32 v0, v0, v5
+; GFX6-NEXT: v_exp_f32_e32 v5, v0
+; GFX6-NEXT: s_and_b64 s[4:5], s[8:9], s[10:11]
+; GFX6-NEXT: v_cndmask_b32_e64 v0, v2, v4, s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v9, vcc
+; GFX6-NEXT: v_ldexp_f32_e32 v2, v5, v2
+; GFX6-NEXT: v_trunc_f32_e32 v5, v3
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v5, v3
+; GFX6-NEXT: v_mul_f32_e32 v3, 0.5, v3
+; GFX6-NEXT: v_trunc_f32_e32 v5, v3
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v5, v3
+; GFX6-NEXT: v_and_b32_e32 v3, 0x7fffffff, v2
+; GFX6-NEXT: v_and_b32_e32 v5, 0x80000000, v1
+; GFX6-NEXT: v_or_b32_e32 v3, v3, v5
+; GFX6-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e64 v2, v2, v3, s[4:5]
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v1, 24
+; GFX6-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX6-NEXT: v_cndmask_b32_e32 v1, v2, v4, vcc
; GFX6-NEXT: s_setpc_b64 s[30:31]
;
; GFX8-LABEL: v_pow_v2f32:
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX8-NEXT: v_mov_b32_e32 v4, 0x800000
-; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v0, v4
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v4
; GFX8-NEXT: v_cndmask_b32_e64 v5, 0, 1, vcc
-; GFX8-NEXT: v_cmp_lt_f32_e64 s[4:5], v1, v4
; GFX8-NEXT: v_lshlrev_b32_e32 v5, 5, v5
-; GFX8-NEXT: v_cndmask_b32_e64 v4, 0, 1, s[4:5]
-; GFX8-NEXT: v_ldexp_f32 v0, v0, v5
-; GFX8-NEXT: v_lshlrev_b32_e32 v4, 5, v4
-; GFX8-NEXT: v_log_f32_e32 v0, v0
-; GFX8-NEXT: v_ldexp_f32 v1, v1, v4
-; GFX8-NEXT: v_log_f32_e32 v1, v1
-; GFX8-NEXT: v_mov_b32_e32 v5, 0x42000000
-; GFX8-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
-; GFX8-NEXT: v_sub_f32_e32 v0, v0, v6
-; GFX8-NEXT: v_cndmask_b32_e64 v5, 0, v5, s[4:5]
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v0, v2
-; GFX8-NEXT: v_mov_b32_e32 v2, 0xc2fc0000
-; GFX8-NEXT: v_sub_f32_e32 v1, v1, v5
-; GFX8-NEXT: v_mov_b32_e32 v6, 0x42800000
-; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v0, v2
-; GFX8-NEXT: v_mul_legacy_f32_e32 v1, v1, v3
+; GFX8-NEXT: v_ldexp_f32 v5, |v0|, v5
+; GFX8-NEXT: v_log_f32_e32 v5, v5
+; GFX8-NEXT: v_mov_b32_e32 v6, 0x42000000
; GFX8-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
-; GFX8-NEXT: v_cmp_lt_f32_e64 s[4:5], v1, v2
-; GFX8-NEXT: v_add_f32_e32 v0, v0, v7
-; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, v6, s[4:5]
-; GFX8-NEXT: v_exp_f32_e32 v0, v0
-; GFX8-NEXT: v_add_f32_e32 v1, v1, v2
-; GFX8-NEXT: v_exp_f32_e32 v1, v1
-; GFX8-NEXT: v_not_b32_e32 v4, 63
-; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v4, vcc
-; GFX8-NEXT: v_ldexp_f32 v0, v0, v2
-; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, v4, s[4:5]
-; GFX8-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX8-NEXT: v_mov_b32_e32 v8, 0x42800000
+; GFX8-NEXT: v_sub_f32_e32 v5, v5, v7
+; GFX8-NEXT: v_mul_legacy_f32_e32 v5, v2, v5
+; GFX8-NEXT: v_mov_b32_e32 v7, 0xc2fc0000
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v5, v7
+; GFX8-NEXT: v_cndmask_b32_e32 v9, 0, v8, vcc
+; GFX8-NEXT: v_add_f32_e32 v5, v5, v9
+; GFX8-NEXT: v_exp_f32_e32 v5, v5
+; GFX8-NEXT: v_not_b32_e32 v9, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v10, 0, v9, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 s[8:9], v0, 24
+; GFX8-NEXT: v_ldexp_f32 v5, v5, v10
+; GFX8-NEXT: v_trunc_f32_e32 v10, v2
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v10, v2
+; GFX8-NEXT: v_mul_f32_e32 v2, 0.5, v2
+; GFX8-NEXT: v_trunc_f32_e32 v10, v2
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v10, v2
+; GFX8-NEXT: v_and_b32_e32 v2, 0x7fffffff, v5
+; GFX8-NEXT: v_and_b32_e32 v10, 0x80000000, v0
+; GFX8-NEXT: v_or_b32_e32 v2, v2, v10
+; GFX8-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e64 v2, v5, v2, s[4:5]
+; GFX8-NEXT: v_cmp_lt_f32_e64 s[4:5], |v1|, v4
+; GFX8-NEXT: v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX8-NEXT: v_lshlrev_b32_e32 v0, 5, v0
+; GFX8-NEXT: v_ldexp_f32 v0, |v1|, v0
+; GFX8-NEXT: v_log_f32_e32 v0, v0
+; GFX8-NEXT: v_cndmask_b32_e64 v5, 0, v6, s[4:5]
+; GFX8-NEXT: s_xor_b64 s[10:11], vcc, exec
+; GFX8-NEXT: v_mov_b32_e32 v4, 0x7fc00000
+; GFX8-NEXT: v_sub_f32_e32 v0, v0, v5
+; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v3, v0
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v0, v7
+; GFX8-NEXT: v_cndmask_b32_e32 v5, 0, v8, vcc
+; GFX8-NEXT: v_add_f32_e32 v0, v0, v5
+; GFX8-NEXT: v_exp_f32_e32 v5, v0
+; GFX8-NEXT: s_and_b64 s[4:5], s[8:9], s[10:11]
+; GFX8-NEXT: v_cndmask_b32_e64 v0, v2, v4, s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v9, vcc
+; GFX8-NEXT: v_ldexp_f32 v2, v5, v2
+; GFX8-NEXT: v_trunc_f32_e32 v5, v3
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v5, v3
+; GFX8-NEXT: v_mul_f32_e32 v3, 0.5, v3
+; GFX8-NEXT: v_trunc_f32_e32 v5, v3
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v5, v3
+; GFX8-NEXT: v_and_b32_e32 v3, 0x7fffffff, v2
+; GFX8-NEXT: v_and_b32_e32 v5, 0x80000000, v1
+; GFX8-NEXT: v_or_b32_e32 v3, v3, v5
+; GFX8-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e64 v2, v2, v3, s[4:5]
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v1, 24
+; GFX8-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX8-NEXT: v_cndmask_b32_e32 v1, v2, v4, vcc
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: v_pow_v2f32:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_mov_b32_e32 v4, 0x800000
-; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v0, v4
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v4
; GFX9-NEXT: v_cndmask_b32_e64 v5, 0, 1, vcc
-; GFX9-NEXT: v_cmp_lt_f32_e64 s[4:5], v1, v4
; GFX9-NEXT: v_lshlrev_b32_e32 v5, 5, v5
-; GFX9-NEXT: v_cndmask_b32_e64 v4, 0, 1, s[4:5]
-; GFX9-NEXT: v_ldexp_f32 v0, v0, v5
-; GFX9-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX9-NEXT: v_ldexp_f32 v5, |v0|, v5
+; GFX9-NEXT: v_log_f32_e32 v5, v5
+; GFX9-NEXT: v_mov_b32_e32 v6, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX9-NEXT: v_mov_b32_e32 v8, 0x42800000
+; GFX9-NEXT: v_sub_f32_e32 v5, v5, v7
+; GFX9-NEXT: v_mul_legacy_f32_e32 v5, v2, v5
+; GFX9-NEXT: v_mov_b32_e32 v7, 0xc2fc0000
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v5, v7
+; GFX9-NEXT: v_cndmask_b32_e32 v9, 0, v8, vcc
+; GFX9-NEXT: v_add_f32_e32 v5, v5, v9
+; GFX9-NEXT: v_exp_f32_e32 v5, v5
+; GFX9-NEXT: v_not_b32_e32 v9, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v10, 0, v9, vcc
+; GFX9-NEXT: v_cmp_class_f32_e64 s[8:9], v0, 24
+; GFX9-NEXT: v_ldexp_f32 v5, v5, v10
+; GFX9-NEXT: v_trunc_f32_e32 v10, v2
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v10, v2
+; GFX9-NEXT: v_mul_f32_e32 v2, 0.5, v2
+; GFX9-NEXT: v_trunc_f32_e32 v10, v2
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v10, v2
+; GFX9-NEXT: v_bfrev_b32_e32 v2, -2
+; GFX9-NEXT: v_and_b32_e32 v10, 0x80000000, v0
+; GFX9-NEXT: v_and_or_b32 v10, v5, v2, v10
+; GFX9-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX9-NEXT: v_cndmask_b32_e64 v5, v5, v10, s[4:5]
+; GFX9-NEXT: v_cmp_lt_f32_e64 s[4:5], |v1|, v4
+; GFX9-NEXT: v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX9-NEXT: v_lshlrev_b32_e32 v0, 5, v0
+; GFX9-NEXT: v_ldexp_f32 v0, |v1|, v0
; GFX9-NEXT: v_log_f32_e32 v0, v0
-; GFX9-NEXT: v_ldexp_f32 v1, v1, v4
-; GFX9-NEXT: v_log_f32_e32 v1, v1
-; GFX9-NEXT: v_mov_b32_e32 v5, 0x42000000
-; GFX9-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
+; GFX9-NEXT: v_cndmask_b32_e64 v6, 0, v6, s[4:5]
+; GFX9-NEXT: s_xor_b64 s[10:11], vcc, exec
+; GFX9-NEXT: v_mov_b32_e32 v4, 0x7fc00000
; GFX9-NEXT: v_sub_f32_e32 v0, v0, v6
-; GFX9-NEXT: v_cndmask_b32_e64 v5, 0, v5, s[4:5]
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v0, v2
-; GFX9-NEXT: v_mov_b32_e32 v2, 0xc2fc0000
-; GFX9-NEXT: v_sub_f32_e32 v1, v1, v5
-; GFX9-NEXT: v_mov_b32_e32 v6, 0x42800000
-; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v0, v2
-; GFX9-NEXT: v_mul_legacy_f32_e32 v1, v1, v3
-; GFX9-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
-; GFX9-NEXT: v_cmp_lt_f32_e64 s[4:5], v1, v2
-; GFX9-NEXT: v_add_f32_e32 v0, v0, v7
-; GFX9-NEXT: v_cndmask_b32_e64 v2, 0, v6, s[4:5]
-; GFX9-NEXT: v_exp_f32_e32 v0, v0
-; GFX9-NEXT: v_add_f32_e32 v1, v1, v2
-; GFX9-NEXT: v_exp_f32_e32 v1, v1
-; GFX9-NEXT: v_not_b32_e32 v4, 63
-; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v4, vcc
-; GFX9-NEXT: v_ldexp_f32 v0, v0, v2
-; GFX9-NEXT: v_cndmask_b32_e64 v2, 0, v4, s[4:5]
-; GFX9-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v3, v0
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v0, v7
+; GFX9-NEXT: v_cndmask_b32_e32 v6, 0, v8, vcc
+; GFX9-NEXT: v_add_f32_e32 v0, v0, v6
+; GFX9-NEXT: v_exp_f32_e32 v6, v0
+; GFX9-NEXT: s_and_b64 s[4:5], s[8:9], s[10:11]
+; GFX9-NEXT: v_cndmask_b32_e64 v0, v5, v4, s[4:5]
+; GFX9-NEXT: v_cndmask_b32_e32 v5, 0, v9, vcc
+; GFX9-NEXT: v_ldexp_f32 v5, v6, v5
+; GFX9-NEXT: v_trunc_f32_e32 v6, v3
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v6, v3
+; GFX9-NEXT: v_mul_f32_e32 v3, 0.5, v3
+; GFX9-NEXT: v_trunc_f32_e32 v6, v3
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v6, v3
+; GFX9-NEXT: v_and_b32_e32 v3, 0x80000000, v1
+; GFX9-NEXT: v_and_or_b32 v2, v5, v2, v3
+; GFX9-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX9-NEXT: v_cndmask_b32_e64 v2, v5, v2, s[4:5]
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v1, 24
+; GFX9-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX9-NEXT: v_cndmask_b32_e32 v1, v2, v4, vcc
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_v2f32:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0x800000, v0
-; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, v1
-; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 1, vcc_lo
-; GFX10-NEXT: v_cndmask_b32_e64 v5, 0, 1, s4
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v0|
+; GFX10-NEXT: v_cmp_gt_f32_e64 s5, 0x800000, |v1|
+; GFX10-NEXT: v_cmp_class_f32_e64 s8, v0, 24
+; GFX10-NEXT: v_trunc_f32_e32 v8, v2
+; GFX10-NEXT: v_mul_f32_e32 v9, 0.5, v3
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 1, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v5, 0, 1, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v7, 0, 0x42000000, s5
+; GFX10-NEXT: v_and_b32_e32 v10, 0x80000000, v1
; GFX10-NEXT: v_lshlrev_b32_e32 v4, 5, v4
; GFX10-NEXT: v_lshlrev_b32_e32 v5, 5, v5
-; GFX10-NEXT: v_ldexp_f32 v0, v0, v4
-; GFX10-NEXT: v_ldexp_f32 v1, v1, v5
-; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 0x42000000, vcc_lo
-; GFX10-NEXT: v_cndmask_b32_e64 v5, 0, 0x42000000, s4
-; GFX10-NEXT: v_log_f32_e32 v0, v0
-; GFX10-NEXT: v_log_f32_e32 v1, v1
-; GFX10-NEXT: v_sub_f32_e32 v0, v0, v4
-; GFX10-NEXT: v_sub_f32_e32 v1, v1, v5
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v0, v2
-; GFX10-NEXT: v_mul_legacy_f32_e32 v1, v1, v3
-; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
-; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0xc2fc0000, v1
-; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42800000, vcc_lo
-; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, s4
-; GFX10-NEXT: v_add_f32_e32 v0, v0, v2
-; GFX10-NEXT: v_add_f32_e32 v1, v1, v3
-; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0xffffffc0, vcc_lo
-; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0xffffffc0, s4
-; GFX10-NEXT: v_exp_f32_e32 v0, v0
-; GFX10-NEXT: v_exp_f32_e32 v1, v1
-; GFX10-NEXT: v_ldexp_f32 v0, v0, v2
-; GFX10-NEXT: v_ldexp_f32 v1, v1, v3
+; GFX10-NEXT: v_cmp_class_f32_e64 s9, v1, 24
+; GFX10-NEXT: v_ldexp_f32 v4, |v0|, v4
+; GFX10-NEXT: v_ldexp_f32 v5, |v1|, v5
+; GFX10-NEXT: v_log_f32_e32 v4, v4
+; GFX10-NEXT: v_log_f32_e32 v5, v5
+; GFX10-NEXT: v_sub_f32_e32 v4, v4, v6
+; GFX10-NEXT: v_sub_f32_e32 v5, v5, v7
+; GFX10-NEXT: v_mul_legacy_f32_e32 v4, v2, v4
+; GFX10-NEXT: v_mul_legacy_f32_e32 v5, v3, v5
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v4
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0xc2fc0000, v5
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v7, 0, 0x42800000, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v11, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, s4
+; GFX10-NEXT: v_cmp_eq_f32_e32 vcc_lo, v8, v2
+; GFX10-NEXT: v_add_f32_e32 v4, v4, v6
+; GFX10-NEXT: v_add_f32_e32 v5, v5, v7
+; GFX10-NEXT: v_and_b32_e32 v7, 0x80000000, v0
+; GFX10-NEXT: v_mul_f32_e32 v6, 0.5, v2
+; GFX10-NEXT: v_trunc_f32_e32 v8, v9
+; GFX10-NEXT: v_exp_f32_e32 v0, v4
+; GFX10-NEXT: v_exp_f32_e32 v5, v5
+; GFX10-NEXT: v_trunc_f32_e32 v4, v3
+; GFX10-NEXT: v_trunc_f32_e32 v2, v6
+; GFX10-NEXT: v_cmp_lg_f32_e64 s6, v8, v9
+; GFX10-NEXT: s_xor_b32 s10, vcc_lo, exec_lo
+; GFX10-NEXT: v_cmp_eq_f32_e64 s4, v4, v3
+; GFX10-NEXT: v_cmp_lg_f32_e64 s5, v2, v6
+; GFX10-NEXT: v_ldexp_f32 v0, v0, v11
+; GFX10-NEXT: v_ldexp_f32 v1, v5, v1
+; GFX10-NEXT: s_and_b32 vcc_lo, vcc_lo, s5
+; GFX10-NEXT: s_and_b32 s5, s8, s10
+; GFX10-NEXT: v_and_or_b32 v2, 0x7fffffff, v0, v7
+; GFX10-NEXT: v_and_or_b32 v3, 0x7fffffff, v1, v10
+; GFX10-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc_lo
+; GFX10-NEXT: s_and_b32 vcc_lo, s4, s6
+; GFX10-NEXT: s_xor_b32 s4, s4, exec_lo
+; GFX10-NEXT: v_cndmask_b32_e32 v1, v1, v3, vcc_lo
+; GFX10-NEXT: s_and_b32 s4, s9, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s4
; GFX10-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: v_pow_v2f32:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, v1
-; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0x800000, v0
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_2)
-; GFX11-NEXT: v_cndmask_b32_e64 v5, 0, 1, s0
-; GFX11-NEXT: v_cndmask_b32_e64 v4, 0, 1, vcc_lo
+; GFX11-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v1|
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-NEXT: v_cmp_class_f32_e64 s4, v0, 24
+; GFX11-NEXT: v_trunc_f32_e32 v8, v2
+; GFX11-NEXT: v_dual_mul_f32 v9, 0.5, v3 :: v_dual_and_b32 v10, 0x80000000, v1
+; GFX11-NEXT: v_cndmask_b32_e64 v5, 0, 1, s1
+; GFX11-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v4, 0, 1, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v7, 0, 0x42000000, s1
+; GFX11-NEXT: v_cmp_class_f32_e64 s5, v1, 24
; GFX11-NEXT: v_lshlrev_b32_e32 v5, 5, v5
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
-; GFX11-NEXT: v_ldexp_f32 v1, v1, v5
-; GFX11-NEXT: v_cndmask_b32_e64 v5, 0, 0x42000000, s0
-; GFX11-NEXT: v_log_f32_e32 v1, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_ldexp_f32 v5, |v1|, v5
+; GFX11-NEXT: v_log_f32_e32 v5, v5
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_dual_sub_f32 v1, v1, v5 :: v_dual_lshlrev_b32 v4, 5, v4
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_3)
-; GFX11-NEXT: v_ldexp_f32 v0, v0, v4
-; GFX11-NEXT: v_cndmask_b32_e64 v4, 0, 0x42000000, vcc_lo
-; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v1, v1, v3
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-NEXT: v_log_f32_e32 v0, v0
-; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v1
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
-; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, s0
+; GFX11-NEXT: v_dual_sub_f32 v5, v5, v7 :: v_dual_lshlrev_b32 v4, 5, v4
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_ldexp_f32 v4, |v0|, v4
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v5, v3, v5
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_log_f32_e32 v4, v4
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v5
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_3) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_cndmask_b32_e64 v7, 0, 0x42800000, s0
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_dual_sub_f32 v0, v0, v4 :: v_dual_add_f32 v1, v1, v3
-; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, v0, v2
-; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0xffffffc0, s0
+; GFX11-NEXT: v_sub_f32_e32 v4, v4, v6
+; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, s0
+; GFX11-NEXT: v_dual_add_f32 v5, v5, v7 :: v_dual_mul_dx9_zero_f32 v4, v2, v4
+; GFX11-NEXT: v_and_b32_e32 v7, 0x80000000, v0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_exp_f32_e32 v5, v5
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v4
+; GFX11-NEXT: v_cndmask_b32_e64 v6, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_cndmask_b32_e64 v11, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: v_cmp_eq_f32_e32 vcc_lo, v8, v2
+; GFX11-NEXT: v_trunc_f32_e32 v8, v9
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_ldexp_f32 v1, v5, v1
+; GFX11-NEXT: v_add_f32_e32 v4, v4, v6
+; GFX11-NEXT: v_mul_f32_e32 v6, 0.5, v2
+; GFX11-NEXT: s_xor_b32 s6, vcc_lo, exec_lo
+; GFX11-NEXT: v_cmp_lg_f32_e64 s2, v8, v9
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-NEXT: v_exp_f32_e32 v1, v1
-; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
-; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_exp_f32_e32 v0, v4
+; GFX11-NEXT: v_trunc_f32_e32 v2, v6
+; GFX11-NEXT: v_trunc_f32_e32 v4, v3
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_cmp_lg_f32_e64 s1, v2, v6
+; GFX11-NEXT: v_cmp_eq_f32_e64 s0, v4, v3
+; GFX11-NEXT: v_and_or_b32 v3, 0x7fffffff, v1, v10
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_ldexp_f32 v1, v1, v3
-; GFX11-NEXT: v_add_f32_e32 v0, v0, v2
-; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: v_ldexp_f32 v0, v0, v11
+; GFX11-NEXT: s_and_b32 vcc_lo, vcc_lo, s1
+; GFX11-NEXT: s_and_b32 s1, s4, s6
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_and_or_b32 v2, 0x7fffffff, v0, v7
+; GFX11-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc_lo
+; GFX11-NEXT: s_and_b32 vcc_lo, s0, s2
+; GFX11-NEXT: s_xor_b32 s0, s0, exec_lo
+; GFX11-NEXT: v_cndmask_b32_e32 v1, v1, v3, vcc_lo
+; GFX11-NEXT: s_and_b32 s0, s5, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s1
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2)
-; GFX11-NEXT: v_exp_f32_e32 v0, v0
-; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_ldexp_f32 v0, v0, v2
+; GFX11-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
%pow = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> %y)
ret <2 x float> %pow
@@ -324,80 +537,256 @@ define half @v_pow_f16(half %x, half %y) {
; GFX6: ; %bb.0:
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x800000
; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX6-NEXT: v_mov_b32_e32 v2, 0xc2fc0000
-; GFX6-NEXT: v_mov_b32_e32 v3, 0x42800000
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v2
-; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v3, vcc
-; GFX6-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
-; GFX6-NEXT: v_not_b32_e32 v1, 63
-; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v1
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
+; GFX6-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX6-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX6-NEXT: v_ldexp_f32_e64 v2, |v0|, v2
+; GFX6-NEXT: v_log_f32_e32 v2, v2
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX6-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX6-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX6-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_exp_f32_e32 v2, v2
+; GFX6-NEXT: v_not_b32_e32 v3, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: v_ldexp_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_trunc_f32_e32 v3, v1
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v3, v1
+; GFX6-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX6-NEXT: v_trunc_f32_e32 v3, v1
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v3, v1
+; GFX6-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX6-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX6-NEXT: v_or_b32_e32 v1, v1, v3
+; GFX6-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX6-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX6-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v0
; GFX6-NEXT: s_setpc_b64 s[30:31]
;
; GFX8-LABEL: v_pow_f16:
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX8-NEXT: v_log_f16_e32 v0, v0
-; GFX8-NEXT: v_cvt_f32_f16_e32 v1, v1
; GFX8-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x800000
+; GFX8-NEXT: v_cvt_f32_f16_e32 v1, v1
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
+; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX8-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX8-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX8-NEXT: v_log_f32_e32 v2, v2
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX8-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX8-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX8-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_exp_f32_e32 v2, v2
+; GFX8-NEXT: v_not_b32_e32 v3, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX8-NEXT: v_trunc_f32_e32 v3, v1
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v3, v1
+; GFX8-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v3, v1
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v3, v1
+; GFX8-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX8-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX8-NEXT: v_or_b32_e32 v1, v1, v3
+; GFX8-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX8-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX8-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX8-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX8-NEXT: v_exp_f16_e32 v0, v0
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: v_pow_f16:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT: v_log_f16_e32 v0, v0
-; GFX9-NEXT: v_cvt_f32_f16_e32 v1, v1
; GFX9-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x800000
+; GFX9-NEXT: v_cvt_f32_f16_e32 v1, v1
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
+; GFX9-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX9-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX9-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX9-NEXT: v_log_f32_e32 v2, v2
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX9-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX9-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX9-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX9-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX9-NEXT: v_exp_f32_e32 v2, v2
+; GFX9-NEXT: v_not_b32_e32 v3, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX9-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX9-NEXT: v_trunc_f32_e32 v3, v1
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v3, v1
+; GFX9-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX9-NEXT: v_trunc_f32_e32 v3, v1
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v3, v1
+; GFX9-NEXT: v_bfrev_b32_e32 v1, -2
+; GFX9-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX9-NEXT: v_and_or_b32 v1, v2, v1, v3
+; GFX9-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX9-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX9-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX9-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX9-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX9-NEXT: v_exp_f16_e32 v0, v0
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_f16:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_log_f16_e32 v0, v0
-; GFX10-NEXT: v_cvt_f32_f16_e32 v1, v1
; GFX10-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
+; GFX10-NEXT: v_cvt_f32_f16_e32 v4, v1
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v0|
+; GFX10-NEXT: v_trunc_f32_e32 v5, v4
+; GFX10-NEXT: v_cmp_class_f32_e64 s6, v0, 24
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 1, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s4
+; GFX10-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX10-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX10-NEXT: v_log_f32_e32 v2, v2
+; GFX10-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX10-NEXT: v_mul_legacy_f32_e32 v2, v4, v2
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX10-NEXT: v_mov_b32_e32 v3, 0.5
+; GFX10-NEXT: v_exp_f32_e32 v2, v2
+; GFX10-NEXT: v_fma_mix_f32 v1, v1, v3, neg(0) op_sel_hi:[1,0,0]
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_cmp_eq_f32_e32 vcc_lo, v5, v4
+; GFX10-NEXT: v_trunc_f32_e32 v6, v1
+; GFX10-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX10-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX10-NEXT: v_cmp_lg_f32_e64 s4, v6, v1
+; GFX10-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v3
+; GFX10-NEXT: s_and_b32 s4, vcc_lo, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v2, v1, s4
+; GFX10-NEXT: s_xor_b32 s4, vcc_lo, exec_lo
+; GFX10-NEXT: s_and_b32 s4, s6, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s4
; GFX10-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX10-NEXT: v_exp_f16_e32 v0, v0
; GFX10-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-TRUE16-LABEL: v_pow_f16:
; GFX11-TRUE16: ; %bb.0:
; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-TRUE16-NEXT: v_log_f16_e32 v0.l, v0.l
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.l
; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v1.l
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v5, v1
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s2, v0, 24
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v2, 0, 1, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s0
+; GFX11-TRUE16-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v2, v2
; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.l
+; GFX11-TRUE16-NEXT: v_sub_f32_e32 v2, v2, v3
; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v0, v1
-; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v0
+; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v2, v1, v2
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e32 vcc_lo, v5, v1
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_dual_add_f32 v2, v2, v3 :: v_dual_mul_f32 v3, 0.5, v1
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v2, v2
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v6, v3
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e64 s0, v6, v3
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX11-TRUE16-NEXT: v_and_b32_e32 v4, 0x80000000, v0
+; GFX11-TRUE16-NEXT: s_and_b32 s0, vcc_lo, s0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v4
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v0, v2, v1, s0
+; GFX11-TRUE16-NEXT: s_xor_b32 s0, vcc_lo, exec_lo
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
+; GFX11-TRUE16-NEXT: s_and_b32 s0, s2, s0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
-; GFX11-TRUE16-NEXT: v_exp_f16_e32 v0.l, v0.l
+; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v0
; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-FAKE16-LABEL: v_pow_f16:
; GFX11-FAKE16: ; %bb.0:
; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-FAKE16-NEXT: v_log_f16_e32 v0, v0
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v4, v1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v5, v4
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s2, v0, 24
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v2, 0, 1, s0
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s0
+; GFX11-FAKE16-NEXT: v_lshlrev_b32_e32 v2, 5, v2
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v0, v1
-; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v2, v2
+; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v2, v4, v2
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_dual_add_f32 v2, v2, v3 :: v_dual_mov_b32 v3, 0.5
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v2, v2
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v1, v1, v3, neg(0) op_sel_hi:[1,0,0]
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v3, 0, 0xffffffc0, vcc_lo
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e32 vcc_lo, v5, v4
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v6, v1
+; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX11-FAKE16-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e64 s0, v6, v1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v3
+; GFX11-FAKE16-NEXT: s_and_b32 s0, vcc_lo, s0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v0, v2, v1, s0
+; GFX11-FAKE16-NEXT: s_xor_b32 s0, vcc_lo, exec_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s2, s0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_exp_f16_e32 v0, v0
+; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
%pow = call half @llvm.pow.f16(half %x, half %y)
ret half %pow
@@ -408,34 +797,77 @@ define <2 x half> @v_pow_v2f16(<2 x half> %x, <2 x half> %y) {
; GFX6: ; %bb.0:
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX6-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x800000
+; GFX6-NEXT: v_cvt_f32_f16_e32 v5, v1
+; GFX6-NEXT: v_mov_b32_e32 v6, 0x42000000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, v3
+; GFX6-NEXT: v_cndmask_b32_e64 v4, 0, 1, vcc
+; GFX6-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX6-NEXT: v_ldexp_f32_e64 v4, |v2|, v4
+; GFX6-NEXT: v_log_f32_e32 v4, v4
+; GFX6-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX6-NEXT: v_mov_b32_e32 v8, 0x42800000
; GFX6-NEXT: v_lshrrev_b32_e32 v0, 16, v0
+; GFX6-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX6-NEXT: v_mul_legacy_f32_e32 v4, v5, v4
+; GFX6-NEXT: v_mov_b32_e32 v7, 0xc2fc0000
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v4, v7
+; GFX6-NEXT: v_cndmask_b32_e32 v9, 0, v8, vcc
+; GFX6-NEXT: v_add_f32_e32 v4, v4, v9
+; GFX6-NEXT: v_exp_f32_e32 v4, v4
+; GFX6-NEXT: v_not_b32_e32 v9, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v10, 0, v9, vcc
; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX6-NEXT: v_cvt_f32_f16_e32 v4, v1
-; GFX6-NEXT: v_log_f32_e32 v2, v2
+; GFX6-NEXT: v_ldexp_f32_e32 v4, v4, v10
+; GFX6-NEXT: v_trunc_f32_e32 v10, v5
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v10, v5
+; GFX6-NEXT: v_mul_f32_e32 v5, 0.5, v5
+; GFX6-NEXT: v_trunc_f32_e32 v10, v5
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v10, v5
+; GFX6-NEXT: v_and_b32_e32 v5, 0x7fffffff, v4
+; GFX6-NEXT: v_and_b32_e32 v10, 0x80000000, v2
+; GFX6-NEXT: v_or_b32_e32 v5, v5, v10
+; GFX6-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX6-NEXT: s_xor_b64 s[8:9], vcc, exec
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v3
+; GFX6-NEXT: v_cndmask_b32_e64 v4, v4, v5, s[4:5]
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v2, 24
+; GFX6-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX6-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX6-NEXT: v_ldexp_f32_e64 v2, |v0|, v2
; GFX6-NEXT: v_lshrrev_b32_e32 v1, 16, v1
+; GFX6-NEXT: v_log_f32_e32 v2, v2
; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
-; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v2, v4
-; GFX6-NEXT: v_mov_b32_e32 v5, 0x42800000
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
-; GFX6-NEXT: v_cndmask_b32_e32 v4, 0, v5, vcc
-; GFX6-NEXT: v_add_f32_e32 v2, v2, v4
-; GFX6-NEXT: v_not_b32_e32 v4, 63
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_cndmask_b32_e32 v6, 0, v4, vcc
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v3
-; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v5, vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v5, 0, v6, vcc
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x7fc00000
+; GFX6-NEXT: v_sub_f32_e32 v2, v2, v5
+; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v2, v7
+; GFX6-NEXT: v_cndmask_b32_e32 v5, 0, v8, vcc
+; GFX6-NEXT: v_add_f32_e32 v2, v2, v5
; GFX6-NEXT: v_exp_f32_e32 v2, v2
-; GFX6-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
-; GFX6-NEXT: v_ldexp_f32_e32 v1, v2, v6
-; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v4, vcc
-; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v2
+; GFX6-NEXT: v_cndmask_b32_e32 v5, 0, v9, vcc
+; GFX6-NEXT: s_and_b64 s[4:5], s[4:5], s[8:9]
+; GFX6-NEXT: v_cndmask_b32_e64 v4, v4, v3, s[4:5]
+; GFX6-NEXT: v_ldexp_f32_e32 v2, v2, v5
+; GFX6-NEXT: v_trunc_f32_e32 v5, v1
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v5, v1
+; GFX6-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX6-NEXT: v_trunc_f32_e32 v5, v1
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v5, v1
+; GFX6-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX6-NEXT: v_and_b32_e32 v5, 0x80000000, v0
+; GFX6-NEXT: v_or_b32_e32 v1, v1, v5
+; GFX6-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX6-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v1, v3, vcc
; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX6-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX6-NEXT: v_cvt_f16_f32_e32 v4, v4
; GFX6-NEXT: v_bfe_u32 v0, v0, 0, 16
-; GFX6-NEXT: v_bfe_u32 v1, v1, 0, 16
+; GFX6-NEXT: v_bfe_u32 v1, v4, 0, 16
; GFX6-NEXT: v_lshlrev_b32_e32 v0, 16, v0
; GFX6-NEXT: v_or_b32_e32 v0, v1, v0
; GFX6-NEXT: s_setpc_b64 s[30:31]
@@ -443,19 +875,75 @@ define <2 x half> @v_pow_v2f16(<2 x half> %x, <2 x half> %y) {
; GFX8-LABEL: v_pow_v2f16:
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX8-NEXT: v_log_f16_e32 v2, v0
-; GFX8-NEXT: v_log_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX8-NEXT: v_cvt_f32_f16_e32 v3, v1
+; GFX8-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x800000
+; GFX8-NEXT: v_cvt_f32_f16_e32 v5, v1
+; GFX8-NEXT: v_mov_b32_e32 v6, 0x42000000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, v3
+; GFX8-NEXT: v_cndmask_b32_e64 v4, 0, 1, vcc
+; GFX8-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX8-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX8-NEXT: v_log_f32_e32 v4, v4
+; GFX8-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX8-NEXT: v_mov_b32_e32 v8, 0x42800000
+; GFX8-NEXT: v_cvt_f32_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX8-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX8-NEXT: v_mul_legacy_f32_e32 v4, v5, v4
+; GFX8-NEXT: v_mov_b32_e32 v7, 0xc2fc0000
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v4, v7
+; GFX8-NEXT: v_cndmask_b32_e32 v9, 0, v8, vcc
+; GFX8-NEXT: v_add_f32_e32 v4, v4, v9
+; GFX8-NEXT: v_exp_f32_e32 v4, v4
+; GFX8-NEXT: v_not_b32_e32 v9, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v10, 0, v9, vcc
; GFX8-NEXT: v_cvt_f32_f16_sdwa v1, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX8-NEXT: v_cvt_f32_f16_e32 v2, v2
-; GFX8-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v2, v3
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
+; GFX8-NEXT: v_ldexp_f32 v4, v4, v10
+; GFX8-NEXT: v_trunc_f32_e32 v10, v5
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v10, v5
+; GFX8-NEXT: v_mul_f32_e32 v5, 0.5, v5
+; GFX8-NEXT: v_trunc_f32_e32 v10, v5
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v10, v5
+; GFX8-NEXT: v_and_b32_e32 v5, 0x7fffffff, v4
+; GFX8-NEXT: v_and_b32_e32 v10, 0x80000000, v2
+; GFX8-NEXT: v_or_b32_e32 v5, v5, v10
+; GFX8-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX8-NEXT: s_xor_b64 s[8:9], vcc, exec
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v3
+; GFX8-NEXT: v_cndmask_b32_e64 v4, v4, v5, s[4:5]
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v2, 24
+; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX8-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX8-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX8-NEXT: v_log_f32_e32 v2, v2
+; GFX8-NEXT: v_cndmask_b32_e32 v5, 0, v6, vcc
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x7fc00000
+; GFX8-NEXT: s_and_b64 s[4:5], s[4:5], s[8:9]
+; GFX8-NEXT: v_sub_f32_e32 v2, v2, v5
+; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v2, v7
+; GFX8-NEXT: v_cndmask_b32_e32 v5, 0, v8, vcc
+; GFX8-NEXT: v_add_f32_e32 v2, v2, v5
+; GFX8-NEXT: v_exp_f32_e32 v2, v2
+; GFX8-NEXT: v_cndmask_b32_e32 v5, 0, v9, vcc
+; GFX8-NEXT: v_cndmask_b32_e64 v4, v4, v3, s[4:5]
+; GFX8-NEXT: v_ldexp_f32 v2, v2, v5
+; GFX8-NEXT: v_trunc_f32_e32 v5, v1
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v5, v1
+; GFX8-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v5, v1
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v5, v1
+; GFX8-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX8-NEXT: v_and_b32_e32 v5, 0x80000000, v0
+; GFX8-NEXT: v_or_b32_e32 v1, v1, v5
+; GFX8-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX8-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v1, v3, vcc
; GFX8-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX8-NEXT: v_cvt_f16_f32_e32 v1, v2
+; GFX8-NEXT: v_cvt_f16_f32_e32 v1, v4
; GFX8-NEXT: v_mov_b32_e32 v2, 16
-; GFX8-NEXT: v_exp_f16_e32 v0, v0
-; GFX8-NEXT: v_exp_f16_e32 v1, v1
; GFX8-NEXT: v_lshlrev_b32_sdwa v0, v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
; GFX8-NEXT: v_or_b32_sdwa v0, v1, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
; GFX8-NEXT: s_setpc_b64 s[30:31]
@@ -463,83 +951,309 @@ define <2 x half> @v_pow_v2f16(<2 x half> %x, <2 x half> %y) {
; GFX9-LABEL: v_pow_v2f16:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT: v_log_f16_e32 v2, v0
-; GFX9-NEXT: v_log_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX9-NEXT: v_cvt_f32_f16_e32 v3, v1
+; GFX9-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x800000
+; GFX9-NEXT: v_cvt_f32_f16_e32 v5, v1
+; GFX9-NEXT: v_mov_b32_e32 v6, 0x42000000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, v3
+; GFX9-NEXT: v_cndmask_b32_e64 v4, 0, 1, vcc
+; GFX9-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX9-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX9-NEXT: v_log_f32_e32 v4, v4
+; GFX9-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX9-NEXT: v_mov_b32_e32 v8, 0x42800000
+; GFX9-NEXT: v_cvt_f32_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX9-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX9-NEXT: v_mul_legacy_f32_e32 v4, v5, v4
+; GFX9-NEXT: v_mov_b32_e32 v7, 0xc2fc0000
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v4, v7
+; GFX9-NEXT: v_cndmask_b32_e32 v9, 0, v8, vcc
+; GFX9-NEXT: v_add_f32_e32 v4, v4, v9
+; GFX9-NEXT: v_exp_f32_e32 v4, v4
+; GFX9-NEXT: v_not_b32_e32 v9, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v10, 0, v9, vcc
; GFX9-NEXT: v_cvt_f32_f16_sdwa v1, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX9-NEXT: v_cvt_f32_f16_e32 v2, v2
-; GFX9-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v2, v3
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX9-NEXT: v_cvt_f16_f32_e32 v1, v2
+; GFX9-NEXT: v_ldexp_f32 v4, v4, v10
+; GFX9-NEXT: v_trunc_f32_e32 v10, v5
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v10, v5
+; GFX9-NEXT: v_mul_f32_e32 v5, 0.5, v5
+; GFX9-NEXT: v_trunc_f32_e32 v10, v5
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v10, v5
+; GFX9-NEXT: v_bfrev_b32_e32 v5, -2
+; GFX9-NEXT: v_and_b32_e32 v10, 0x80000000, v2
+; GFX9-NEXT: v_and_or_b32 v10, v4, v5, v10
+; GFX9-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX9-NEXT: s_xor_b64 s[8:9], vcc, exec
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v3
+; GFX9-NEXT: v_cndmask_b32_e64 v4, v4, v10, s[4:5]
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v2, 24
+; GFX9-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX9-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX9-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX9-NEXT: v_log_f32_e32 v2, v2
+; GFX9-NEXT: v_cndmask_b32_e32 v6, 0, v6, vcc
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x7fc00000
+; GFX9-NEXT: s_and_b64 s[4:5], s[4:5], s[8:9]
+; GFX9-NEXT: v_sub_f32_e32 v2, v2, v6
+; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v2, v7
+; GFX9-NEXT: v_cndmask_b32_e32 v6, 0, v8, vcc
+; GFX9-NEXT: v_add_f32_e32 v2, v2, v6
+; GFX9-NEXT: v_exp_f32_e32 v2, v2
+; GFX9-NEXT: v_cndmask_b32_e32 v6, 0, v9, vcc
+; GFX9-NEXT: v_cndmask_b32_e64 v4, v4, v3, s[4:5]
+; GFX9-NEXT: v_cvt_f16_f32_e32 v4, v4
+; GFX9-NEXT: v_ldexp_f32 v2, v2, v6
+; GFX9-NEXT: v_trunc_f32_e32 v6, v1
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v6, v1
+; GFX9-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX9-NEXT: v_trunc_f32_e32 v6, v1
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v6, v1
+; GFX9-NEXT: v_and_b32_e32 v1, 0x80000000, v0
+; GFX9-NEXT: v_and_or_b32 v1, v2, v5, v1
+; GFX9-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX9-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX9-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v1, v3, vcc
; GFX9-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX9-NEXT: v_exp_f16_e32 v1, v1
-; GFX9-NEXT: v_exp_f16_e32 v0, v0
-; GFX9-NEXT: v_lshl_or_b32 v0, v0, 16, v1
+; GFX9-NEXT: v_pack_b32_f16 v0, v4, v0
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_v2f16:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_log_f16_e32 v2, v0
-; GFX10-NEXT: v_log_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX10-NEXT: v_cvt_f32_f16_e32 v3, v1
-; GFX10-NEXT: v_cvt_f32_f16_sdwa v1, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX10-NEXT: v_cvt_f32_f16_e32 v2, v2
-; GFX10-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX10-NEXT: v_mul_legacy_f32_e32 v2, v2, v3
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX10-NEXT: v_cvt_f16_f32_e32 v1, v2
+; GFX10-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX10-NEXT: v_cvt_f32_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX10-NEXT: v_cvt_f32_f16_e32 v7, v1
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v2|
+; GFX10-NEXT: v_cmp_gt_f32_e64 s5, 0x800000, |v0|
+; GFX10-NEXT: v_cmp_class_f32_e64 s8, v2, 24
+; GFX10-NEXT: v_and_b32_e32 v14, 0x80000000, v0
+; GFX10-NEXT: v_cmp_class_f32_e64 s9, v0, 24
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 1, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 1, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v5, 0, 0x42000000, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s5
+; GFX10-NEXT: v_lshlrev_b32_e32 v3, 5, v3
+; GFX10-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX10-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX10-NEXT: v_ldexp_f32 v4, |v0|, v4
+; GFX10-NEXT: v_log_f32_e32 v3, v3
+; GFX10-NEXT: v_log_f32_e32 v4, v4
+; GFX10-NEXT: v_sub_f32_e32 v3, v3, v5
+; GFX10-NEXT: v_cvt_f32_f16_sdwa v5, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX10-NEXT: v_sub_f32_e32 v4, v4, v6
+; GFX10-NEXT: v_mov_b32_e32 v6, 0.5
+; GFX10-NEXT: v_mul_legacy_f32_e32 v3, v7, v3
+; GFX10-NEXT: v_mul_legacy_f32_e32 v4, v5, v4
+; GFX10-NEXT: v_fma_mix_f32 v10, v1, v6, neg(0) op_sel_hi:[1,0,0]
+; GFX10-NEXT: v_fma_mix_f32 v1, v1, v6, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v3
+; GFX10-NEXT: v_trunc_f32_e32 v6, v7
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0xc2fc0000, v4
+; GFX10-NEXT: v_trunc_f32_e32 v12, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v8, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v11, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v9, 0, 0x42800000, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v13, 0, 0xffffffc0, s4
+; GFX10-NEXT: v_cmp_eq_f32_e32 vcc_lo, v6, v7
+; GFX10-NEXT: v_add_f32_e32 v3, v3, v8
+; GFX10-NEXT: v_trunc_f32_e32 v8, v10
+; GFX10-NEXT: v_add_f32_e32 v4, v4, v9
+; GFX10-NEXT: v_and_b32_e32 v9, 0x80000000, v2
+; GFX10-NEXT: v_trunc_f32_e32 v2, v5
+; GFX10-NEXT: v_exp_f32_e32 v3, v3
+; GFX10-NEXT: v_cmp_lg_f32_e64 s4, v8, v10
+; GFX10-NEXT: v_exp_f32_e32 v4, v4
+; GFX10-NEXT: v_cmp_lg_f32_e64 s6, v12, v1
+; GFX10-NEXT: v_cmp_eq_f32_e64 s5, v2, v5
+; GFX10-NEXT: s_xor_b32 s10, vcc_lo, exec_lo
+; GFX10-NEXT: s_and_b32 vcc_lo, vcc_lo, s4
+; GFX10-NEXT: s_xor_b32 s4, s5, exec_lo
+; GFX10-NEXT: v_ldexp_f32 v0, v3, v11
+; GFX10-NEXT: s_and_b32 s4, s9, s4
+; GFX10-NEXT: v_ldexp_f32 v3, v4, v13
+; GFX10-NEXT: v_and_or_b32 v2, 0x7fffffff, v0, v9
+; GFX10-NEXT: v_and_or_b32 v1, 0x7fffffff, v3, v14
+; GFX10-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc_lo
+; GFX10-NEXT: s_and_b32 vcc_lo, s5, s6
+; GFX10-NEXT: s_and_b32 s5, s8, s10
+; GFX10-NEXT: v_cndmask_b32_e32 v1, v3, v1, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s4
; GFX10-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX10-NEXT: v_exp_f16_e32 v1, v1
-; GFX10-NEXT: v_exp_f16_sdwa v0, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD
-; GFX10-NEXT: v_or_b32_sdwa v0, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
+; GFX10-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX10-NEXT: v_pack_b32_f16 v0, v0, v1
; GFX10-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-TRUE16-LABEL: v_pow_v2f16:
; GFX11-TRUE16: ; %bb.0:
; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-TRUE16-NEXT: v_log_f16_e32 v0.l, v0.l
-; GFX11-TRUE16-NEXT: v_log_f16_e32 v0.h, v0.h
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v2, v1.l
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v2, v0.l
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.h
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v7, v1.l
; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v1.h
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v2|
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v0|
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s4, v2, 24
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v8, v7
+; GFX11-TRUE16-NEXT: v_dual_mul_f32 v9, 0.5, v1 :: v_dual_and_b32 v10, 0x80000000, v0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v4, 0, 1, s1
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v5, 0, 0x42000000, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v3, 0, 1, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s1
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s5, v0, 24
+; GFX11-TRUE16-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v4, |v0|, v4
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v4, v4
; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v3, v0.l
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.h
+; GFX11-TRUE16-NEXT: v_dual_sub_f32 v4, v4, v6 :: v_dual_lshlrev_b32 v3, 5, v3
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v4, v1, v4
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v3, v3
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v4
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_3) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v6, 0, 0x42800000, s0
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_sub_f32_e32 v3, v3, v5
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v0, 0, 0xffffffc0, s0
+; GFX11-TRUE16-NEXT: v_dual_add_f32 v4, v4, v6 :: v_dual_mul_dx9_zero_f32 v3, v7, v3
+; GFX11-TRUE16-NEXT: v_and_b32_e32 v6, 0x80000000, v2
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v4, v4
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v3
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v5, 0, 0x42800000, vcc_lo
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v11, 0, 0xffffffc0, vcc_lo
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e32 vcc_lo, v8, v7
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v8, v9
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v0, v4, v0
+; GFX11-TRUE16-NEXT: v_add_f32_e32 v3, v3, v5
+; GFX11-TRUE16-NEXT: v_mul_f32_e32 v5, 0.5, v7
+; GFX11-TRUE16-NEXT: s_xor_b32 s6, vcc_lo, exec_lo
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e64 s2, v8, v9
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v2, v3
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v7, v5
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v3, v1
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e64 s1, v7, v5
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e64 s0, v3, v1
+; GFX11-TRUE16-NEXT: v_and_or_b32 v3, 0x7fffffff, v0, v10
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v2, v2, v11
+; GFX11-TRUE16-NEXT: s_and_b32 vcc_lo, vcc_lo, s1
+; GFX11-TRUE16-NEXT: s_and_b32 s1, s4, s6
; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-TRUE16-NEXT: v_dual_mul_dx9_zero_f32 v2, v3, v2 :: v_dual_mul_dx9_zero_f32 v1, v0, v1
-; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v2
+; GFX11-TRUE16-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v6
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e32 v1, v2, v1, vcc_lo
+; GFX11-TRUE16-NEXT: s_and_b32 vcc_lo, s0, s2
+; GFX11-TRUE16-NEXT: s_xor_b32 s0, s0, exec_lo
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e32 v0, v0, v3, vcc_lo
+; GFX11-TRUE16-NEXT: s_and_b32 s0, s5, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s1
; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.h, v1
-; GFX11-TRUE16-NEXT: v_exp_f16_e32 v0.l, v0.l
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
-; GFX11-TRUE16-NEXT: v_exp_f16_e32 v0.h, v0.h
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v2, v0, 0x7fc00000, s0
+; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v1
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.h, v2
; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-FAKE16-LABEL: v_pow_v2f16:
; GFX11-FAKE16: ; %bb.0:
; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-FAKE16-NEXT: v_log_f16_e32 v2, v0
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v2, v0
; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v0, 16, v0
-; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v3, 16, v1
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-FAKE16-NEXT: v_log_f16_e32 v0, v0
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v3, v3
-; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v2, v2
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v6, v1
+; GFX11-FAKE16-NEXT: v_mov_b32_e32 v8, 0.5
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v2|
; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX11-FAKE16-NEXT: v_and_b32_e32 v11, 0x80000000, v2
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v9, v1, v8, neg(0) op_sel_hi:[1,0,0]
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v5, 0, 0x42000000, s0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(SKIP_2) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v0|
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v3, 0, 1, s0
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s5, v0, 24
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v4, 0, 1, s1
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v7, 0, 0x42000000, s1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v4, |v0|, v4
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_3) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v4, v4
+; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX11-FAKE16-NEXT: v_lshlrev_b32_e32 v3, 5, v3
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v3, v3
+; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_sub_f32_e32 v3, v3, v5
+; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v5, 16, v1
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v1, v1, v8, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v8, v9
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
+; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v3, v6, v3
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v5, v5
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v12, v1
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v3
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v4, v5, v4
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e64 s1, v12, v1
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v7, 0, 0x42800000, vcc_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v4
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v10, 0, 0xffffffc0, vcc_lo
+; GFX11-FAKE16-NEXT: v_add_f32_e32 v3, v3, v7
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v7, 0, 0x42800000, s0
+; GFX11-FAKE16-NEXT: v_add_f32_e32 v4, v4, v7
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v7, v6
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v4, v4
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e32 vcc_lo, v7, v6
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v6, 0, 0xffffffc0, s0
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e64 s0, v8, v9
+; GFX11-FAKE16-NEXT: v_and_b32_e32 v8, 0x80000000, v0
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v3, v3
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v7, v5
+; GFX11-FAKE16-NEXT: s_xor_b32 s4, vcc_lo, exec_lo
+; GFX11-FAKE16-NEXT: s_and_b32 s0, vcc_lo, s0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(TRANS32_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v4, v4, v6
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e64 s2, v7, v5
+; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v3, v3, v10
+; GFX11-FAKE16-NEXT: s_and_b32 vcc_lo, s2, s1
+; GFX11-FAKE16-NEXT: s_xor_b32 s1, s2, exec_lo
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_dual_mul_dx9_zero_f32 v1, v2, v1 :: v_dual_mul_dx9_zero_f32 v0, v0, v3
-; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX11-FAKE16-NEXT: v_and_or_b32 v9, 0x7fffffff, v3, v11
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v1, v3, v9, s0
+; GFX11-FAKE16-NEXT: v_and_or_b32 v3, 0x7fffffff, v4, v8
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s0, v2, 24
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(SALU_CYCLE_1)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e32 v0, v4, v3, vcc_lo
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s0, s4
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s0
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s5, s1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instid1(SALU_CYCLE_1)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v1, v1
; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX11-FAKE16-NEXT: v_exp_f16_e32 v1, v1
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_exp_f16_e32 v0, v0
-; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_and_b32_e32 v1, 0xffff, v1
-; GFX11-FAKE16-NEXT: v_lshl_or_b32 v0, v0, 16, v1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_pack_b32_f16 v0, v1, v0
; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
%pow = call <2 x half> @llvm.pow.v2f16(<2 x half> %x, <2 x half> %y)
ret <2 x half> %pow
@@ -551,34 +1265,77 @@ define <2 x half> @v_pow_v2f16_fneg_lhs(<2 x half> %x, <2 x half> %y) {
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX6-NEXT: v_xor_b32_e32 v0, 0x80008000, v0
; GFX6-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x800000
+; GFX6-NEXT: v_cvt_f32_f16_e32 v5, v1
+; GFX6-NEXT: v_mov_b32_e32 v6, 0x42000000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, v3
+; GFX6-NEXT: v_cndmask_b32_e64 v4, 0, 1, vcc
+; GFX6-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX6-NEXT: v_ldexp_f32_e64 v4, |v2|, v4
+; GFX6-NEXT: v_log_f32_e32 v4, v4
+; GFX6-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX6-NEXT: v_mov_b32_e32 v8, 0x42800000
; GFX6-NEXT: v_lshrrev_b32_e32 v0, 16, v0
+; GFX6-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX6-NEXT: v_mul_legacy_f32_e32 v4, v5, v4
+; GFX6-NEXT: v_mov_b32_e32 v7, 0xc2fc0000
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v4, v7
+; GFX6-NEXT: v_cndmask_b32_e32 v9, 0, v8, vcc
+; GFX6-NEXT: v_add_f32_e32 v4, v4, v9
+; GFX6-NEXT: v_exp_f32_e32 v4, v4
+; GFX6-NEXT: v_not_b32_e32 v9, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v10, 0, v9, vcc
; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX6-NEXT: v_cvt_f32_f16_e32 v4, v1
-; GFX6-NEXT: v_log_f32_e32 v2, v2
+; GFX6-NEXT: v_ldexp_f32_e32 v4, v4, v10
+; GFX6-NEXT: v_trunc_f32_e32 v10, v5
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v10, v5
+; GFX6-NEXT: v_mul_f32_e32 v5, 0.5, v5
+; GFX6-NEXT: v_trunc_f32_e32 v10, v5
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v10, v5
+; GFX6-NEXT: v_and_b32_e32 v5, 0x7fffffff, v4
+; GFX6-NEXT: v_and_b32_e32 v10, 0x80000000, v2
+; GFX6-NEXT: v_or_b32_e32 v5, v5, v10
+; GFX6-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX6-NEXT: s_xor_b64 s[8:9], vcc, exec
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v3
+; GFX6-NEXT: v_cndmask_b32_e64 v4, v4, v5, s[4:5]
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v2, 24
+; GFX6-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX6-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX6-NEXT: v_ldexp_f32_e64 v2, |v0|, v2
; GFX6-NEXT: v_lshrrev_b32_e32 v1, 16, v1
+; GFX6-NEXT: v_log_f32_e32 v2, v2
; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
-; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v2, v4
-; GFX6-NEXT: v_mov_b32_e32 v5, 0x42800000
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
-; GFX6-NEXT: v_cndmask_b32_e32 v4, 0, v5, vcc
-; GFX6-NEXT: v_add_f32_e32 v2, v2, v4
-; GFX6-NEXT: v_not_b32_e32 v4, 63
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_cndmask_b32_e32 v6, 0, v4, vcc
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v3
-; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v5, vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v5, 0, v6, vcc
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x7fc00000
+; GFX6-NEXT: v_sub_f32_e32 v2, v2, v5
+; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v2, v7
+; GFX6-NEXT: v_cndmask_b32_e32 v5, 0, v8, vcc
+; GFX6-NEXT: v_add_f32_e32 v2, v2, v5
; GFX6-NEXT: v_exp_f32_e32 v2, v2
-; GFX6-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
-; GFX6-NEXT: v_ldexp_f32_e32 v1, v2, v6
-; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v4, vcc
-; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v2
+; GFX6-NEXT: v_cndmask_b32_e32 v5, 0, v9, vcc
+; GFX6-NEXT: s_and_b64 s[4:5], s[4:5], s[8:9]
+; GFX6-NEXT: v_cndmask_b32_e64 v4, v4, v3, s[4:5]
+; GFX6-NEXT: v_ldexp_f32_e32 v2, v2, v5
+; GFX6-NEXT: v_trunc_f32_e32 v5, v1
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v5, v1
+; GFX6-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX6-NEXT: v_trunc_f32_e32 v5, v1
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v5, v1
+; GFX6-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX6-NEXT: v_and_b32_e32 v5, 0x80000000, v0
+; GFX6-NEXT: v_or_b32_e32 v1, v1, v5
+; GFX6-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX6-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v1, v3, vcc
; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX6-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX6-NEXT: v_cvt_f16_f32_e32 v4, v4
; GFX6-NEXT: v_bfe_u32 v0, v0, 0, 16
-; GFX6-NEXT: v_bfe_u32 v1, v1, 0, 16
+; GFX6-NEXT: v_bfe_u32 v1, v4, 0, 16
; GFX6-NEXT: v_lshlrev_b32_e32 v0, 16, v0
; GFX6-NEXT: v_or_b32_e32 v0, v1, v0
; GFX6-NEXT: s_setpc_b64 s[30:31]
@@ -587,19 +1344,75 @@ define <2 x half> @v_pow_v2f16_fneg_lhs(<2 x half> %x, <2 x half> %y) {
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX8-NEXT: v_xor_b32_e32 v0, 0x80008000, v0
-; GFX8-NEXT: v_log_f16_e32 v2, v0
-; GFX8-NEXT: v_log_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX8-NEXT: v_cvt_f32_f16_e32 v3, v1
+; GFX8-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x800000
+; GFX8-NEXT: v_cvt_f32_f16_e32 v5, v1
+; GFX8-NEXT: v_mov_b32_e32 v6, 0x42000000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, v3
+; GFX8-NEXT: v_cndmask_b32_e64 v4, 0, 1, vcc
+; GFX8-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX8-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX8-NEXT: v_log_f32_e32 v4, v4
+; GFX8-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX8-NEXT: v_mov_b32_e32 v8, 0x42800000
+; GFX8-NEXT: v_cvt_f32_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX8-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX8-NEXT: v_mul_legacy_f32_e32 v4, v5, v4
+; GFX8-NEXT: v_mov_b32_e32 v7, 0xc2fc0000
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v4, v7
+; GFX8-NEXT: v_cndmask_b32_e32 v9, 0, v8, vcc
+; GFX8-NEXT: v_add_f32_e32 v4, v4, v9
+; GFX8-NEXT: v_exp_f32_e32 v4, v4
+; GFX8-NEXT: v_not_b32_e32 v9, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v10, 0, v9, vcc
; GFX8-NEXT: v_cvt_f32_f16_sdwa v1, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX8-NEXT: v_cvt_f32_f16_e32 v2, v2
-; GFX8-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v2, v3
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
+; GFX8-NEXT: v_ldexp_f32 v4, v4, v10
+; GFX8-NEXT: v_trunc_f32_e32 v10, v5
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v10, v5
+; GFX8-NEXT: v_mul_f32_e32 v5, 0.5, v5
+; GFX8-NEXT: v_trunc_f32_e32 v10, v5
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v10, v5
+; GFX8-NEXT: v_and_b32_e32 v5, 0x7fffffff, v4
+; GFX8-NEXT: v_and_b32_e32 v10, 0x80000000, v2
+; GFX8-NEXT: v_or_b32_e32 v5, v5, v10
+; GFX8-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX8-NEXT: s_xor_b64 s[8:9], vcc, exec
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v3
+; GFX8-NEXT: v_cndmask_b32_e64 v4, v4, v5, s[4:5]
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v2, 24
+; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX8-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX8-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX8-NEXT: v_log_f32_e32 v2, v2
+; GFX8-NEXT: v_cndmask_b32_e32 v5, 0, v6, vcc
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x7fc00000
+; GFX8-NEXT: s_and_b64 s[4:5], s[4:5], s[8:9]
+; GFX8-NEXT: v_sub_f32_e32 v2, v2, v5
+; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v2, v7
+; GFX8-NEXT: v_cndmask_b32_e32 v5, 0, v8, vcc
+; GFX8-NEXT: v_add_f32_e32 v2, v2, v5
+; GFX8-NEXT: v_exp_f32_e32 v2, v2
+; GFX8-NEXT: v_cndmask_b32_e32 v5, 0, v9, vcc
+; GFX8-NEXT: v_cndmask_b32_e64 v4, v4, v3, s[4:5]
+; GFX8-NEXT: v_ldexp_f32 v2, v2, v5
+; GFX8-NEXT: v_trunc_f32_e32 v5, v1
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v5, v1
+; GFX8-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v5, v1
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v5, v1
+; GFX8-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX8-NEXT: v_and_b32_e32 v5, 0x80000000, v0
+; GFX8-NEXT: v_or_b32_e32 v1, v1, v5
+; GFX8-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX8-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v1, v3, vcc
; GFX8-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX8-NEXT: v_cvt_f16_f32_e32 v1, v2
+; GFX8-NEXT: v_cvt_f16_f32_e32 v1, v4
; GFX8-NEXT: v_mov_b32_e32 v2, 16
-; GFX8-NEXT: v_exp_f16_e32 v0, v0
-; GFX8-NEXT: v_exp_f16_e32 v1, v1
; GFX8-NEXT: v_lshlrev_b32_sdwa v0, v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
; GFX8-NEXT: v_or_b32_sdwa v0, v1, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
; GFX8-NEXT: s_setpc_b64 s[30:31]
@@ -608,88 +1421,316 @@ define <2 x half> @v_pow_v2f16_fneg_lhs(<2 x half> %x, <2 x half> %y) {
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_xor_b32_e32 v0, 0x80008000, v0
-; GFX9-NEXT: v_log_f16_e32 v2, v0
-; GFX9-NEXT: v_log_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX9-NEXT: v_cvt_f32_f16_e32 v3, v1
+; GFX9-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x800000
+; GFX9-NEXT: v_cvt_f32_f16_e32 v5, v1
+; GFX9-NEXT: v_mov_b32_e32 v6, 0x42000000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, v3
+; GFX9-NEXT: v_cndmask_b32_e64 v4, 0, 1, vcc
+; GFX9-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX9-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX9-NEXT: v_log_f32_e32 v4, v4
+; GFX9-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX9-NEXT: v_mov_b32_e32 v8, 0x42800000
+; GFX9-NEXT: v_cvt_f32_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX9-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX9-NEXT: v_mul_legacy_f32_e32 v4, v5, v4
+; GFX9-NEXT: v_mov_b32_e32 v7, 0xc2fc0000
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v4, v7
+; GFX9-NEXT: v_cndmask_b32_e32 v9, 0, v8, vcc
+; GFX9-NEXT: v_add_f32_e32 v4, v4, v9
+; GFX9-NEXT: v_exp_f32_e32 v4, v4
+; GFX9-NEXT: v_not_b32_e32 v9, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v10, 0, v9, vcc
; GFX9-NEXT: v_cvt_f32_f16_sdwa v1, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX9-NEXT: v_cvt_f32_f16_e32 v2, v2
-; GFX9-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v2, v3
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX9-NEXT: v_cvt_f16_f32_e32 v1, v2
+; GFX9-NEXT: v_ldexp_f32 v4, v4, v10
+; GFX9-NEXT: v_trunc_f32_e32 v10, v5
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v10, v5
+; GFX9-NEXT: v_mul_f32_e32 v5, 0.5, v5
+; GFX9-NEXT: v_trunc_f32_e32 v10, v5
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v10, v5
+; GFX9-NEXT: v_bfrev_b32_e32 v5, -2
+; GFX9-NEXT: v_and_b32_e32 v10, 0x80000000, v2
+; GFX9-NEXT: v_and_or_b32 v10, v4, v5, v10
+; GFX9-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX9-NEXT: s_xor_b64 s[8:9], vcc, exec
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v3
+; GFX9-NEXT: v_cndmask_b32_e64 v4, v4, v10, s[4:5]
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v2, 24
+; GFX9-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX9-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX9-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX9-NEXT: v_log_f32_e32 v2, v2
+; GFX9-NEXT: v_cndmask_b32_e32 v6, 0, v6, vcc
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x7fc00000
+; GFX9-NEXT: s_and_b64 s[4:5], s[4:5], s[8:9]
+; GFX9-NEXT: v_sub_f32_e32 v2, v2, v6
+; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v2, v7
+; GFX9-NEXT: v_cndmask_b32_e32 v6, 0, v8, vcc
+; GFX9-NEXT: v_add_f32_e32 v2, v2, v6
+; GFX9-NEXT: v_exp_f32_e32 v2, v2
+; GFX9-NEXT: v_cndmask_b32_e32 v6, 0, v9, vcc
+; GFX9-NEXT: v_cndmask_b32_e64 v4, v4, v3, s[4:5]
+; GFX9-NEXT: v_cvt_f16_f32_e32 v4, v4
+; GFX9-NEXT: v_ldexp_f32 v2, v2, v6
+; GFX9-NEXT: v_trunc_f32_e32 v6, v1
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v6, v1
+; GFX9-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX9-NEXT: v_trunc_f32_e32 v6, v1
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v6, v1
+; GFX9-NEXT: v_and_b32_e32 v1, 0x80000000, v0
+; GFX9-NEXT: v_and_or_b32 v1, v2, v5, v1
+; GFX9-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX9-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX9-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v1, v3, vcc
; GFX9-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX9-NEXT: v_exp_f16_e32 v1, v1
-; GFX9-NEXT: v_exp_f16_e32 v0, v0
-; GFX9-NEXT: v_lshl_or_b32 v0, v0, 16, v1
+; GFX9-NEXT: v_pack_b32_f16 v0, v4, v0
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_v2f16_fneg_lhs:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX10-NEXT: v_xor_b32_e32 v0, 0x80008000, v0
-; GFX10-NEXT: v_cvt_f32_f16_e32 v3, v1
-; GFX10-NEXT: v_cvt_f32_f16_sdwa v1, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX10-NEXT: v_log_f16_e32 v2, v0
-; GFX10-NEXT: v_log_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX10-NEXT: v_cvt_f32_f16_e32 v2, v2
-; GFX10-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX10-NEXT: v_mul_legacy_f32_e32 v2, v2, v3
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX10-NEXT: v_cvt_f16_f32_e32 v1, v2
+; GFX10-NEXT: v_cvt_f32_f16_e32 v7, v1
+; GFX10-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX10-NEXT: v_cvt_f32_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v2|
+; GFX10-NEXT: v_cmp_gt_f32_e64 s5, 0x800000, |v0|
+; GFX10-NEXT: v_cmp_class_f32_e64 s8, v2, 24
+; GFX10-NEXT: v_cmp_class_f32_e64 s9, v0, 24
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 1, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 1, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v5, 0, 0x42000000, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s5
+; GFX10-NEXT: v_lshlrev_b32_e32 v3, 5, v3
+; GFX10-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX10-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX10-NEXT: v_ldexp_f32 v4, |v0|, v4
+; GFX10-NEXT: v_log_f32_e32 v3, v3
+; GFX10-NEXT: v_log_f32_e32 v4, v4
+; GFX10-NEXT: v_sub_f32_e32 v3, v3, v5
+; GFX10-NEXT: v_cvt_f32_f16_sdwa v5, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX10-NEXT: v_sub_f32_e32 v4, v4, v6
+; GFX10-NEXT: v_mov_b32_e32 v6, 0.5
+; GFX10-NEXT: v_mul_legacy_f32_e32 v3, v7, v3
+; GFX10-NEXT: v_mul_legacy_f32_e32 v4, v5, v4
+; GFX10-NEXT: v_fma_mix_f32 v10, v1, v6, neg(0) op_sel_hi:[1,0,0]
+; GFX10-NEXT: v_fma_mix_f32 v1, v1, v6, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v3
+; GFX10-NEXT: v_trunc_f32_e32 v6, v7
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0xc2fc0000, v4
+; GFX10-NEXT: v_trunc_f32_e32 v11, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v8, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cmp_eq_f32_e64 s5, v6, v7
+; GFX10-NEXT: v_cndmask_b32_e64 v9, 0, 0x42800000, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v7, 0, 0xffffffc0, s4
+; GFX10-NEXT: v_add_f32_e32 v3, v3, v8
+; GFX10-NEXT: v_trunc_f32_e32 v8, v10
+; GFX10-NEXT: v_add_f32_e32 v4, v4, v9
+; GFX10-NEXT: v_trunc_f32_e32 v9, v5
+; GFX10-NEXT: v_cmp_lg_f32_e64 s6, v11, v1
+; GFX10-NEXT: v_exp_f32_e32 v3, v3
+; GFX10-NEXT: v_cmp_lg_f32_e32 vcc_lo, v8, v10
+; GFX10-NEXT: v_exp_f32_e32 v4, v4
+; GFX10-NEXT: v_and_b32_e32 v8, 0x80000000, v2
+; GFX10-NEXT: v_cmp_eq_f32_e64 s4, v9, v5
+; GFX10-NEXT: s_xor_b32 s10, s5, exec_lo
+; GFX10-NEXT: s_and_b32 vcc_lo, s5, vcc_lo
+; GFX10-NEXT: s_and_b32 s5, s8, s10
+; GFX10-NEXT: v_ldexp_f32 v2, v3, v6
+; GFX10-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX10-NEXT: v_ldexp_f32 v4, v4, v7
+; GFX10-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v8
+; GFX10-NEXT: v_and_or_b32 v0, 0x7fffffff, v4, v3
+; GFX10-NEXT: v_cndmask_b32_e32 v1, v2, v1, vcc_lo
+; GFX10-NEXT: s_and_b32 vcc_lo, s4, s6
+; GFX10-NEXT: s_xor_b32 s4, s4, exec_lo
+; GFX10-NEXT: v_cndmask_b32_e32 v0, v4, v0, vcc_lo
+; GFX10-NEXT: s_and_b32 s4, s9, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s4
+; GFX10-NEXT: v_cvt_f16_f32_e32 v1, v1
; GFX10-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX10-NEXT: v_exp_f16_e32 v1, v1
-; GFX10-NEXT: v_exp_f16_sdwa v0, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD
-; GFX10-NEXT: v_or_b32_sdwa v0, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
+; GFX10-NEXT: v_pack_b32_f16 v0, v1, v0
; GFX10-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-TRUE16-LABEL: v_pow_v2f16_fneg_lhs:
; GFX11-TRUE16: ; %bb.0:
; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-TRUE16-NEXT: v_xor_b32_e32 v0, 0x80008000, v0
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v2, v1.l
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v7, v1.l
; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v1.h
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
-; GFX11-TRUE16-NEXT: v_log_f16_e32 v0.l, v0.l
-; GFX11-TRUE16-NEXT: v_log_f16_e32 v0.h, v0.h
-; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v3, v0.l
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v2, v0.l
; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.h
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v8, v7
+; GFX11-TRUE16-NEXT: v_mul_f32_e32 v9, 0.5, v1
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v2|
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v0|
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s4, v2, 24
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s5, v0, 24
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v5, 0, 0x42000000, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v4, 0, 1, s1
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v3, 0, 1, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s1
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e64 s1, v8, v7
+; GFX11-TRUE16-NEXT: v_and_b32_e32 v8, 0x80000000, v2
+; GFX11-TRUE16-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX11-TRUE16-NEXT: s_xor_b32 s6, s1, exec_lo
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v4, |v0|, v4
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v4, v4
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_dual_sub_f32 v4, v4, v6 :: v_dual_lshlrev_b32 v3, 5, v3
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v4, v1, v4
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v3, v3
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v4
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_3) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v6, 0, 0x42800000, s0
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_sub_f32_e32 v3, v3, v5
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v2, 0, 0xffffffc0, s0
+; GFX11-TRUE16-NEXT: v_dual_add_f32 v4, v4, v6 :: v_dual_mul_dx9_zero_f32 v3, v7, v3
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v6, v1
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v4, v4
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v3
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v5, 0, 0x42800000, vcc_lo
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v10, 0, 0xffffffc0, vcc_lo
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e32 vcc_lo, v6, v1
+; GFX11-TRUE16-NEXT: v_and_b32_e32 v6, 0x80000000, v0
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v1, v9
+; GFX11-TRUE16-NEXT: v_add_f32_e32 v3, v3, v5
+; GFX11-TRUE16-NEXT: v_mul_f32_e32 v5, 0.5, v7
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(TRANS32_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v2, v4, v2
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e64 s2, v1, v9
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v3, v3
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v7, v5
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v6
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e64 s0, v7, v5
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v3, v3, v10
+; GFX11-TRUE16-NEXT: s_and_b32 s0, s1, s0
+; GFX11-TRUE16-NEXT: s_and_b32 s1, s4, s6
; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-TRUE16-NEXT: v_dual_mul_dx9_zero_f32 v2, v3, v2 :: v_dual_mul_dx9_zero_f32 v1, v0, v1
-; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v2
+; GFX11-TRUE16-NEXT: v_and_or_b32 v0, 0x7fffffff, v3, v8
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v0, v3, v0, s0
+; GFX11-TRUE16-NEXT: s_and_b32 s0, vcc_lo, s2
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v1, v2, v1, s0
+; GFX11-TRUE16-NEXT: s_xor_b32 s0, vcc_lo, exec_lo
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s1
+; GFX11-TRUE16-NEXT: s_and_b32 s0, s5, s0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instid1(SALU_CYCLE_1)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s0
; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v0
; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.h, v1
-; GFX11-TRUE16-NEXT: v_exp_f16_e32 v0.l, v0.l
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
-; GFX11-TRUE16-NEXT: v_exp_f16_e32 v0.h, v0.h
; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-FAKE16-LABEL: v_pow_v2f16_fneg_lhs:
; GFX11-FAKE16: ; %bb.0:
; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-FAKE16-NEXT: v_xor_b32_e32 v0, 0x80008000, v0
-; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v3, 16, v1
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v1, v1
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v6, v1
+; GFX11-FAKE16-NEXT: v_mov_b32_e32 v8, 0.5
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_3)
-; GFX11-FAKE16-NEXT: v_log_f16_e32 v2, v0
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v2, v0
; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v0, 16, v0
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v3, v3
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_3) | instid1(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_log_f16_e32 v0, v0
-; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v2, v2
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v9, v1, v8, neg(0) op_sel_hi:[1,0,0]
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v2|
; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX11-FAKE16-NEXT: v_dual_mul_dx9_zero_f32 v1, v2, v1 :: v_dual_mul_dx9_zero_f32 v0, v0, v3
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v5, 0, 0x42000000, s0
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v0|
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v3, 0, 1, s0
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s5, v0, 24
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v4, 0, 1, s1
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v7, 0, 0x42000000, s1
+; GFX11-FAKE16-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v4, |v0|, v4
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v4, v4
+; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX11-FAKE16-NEXT: v_lshlrev_b32_e32 v3, 5, v3
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v3, v3
+; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_sub_f32_e32 v3, v3, v5
+; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v5, 16, v1
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v1, v1, v8, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v8, v9
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
+; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v3, v6, v3
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v5, v5
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v11, v1
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v3
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v4, v5, v4
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e64 s1, v11, v1
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v7, 0, 0x42800000, vcc_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v4
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v10, 0, 0xffffffc0, vcc_lo
+; GFX11-FAKE16-NEXT: v_add_f32_e32 v3, v3, v7
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v7, 0, 0x42800000, s0
+; GFX11-FAKE16-NEXT: v_add_f32_e32 v4, v4, v7
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v7, v6
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v4, v4
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e32 vcc_lo, v7, v6
+; GFX11-FAKE16-NEXT: v_and_b32_e32 v6, 0x80000000, v2
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v3, v3
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v7, 0, 0xffffffc0, s0
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e64 s0, v8, v9
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v8, v5
+; GFX11-FAKE16-NEXT: v_and_b32_e32 v9, 0x80000000, v0
+; GFX11-FAKE16-NEXT: s_xor_b32 s4, vcc_lo, exec_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(TRANS32_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v4, v4, v7
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e64 s2, v8, v5
+; GFX11-FAKE16-NEXT: s_and_b32 s0, vcc_lo, s0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(TRANS32_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v3, v3, v10
+; GFX11-FAKE16-NEXT: s_and_b32 vcc_lo, s2, s1
+; GFX11-FAKE16-NEXT: s_xor_b32 s1, s2, exec_lo
+; GFX11-FAKE16-NEXT: v_and_or_b32 v6, 0x7fffffff, v3, v6
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v1, v3, v6, s0
+; GFX11-FAKE16-NEXT: v_and_or_b32 v3, 0x7fffffff, v4, v9
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s0, v2, 24
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e32 v0, v4, v3, vcc_lo
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s0, s4
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s0
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s5, s1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instid1(SALU_CYCLE_1)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v1, v1
; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_exp_f16_e32 v1, v1
-; GFX11-FAKE16-NEXT: v_exp_f16_e32 v0, v0
-; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_and_b32_e32 v1, 0xffff, v1
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_lshl_or_b32 v0, v0, 16, v1
+; GFX11-FAKE16-NEXT: v_pack_b32_f16 v0, v1, v0
; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
%x.fneg = fneg <2 x half> %x
%pow = call <2 x half> @llvm.pow.v2f16(<2 x half> %x.fneg, <2 x half> %y)
@@ -701,35 +1742,78 @@ define <2 x half> @v_pow_v2f16_fneg_rhs(<2 x half> %x, <2 x half> %y) {
; GFX6: ; %bb.0:
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX6-NEXT: v_cvt_f32_f16_e32 v2, v0
-; GFX6-NEXT: v_lshrrev_b32_e32 v0, 16, v0
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x800000
; GFX6-NEXT: v_xor_b32_e32 v1, 0x80008000, v1
+; GFX6-NEXT: v_cvt_f32_f16_e32 v5, v1
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, v3
+; GFX6-NEXT: v_cndmask_b32_e64 v4, 0, 1, vcc
+; GFX6-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX6-NEXT: v_ldexp_f32_e64 v4, |v2|, v4
+; GFX6-NEXT: v_log_f32_e32 v4, v4
+; GFX6-NEXT: v_mov_b32_e32 v6, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX6-NEXT: v_mov_b32_e32 v8, 0x42800000
+; GFX6-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX6-NEXT: v_mul_legacy_f32_e32 v4, v5, v4
+; GFX6-NEXT: v_mov_b32_e32 v7, 0xc2fc0000
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v4, v7
+; GFX6-NEXT: v_cndmask_b32_e32 v9, 0, v8, vcc
+; GFX6-NEXT: v_add_f32_e32 v4, v4, v9
+; GFX6-NEXT: v_exp_f32_e32 v4, v4
+; GFX6-NEXT: v_not_b32_e32 v9, 63
+; GFX6-NEXT: v_lshrrev_b32_e32 v0, 16, v0
+; GFX6-NEXT: v_cndmask_b32_e32 v10, 0, v9, vcc
+; GFX6-NEXT: v_ldexp_f32_e32 v4, v4, v10
+; GFX6-NEXT: v_trunc_f32_e32 v10, v5
; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX6-NEXT: v_cvt_f32_f16_e32 v3, v1
-; GFX6-NEXT: v_log_f32_e32 v2, v2
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v10, v5
+; GFX6-NEXT: v_mul_f32_e32 v5, 0.5, v5
+; GFX6-NEXT: v_trunc_f32_e32 v10, v5
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v10, v5
+; GFX6-NEXT: v_and_b32_e32 v5, 0x7fffffff, v4
+; GFX6-NEXT: v_and_b32_e32 v10, 0x80000000, v2
+; GFX6-NEXT: v_or_b32_e32 v5, v5, v10
+; GFX6-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX6-NEXT: s_xor_b64 s[8:9], vcc, exec
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v3
+; GFX6-NEXT: v_cndmask_b32_e64 v4, v4, v5, s[4:5]
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v2, 24
+; GFX6-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX6-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX6-NEXT: v_ldexp_f32_e64 v2, |v0|, v2
; GFX6-NEXT: v_lshrrev_b32_e32 v1, 16, v1
+; GFX6-NEXT: v_log_f32_e32 v2, v2
; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_mov_b32_e32 v4, 0xc2fc0000
-; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v2, v3
-; GFX6-NEXT: v_mov_b32_e32 v3, 0x42800000
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v2, v4
-; GFX6-NEXT: v_cndmask_b32_e32 v5, 0, v3, vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v5, 0, v6, vcc
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x7fc00000
+; GFX6-NEXT: v_sub_f32_e32 v2, v2, v5
+; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v2, v7
+; GFX6-NEXT: v_cndmask_b32_e32 v5, 0, v8, vcc
; GFX6-NEXT: v_add_f32_e32 v2, v2, v5
-; GFX6-NEXT: v_not_b32_e32 v5, 63
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v4
-; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v3, vcc
; GFX6-NEXT: v_exp_f32_e32 v2, v2
-; GFX6-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
-; GFX6-NEXT: v_ldexp_f32_e32 v1, v2, v6
-; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v5, vcc
-; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v2
+; GFX6-NEXT: v_cndmask_b32_e32 v5, 0, v9, vcc
+; GFX6-NEXT: s_and_b64 s[4:5], s[4:5], s[8:9]
+; GFX6-NEXT: v_cndmask_b32_e64 v4, v4, v3, s[4:5]
+; GFX6-NEXT: v_ldexp_f32_e32 v2, v2, v5
+; GFX6-NEXT: v_trunc_f32_e32 v5, v1
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v5, v1
+; GFX6-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX6-NEXT: v_trunc_f32_e32 v5, v1
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v5, v1
+; GFX6-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX6-NEXT: v_and_b32_e32 v5, 0x80000000, v0
+; GFX6-NEXT: v_or_b32_e32 v1, v1, v5
+; GFX6-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX6-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v1, v3, vcc
; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX6-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX6-NEXT: v_cvt_f16_f32_e32 v4, v4
; GFX6-NEXT: v_bfe_u32 v0, v0, 0, 16
-; GFX6-NEXT: v_bfe_u32 v1, v1, 0, 16
+; GFX6-NEXT: v_bfe_u32 v1, v4, 0, 16
; GFX6-NEXT: v_lshlrev_b32_e32 v0, 16, v0
; GFX6-NEXT: v_or_b32_e32 v0, v1, v0
; GFX6-NEXT: s_setpc_b64 s[30:31]
@@ -737,20 +1821,76 @@ define <2 x half> @v_pow_v2f16_fneg_rhs(<2 x half> %x, <2 x half> %y) {
; GFX8-LABEL: v_pow_v2f16_fneg_rhs:
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX8-NEXT: v_log_f16_e32 v2, v0
-; GFX8-NEXT: v_log_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX8-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x800000
; GFX8-NEXT: v_xor_b32_e32 v1, 0x80008000, v1
-; GFX8-NEXT: v_cvt_f32_f16_e32 v3, v1
+; GFX8-NEXT: v_cvt_f32_f16_e32 v5, v1
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, v3
+; GFX8-NEXT: v_cndmask_b32_e64 v4, 0, 1, vcc
+; GFX8-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX8-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX8-NEXT: v_log_f32_e32 v4, v4
+; GFX8-NEXT: v_mov_b32_e32 v6, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX8-NEXT: v_mov_b32_e32 v8, 0x42800000
+; GFX8-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX8-NEXT: v_mul_legacy_f32_e32 v4, v5, v4
+; GFX8-NEXT: v_mov_b32_e32 v7, 0xc2fc0000
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v4, v7
+; GFX8-NEXT: v_cndmask_b32_e32 v9, 0, v8, vcc
+; GFX8-NEXT: v_add_f32_e32 v4, v4, v9
+; GFX8-NEXT: v_exp_f32_e32 v4, v4
+; GFX8-NEXT: v_not_b32_e32 v9, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v10, 0, v9, vcc
+; GFX8-NEXT: v_cvt_f32_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX8-NEXT: v_ldexp_f32 v4, v4, v10
+; GFX8-NEXT: v_trunc_f32_e32 v10, v5
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v10, v5
+; GFX8-NEXT: v_mul_f32_e32 v5, 0.5, v5
+; GFX8-NEXT: v_trunc_f32_e32 v10, v5
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v10, v5
+; GFX8-NEXT: v_and_b32_e32 v5, 0x7fffffff, v4
+; GFX8-NEXT: v_and_b32_e32 v10, 0x80000000, v2
+; GFX8-NEXT: v_or_b32_e32 v5, v5, v10
+; GFX8-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX8-NEXT: s_xor_b64 s[8:9], vcc, exec
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v3
+; GFX8-NEXT: v_cndmask_b32_e64 v4, v4, v5, s[4:5]
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v2, 24
+; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX8-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX8-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX8-NEXT: v_log_f32_e32 v2, v2
; GFX8-NEXT: v_cvt_f32_f16_sdwa v1, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX8-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX8-NEXT: v_cvt_f32_f16_e32 v2, v2
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v5, 0, v6, vcc
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x7fc00000
+; GFX8-NEXT: v_sub_f32_e32 v2, v2, v5
+; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v2, v7
+; GFX8-NEXT: v_cndmask_b32_e32 v5, 0, v8, vcc
+; GFX8-NEXT: v_add_f32_e32 v2, v2, v5
+; GFX8-NEXT: v_exp_f32_e32 v2, v2
+; GFX8-NEXT: v_cndmask_b32_e32 v5, 0, v9, vcc
+; GFX8-NEXT: s_and_b64 s[4:5], s[4:5], s[8:9]
+; GFX8-NEXT: v_cndmask_b32_e64 v4, v4, v3, s[4:5]
+; GFX8-NEXT: v_ldexp_f32 v2, v2, v5
+; GFX8-NEXT: v_trunc_f32_e32 v5, v1
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v5, v1
+; GFX8-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v5, v1
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v5, v1
+; GFX8-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX8-NEXT: v_and_b32_e32 v5, 0x80000000, v0
+; GFX8-NEXT: v_or_b32_e32 v1, v1, v5
+; GFX8-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX8-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v1, v3, vcc
; GFX8-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX8-NEXT: v_cvt_f16_f32_e32 v1, v2
+; GFX8-NEXT: v_cvt_f16_f32_e32 v1, v4
; GFX8-NEXT: v_mov_b32_e32 v2, 16
-; GFX8-NEXT: v_exp_f16_e32 v0, v0
-; GFX8-NEXT: v_exp_f16_e32 v1, v1
; GFX8-NEXT: v_lshlrev_b32_sdwa v0, v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
; GFX8-NEXT: v_or_b32_sdwa v0, v1, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
; GFX8-NEXT: s_setpc_b64 s[30:31]
@@ -758,88 +1898,309 @@ define <2 x half> @v_pow_v2f16_fneg_rhs(<2 x half> %x, <2 x half> %y) {
; GFX9-LABEL: v_pow_v2f16_fneg_rhs:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT: v_log_f16_e32 v2, v0
-; GFX9-NEXT: v_log_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX9-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x800000
; GFX9-NEXT: v_xor_b32_e32 v1, 0x80008000, v1
-; GFX9-NEXT: v_cvt_f32_f16_e32 v3, v1
-; GFX9-NEXT: v_cvt_f32_f16_e32 v2, v2
+; GFX9-NEXT: v_cvt_f32_f16_e32 v5, v1
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, v3
+; GFX9-NEXT: v_cndmask_b32_e64 v4, 0, 1, vcc
+; GFX9-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX9-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX9-NEXT: v_log_f32_e32 v4, v4
+; GFX9-NEXT: v_mov_b32_e32 v6, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX9-NEXT: v_mov_b32_e32 v8, 0x42800000
+; GFX9-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX9-NEXT: v_mul_legacy_f32_e32 v4, v5, v4
+; GFX9-NEXT: v_mov_b32_e32 v7, 0xc2fc0000
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v4, v7
+; GFX9-NEXT: v_cndmask_b32_e32 v9, 0, v8, vcc
+; GFX9-NEXT: v_add_f32_e32 v4, v4, v9
+; GFX9-NEXT: v_exp_f32_e32 v4, v4
+; GFX9-NEXT: v_not_b32_e32 v9, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v10, 0, v9, vcc
+; GFX9-NEXT: v_cvt_f32_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX9-NEXT: v_ldexp_f32 v4, v4, v10
+; GFX9-NEXT: v_trunc_f32_e32 v10, v5
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v10, v5
+; GFX9-NEXT: v_mul_f32_e32 v5, 0.5, v5
+; GFX9-NEXT: v_trunc_f32_e32 v10, v5
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v10, v5
+; GFX9-NEXT: v_bfrev_b32_e32 v5, -2
+; GFX9-NEXT: v_and_b32_e32 v10, 0x80000000, v2
+; GFX9-NEXT: v_and_or_b32 v10, v4, v5, v10
+; GFX9-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX9-NEXT: s_xor_b64 s[8:9], vcc, exec
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v3
+; GFX9-NEXT: v_cndmask_b32_e64 v4, v4, v10, s[4:5]
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v2, 24
+; GFX9-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX9-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX9-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX9-NEXT: v_log_f32_e32 v2, v2
; GFX9-NEXT: v_cvt_f32_f16_sdwa v1, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX9-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v2, v3
-; GFX9-NEXT: v_cvt_f16_f32_e32 v2, v2
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
+; GFX9-NEXT: v_cndmask_b32_e32 v6, 0, v6, vcc
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x7fc00000
+; GFX9-NEXT: v_sub_f32_e32 v2, v2, v6
+; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v2, v7
+; GFX9-NEXT: v_cndmask_b32_e32 v6, 0, v8, vcc
+; GFX9-NEXT: v_add_f32_e32 v2, v2, v6
+; GFX9-NEXT: v_exp_f32_e32 v2, v2
+; GFX9-NEXT: v_cndmask_b32_e32 v6, 0, v9, vcc
+; GFX9-NEXT: s_and_b64 s[4:5], s[4:5], s[8:9]
+; GFX9-NEXT: v_cndmask_b32_e64 v4, v4, v3, s[4:5]
+; GFX9-NEXT: v_ldexp_f32 v2, v2, v6
+; GFX9-NEXT: v_trunc_f32_e32 v6, v1
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v6, v1
+; GFX9-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX9-NEXT: v_trunc_f32_e32 v6, v1
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v6, v1
+; GFX9-NEXT: v_and_b32_e32 v1, 0x80000000, v0
+; GFX9-NEXT: v_and_or_b32 v1, v2, v5, v1
+; GFX9-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX9-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX9-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v1, v3, vcc
+; GFX9-NEXT: v_cvt_f16_f32_e32 v4, v4
; GFX9-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX9-NEXT: v_exp_f16_e32 v1, v2
-; GFX9-NEXT: v_exp_f16_e32 v0, v0
-; GFX9-NEXT: v_lshl_or_b32 v0, v0, 16, v1
+; GFX9-NEXT: v_pack_b32_f16 v0, v4, v0
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_v2f16_fneg_rhs:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_log_f16_e32 v2, v0
-; GFX10-NEXT: v_log_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX10-NEXT: v_xor_b32_e32 v1, 0x80008000, v1
-; GFX10-NEXT: v_cvt_f32_f16_e32 v3, v1
-; GFX10-NEXT: v_cvt_f32_f16_sdwa v1, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX10-NEXT: v_cvt_f32_f16_e32 v2, v2
-; GFX10-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX10-NEXT: v_mul_legacy_f32_e32 v2, v2, v3
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX10-NEXT: v_cvt_f16_f32_e32 v1, v2
+; GFX10-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX10-NEXT: v_cvt_f32_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX10-NEXT: v_xor_b32_e32 v5, 0x80008000, v1
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v2|
+; GFX10-NEXT: v_cmp_gt_f32_e64 s5, 0x800000, |v0|
+; GFX10-NEXT: v_cvt_f32_f16_e32 v8, v5
+; GFX10-NEXT: v_cmp_class_f32_e64 s8, v2, 24
+; GFX10-NEXT: v_cmp_class_f32_e64 s9, v0, 24
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 1, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 1, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v7, 0, 0x42000000, s5
+; GFX10-NEXT: v_lshlrev_b32_e32 v3, 5, v3
+; GFX10-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX10-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX10-NEXT: v_ldexp_f32 v4, |v0|, v4
+; GFX10-NEXT: v_log_f32_e32 v3, v3
+; GFX10-NEXT: v_log_f32_e32 v4, v4
+; GFX10-NEXT: v_sub_f32_e32 v3, v3, v6
+; GFX10-NEXT: v_cvt_f32_f16_sdwa v6, v5 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX10-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX10-NEXT: v_mov_b32_e32 v7, 0.5
+; GFX10-NEXT: v_mul_legacy_f32_e32 v3, v8, v3
+; GFX10-NEXT: v_trunc_f32_e32 v13, v6
+; GFX10-NEXT: v_mul_legacy_f32_e32 v4, v6, v4
+; GFX10-NEXT: v_fma_mix_f32 v1, -v1, v7, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX10-NEXT: v_fma_mix_f32 v5, v5, v7, neg(0) op_sel_hi:[1,0,0]
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v3
+; GFX10-NEXT: v_and_b32_e32 v7, 0x80000000, v2
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0xc2fc0000, v4
+; GFX10-NEXT: v_cmp_eq_f32_e64 s6, v13, v6
+; GFX10-NEXT: v_trunc_f32_e32 v12, v5
+; GFX10-NEXT: v_cndmask_b32_e64 v9, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v10, 0, 0x42800000, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v11, 0, 0xffffffc0, s4
+; GFX10-NEXT: v_cmp_lg_f32_e64 s5, v12, v5
+; GFX10-NEXT: v_add_f32_e32 v3, v3, v9
+; GFX10-NEXT: v_and_b32_e32 v9, 0x80000000, v0
+; GFX10-NEXT: v_add_f32_e32 v4, v4, v10
+; GFX10-NEXT: v_cndmask_b32_e64 v0, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_trunc_f32_e32 v10, v8
+; GFX10-NEXT: v_exp_f32_e32 v2, v3
+; GFX10-NEXT: v_trunc_f32_e32 v3, v1
+; GFX10-NEXT: v_exp_f32_e32 v4, v4
+; GFX10-NEXT: v_cmp_eq_f32_e64 s4, v10, v8
+; GFX10-NEXT: v_cmp_lg_f32_e32 vcc_lo, v3, v1
+; GFX10-NEXT: s_xor_b32 s10, s4, exec_lo
+; GFX10-NEXT: v_ldexp_f32 v0, v2, v0
+; GFX10-NEXT: s_and_b32 s4, s4, s5
+; GFX10-NEXT: v_ldexp_f32 v1, v4, v11
+; GFX10-NEXT: s_and_b32 vcc_lo, s6, vcc_lo
+; GFX10-NEXT: s_and_b32 s5, s8, s10
+; GFX10-NEXT: v_and_or_b32 v2, 0x7fffffff, v0, v7
+; GFX10-NEXT: v_and_or_b32 v3, 0x7fffffff, v1, v9
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, v2, s4
+; GFX10-NEXT: s_xor_b32 s4, s6, exec_lo
+; GFX10-NEXT: v_cndmask_b32_e32 v1, v1, v3, vcc_lo
+; GFX10-NEXT: s_and_b32 s4, s9, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s4
; GFX10-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX10-NEXT: v_exp_f16_e32 v1, v1
-; GFX10-NEXT: v_exp_f16_sdwa v0, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD
-; GFX10-NEXT: v_or_b32_sdwa v0, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
+; GFX10-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX10-NEXT: v_pack_b32_f16 v0, v0, v1
; GFX10-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-TRUE16-LABEL: v_pow_v2f16_fneg_rhs:
; GFX11-TRUE16: ; %bb.0:
; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-TRUE16-NEXT: v_log_f16_e32 v0.l, v0.l
-; GFX11-TRUE16-NEXT: v_log_f16_e32 v0.h, v0.h
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v2, v0.l
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.h
; GFX11-TRUE16-NEXT: v_xor_b32_e32 v1, 0x80008000, v1
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v2, v1.l
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v2|
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v0|
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v7, v1.l
; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v1.h
-; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v3, v0.l
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.h
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s4, v2, 24
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v5, 0, 0x42000000, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v4, 0, 1, s1
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v3, 0, 1, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s1
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s5, v0, 24
+; GFX11-TRUE16-NEXT: v_mul_f32_e32 v10, 0.5, v1
+; GFX11-TRUE16-NEXT: v_lshlrev_b32_e32 v4, 5, v4
; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-TRUE16-NEXT: v_dual_mul_dx9_zero_f32 v2, v3, v2 :: v_dual_mul_dx9_zero_f32 v1, v0, v1
-; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v2
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v4, |v0|, v4
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v4, v4
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_dual_sub_f32 v4, v4, v6 :: v_dual_lshlrev_b32 v3, 5, v3
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v4, v1, v4
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v3, v3
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v4
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_3) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v6, 0, 0x42800000, s0
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_sub_f32_e32 v3, v3, v5
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v11, 0, 0xffffffc0, s0
+; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v3, v7, v3
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v3
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v5, 0, 0x42800000, vcc_lo
+; GFX11-TRUE16-NEXT: v_and_b32_e32 v8, 0x80000000, v2
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v9, 0, 0xffffffc0, vcc_lo
+; GFX11-TRUE16-NEXT: v_add_f32_e32 v2, v4, v6
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v6, v1
+; GFX11-TRUE16-NEXT: v_add_f32_e32 v3, v3, v5
+; GFX11-TRUE16-NEXT: v_mul_f32_e32 v5, 0.5, v7
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v2, v2
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e64 s0, v6, v1
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v2, v2, v11
+; GFX11-TRUE16-NEXT: v_and_b32_e32 v4, 0x80000000, v0
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v0, v3
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v3, v7
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e32 vcc_lo, v3, v7
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v3, v5
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v7, v10
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v0, v0, v9
+; GFX11-TRUE16-NEXT: s_xor_b32 s6, vcc_lo, exec_lo
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e64 s1, v3, v5
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e64 s2, v7, v10
+; GFX11-TRUE16-NEXT: v_and_or_b32 v3, 0x7fffffff, v2, v4
+; GFX11-TRUE16-NEXT: v_and_or_b32 v1, 0x7fffffff, v0, v8
+; GFX11-TRUE16-NEXT: s_and_b32 vcc_lo, vcc_lo, s1
+; GFX11-TRUE16-NEXT: s_and_b32 s1, s4, s6
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc_lo
+; GFX11-TRUE16-NEXT: s_and_b32 vcc_lo, s0, s2
+; GFX11-TRUE16-NEXT: s_xor_b32 s0, s0, exec_lo
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e32 v1, v2, v3, vcc_lo
+; GFX11-TRUE16-NEXT: s_and_b32 s0, s5, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s1
; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s0
+; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2)
; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.h, v1
-; GFX11-TRUE16-NEXT: v_exp_f16_e32 v0.l, v0.l
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
-; GFX11-TRUE16-NEXT: v_exp_f16_e32 v0.h, v0.h
; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-FAKE16-LABEL: v_pow_v2f16_fneg_rhs:
; GFX11-FAKE16: ; %bb.0:
; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-FAKE16-NEXT: v_log_f16_e32 v2, v0
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v2, v0
; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v0, 16, v0
-; GFX11-FAKE16-NEXT: v_xor_b32_e32 v1, 0x80008000, v1
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_log_f16_e32 v0, v0
-; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v3, 16, v1
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v2, v2
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v3, v3
+; GFX11-FAKE16-NEXT: v_xor_b32_e32 v5, 0x80008000, v1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v2|
; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v7, v5
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_4)
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v0|
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v3, 0, 1, s0
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v11, v7
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s5, v0, 24
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v4, 0, 1, s1
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v8, 0, 0x42000000, s1
+; GFX11-FAKE16-NEXT: v_lshlrev_b32_e32 v4, 5, v4
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_dual_mul_dx9_zero_f32 v1, v2, v1 :: v_dual_mul_dx9_zero_f32 v0, v0, v3
-; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v4, |v0|, v4
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v4, v4
+; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_dual_sub_f32 v4, v4, v8 :: v_dual_lshlrev_b32 v3, 5, v3
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v3, v3
+; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_sub_f32_e32 v3, v3, v6
+; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v6, 16, v5
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v6, v6
+; GFX11-FAKE16-NEXT: v_dual_mul_dx9_zero_f32 v3, v7, v3 :: v_dual_mul_dx9_zero_f32 v4, v6, v4
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v3
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v4
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v8, 0, 0x42800000, vcc_lo
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v10, 0, 0xffffffc0, vcc_lo
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e32 vcc_lo, v11, v7
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v7, v6
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(SKIP_2) | instid1(VALU_DEP_4)
+; GFX11-FAKE16-NEXT: v_add_f32_e32 v3, v3, v8
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v8, 0, 0x42800000, s0
+; GFX11-FAKE16-NEXT: v_mov_b32_e32 v9, 0.5
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e64 s2, v7, v6
+; GFX11-FAKE16-NEXT: s_xor_b32 s4, vcc_lo, exec_lo
+; GFX11-FAKE16-NEXT: v_add_f32_e32 v4, v4, v8
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v1, -v1, v9, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v5, v5, v9, neg(0) op_sel_hi:[1,0,0]
+; GFX11-FAKE16-NEXT: v_and_b32_e32 v8, 0x80000000, v2
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v3, v3
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v4, v4
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v9, v1
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v12, v5
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_4) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e64 s1, v9, v1
+; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v3, v3, v10
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v10, 0, 0xffffffc0, s0
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e64 s0, v12, v5
+; GFX11-FAKE16-NEXT: v_and_or_b32 v5, 0x7fffffff, v3, v8
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v4, v4, v10
+; GFX11-FAKE16-NEXT: s_and_b32 s0, vcc_lo, s0
+; GFX11-FAKE16-NEXT: s_and_b32 vcc_lo, s2, s1
+; GFX11-FAKE16-NEXT: v_and_b32_e32 v13, 0x80000000, v0
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v1, v3, v5, s0
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s0, v2, 24
+; GFX11-FAKE16-NEXT: s_xor_b32 s1, s2, exec_lo
+; GFX11-FAKE16-NEXT: v_and_or_b32 v3, 0x7fffffff, v4, v13
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s0, s4
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s0
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e32 v0, v4, v3, vcc_lo
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s5, s1
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX11-FAKE16-NEXT: v_exp_f16_e32 v1, v1
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_exp_f16_e32 v0, v0
-; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_and_b32_e32 v1, 0xffff, v1
-; GFX11-FAKE16-NEXT: v_lshl_or_b32 v0, v0, 16, v1
+; GFX11-FAKE16-NEXT: v_pack_b32_f16 v0, v1, v0
; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
%y.fneg = fneg <2 x half> %y
%pow = call <2 x half> @llvm.pow.v2f16(<2 x half> %x, <2 x half> %y.fneg)
@@ -852,35 +2213,78 @@ define <2 x half> @v_pow_v2f16_fneg_lhs_rhs(<2 x half> %x, <2 x half> %y) {
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX6-NEXT: v_xor_b32_e32 v0, 0x80008000, v0
; GFX6-NEXT: v_cvt_f32_f16_e32 v2, v0
-; GFX6-NEXT: v_lshrrev_b32_e32 v0, 16, v0
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x800000
; GFX6-NEXT: v_xor_b32_e32 v1, 0x80008000, v1
+; GFX6-NEXT: v_cvt_f32_f16_e32 v5, v1
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, v3
+; GFX6-NEXT: v_cndmask_b32_e64 v4, 0, 1, vcc
+; GFX6-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX6-NEXT: v_ldexp_f32_e64 v4, |v2|, v4
+; GFX6-NEXT: v_log_f32_e32 v4, v4
+; GFX6-NEXT: v_mov_b32_e32 v6, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX6-NEXT: v_mov_b32_e32 v8, 0x42800000
+; GFX6-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX6-NEXT: v_mul_legacy_f32_e32 v4, v5, v4
+; GFX6-NEXT: v_mov_b32_e32 v7, 0xc2fc0000
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v4, v7
+; GFX6-NEXT: v_cndmask_b32_e32 v9, 0, v8, vcc
+; GFX6-NEXT: v_add_f32_e32 v4, v4, v9
+; GFX6-NEXT: v_exp_f32_e32 v4, v4
+; GFX6-NEXT: v_not_b32_e32 v9, 63
+; GFX6-NEXT: v_lshrrev_b32_e32 v0, 16, v0
+; GFX6-NEXT: v_cndmask_b32_e32 v10, 0, v9, vcc
+; GFX6-NEXT: v_ldexp_f32_e32 v4, v4, v10
+; GFX6-NEXT: v_trunc_f32_e32 v10, v5
; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX6-NEXT: v_cvt_f32_f16_e32 v3, v1
-; GFX6-NEXT: v_log_f32_e32 v2, v2
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v10, v5
+; GFX6-NEXT: v_mul_f32_e32 v5, 0.5, v5
+; GFX6-NEXT: v_trunc_f32_e32 v10, v5
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v10, v5
+; GFX6-NEXT: v_and_b32_e32 v5, 0x7fffffff, v4
+; GFX6-NEXT: v_and_b32_e32 v10, 0x80000000, v2
+; GFX6-NEXT: v_or_b32_e32 v5, v5, v10
+; GFX6-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX6-NEXT: s_xor_b64 s[8:9], vcc, exec
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v3
+; GFX6-NEXT: v_cndmask_b32_e64 v4, v4, v5, s[4:5]
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v2, 24
+; GFX6-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX6-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX6-NEXT: v_ldexp_f32_e64 v2, |v0|, v2
; GFX6-NEXT: v_lshrrev_b32_e32 v1, 16, v1
+; GFX6-NEXT: v_log_f32_e32 v2, v2
; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_mov_b32_e32 v4, 0xc2fc0000
-; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v2, v3
-; GFX6-NEXT: v_mov_b32_e32 v3, 0x42800000
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v2, v4
-; GFX6-NEXT: v_cndmask_b32_e32 v5, 0, v3, vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v5, 0, v6, vcc
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x7fc00000
+; GFX6-NEXT: v_sub_f32_e32 v2, v2, v5
+; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v2, v7
+; GFX6-NEXT: v_cndmask_b32_e32 v5, 0, v8, vcc
; GFX6-NEXT: v_add_f32_e32 v2, v2, v5
-; GFX6-NEXT: v_not_b32_e32 v5, 63
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v4
-; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v3, vcc
; GFX6-NEXT: v_exp_f32_e32 v2, v2
-; GFX6-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
-; GFX6-NEXT: v_ldexp_f32_e32 v1, v2, v6
-; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v5, vcc
-; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v2
+; GFX6-NEXT: v_cndmask_b32_e32 v5, 0, v9, vcc
+; GFX6-NEXT: s_and_b64 s[4:5], s[4:5], s[8:9]
+; GFX6-NEXT: v_cndmask_b32_e64 v4, v4, v3, s[4:5]
+; GFX6-NEXT: v_ldexp_f32_e32 v2, v2, v5
+; GFX6-NEXT: v_trunc_f32_e32 v5, v1
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v5, v1
+; GFX6-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX6-NEXT: v_trunc_f32_e32 v5, v1
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v5, v1
+; GFX6-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX6-NEXT: v_and_b32_e32 v5, 0x80000000, v0
+; GFX6-NEXT: v_or_b32_e32 v1, v1, v5
+; GFX6-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX6-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v1, v3, vcc
; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX6-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX6-NEXT: v_cvt_f16_f32_e32 v4, v4
; GFX6-NEXT: v_bfe_u32 v0, v0, 0, 16
-; GFX6-NEXT: v_bfe_u32 v1, v1, 0, 16
+; GFX6-NEXT: v_bfe_u32 v1, v4, 0, 16
; GFX6-NEXT: v_lshlrev_b32_e32 v0, 16, v0
; GFX6-NEXT: v_or_b32_e32 v0, v1, v0
; GFX6-NEXT: s_setpc_b64 s[30:31]
@@ -889,20 +2293,76 @@ define <2 x half> @v_pow_v2f16_fneg_lhs_rhs(<2 x half> %x, <2 x half> %y) {
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX8-NEXT: v_xor_b32_e32 v0, 0x80008000, v0
-; GFX8-NEXT: v_log_f16_e32 v2, v0
-; GFX8-NEXT: v_log_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX8-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x800000
; GFX8-NEXT: v_xor_b32_e32 v1, 0x80008000, v1
-; GFX8-NEXT: v_cvt_f32_f16_e32 v3, v1
+; GFX8-NEXT: v_cvt_f32_f16_e32 v5, v1
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, v3
+; GFX8-NEXT: v_cndmask_b32_e64 v4, 0, 1, vcc
+; GFX8-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX8-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX8-NEXT: v_log_f32_e32 v4, v4
+; GFX8-NEXT: v_mov_b32_e32 v6, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX8-NEXT: v_mov_b32_e32 v8, 0x42800000
+; GFX8-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX8-NEXT: v_mul_legacy_f32_e32 v4, v5, v4
+; GFX8-NEXT: v_mov_b32_e32 v7, 0xc2fc0000
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v4, v7
+; GFX8-NEXT: v_cndmask_b32_e32 v9, 0, v8, vcc
+; GFX8-NEXT: v_add_f32_e32 v4, v4, v9
+; GFX8-NEXT: v_exp_f32_e32 v4, v4
+; GFX8-NEXT: v_not_b32_e32 v9, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v10, 0, v9, vcc
+; GFX8-NEXT: v_cvt_f32_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX8-NEXT: v_ldexp_f32 v4, v4, v10
+; GFX8-NEXT: v_trunc_f32_e32 v10, v5
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v10, v5
+; GFX8-NEXT: v_mul_f32_e32 v5, 0.5, v5
+; GFX8-NEXT: v_trunc_f32_e32 v10, v5
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v10, v5
+; GFX8-NEXT: v_and_b32_e32 v5, 0x7fffffff, v4
+; GFX8-NEXT: v_and_b32_e32 v10, 0x80000000, v2
+; GFX8-NEXT: v_or_b32_e32 v5, v5, v10
+; GFX8-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX8-NEXT: s_xor_b64 s[8:9], vcc, exec
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v3
+; GFX8-NEXT: v_cndmask_b32_e64 v4, v4, v5, s[4:5]
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v2, 24
+; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX8-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX8-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX8-NEXT: v_log_f32_e32 v2, v2
; GFX8-NEXT: v_cvt_f32_f16_sdwa v1, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX8-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX8-NEXT: v_cvt_f32_f16_e32 v2, v2
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v5, 0, v6, vcc
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x7fc00000
+; GFX8-NEXT: v_sub_f32_e32 v2, v2, v5
+; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v2, v7
+; GFX8-NEXT: v_cndmask_b32_e32 v5, 0, v8, vcc
+; GFX8-NEXT: v_add_f32_e32 v2, v2, v5
+; GFX8-NEXT: v_exp_f32_e32 v2, v2
+; GFX8-NEXT: v_cndmask_b32_e32 v5, 0, v9, vcc
+; GFX8-NEXT: s_and_b64 s[4:5], s[4:5], s[8:9]
+; GFX8-NEXT: v_cndmask_b32_e64 v4, v4, v3, s[4:5]
+; GFX8-NEXT: v_ldexp_f32 v2, v2, v5
+; GFX8-NEXT: v_trunc_f32_e32 v5, v1
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v5, v1
+; GFX8-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v5, v1
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v5, v1
+; GFX8-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX8-NEXT: v_and_b32_e32 v5, 0x80000000, v0
+; GFX8-NEXT: v_or_b32_e32 v1, v1, v5
+; GFX8-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX8-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v1, v3, vcc
; GFX8-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX8-NEXT: v_cvt_f16_f32_e32 v1, v2
+; GFX8-NEXT: v_cvt_f16_f32_e32 v1, v4
; GFX8-NEXT: v_mov_b32_e32 v2, 16
-; GFX8-NEXT: v_exp_f16_e32 v0, v0
-; GFX8-NEXT: v_exp_f16_e32 v1, v1
; GFX8-NEXT: v_lshlrev_b32_sdwa v0, v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
; GFX8-NEXT: v_or_b32_sdwa v0, v1, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
; GFX8-NEXT: s_setpc_b64 s[30:31]
@@ -911,40 +2371,144 @@ define <2 x half> @v_pow_v2f16_fneg_lhs_rhs(<2 x half> %x, <2 x half> %y) {
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_xor_b32_e32 v0, 0x80008000, v0
-; GFX9-NEXT: v_log_f16_e32 v2, v0
-; GFX9-NEXT: v_log_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX9-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x800000
; GFX9-NEXT: v_xor_b32_e32 v1, 0x80008000, v1
-; GFX9-NEXT: v_cvt_f32_f16_e32 v3, v1
-; GFX9-NEXT: v_cvt_f32_f16_e32 v2, v2
+; GFX9-NEXT: v_cvt_f32_f16_e32 v5, v1
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, v3
+; GFX9-NEXT: v_cndmask_b32_e64 v4, 0, 1, vcc
+; GFX9-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX9-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX9-NEXT: v_log_f32_e32 v4, v4
+; GFX9-NEXT: v_mov_b32_e32 v6, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX9-NEXT: v_mov_b32_e32 v8, 0x42800000
+; GFX9-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX9-NEXT: v_mul_legacy_f32_e32 v4, v5, v4
+; GFX9-NEXT: v_mov_b32_e32 v7, 0xc2fc0000
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v4, v7
+; GFX9-NEXT: v_cndmask_b32_e32 v9, 0, v8, vcc
+; GFX9-NEXT: v_add_f32_e32 v4, v4, v9
+; GFX9-NEXT: v_exp_f32_e32 v4, v4
+; GFX9-NEXT: v_not_b32_e32 v9, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v10, 0, v9, vcc
+; GFX9-NEXT: v_cvt_f32_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX9-NEXT: v_ldexp_f32 v4, v4, v10
+; GFX9-NEXT: v_trunc_f32_e32 v10, v5
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v10, v5
+; GFX9-NEXT: v_mul_f32_e32 v5, 0.5, v5
+; GFX9-NEXT: v_trunc_f32_e32 v10, v5
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v10, v5
+; GFX9-NEXT: v_bfrev_b32_e32 v5, -2
+; GFX9-NEXT: v_and_b32_e32 v10, 0x80000000, v2
+; GFX9-NEXT: v_and_or_b32 v10, v4, v5, v10
+; GFX9-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX9-NEXT: s_xor_b64 s[8:9], vcc, exec
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v3
+; GFX9-NEXT: v_cndmask_b32_e64 v4, v4, v10, s[4:5]
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v2, 24
+; GFX9-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX9-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX9-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX9-NEXT: v_log_f32_e32 v2, v2
; GFX9-NEXT: v_cvt_f32_f16_sdwa v1, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX9-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v2, v3
-; GFX9-NEXT: v_cvt_f16_f32_e32 v2, v2
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
+; GFX9-NEXT: v_cndmask_b32_e32 v6, 0, v6, vcc
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x7fc00000
+; GFX9-NEXT: v_sub_f32_e32 v2, v2, v6
+; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v2, v7
+; GFX9-NEXT: v_cndmask_b32_e32 v6, 0, v8, vcc
+; GFX9-NEXT: v_add_f32_e32 v2, v2, v6
+; GFX9-NEXT: v_exp_f32_e32 v2, v2
+; GFX9-NEXT: v_cndmask_b32_e32 v6, 0, v9, vcc
+; GFX9-NEXT: s_and_b64 s[4:5], s[4:5], s[8:9]
+; GFX9-NEXT: v_cndmask_b32_e64 v4, v4, v3, s[4:5]
+; GFX9-NEXT: v_ldexp_f32 v2, v2, v6
+; GFX9-NEXT: v_trunc_f32_e32 v6, v1
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v6, v1
+; GFX9-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX9-NEXT: v_trunc_f32_e32 v6, v1
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v6, v1
+; GFX9-NEXT: v_and_b32_e32 v1, 0x80000000, v0
+; GFX9-NEXT: v_and_or_b32 v1, v2, v5, v1
+; GFX9-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX9-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX9-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v1, v3, vcc
+; GFX9-NEXT: v_cvt_f16_f32_e32 v4, v4
; GFX9-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX9-NEXT: v_exp_f16_e32 v1, v2
-; GFX9-NEXT: v_exp_f16_e32 v0, v0
-; GFX9-NEXT: v_lshl_or_b32 v0, v0, 16, v1
+; GFX9-NEXT: v_pack_b32_f16 v0, v4, v0
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_v2f16_fneg_lhs_rhs:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX10-NEXT: v_xor_b32_e32 v0, 0x80008000, v0
-; GFX10-NEXT: v_xor_b32_e32 v1, 0x80008000, v1
-; GFX10-NEXT: v_log_f16_e32 v2, v0
-; GFX10-NEXT: v_log_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX10-NEXT: v_cvt_f32_f16_e32 v3, v1
-; GFX10-NEXT: v_cvt_f32_f16_sdwa v1, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX10-NEXT: v_cvt_f32_f16_e32 v2, v2
-; GFX10-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX10-NEXT: v_mul_legacy_f32_e32 v2, v2, v3
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX10-NEXT: v_cvt_f16_f32_e32 v1, v2
+; GFX10-NEXT: v_xor_b32_e32 v5, 0x80008000, v1
+; GFX10-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX10-NEXT: v_cvt_f32_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX10-NEXT: v_cvt_f32_f16_e32 v8, v5
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v2|
+; GFX10-NEXT: v_cmp_gt_f32_e64 s5, 0x800000, |v0|
+; GFX10-NEXT: v_and_b32_e32 v11, 0x80000000, v2
+; GFX10-NEXT: v_cmp_class_f32_e64 s8, v2, 24
+; GFX10-NEXT: v_cmp_class_f32_e64 s9, v0, 24
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 1, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 1, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v7, 0, 0x42000000, s5
+; GFX10-NEXT: v_lshlrev_b32_e32 v3, 5, v3
+; GFX10-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX10-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX10-NEXT: v_ldexp_f32 v4, |v0|, v4
+; GFX10-NEXT: v_log_f32_e32 v3, v3
+; GFX10-NEXT: v_log_f32_e32 v4, v4
+; GFX10-NEXT: v_sub_f32_e32 v3, v3, v6
+; GFX10-NEXT: v_cvt_f32_f16_sdwa v6, v5 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX10-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX10-NEXT: v_mov_b32_e32 v7, 0.5
+; GFX10-NEXT: v_mul_legacy_f32_e32 v3, v8, v3
+; GFX10-NEXT: v_trunc_f32_e32 v12, v6
+; GFX10-NEXT: v_mul_legacy_f32_e32 v4, v6, v4
+; GFX10-NEXT: v_fma_mix_f32 v1, -v1, v7, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX10-NEXT: v_fma_mix_f32 v5, v5, v7, neg(0) op_sel_hi:[1,0,0]
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v3
+; GFX10-NEXT: v_cmp_eq_f32_e64 s6, v12, v6
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0xc2fc0000, v4
+; GFX10-NEXT: v_trunc_f32_e32 v7, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v9, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v10, 0, 0x42800000, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v13, 0, 0xffffffc0, s4
+; GFX10-NEXT: v_cmp_lg_f32_e32 vcc_lo, v7, v1
+; GFX10-NEXT: v_add_f32_e32 v3, v3, v9
+; GFX10-NEXT: v_trunc_f32_e32 v9, v8
+; GFX10-NEXT: v_add_f32_e32 v4, v4, v10
+; GFX10-NEXT: v_trunc_f32_e32 v10, v5
+; GFX10-NEXT: v_and_b32_e32 v1, 0x80000000, v0
+; GFX10-NEXT: v_exp_f32_e32 v3, v3
+; GFX10-NEXT: v_cmp_eq_f32_e64 s4, v9, v8
+; GFX10-NEXT: v_exp_f32_e32 v4, v4
+; GFX10-NEXT: v_cmp_lg_f32_e64 s5, v10, v5
+; GFX10-NEXT: s_and_b32 vcc_lo, s6, vcc_lo
+; GFX10-NEXT: s_xor_b32 s10, s4, exec_lo
+; GFX10-NEXT: s_and_b32 s4, s4, s5
+; GFX10-NEXT: s_and_b32 s5, s8, s10
+; GFX10-NEXT: v_ldexp_f32 v2, v3, v2
+; GFX10-NEXT: v_ldexp_f32 v0, v4, v13
+; GFX10-NEXT: v_and_or_b32 v3, 0x7fffffff, v2, v11
+; GFX10-NEXT: v_and_or_b32 v1, 0x7fffffff, v0, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v2, v2, v3, s4
+; GFX10-NEXT: s_xor_b32 s4, s6, exec_lo
+; GFX10-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc_lo
+; GFX10-NEXT: s_and_b32 s4, s9, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v1, v2, 0x7fc00000, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s4
+; GFX10-NEXT: v_cvt_f16_f32_e32 v1, v1
; GFX10-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX10-NEXT: v_exp_f16_e32 v1, v1
-; GFX10-NEXT: v_exp_f16_sdwa v0, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD
-; GFX10-NEXT: v_or_b32_sdwa v0, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
+; GFX10-NEXT: v_pack_b32_f16 v0, v1, v0
; GFX10-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-TRUE16-LABEL: v_pow_v2f16_fneg_lhs_rhs:
@@ -952,52 +2516,169 @@ define <2 x half> @v_pow_v2f16_fneg_lhs_rhs(<2 x half> %x, <2 x half> %y) {
; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-TRUE16-NEXT: v_xor_b32_e32 v0, 0x80008000, v0
; GFX11-TRUE16-NEXT: v_xor_b32_e32 v1, 0x80008000, v1
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-TRUE16-NEXT: v_log_f16_e32 v0.l, v0.l
-; GFX11-TRUE16-NEXT: v_log_f16_e32 v0.h, v0.h
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v2, v1.l
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v2, v0.l
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.h
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v7, v1.l
; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v1.h
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v2|
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v0|
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s4, v2, 24
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v8, v7
+; GFX11-TRUE16-NEXT: v_dual_mul_f32 v9, 0.5, v1 :: v_dual_and_b32 v10, 0x80000000, v0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v4, 0, 1, s1
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v5, 0, 0x42000000, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v3, 0, 1, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s1
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s5, v0, 24
+; GFX11-TRUE16-NEXT: v_lshlrev_b32_e32 v4, 5, v4
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v4, |v0|, v4
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v4, v4
; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v3, v0.l
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.h
+; GFX11-TRUE16-NEXT: v_dual_sub_f32 v4, v4, v6 :: v_dual_lshlrev_b32 v3, 5, v3
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v4, v1, v4
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v3, v3
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v4
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_3) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v6, 0, 0x42800000, s0
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_sub_f32_e32 v3, v3, v5
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v0, 0, 0xffffffc0, s0
+; GFX11-TRUE16-NEXT: v_dual_add_f32 v4, v4, v6 :: v_dual_mul_dx9_zero_f32 v3, v7, v3
+; GFX11-TRUE16-NEXT: v_and_b32_e32 v6, 0x80000000, v2
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v4, v4
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v3
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v5, 0, 0x42800000, vcc_lo
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v11, 0, 0xffffffc0, vcc_lo
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e32 vcc_lo, v8, v7
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v8, v9
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v0, v4, v0
+; GFX11-TRUE16-NEXT: v_add_f32_e32 v3, v3, v5
+; GFX11-TRUE16-NEXT: v_mul_f32_e32 v5, 0.5, v7
+; GFX11-TRUE16-NEXT: s_xor_b32 s6, vcc_lo, exec_lo
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e64 s2, v8, v9
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v2, v3
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v7, v5
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v3, v1
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e64 s1, v7, v5
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e64 s0, v3, v1
+; GFX11-TRUE16-NEXT: v_and_or_b32 v3, 0x7fffffff, v0, v10
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v2, v2, v11
+; GFX11-TRUE16-NEXT: s_and_b32 vcc_lo, vcc_lo, s1
+; GFX11-TRUE16-NEXT: s_and_b32 s1, s4, s6
; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-TRUE16-NEXT: v_dual_mul_dx9_zero_f32 v2, v3, v2 :: v_dual_mul_dx9_zero_f32 v1, v0, v1
-; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v2
+; GFX11-TRUE16-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v6
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e32 v1, v2, v1, vcc_lo
+; GFX11-TRUE16-NEXT: s_and_b32 vcc_lo, s0, s2
+; GFX11-TRUE16-NEXT: s_xor_b32 s0, s0, exec_lo
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e32 v0, v0, v3, vcc_lo
+; GFX11-TRUE16-NEXT: s_and_b32 s0, s5, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s1
; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.h, v1
-; GFX11-TRUE16-NEXT: v_exp_f16_e32 v0.l, v0.l
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
-; GFX11-TRUE16-NEXT: v_exp_f16_e32 v0.h, v0.h
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v2, v0, 0x7fc00000, s0
+; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v1
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.h, v2
; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-FAKE16-LABEL: v_pow_v2f16_fneg_lhs_rhs:
; GFX11-FAKE16: ; %bb.0:
; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-FAKE16-NEXT: v_xor_b32_e32 v0, 0x80008000, v0
-; GFX11-FAKE16-NEXT: v_xor_b32_e32 v1, 0x80008000, v1
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_2)
-; GFX11-FAKE16-NEXT: v_log_f16_e32 v2, v0
+; GFX11-FAKE16-NEXT: v_xor_b32_e32 v5, 0x80008000, v1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v2, v0
; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v0, 16, v0
-; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v3, 16, v1
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-FAKE16-NEXT: v_log_f16_e32 v0, v0
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v3, v3
-; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v2, v2
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v7, v5
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v2|
; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX11-FAKE16-NEXT: v_and_b32_e32 v12, 0x80000000, v2
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s0
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v0|
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v3, 0, 1, s0
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s5, v0, 24
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v4, 0, 1, s1
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v8, 0, 0x42000000, s1
+; GFX11-FAKE16-NEXT: v_lshlrev_b32_e32 v4, 5, v4
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_dual_mul_dx9_zero_f32 v1, v2, v1 :: v_dual_mul_dx9_zero_f32 v0, v0, v3
-; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v4, |v0|, v4
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v4, v4
+; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_dual_sub_f32 v4, v4, v8 :: v_dual_lshlrev_b32 v3, 5, v3
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v3, v3
+; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_sub_f32_e32 v3, v3, v6
+; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v6, 16, v5
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v6, v6
+; GFX11-FAKE16-NEXT: v_dual_mul_dx9_zero_f32 v3, v7, v3 :: v_dual_mul_dx9_zero_f32 v4, v6, v4
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v3
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v4
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v8, 0, 0x42800000, vcc_lo
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v10, 0, 0xffffffc0, vcc_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_4)
+; GFX11-FAKE16-NEXT: v_add_f32_e32 v3, v3, v8
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v8, 0, 0x42800000, s0
+; GFX11-FAKE16-NEXT: v_mov_b32_e32 v9, 0.5
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v3, v3
+; GFX11-FAKE16-NEXT: v_add_f32_e32 v4, v4, v8
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_4)
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v5, v5, v9, neg(0) op_sel_hi:[1,0,0]
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v1, -v1, v9, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v9, v7
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v4, v4
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v11, v5
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v8, v1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e32 vcc_lo, v9, v7
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v7, 0, 0xffffffc0, s0
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v3, v3, v10
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e64 s0, v11, v5
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v5, v6
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e64 s1, v8, v1
+; GFX11-FAKE16-NEXT: s_xor_b32 s4, vcc_lo, exec_lo
+; GFX11-FAKE16-NEXT: v_and_or_b32 v10, 0x7fffffff, v3, v12
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v4, v4, v7
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e64 s2, v5, v6
+; GFX11-FAKE16-NEXT: s_and_b32 s0, vcc_lo, s0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v1, v3, v10, s0
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s0, v2, 24
+; GFX11-FAKE16-NEXT: s_and_b32 vcc_lo, s2, s1
+; GFX11-FAKE16-NEXT: v_and_b32_e32 v9, 0x80000000, v0
+; GFX11-FAKE16-NEXT: s_xor_b32 s1, s2, exec_lo
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s0, s4
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_and_or_b32 v3, 0x7fffffff, v4, v9
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s0
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s5, s1
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e32 v0, v4, v3, vcc_lo
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX11-FAKE16-NEXT: v_exp_f16_e32 v1, v1
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_exp_f16_e32 v0, v0
-; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_and_b32_e32 v1, 0xffff, v1
-; GFX11-FAKE16-NEXT: v_lshl_or_b32 v0, v0, 16, v1
+; GFX11-FAKE16-NEXT: v_pack_b32_f16 v0, v1, v0
; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
%x.fneg = fneg <2 x half> %x
%y.fneg = fneg <2 x half> %y
@@ -1024,7 +2705,7 @@ define float @v_pow_f32_fabs_lhs(float %x, float %y) {
; GFX6-NEXT: v_mov_b32_e32 v2, 0x42000000
; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
; GFX6-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
+; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
; GFX6-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
; GFX6-NEXT: v_mov_b32_e32 v2, 0x42800000
; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
@@ -1048,7 +2729,7 @@ define float @v_pow_f32_fabs_lhs(float %x, float %y) {
; GFX8-NEXT: v_mov_b32_e32 v2, 0x42000000
; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
; GFX8-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
+; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
; GFX8-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
; GFX8-NEXT: v_mov_b32_e32 v2, 0x42800000
; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
@@ -1072,7 +2753,7 @@ define float @v_pow_f32_fabs_lhs(float %x, float %y) {
; GFX9-NEXT: v_mov_b32_e32 v2, 0x42000000
; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
; GFX9-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
+; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
; GFX9-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
; GFX9-NEXT: v_mov_b32_e32 v2, 0x42800000
; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
@@ -1094,7 +2775,7 @@ define float @v_pow_f32_fabs_lhs(float %x, float %y) {
; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s4
; GFX10-NEXT: v_log_f32_e32 v0, v0
; GFX10-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
+; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
; GFX10-NEXT: v_add_f32_e32 v0, v0, v1
@@ -1117,7 +2798,7 @@ define float @v_pow_f32_fabs_lhs(float %x, float %y) {
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
; GFX11-NEXT: v_sub_f32_e32 v0, v0, v2
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, v0, v1
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
@@ -1137,116 +2818,191 @@ define float @v_pow_f32_fabs_rhs(float %x, float %y) {
; GFX6: ; %bb.0:
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX6-NEXT: v_mov_b32_e32 v2, 0x800000
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v2
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
; GFX6-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
; GFX6-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v2
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_mov_b32_e32 v2, 0x42000000
-; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
-; GFX6-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX6-NEXT: v_mul_legacy_f32_e64 v0, v0, |v1|
-; GFX6-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX6-NEXT: v_mov_b32_e32 v2, 0x42800000
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
-; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
-; GFX6-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
-; GFX6-NEXT: v_not_b32_e32 v1, 63
-; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v1
+; GFX6-NEXT: v_ldexp_f32_e64 v2, |v0|, v2
+; GFX6-NEXT: v_log_f32_e32 v2, v2
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX6-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_mul_legacy_f32_e64 v2, |v1|, v2
+; GFX6-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX6-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_exp_f32_e32 v2, v2
+; GFX6-NEXT: v_not_b32_e32 v3, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: v_cmp_class_f32_e64 s[8:9], v0, 24
+; GFX6-NEXT: v_ldexp_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_trunc_f32_e64 v3, |v1|
+; GFX6-NEXT: v_cmp_eq_f32_e64 s[6:7], v3, |v1|
+; GFX6-NEXT: v_mul_f32_e64 v1, |v1|, 0.5
+; GFX6-NEXT: v_trunc_f32_e32 v3, v1
+; GFX6-NEXT: v_cmp_lg_f32_e32 vcc, v3, v1
+; GFX6-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX6-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX6-NEXT: v_or_b32_e32 v1, v1, v3
+; GFX6-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX6-NEXT: s_xor_b64 s[4:5], s[6:7], exec
+; GFX6-NEXT: v_cndmask_b32_e32 v1, v2, v1, vcc
+; GFX6-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX6-NEXT: s_and_b64 vcc, s[8:9], s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX6-NEXT: s_setpc_b64 s[30:31]
;
; GFX8-LABEL: v_pow_f32_fabs_rhs:
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX8-NEXT: v_mov_b32_e32 v2, 0x800000
-; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v0, v2
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
; GFX8-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX8-NEXT: v_ldexp_f32 v0, v0, v2
-; GFX8-NEXT: v_log_f32_e32 v0, v0
-; GFX8-NEXT: v_mov_b32_e32 v2, 0x42000000
-; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
-; GFX8-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX8-NEXT: v_mul_legacy_f32_e64 v0, v0, |v1|
-; GFX8-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX8-NEXT: v_mov_b32_e32 v2, 0x42800000
-; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
-; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
-; GFX8-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX8-NEXT: v_exp_f32_e32 v0, v0
-; GFX8-NEXT: v_not_b32_e32 v1, 63
-; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX8-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX8-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX8-NEXT: v_log_f32_e32 v2, v2
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX8-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_mul_legacy_f32_e64 v2, |v1|, v2
+; GFX8-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX8-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_exp_f32_e32 v2, v2
+; GFX8-NEXT: v_not_b32_e32 v3, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 s[8:9], v0, 24
+; GFX8-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX8-NEXT: v_trunc_f32_e64 v3, |v1|
+; GFX8-NEXT: v_cmp_eq_f32_e64 s[6:7], v3, |v1|
+; GFX8-NEXT: v_mul_f32_e64 v1, |v1|, 0.5
+; GFX8-NEXT: v_trunc_f32_e32 v3, v1
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v3, v1
+; GFX8-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX8-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX8-NEXT: v_or_b32_e32 v1, v1, v3
+; GFX8-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX8-NEXT: s_xor_b64 s[4:5], s[6:7], exec
+; GFX8-NEXT: v_cndmask_b32_e32 v1, v2, v1, vcc
+; GFX8-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[8:9], s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: v_pow_f32_fabs_rhs:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_mov_b32_e32 v2, 0x800000
-; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v0, v2
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
; GFX9-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
; GFX9-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX9-NEXT: v_ldexp_f32 v0, v0, v2
-; GFX9-NEXT: v_log_f32_e32 v0, v0
-; GFX9-NEXT: v_mov_b32_e32 v2, 0x42000000
-; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
-; GFX9-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX9-NEXT: v_mul_legacy_f32_e64 v0, v0, |v1|
-; GFX9-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX9-NEXT: v_mov_b32_e32 v2, 0x42800000
-; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
-; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
-; GFX9-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX9-NEXT: v_exp_f32_e32 v0, v0
-; GFX9-NEXT: v_not_b32_e32 v1, 63
-; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX9-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX9-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX9-NEXT: v_log_f32_e32 v2, v2
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX9-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX9-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX9-NEXT: v_mul_legacy_f32_e64 v2, |v1|, v2
+; GFX9-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX9-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX9-NEXT: v_exp_f32_e32 v2, v2
+; GFX9-NEXT: v_not_b32_e32 v3, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX9-NEXT: v_cmp_class_f32_e64 s[8:9], v0, 24
+; GFX9-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX9-NEXT: v_trunc_f32_e64 v3, |v1|
+; GFX9-NEXT: v_cmp_eq_f32_e64 s[6:7], v3, |v1|
+; GFX9-NEXT: v_mul_f32_e64 v1, |v1|, 0.5
+; GFX9-NEXT: v_trunc_f32_e32 v3, v1
+; GFX9-NEXT: v_cmp_lg_f32_e32 vcc, v3, v1
+; GFX9-NEXT: v_bfrev_b32_e32 v1, -2
+; GFX9-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX9-NEXT: v_and_or_b32 v1, v2, v1, v3
+; GFX9-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX9-NEXT: s_xor_b64 s[4:5], s[6:7], exec
+; GFX9-NEXT: v_cndmask_b32_e32 v1, v2, v1, vcc
+; GFX9-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX9-NEXT: s_and_b64 vcc, s[8:9], s[4:5]
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_f32_fabs_rhs:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0x800000, v0
-; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc_lo
+; GFX10-NEXT: v_cmp_gt_f32_e64 s5, 0x800000, |v0|
+; GFX10-NEXT: v_trunc_f32_e64 v5, |v1|
+; GFX10-NEXT: v_cmp_class_f32_e64 s6, v0, 24
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 1, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s5
+; GFX10-NEXT: v_cmp_eq_f32_e64 s5, v5, |v1|
; GFX10-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX10-NEXT: v_ldexp_f32 v0, v0, v2
-; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, vcc_lo
-; GFX10-NEXT: v_log_f32_e32 v0, v0
-; GFX10-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX10-NEXT: v_mul_legacy_f32_e64 v0, v0, |v1|
-; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
-; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
-; GFX10-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, vcc_lo
-; GFX10-NEXT: v_exp_f32_e32 v0, v0
-; GFX10-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX10-NEXT: s_xor_b32 s4, s5, exec_lo
+; GFX10-NEXT: s_and_b32 s4, s6, s4
+; GFX10-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX10-NEXT: v_log_f32_e32 v2, v2
+; GFX10-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX10-NEXT: v_mul_legacy_f32_e64 v2, |v1|, v2
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX10-NEXT: v_mul_f32_e64 v3, |v1|, 0.5
+; GFX10-NEXT: v_exp_f32_e32 v2, v2
+; GFX10-NEXT: v_trunc_f32_e32 v6, v3
+; GFX10-NEXT: v_cmp_lg_f32_e32 vcc_lo, v6, v3
+; GFX10-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX10-NEXT: v_and_b32_e32 v4, 0x80000000, v0
+; GFX10-NEXT: s_and_b32 vcc_lo, s5, vcc_lo
+; GFX10-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v4
+; GFX10-NEXT: v_cndmask_b32_e32 v0, v2, v1, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s4
; GFX10-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: v_pow_f32_fabs_rhs:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0x800000, v0
-; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc_lo
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v0|
+; GFX11-NEXT: v_trunc_f32_e64 v5, |v1|
+; GFX11-NEXT: v_cmp_class_f32_e64 s2, v0, 24
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_4)
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 1, s1
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s1
+; GFX11-NEXT: v_cmp_eq_f32_e64 s1, v5, |v1|
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(SALU_CYCLE_1)
; GFX11-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX11-NEXT: v_ldexp_f32 v0, v0, v2
-; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, vcc_lo
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_1)
-; GFX11-NEXT: v_log_f32_e32 v0, v0
+; GFX11-NEXT: s_xor_b32 s0, s1, exec_lo
+; GFX11-NEXT: s_and_b32 s0, s2, s0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX11-NEXT: v_log_f32_e32 v2, v2
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX11-NEXT: v_mul_dx9_zero_f32_e64 v0, v0, |v1|
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
-; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
-; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
-; GFX11-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, vcc_lo
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2)
-; GFX11-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_mul_dx9_zero_f32_e64 v2, |v1|, v2
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX11-NEXT: v_mul_f32_e64 v3, |v1|, 0.5
+; GFX11-NEXT: v_exp_f32_e32 v2, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_trunc_f32_e32 v6, v3
+; GFX11-NEXT: v_cmp_lg_f32_e32 vcc_lo, v6, v3
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX11-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX11-NEXT: v_and_b32_e32 v4, 0x80000000, v0
+; GFX11-NEXT: s_and_b32 vcc_lo, s1, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v4
+; GFX11-NEXT: v_cndmask_b32_e32 v0, v2, v1, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
%fabs.y = call float @llvm.fabs.f32(float %y)
%pow = call float @llvm.pow.f32(float %x, float %fabs.y)
@@ -1266,7 +3022,7 @@ define float @v_pow_f32_fabs_lhs_rhs(float %x, float %y) {
; GFX6-NEXT: v_mov_b32_e32 v2, 0x42000000
; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
; GFX6-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX6-NEXT: v_mul_legacy_f32_e64 v0, v0, |v1|
+; GFX6-NEXT: v_mul_legacy_f32_e64 v0, |v1|, v0
; GFX6-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
; GFX6-NEXT: v_mov_b32_e32 v2, 0x42800000
; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
@@ -1290,7 +3046,7 @@ define float @v_pow_f32_fabs_lhs_rhs(float %x, float %y) {
; GFX8-NEXT: v_mov_b32_e32 v2, 0x42000000
; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
; GFX8-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX8-NEXT: v_mul_legacy_f32_e64 v0, v0, |v1|
+; GFX8-NEXT: v_mul_legacy_f32_e64 v0, |v1|, v0
; GFX8-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
; GFX8-NEXT: v_mov_b32_e32 v2, 0x42800000
; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
@@ -1314,7 +3070,7 @@ define float @v_pow_f32_fabs_lhs_rhs(float %x, float %y) {
; GFX9-NEXT: v_mov_b32_e32 v2, 0x42000000
; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
; GFX9-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX9-NEXT: v_mul_legacy_f32_e64 v0, v0, |v1|
+; GFX9-NEXT: v_mul_legacy_f32_e64 v0, |v1|, v0
; GFX9-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
; GFX9-NEXT: v_mov_b32_e32 v2, 0x42800000
; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
@@ -1336,7 +3092,7 @@ define float @v_pow_f32_fabs_lhs_rhs(float %x, float %y) {
; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s4
; GFX10-NEXT: v_log_f32_e32 v0, v0
; GFX10-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX10-NEXT: v_mul_legacy_f32_e64 v0, v0, |v1|
+; GFX10-NEXT: v_mul_legacy_f32_e64 v0, |v1|, v0
; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
; GFX10-NEXT: v_add_f32_e32 v0, v0, v1
@@ -1359,7 +3115,7 @@ define float @v_pow_f32_fabs_lhs_rhs(float %x, float %y) {
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
; GFX11-NEXT: v_sub_f32_e32 v0, v0, v2
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-NEXT: v_mul_dx9_zero_f32_e64 v0, v0, |v1|
+; GFX11-NEXT: v_mul_dx9_zero_f32_e64 v0, |v1|, v0
; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
@@ -1379,126 +3135,219 @@ define amdgpu_ps float @v_pow_f32_sgpr_vgpr(float inreg %x, float %y) {
; GFX6-LABEL: v_pow_f32_sgpr_vgpr:
; GFX6: ; %bb.0:
; GFX6-NEXT: v_mov_b32_e32 v1, 0x800000
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, s0, v1
-; GFX6-NEXT: s_or_b64 s[2:3], vcc, vcc
+; GFX6-NEXT: v_cmp_lt_f32_e64 s[2:3], |s0|, v1
+; GFX6-NEXT: s_or_b64 s[2:3], s[2:3], s[2:3]
; GFX6-NEXT: s_cselect_b32 s2, 1, 0
; GFX6-NEXT: s_cselect_b32 s1, 1, 0
; GFX6-NEXT: s_lshl_b32 s2, s2, 5
; GFX6-NEXT: v_mov_b32_e32 v1, s2
-; GFX6-NEXT: v_ldexp_f32_e32 v1, s0, v1
+; GFX6-NEXT: v_ldexp_f32_e64 v1, |s0|, v1
; GFX6-NEXT: v_log_f32_e32 v1, v1
; GFX6-NEXT: s_cmp_lg_u32 s1, 0
-; GFX6-NEXT: s_cselect_b32 s0, 0x42000000, 0
-; GFX6-NEXT: v_mov_b32_e32 v2, 0x42800000
-; GFX6-NEXT: v_subrev_f32_e32 v1, s0, v1
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX6-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
-; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
-; GFX6-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
-; GFX6-NEXT: v_not_b32_e32 v1, 63
-; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v1
+; GFX6-NEXT: s_cselect_b32 s1, 0x42000000, 0
+; GFX6-NEXT: v_mov_b32_e32 v2, 0xc2fc0000
+; GFX6-NEXT: v_subrev_f32_e32 v1, s1, v1
+; GFX6-NEXT: v_mul_legacy_f32_e32 v1, v0, v1
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v1, v2
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v3, vcc
+; GFX6-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX6-NEXT: v_exp_f32_e32 v1, v1
+; GFX6-NEXT: v_not_b32_e32 v2, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: s_and_b32 s1, s0, 0x80000000
+; GFX6-NEXT: v_ldexp_f32_e32 v1, v1, v2
+; GFX6-NEXT: v_trunc_f32_e32 v2, v0
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v2, v0
+; GFX6-NEXT: v_mul_f32_e32 v0, 0.5, v0
+; GFX6-NEXT: v_trunc_f32_e32 v2, v0
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[2:3], v2, v0
+; GFX6-NEXT: v_and_b32_e32 v0, 0x7fffffff, v1
+; GFX6-NEXT: v_or_b32_e32 v0, s1, v0
+; GFX6-NEXT: s_and_b64 s[2:3], vcc, s[2:3]
+; GFX6-NEXT: v_cmp_class_f32_e64 s[0:1], s0, 24
+; GFX6-NEXT: s_or_b64 s[0:1], s[0:1], s[0:1]
+; GFX6-NEXT: v_cndmask_b32_e64 v0, v1, v0, s[2:3]
+; GFX6-NEXT: s_cselect_b32 s2, 1, 0
+; GFX6-NEXT: s_xor_b64 s[0:1], vcc, exec
+; GFX6-NEXT: s_cmp_lg_u32 s2, 0
+; GFX6-NEXT: s_cselect_b64 s[2:3], exec, 0
+; GFX6-NEXT: v_mov_b32_e32 v1, 0x7fc00000
+; GFX6-NEXT: s_and_b64 vcc, s[2:3], s[0:1]
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc
; GFX6-NEXT: ; return to shader part epilog
;
; GFX8-LABEL: v_pow_f32_sgpr_vgpr:
; GFX8: ; %bb.0:
; GFX8-NEXT: v_mov_b32_e32 v1, 0x800000
-; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, s0, v1
-; GFX8-NEXT: s_cmp_lg_u64 vcc, 0
+; GFX8-NEXT: v_cmp_lt_f32_e64 s[2:3], |s0|, v1
+; GFX8-NEXT: s_cmp_lg_u64 s[2:3], 0
; GFX8-NEXT: s_cselect_b32 s2, 1, 0
; GFX8-NEXT: s_cselect_b32 s1, 1, 0
; GFX8-NEXT: s_lshl_b32 s2, s2, 5
; GFX8-NEXT: v_mov_b32_e32 v1, s2
-; GFX8-NEXT: v_ldexp_f32 v1, s0, v1
+; GFX8-NEXT: v_ldexp_f32 v1, |s0|, v1
; GFX8-NEXT: v_log_f32_e32 v1, v1
; GFX8-NEXT: s_cmp_lg_u32 s1, 0
-; GFX8-NEXT: s_cselect_b32 s0, 0x42000000, 0
-; GFX8-NEXT: v_mov_b32_e32 v2, 0x42800000
-; GFX8-NEXT: v_subrev_f32_e32 v1, s0, v1
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX8-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
-; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
-; GFX8-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX8-NEXT: v_exp_f32_e32 v0, v0
-; GFX8-NEXT: v_not_b32_e32 v1, 63
-; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX8-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX8-NEXT: s_cselect_b32 s1, 0x42000000, 0
+; GFX8-NEXT: v_mov_b32_e32 v2, 0xc2fc0000
+; GFX8-NEXT: v_subrev_f32_e32 v1, s1, v1
+; GFX8-NEXT: v_mul_legacy_f32_e32 v1, v0, v1
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v1, v2
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v3, vcc
+; GFX8-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX8-NEXT: v_exp_f32_e32 v1, v1
+; GFX8-NEXT: v_not_b32_e32 v2, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: s_and_b32 s1, s0, 0x80000000
+; GFX8-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX8-NEXT: v_trunc_f32_e32 v2, v0
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v2, v0
+; GFX8-NEXT: v_mul_f32_e32 v0, 0.5, v0
+; GFX8-NEXT: v_trunc_f32_e32 v2, v0
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[2:3], v2, v0
+; GFX8-NEXT: v_and_b32_e32 v0, 0x7fffffff, v1
+; GFX8-NEXT: v_or_b32_e32 v0, s1, v0
+; GFX8-NEXT: s_and_b64 s[2:3], vcc, s[2:3]
+; GFX8-NEXT: v_cmp_class_f32_e64 s[0:1], s0, 24
+; GFX8-NEXT: s_cmp_lg_u64 s[0:1], 0
+; GFX8-NEXT: v_cndmask_b32_e64 v0, v1, v0, s[2:3]
+; GFX8-NEXT: s_cselect_b32 s2, 1, 0
+; GFX8-NEXT: s_xor_b64 s[0:1], vcc, exec
+; GFX8-NEXT: s_cmp_lg_u32 s2, 0
+; GFX8-NEXT: s_cselect_b64 s[2:3], exec, 0
+; GFX8-NEXT: v_mov_b32_e32 v1, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[2:3], s[0:1]
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc
; GFX8-NEXT: ; return to shader part epilog
;
; GFX9-LABEL: v_pow_f32_sgpr_vgpr:
; GFX9: ; %bb.0:
; GFX9-NEXT: v_mov_b32_e32 v1, 0x800000
-; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, s0, v1
-; GFX9-NEXT: s_cmp_lg_u64 vcc, 0
+; GFX9-NEXT: v_cmp_lt_f32_e64 s[2:3], |s0|, v1
+; GFX9-NEXT: s_cmp_lg_u64 s[2:3], 0
; GFX9-NEXT: s_cselect_b32 s2, 1, 0
; GFX9-NEXT: s_cselect_b32 s1, 1, 0
; GFX9-NEXT: s_lshl_b32 s2, s2, 5
; GFX9-NEXT: v_mov_b32_e32 v1, s2
-; GFX9-NEXT: v_ldexp_f32 v1, s0, v1
+; GFX9-NEXT: v_ldexp_f32 v1, |s0|, v1
; GFX9-NEXT: v_log_f32_e32 v1, v1
; GFX9-NEXT: s_cmp_lg_u32 s1, 0
-; GFX9-NEXT: s_cselect_b32 s0, 0x42000000, 0
-; GFX9-NEXT: v_mov_b32_e32 v2, 0x42800000
-; GFX9-NEXT: v_subrev_f32_e32 v1, s0, v1
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX9-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
-; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
-; GFX9-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX9-NEXT: v_exp_f32_e32 v0, v0
-; GFX9-NEXT: v_not_b32_e32 v1, 63
-; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX9-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX9-NEXT: s_cselect_b32 s1, 0x42000000, 0
+; GFX9-NEXT: v_mov_b32_e32 v2, 0xc2fc0000
+; GFX9-NEXT: v_subrev_f32_e32 v1, s1, v1
+; GFX9-NEXT: v_mul_legacy_f32_e32 v1, v0, v1
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v1, v2
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v3, vcc
+; GFX9-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX9-NEXT: v_exp_f32_e32 v1, v1
+; GFX9-NEXT: v_not_b32_e32 v2, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: s_and_b32 s1, s0, 0x80000000
+; GFX9-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX9-NEXT: v_trunc_f32_e32 v2, v0
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v2, v0
+; GFX9-NEXT: v_mul_f32_e32 v0, 0.5, v0
+; GFX9-NEXT: v_trunc_f32_e32 v2, v0
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[2:3], v2, v0
+; GFX9-NEXT: v_bfrev_b32_e32 v0, -2
+; GFX9-NEXT: v_and_or_b32 v0, v1, v0, s1
+; GFX9-NEXT: s_and_b64 s[2:3], vcc, s[2:3]
+; GFX9-NEXT: v_cmp_class_f32_e64 s[0:1], s0, 24
+; GFX9-NEXT: s_cmp_lg_u64 s[0:1], 0
+; GFX9-NEXT: v_cndmask_b32_e64 v0, v1, v0, s[2:3]
+; GFX9-NEXT: s_cselect_b32 s2, 1, 0
+; GFX9-NEXT: s_xor_b64 s[0:1], vcc, exec
+; GFX9-NEXT: s_cmp_lg_u32 s2, 0
+; GFX9-NEXT: s_cselect_b64 s[2:3], exec, 0
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x7fc00000
+; GFX9-NEXT: s_and_b64 vcc, s[2:3], s[0:1]
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc
; GFX9-NEXT: ; return to shader part epilog
;
; GFX10-LABEL: v_pow_f32_sgpr_vgpr:
; GFX10: ; %bb.0:
-; GFX10-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, s0
+; GFX10-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |s0|
+; GFX10-NEXT: v_trunc_f32_e32 v3, v0
; GFX10-NEXT: s_cmp_lg_u32 s1, 0
-; GFX10-NEXT: s_cselect_b32 s2, 1, 0
+; GFX10-NEXT: s_cselect_b32 s3, 1, 0
; GFX10-NEXT: s_cselect_b32 s1, 1, 0
-; GFX10-NEXT: s_lshl_b32 s2, s2, 5
+; GFX10-NEXT: s_lshl_b32 s3, s3, 5
; GFX10-NEXT: s_cmp_lg_u32 s1, 0
-; GFX10-NEXT: v_ldexp_f32 v1, s0, s2
-; GFX10-NEXT: s_cselect_b32 s0, 0x42000000, 0
+; GFX10-NEXT: v_ldexp_f32 v1, |s0|, s3
+; GFX10-NEXT: s_cselect_b32 s1, 0x42000000, 0
+; GFX10-NEXT: v_cmp_class_f32_e64 s3, s0, 24
+; GFX10-NEXT: s_and_b32 s0, s0, 0x80000000
; GFX10-NEXT: v_log_f32_e32 v1, v1
-; GFX10-NEXT: v_subrev_f32_e32 v1, s0, v1
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
-; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
-; GFX10-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, vcc_lo
-; GFX10-NEXT: v_exp_f32_e32 v0, v0
-; GFX10-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX10-NEXT: v_subrev_f32_e32 v1, s1, v1
+; GFX10-NEXT: v_mul_legacy_f32_e32 v1, v0, v1
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_cmp_eq_f32_e32 vcc_lo, v3, v0
+; GFX10-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX10-NEXT: v_mul_f32_e32 v2, 0.5, v0
+; GFX10-NEXT: v_exp_f32_e32 v1, v1
+; GFX10-NEXT: v_trunc_f32_e32 v5, v2
+; GFX10-NEXT: v_cmp_lg_f32_e64 s1, v5, v2
+; GFX10-NEXT: v_ldexp_f32 v0, v1, v4
+; GFX10-NEXT: v_and_or_b32 v1, 0x7fffffff, v0, s0
+; GFX10-NEXT: s_and_b32 s0, vcc_lo, s1
+; GFX10-NEXT: s_cmp_lg_u32 s3, 0
+; GFX10-NEXT: s_cselect_b32 s1, 1, 0
+; GFX10-NEXT: s_xor_b32 s2, vcc_lo, exec_lo
+; GFX10-NEXT: s_cmp_lg_u32 s1, 0
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, v1, s0
+; GFX10-NEXT: s_cselect_b32 s0, exec_lo, 0
+; GFX10-NEXT: s_and_b32 s0, s0, s2
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX10-NEXT: ; return to shader part epilog
;
; GFX11-LABEL: v_pow_f32_sgpr_vgpr:
; GFX11: ; %bb.0:
-; GFX11-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, s0
+; GFX11-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |s0|
+; GFX11-NEXT: v_trunc_f32_e32 v3, v0
; GFX11-NEXT: s_cmp_lg_u32 s1, 0
-; GFX11-NEXT: s_cselect_b32 s2, 1, 0
+; GFX11-NEXT: s_cselect_b32 s3, 1, 0
; GFX11-NEXT: s_cselect_b32 s1, 1, 0
-; GFX11-NEXT: s_lshl_b32 s2, s2, 5
+; GFX11-NEXT: s_lshl_b32 s3, s3, 5
; GFX11-NEXT: s_cmp_lg_u32 s1, 0
-; GFX11-NEXT: v_ldexp_f32 v1, s0, s2
-; GFX11-NEXT: s_cselect_b32 s0, 0x42000000, 0
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_ldexp_f32 v1, |s0|, s3
+; GFX11-NEXT: s_cselect_b32 s1, 0x42000000, 0
+; GFX11-NEXT: v_cmp_class_f32_e64 s3, s0, 24
+; GFX11-NEXT: s_and_b32 s0, s0, 0x80000000
; GFX11-NEXT: v_log_f32_e32 v1, v1
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_subrev_f32_e32 v1, s0, v1
-; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
-; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
-; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
-; GFX11-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, vcc_lo
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2)
-; GFX11-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-NEXT: v_subrev_f32_e32 v1, s1, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v1, v0, v1
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v1
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: v_cmp_eq_f32_e32 vcc_lo, v3, v0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_dual_add_f32 v1, v1, v2 :: v_dual_mul_f32 v2, 0.5, v0
+; GFX11-NEXT: v_exp_f32_e32 v1, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_trunc_f32_e32 v5, v2
+; GFX11-NEXT: v_cmp_lg_f32_e64 s1, v5, v2
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX11-NEXT: v_ldexp_f32 v0, v1, v4
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT: v_and_or_b32 v1, 0x7fffffff, v0, s0
+; GFX11-NEXT: s_and_b32 s0, vcc_lo, s1
+; GFX11-NEXT: s_cmp_lg_u32 s3, 0
+; GFX11-NEXT: s_cselect_b32 s1, 1, 0
+; GFX11-NEXT: s_xor_b32 s2, vcc_lo, exec_lo
+; GFX11-NEXT: s_cmp_lg_u32 s1, 0
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v0, v1, s0
+; GFX11-NEXT: s_cselect_b32 s0, exec_lo, 0
+; GFX11-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
+; GFX11-NEXT: s_and_b32 s0, s0, s2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX11-NEXT: ; return to shader part epilog
%pow = call float @llvm.pow.f32(float %x, float %y)
ret float %pow
@@ -1508,112 +3357,229 @@ define amdgpu_ps float @v_pow_f32_vgpr_sgpr(float %x, float inreg %y) {
; GFX6-LABEL: v_pow_f32_vgpr_sgpr:
; GFX6: ; %bb.0:
; GFX6-NEXT: v_mov_b32_e32 v1, 0x800000
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v1
; GFX6-NEXT: v_cndmask_b32_e64 v1, 0, 1, vcc
; GFX6-NEXT: v_lshlrev_b32_e32 v1, 5, v1
-; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_mov_b32_e32 v1, 0x42000000
-; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX6-NEXT: v_mov_b32_e32 v2, 0x42800000
-; GFX6-NEXT: v_sub_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, s0, v0
-; GFX6-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
-; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
-; GFX6-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
-; GFX6-NEXT: v_not_b32_e32 v1, 63
-; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v1
+; GFX6-NEXT: v_ldexp_f32_e64 v1, |v0|, v1
+; GFX6-NEXT: v_log_f32_e32 v1, v1
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX6-NEXT: v_sub_f32_e32 v1, v1, v2
+; GFX6-NEXT: v_mul_legacy_f32_e32 v1, s0, v1
+; GFX6-NEXT: v_mov_b32_e32 v2, 0xc2fc0000
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v1, v2
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v3, vcc
+; GFX6-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX6-NEXT: v_exp_f32_e32 v1, v1
+; GFX6-NEXT: v_not_b32_e32 v2, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: v_ldexp_f32_e32 v1, v1, v2
+; GFX6-NEXT: v_trunc_f32_e32 v2, s0
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, s0, v2
+; GFX6-NEXT: v_mul_f32_e64 v2, s0, 0.5
+; GFX6-NEXT: v_trunc_f32_e32 v3, v2
+; GFX6-NEXT: s_or_b64 s[2:3], vcc, vcc
+; GFX6-NEXT: v_cmp_lg_f32_e32 vcc, v3, v2
+; GFX6-NEXT: s_cselect_b32 s2, 1, 0
+; GFX6-NEXT: s_or_b64 s[0:1], vcc, vcc
+; GFX6-NEXT: s_cselect_b32 s0, 1, 0
+; GFX6-NEXT: s_and_b32 s0, s2, s0
+; GFX6-NEXT: s_cmp_lg_u32 s0, 0
+; GFX6-NEXT: s_cselect_b64 vcc, exec, 0
+; GFX6-NEXT: s_xor_b32 s2, s2, 1
+; GFX6-NEXT: v_and_b32_e32 v2, 0x7fffffff, v1
+; GFX6-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX6-NEXT: s_cmp_lg_u32 s2, 0
+; GFX6-NEXT: v_or_b32_e32 v2, v2, v3
+; GFX6-NEXT: v_cmp_class_f32_e64 s[0:1], v0, 24
+; GFX6-NEXT: s_cselect_b64 s[2:3], exec, 0
+; GFX6-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc
+; GFX6-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX6-NEXT: s_and_b64 vcc, s[0:1], s[2:3]
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX6-NEXT: ; return to shader part epilog
;
; GFX8-LABEL: v_pow_f32_vgpr_sgpr:
; GFX8: ; %bb.0:
; GFX8-NEXT: v_mov_b32_e32 v1, 0x800000
-; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v1
; GFX8-NEXT: v_cndmask_b32_e64 v1, 0, 1, vcc
; GFX8-NEXT: v_lshlrev_b32_e32 v1, 5, v1
-; GFX8-NEXT: v_ldexp_f32 v0, v0, v1
-; GFX8-NEXT: v_log_f32_e32 v0, v0
-; GFX8-NEXT: v_mov_b32_e32 v1, 0x42000000
-; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX8-NEXT: v_mov_b32_e32 v2, 0x42800000
-; GFX8-NEXT: v_sub_f32_e32 v0, v0, v1
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, s0, v0
-; GFX8-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
-; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
-; GFX8-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX8-NEXT: v_exp_f32_e32 v0, v0
-; GFX8-NEXT: v_not_b32_e32 v1, 63
-; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX8-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX8-NEXT: v_ldexp_f32 v1, |v0|, v1
+; GFX8-NEXT: v_log_f32_e32 v1, v1
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX8-NEXT: v_sub_f32_e32 v1, v1, v2
+; GFX8-NEXT: v_mul_legacy_f32_e32 v1, s0, v1
+; GFX8-NEXT: v_mov_b32_e32 v2, 0xc2fc0000
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v1, v2
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v3, vcc
+; GFX8-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX8-NEXT: v_exp_f32_e32 v1, v1
+; GFX8-NEXT: v_not_b32_e32 v2, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX8-NEXT: v_trunc_f32_e32 v2, s0
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, s0, v2
+; GFX8-NEXT: v_mul_f32_e64 v2, s0, 0.5
+; GFX8-NEXT: v_trunc_f32_e32 v3, v2
+; GFX8-NEXT: s_cmp_lg_u64 vcc, 0
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v3, v2
+; GFX8-NEXT: s_cselect_b32 s2, 1, 0
+; GFX8-NEXT: s_cmp_lg_u64 vcc, 0
+; GFX8-NEXT: s_cselect_b32 s0, 1, 0
+; GFX8-NEXT: s_and_b32 s0, s2, s0
+; GFX8-NEXT: s_cmp_lg_u32 s0, 0
+; GFX8-NEXT: s_cselect_b64 vcc, exec, 0
+; GFX8-NEXT: s_xor_b32 s2, s2, 1
+; GFX8-NEXT: v_and_b32_e32 v2, 0x7fffffff, v1
+; GFX8-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX8-NEXT: s_cmp_lg_u32 s2, 0
+; GFX8-NEXT: v_or_b32_e32 v2, v2, v3
+; GFX8-NEXT: v_cmp_class_f32_e64 s[0:1], v0, 24
+; GFX8-NEXT: s_cselect_b64 s[2:3], exec, 0
+; GFX8-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc
+; GFX8-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[0:1], s[2:3]
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX8-NEXT: ; return to shader part epilog
;
; GFX9-LABEL: v_pow_f32_vgpr_sgpr:
; GFX9: ; %bb.0:
; GFX9-NEXT: v_mov_b32_e32 v1, 0x800000
-; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v1
; GFX9-NEXT: v_cndmask_b32_e64 v1, 0, 1, vcc
; GFX9-NEXT: v_lshlrev_b32_e32 v1, 5, v1
-; GFX9-NEXT: v_ldexp_f32 v0, v0, v1
-; GFX9-NEXT: v_log_f32_e32 v0, v0
-; GFX9-NEXT: v_mov_b32_e32 v1, 0x42000000
-; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX9-NEXT: v_mov_b32_e32 v2, 0x42800000
-; GFX9-NEXT: v_sub_f32_e32 v0, v0, v1
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, s0, v0
-; GFX9-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
-; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
-; GFX9-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX9-NEXT: v_exp_f32_e32 v0, v0
-; GFX9-NEXT: v_not_b32_e32 v1, 63
-; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX9-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX9-NEXT: v_ldexp_f32 v1, |v0|, v1
+; GFX9-NEXT: v_log_f32_e32 v1, v1
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX9-NEXT: v_sub_f32_e32 v1, v1, v2
+; GFX9-NEXT: v_mul_legacy_f32_e32 v1, s0, v1
+; GFX9-NEXT: v_mov_b32_e32 v2, 0xc2fc0000
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v1, v2
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v3, vcc
+; GFX9-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX9-NEXT: v_exp_f32_e32 v1, v1
+; GFX9-NEXT: v_not_b32_e32 v2, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX9-NEXT: v_trunc_f32_e32 v2, s0
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, s0, v2
+; GFX9-NEXT: v_mul_f32_e64 v2, s0, 0.5
+; GFX9-NEXT: v_trunc_f32_e32 v3, v2
+; GFX9-NEXT: s_cmp_lg_u64 vcc, 0
+; GFX9-NEXT: v_cmp_lg_f32_e32 vcc, v3, v2
+; GFX9-NEXT: s_cselect_b32 s2, 1, 0
+; GFX9-NEXT: s_cmp_lg_u64 vcc, 0
+; GFX9-NEXT: s_cselect_b32 s0, 1, 0
+; GFX9-NEXT: s_and_b32 s0, s2, s0
+; GFX9-NEXT: s_cmp_lg_u32 s0, 0
+; GFX9-NEXT: s_cselect_b64 vcc, exec, 0
+; GFX9-NEXT: s_xor_b32 s2, s2, 1
+; GFX9-NEXT: v_bfrev_b32_e32 v2, -2
+; GFX9-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX9-NEXT: s_cmp_lg_u32 s2, 0
+; GFX9-NEXT: v_and_or_b32 v2, v1, v2, v3
+; GFX9-NEXT: v_cmp_class_f32_e64 s[0:1], v0, 24
+; GFX9-NEXT: s_cselect_b64 s[2:3], exec, 0
+; GFX9-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc
+; GFX9-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX9-NEXT: s_and_b64 vcc, s[0:1], s[2:3]
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX9-NEXT: ; return to shader part epilog
;
; GFX10-LABEL: v_pow_f32_vgpr_sgpr:
; GFX10: ; %bb.0:
-; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0x800000, v0
-; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 1, vcc_lo
+; GFX10-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v0|
+; GFX10-NEXT: v_mul_f32_e64 v3, s0, 0.5
+; GFX10-NEXT: v_cmp_class_f32_e64 s2, v0, 24
+; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 1, s1
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s1
+; GFX10-NEXT: v_trunc_f32_e32 v4, v3
; GFX10-NEXT: v_lshlrev_b32_e32 v1, 5, v1
-; GFX10-NEXT: v_ldexp_f32 v0, v0, v1
-; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42000000, vcc_lo
-; GFX10-NEXT: v_log_f32_e32 v0, v0
-; GFX10-NEXT: v_sub_f32_e32 v0, v0, v1
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, s0, v0
-; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
-; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
-; GFX10-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, vcc_lo
-; GFX10-NEXT: v_exp_f32_e32 v0, v0
-; GFX10-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX10-NEXT: v_cmp_lg_f32_e64 s1, v4, v3
+; GFX10-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX10-NEXT: v_ldexp_f32 v1, |v0|, v1
+; GFX10-NEXT: v_log_f32_e32 v1, v1
+; GFX10-NEXT: v_sub_f32_e32 v1, v1, v2
+; GFX10-NEXT: v_mul_legacy_f32_e32 v1, s0, v1
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX10-NEXT: v_trunc_f32_e32 v2, s0
+; GFX10-NEXT: v_exp_f32_e32 v1, v1
+; GFX10-NEXT: v_cmp_eq_f32_e64 s0, s0, v2
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: s_cmp_lg_u32 s0, 0
+; GFX10-NEXT: s_cselect_b32 s0, 1, 0
+; GFX10-NEXT: s_cmp_lg_u32 s1, 0
+; GFX10-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX10-NEXT: s_cselect_b32 s1, 1, 0
+; GFX10-NEXT: s_and_b32 s1, s0, s1
+; GFX10-NEXT: s_cmp_lg_u32 s1, 0
+; GFX10-NEXT: v_and_or_b32 v0, 0x7fffffff, v1, v3
+; GFX10-NEXT: s_cselect_b32 vcc_lo, exec_lo, 0
+; GFX10-NEXT: s_xor_b32 s0, s0, 1
+; GFX10-NEXT: s_cmp_lg_u32 s0, 0
+; GFX10-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc_lo
+; GFX10-NEXT: s_cselect_b32 s0, exec_lo, 0
+; GFX10-NEXT: s_and_b32 s0, s2, s0
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX10-NEXT: ; return to shader part epilog
;
; GFX11-LABEL: v_pow_f32_vgpr_sgpr:
; GFX11: ; %bb.0:
-; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0x800000, v0
-; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 1, vcc_lo
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v0|
+; GFX11-NEXT: v_mul_f32_e64 v3, s0, 0.5
+; GFX11-NEXT: v_cmp_class_f32_e64 s2, v0, 24
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_4)
+; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 1, s1
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s1
+; GFX11-NEXT: v_trunc_f32_e32 v4, v3
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)
; GFX11-NEXT: v_lshlrev_b32_e32 v1, 5, v1
-; GFX11-NEXT: v_ldexp_f32 v0, v0, v1
-; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42000000, vcc_lo
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_1)
-; GFX11-NEXT: v_log_f32_e32 v0, v0
+; GFX11-NEXT: v_cmp_lg_f32_e64 s1, v4, v3
+; GFX11-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_ldexp_f32 v1, |v0|, v1
+; GFX11-NEXT: v_log_f32_e32 v1, v1
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_sub_f32_e32 v0, v0, v1
-; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, s0, v0
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
-; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
-; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
-; GFX11-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, vcc_lo
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2)
-; GFX11-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-NEXT: v_sub_f32_e32 v1, v1, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v1, s0, v1
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v1
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX11-NEXT: v_trunc_f32_e32 v2, s0
+; GFX11-NEXT: v_exp_f32_e32 v1, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT: v_cmp_eq_f32_e64 s0, s0, v2
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: s_cmp_lg_u32 s0, 0
+; GFX11-NEXT: s_cselect_b32 s0, 1, 0
+; GFX11-NEXT: s_cmp_lg_u32 s1, 0
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX11-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX11-NEXT: s_cselect_b32 s1, 1, 0
+; GFX11-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: s_and_b32 s1, s0, s1
+; GFX11-NEXT: s_cmp_lg_u32 s1, 0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_and_or_b32 v0, 0x7fffffff, v1, v3
+; GFX11-NEXT: s_cselect_b32 vcc_lo, exec_lo, 0
+; GFX11-NEXT: s_xor_b32 s0, s0, 1
+; GFX11-NEXT: s_cmp_lg_u32 s0, 0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc_lo
+; GFX11-NEXT: s_cselect_b32 s0, exec_lo, 0
+; GFX11-NEXT: s_and_b32 s0, s2, s0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX11-NEXT: ; return to shader part epilog
%pow = call float @llvm.pow.f32(float %x, float %y)
ret float %pow
@@ -1623,125 +3589,248 @@ define amdgpu_ps float @v_pow_f32_sgpr_sgpr(float inreg %x, float inreg %y) {
; GFX6-LABEL: v_pow_f32_sgpr_sgpr:
; GFX6: ; %bb.0:
; GFX6-NEXT: v_mov_b32_e32 v0, 0x800000
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, s0, v0
-; GFX6-NEXT: s_or_b64 s[2:3], vcc, vcc
+; GFX6-NEXT: v_cmp_lt_f32_e64 s[2:3], |s0|, v0
+; GFX6-NEXT: s_or_b64 s[2:3], s[2:3], s[2:3]
; GFX6-NEXT: s_cselect_b32 s3, 1, 0
; GFX6-NEXT: s_cselect_b32 s2, 1, 0
; GFX6-NEXT: s_lshl_b32 s3, s3, 5
; GFX6-NEXT: v_mov_b32_e32 v0, s3
-; GFX6-NEXT: v_ldexp_f32_e32 v0, s0, v0
+; GFX6-NEXT: v_ldexp_f32_e64 v0, |s0|, v0
; GFX6-NEXT: v_log_f32_e32 v0, v0
; GFX6-NEXT: s_cmp_lg_u32 s2, 0
-; GFX6-NEXT: s_cselect_b32 s0, 0x42000000, 0
+; GFX6-NEXT: s_cselect_b32 s2, 0x42000000, 0
; GFX6-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX6-NEXT: v_subrev_f32_e32 v0, s0, v0
+; GFX6-NEXT: v_subrev_f32_e32 v0, s2, v0
; GFX6-NEXT: v_mul_legacy_f32_e32 v0, s1, v0
; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
-; GFX6-NEXT: s_or_b64 s[0:1], vcc, vcc
-; GFX6-NEXT: s_cselect_b32 s0, 0x42800000, 0
-; GFX6-NEXT: v_add_f32_e32 v0, s0, v0
+; GFX6-NEXT: s_or_b64 s[2:3], vcc, vcc
+; GFX6-NEXT: s_cselect_b32 s2, 0x42800000, 0
+; GFX6-NEXT: v_add_f32_e32 v0, s2, v0
; GFX6-NEXT: v_exp_f32_e32 v0, v0
-; GFX6-NEXT: s_cselect_b32 s0, 0xffffffc0, 0
-; GFX6-NEXT: v_ldexp_f32_e64 v0, v0, s0
+; GFX6-NEXT: s_cselect_b32 s2, 0xffffffc0, 0
+; GFX6-NEXT: v_ldexp_f32_e64 v0, v0, s2
+; GFX6-NEXT: v_readfirstlane_b32 s4, v0
+; GFX6-NEXT: v_trunc_f32_e32 v0, s1
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, s1, v0
+; GFX6-NEXT: v_mul_f32_e64 v0, s1, 0.5
+; GFX6-NEXT: v_trunc_f32_e32 v1, v0
+; GFX6-NEXT: s_or_b64 s[2:3], vcc, vcc
+; GFX6-NEXT: v_cmp_lg_f32_e32 vcc, v1, v0
+; GFX6-NEXT: s_cselect_b32 s5, 1, 0
+; GFX6-NEXT: s_or_b64 s[2:3], vcc, vcc
+; GFX6-NEXT: s_cselect_b32 s1, 1, 0
+; GFX6-NEXT: s_and_b32 s2, s4, 0x7fffffff
+; GFX6-NEXT: s_and_b32 s3, s0, 0x80000000
+; GFX6-NEXT: s_and_b32 s1, s5, s1
+; GFX6-NEXT: s_or_b32 s2, s2, s3
+; GFX6-NEXT: s_cmp_lg_u32 s1, 0
+; GFX6-NEXT: v_cmp_class_f32_e64 s[0:1], s0, 24
+; GFX6-NEXT: s_cselect_b32 s2, s2, s4
+; GFX6-NEXT: s_or_b64 s[0:1], s[0:1], s[0:1]
+; GFX6-NEXT: s_cselect_b32 s0, 1, 0
+; GFX6-NEXT: s_xor_b32 s1, s5, 1
+; GFX6-NEXT: s_and_b32 s0, s0, s1
+; GFX6-NEXT: s_cmp_lg_u32 s0, 0
+; GFX6-NEXT: s_cselect_b32 s0, 0x7fc00000, s2
+; GFX6-NEXT: v_mov_b32_e32 v0, s0
; GFX6-NEXT: ; return to shader part epilog
;
; GFX8-LABEL: v_pow_f32_sgpr_sgpr:
; GFX8: ; %bb.0:
; GFX8-NEXT: v_mov_b32_e32 v0, 0x800000
-; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, s0, v0
-; GFX8-NEXT: s_cmp_lg_u64 vcc, 0
+; GFX8-NEXT: v_cmp_lt_f32_e64 s[2:3], |s0|, v0
+; GFX8-NEXT: s_cmp_lg_u64 s[2:3], 0
; GFX8-NEXT: s_cselect_b32 s3, 1, 0
; GFX8-NEXT: s_cselect_b32 s2, 1, 0
; GFX8-NEXT: s_lshl_b32 s3, s3, 5
; GFX8-NEXT: v_mov_b32_e32 v0, s3
-; GFX8-NEXT: v_ldexp_f32 v0, s0, v0
+; GFX8-NEXT: v_ldexp_f32 v0, |s0|, v0
; GFX8-NEXT: v_log_f32_e32 v0, v0
; GFX8-NEXT: s_cmp_lg_u32 s2, 0
-; GFX8-NEXT: s_cselect_b32 s0, 0x42000000, 0
+; GFX8-NEXT: s_cselect_b32 s2, 0x42000000, 0
; GFX8-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX8-NEXT: v_subrev_f32_e32 v0, s0, v0
+; GFX8-NEXT: v_subrev_f32_e32 v0, s2, v0
; GFX8-NEXT: v_mul_legacy_f32_e32 v0, s1, v0
; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
; GFX8-NEXT: s_cmp_lg_u64 vcc, 0
-; GFX8-NEXT: s_cselect_b32 s0, 0x42800000, 0
-; GFX8-NEXT: v_add_f32_e32 v0, s0, v0
+; GFX8-NEXT: s_cselect_b32 s2, 0x42800000, 0
+; GFX8-NEXT: v_add_f32_e32 v0, s2, v0
; GFX8-NEXT: v_exp_f32_e32 v0, v0
-; GFX8-NEXT: s_cselect_b32 s0, 0xffffffc0, 0
-; GFX8-NEXT: v_ldexp_f32 v0, v0, s0
+; GFX8-NEXT: s_cselect_b32 s2, 0xffffffc0, 0
+; GFX8-NEXT: v_ldexp_f32 v0, v0, s2
+; GFX8-NEXT: v_readfirstlane_b32 s2, v0
+; GFX8-NEXT: v_trunc_f32_e32 v0, s1
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, s1, v0
+; GFX8-NEXT: v_mul_f32_e64 v0, s1, 0.5
+; GFX8-NEXT: v_trunc_f32_e32 v1, v0
+; GFX8-NEXT: s_cmp_lg_u64 vcc, 0
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v1, v0
+; GFX8-NEXT: s_cselect_b32 s3, 1, 0
+; GFX8-NEXT: s_cmp_lg_u64 vcc, 0
+; GFX8-NEXT: s_cselect_b32 s1, 1, 0
+; GFX8-NEXT: s_and_b32 s4, s2, 0x7fffffff
+; GFX8-NEXT: s_and_b32 s5, s0, 0x80000000
+; GFX8-NEXT: s_and_b32 s1, s3, s1
+; GFX8-NEXT: s_or_b32 s4, s4, s5
+; GFX8-NEXT: s_cmp_lg_u32 s1, 0
+; GFX8-NEXT: v_cmp_class_f32_e64 s[0:1], s0, 24
+; GFX8-NEXT: s_cselect_b32 s2, s4, s2
+; GFX8-NEXT: s_cmp_lg_u64 s[0:1], 0
+; GFX8-NEXT: s_cselect_b32 s0, 1, 0
+; GFX8-NEXT: s_xor_b32 s1, s3, 1
+; GFX8-NEXT: s_and_b32 s0, s0, s1
+; GFX8-NEXT: s_cmp_lg_u32 s0, 0
+; GFX8-NEXT: s_cselect_b32 s0, 0x7fc00000, s2
+; GFX8-NEXT: v_mov_b32_e32 v0, s0
; GFX8-NEXT: ; return to shader part epilog
;
; GFX9-LABEL: v_pow_f32_sgpr_sgpr:
; GFX9: ; %bb.0:
; GFX9-NEXT: v_mov_b32_e32 v0, 0x800000
-; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, s0, v0
-; GFX9-NEXT: s_cmp_lg_u64 vcc, 0
+; GFX9-NEXT: v_cmp_lt_f32_e64 s[2:3], |s0|, v0
+; GFX9-NEXT: s_cmp_lg_u64 s[2:3], 0
; GFX9-NEXT: s_cselect_b32 s3, 1, 0
; GFX9-NEXT: s_cselect_b32 s2, 1, 0
; GFX9-NEXT: s_lshl_b32 s3, s3, 5
; GFX9-NEXT: v_mov_b32_e32 v0, s3
-; GFX9-NEXT: v_ldexp_f32 v0, s0, v0
+; GFX9-NEXT: v_ldexp_f32 v0, |s0|, v0
; GFX9-NEXT: v_log_f32_e32 v0, v0
; GFX9-NEXT: s_cmp_lg_u32 s2, 0
-; GFX9-NEXT: s_cselect_b32 s0, 0x42000000, 0
+; GFX9-NEXT: s_cselect_b32 s2, 0x42000000, 0
; GFX9-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX9-NEXT: v_subrev_f32_e32 v0, s0, v0
+; GFX9-NEXT: v_subrev_f32_e32 v0, s2, v0
; GFX9-NEXT: v_mul_legacy_f32_e32 v0, s1, v0
; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
; GFX9-NEXT: s_cmp_lg_u64 vcc, 0
-; GFX9-NEXT: s_cselect_b32 s0, 0x42800000, 0
-; GFX9-NEXT: v_add_f32_e32 v0, s0, v0
+; GFX9-NEXT: s_cselect_b32 s2, 0x42800000, 0
+; GFX9-NEXT: v_add_f32_e32 v0, s2, v0
; GFX9-NEXT: v_exp_f32_e32 v0, v0
-; GFX9-NEXT: s_cselect_b32 s0, 0xffffffc0, 0
-; GFX9-NEXT: v_ldexp_f32 v0, v0, s0
+; GFX9-NEXT: s_cselect_b32 s2, 0xffffffc0, 0
+; GFX9-NEXT: v_ldexp_f32 v0, v0, s2
+; GFX9-NEXT: v_readfirstlane_b32 s2, v0
+; GFX9-NEXT: v_trunc_f32_e32 v0, s1
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, s1, v0
+; GFX9-NEXT: v_mul_f32_e64 v0, s1, 0.5
+; GFX9-NEXT: v_trunc_f32_e32 v1, v0
+; GFX9-NEXT: s_cmp_lg_u64 vcc, 0
+; GFX9-NEXT: v_cmp_lg_f32_e32 vcc, v1, v0
+; GFX9-NEXT: s_cselect_b32 s3, 1, 0
+; GFX9-NEXT: s_cmp_lg_u64 vcc, 0
+; GFX9-NEXT: s_cselect_b32 s1, 1, 0
+; GFX9-NEXT: s_and_b32 s4, s2, 0x7fffffff
+; GFX9-NEXT: s_and_b32 s5, s0, 0x80000000
+; GFX9-NEXT: s_and_b32 s1, s3, s1
+; GFX9-NEXT: s_or_b32 s4, s4, s5
+; GFX9-NEXT: s_cmp_lg_u32 s1, 0
+; GFX9-NEXT: v_cmp_class_f32_e64 s[0:1], s0, 24
+; GFX9-NEXT: s_cselect_b32 s2, s4, s2
+; GFX9-NEXT: s_cmp_lg_u64 s[0:1], 0
+; GFX9-NEXT: s_cselect_b32 s0, 1, 0
+; GFX9-NEXT: s_xor_b32 s1, s3, 1
+; GFX9-NEXT: s_and_b32 s0, s0, s1
+; GFX9-NEXT: s_cmp_lg_u32 s0, 0
+; GFX9-NEXT: s_cselect_b32 s0, 0x7fc00000, s2
+; GFX9-NEXT: v_mov_b32_e32 v0, s0
; GFX9-NEXT: ; return to shader part epilog
;
; GFX10-LABEL: v_pow_f32_sgpr_sgpr:
; GFX10: ; %bb.0:
-; GFX10-NEXT: v_cmp_gt_f32_e64 s2, 0x800000, s0
+; GFX10-NEXT: v_cmp_gt_f32_e64 s2, 0x800000, |s0|
+; GFX10-NEXT: v_mul_f32_e64 v1, s1, 0.5
+; GFX10-NEXT: v_trunc_f32_e32 v2, s1
+; GFX10-NEXT: v_cmp_class_f32_e64 s4, s0, 24
; GFX10-NEXT: s_cmp_lg_u32 s2, 0
+; GFX10-NEXT: v_trunc_f32_e32 v3, v1
; GFX10-NEXT: s_cselect_b32 s3, 1, 0
; GFX10-NEXT: s_cselect_b32 s2, 1, 0
; GFX10-NEXT: s_lshl_b32 s3, s3, 5
; GFX10-NEXT: s_cmp_lg_u32 s2, 0
-; GFX10-NEXT: v_ldexp_f32 v0, s0, s3
-; GFX10-NEXT: s_cselect_b32 s0, 0x42000000, 0
+; GFX10-NEXT: v_ldexp_f32 v0, |s0|, s3
+; GFX10-NEXT: s_cselect_b32 s2, 0x42000000, 0
; GFX10-NEXT: v_log_f32_e32 v0, v0
-; GFX10-NEXT: v_subrev_f32_e32 v0, s0, v0
+; GFX10-NEXT: v_subrev_f32_e32 v0, s2, v0
; GFX10-NEXT: v_mul_legacy_f32_e32 v0, s1, v0
; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
; GFX10-NEXT: s_cmp_lg_u32 vcc_lo, 0
-; GFX10-NEXT: s_cselect_b32 s0, 0x42800000, 0
-; GFX10-NEXT: v_add_f32_e32 v0, s0, v0
-; GFX10-NEXT: s_cselect_b32 s0, 0xffffffc0, 0
+; GFX10-NEXT: v_cmp_eq_f32_e32 vcc_lo, s1, v2
+; GFX10-NEXT: s_cselect_b32 s2, 0x42800000, 0
+; GFX10-NEXT: v_cmp_lg_f32_e64 s1, v3, v1
+; GFX10-NEXT: v_add_f32_e32 v0, s2, v0
+; GFX10-NEXT: s_cselect_b32 s2, 0xffffffc0, 0
+; GFX10-NEXT: s_cmp_lg_u32 vcc_lo, 0
; GFX10-NEXT: v_exp_f32_e32 v0, v0
-; GFX10-NEXT: v_ldexp_f32 v0, v0, s0
+; GFX10-NEXT: v_ldexp_f32 v0, v0, s2
+; GFX10-NEXT: s_cselect_b32 s2, 1, 0
+; GFX10-NEXT: s_cmp_lg_u32 s1, 0
+; GFX10-NEXT: s_cselect_b32 s1, 1, 0
+; GFX10-NEXT: v_readfirstlane_b32 s3, v0
+; GFX10-NEXT: s_and_b32 s0, s0, 0x80000000
+; GFX10-NEXT: s_and_b32 s1, s2, s1
+; GFX10-NEXT: s_and_b32 s5, s3, 0x7fffffff
+; GFX10-NEXT: s_or_b32 s5, s5, s0
+; GFX10-NEXT: s_cmp_lg_u32 s1, 0
+; GFX10-NEXT: s_cselect_b32 s0, s5, s3
+; GFX10-NEXT: s_cmp_lg_u32 s4, 0
+; GFX10-NEXT: s_cselect_b32 s1, 1, 0
+; GFX10-NEXT: s_xor_b32 s2, s2, 1
+; GFX10-NEXT: s_and_b32 s1, s1, s2
+; GFX10-NEXT: s_cmp_lg_u32 s1, 0
+; GFX10-NEXT: s_cselect_b32 s0, 0x7fc00000, s0
+; GFX10-NEXT: v_mov_b32_e32 v0, s0
; GFX10-NEXT: ; return to shader part epilog
;
; GFX11-LABEL: v_pow_f32_sgpr_sgpr:
; GFX11: ; %bb.0:
-; GFX11-NEXT: v_cmp_gt_f32_e64 s2, 0x800000, s0
+; GFX11-NEXT: v_cmp_gt_f32_e64 s2, 0x800000, |s0|
+; GFX11-NEXT: v_mul_f32_e64 v1, s1, 0.5
+; GFX11-NEXT: v_trunc_f32_e32 v2, s1
+; GFX11-NEXT: v_cmp_class_f32_e64 s4, s0, 24
; GFX11-NEXT: s_cmp_lg_u32 s2, 0
+; GFX11-NEXT: v_trunc_f32_e32 v3, v1
; GFX11-NEXT: s_cselect_b32 s3, 1, 0
; GFX11-NEXT: s_cselect_b32 s2, 1, 0
; GFX11-NEXT: s_lshl_b32 s3, s3, 5
; GFX11-NEXT: s_cmp_lg_u32 s2, 0
-; GFX11-NEXT: v_ldexp_f32 v0, s0, s3
-; GFX11-NEXT: s_cselect_b32 s0, 0x42000000, 0
+; GFX11-NEXT: v_ldexp_f32 v0, |s0|, s3
+; GFX11-NEXT: s_cselect_b32 s2, 0x42000000, 0
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
; GFX11-NEXT: v_log_f32_e32 v0, v0
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_subrev_f32_e32 v0, s0, v0
+; GFX11-NEXT: v_subrev_f32_e32 v0, s2, v0
; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, s1, v0
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
; GFX11-NEXT: s_cmp_lg_u32 vcc_lo, 0
-; GFX11-NEXT: s_cselect_b32 s0, 0x42800000, 0
-; GFX11-NEXT: v_add_f32_e32 v0, s0, v0
-; GFX11-NEXT: s_cselect_b32 s0, 0xffffffc0, 0
+; GFX11-NEXT: v_cmp_eq_f32_e32 vcc_lo, s1, v2
+; GFX11-NEXT: s_cselect_b32 s2, 0x42800000, 0
+; GFX11-NEXT: v_cmp_lg_f32_e64 s1, v3, v1
+; GFX11-NEXT: v_add_f32_e32 v0, s2, v0
+; GFX11-NEXT: s_cselect_b32 s2, 0xffffffc0, 0
+; GFX11-NEXT: s_cmp_lg_u32 vcc_lo, 0
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
; GFX11-NEXT: v_exp_f32_e32 v0, v0
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_ldexp_f32 v0, v0, s0
+; GFX11-NEXT: v_ldexp_f32 v0, v0, s2
+; GFX11-NEXT: s_cselect_b32 s2, 1, 0
+; GFX11-NEXT: s_cmp_lg_u32 s1, 0
+; GFX11-NEXT: s_cselect_b32 s1, 1, 0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_3) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_readfirstlane_b32 s3, v0
+; GFX11-NEXT: s_and_b32 s0, s0, 0x80000000
+; GFX11-NEXT: s_and_b32 s1, s2, s1
+; GFX11-NEXT: s_and_b32 s5, s3, 0x7fffffff
+; GFX11-NEXT: s_or_b32 s5, s5, s0
+; GFX11-NEXT: s_cmp_lg_u32 s1, 0
+; GFX11-NEXT: s_cselect_b32 s0, s5, s3
+; GFX11-NEXT: s_cmp_lg_u32 s4, 0
+; GFX11-NEXT: s_cselect_b32 s1, 1, 0
+; GFX11-NEXT: s_xor_b32 s2, s2, 1
+; GFX11-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: s_and_b32 s1, s1, s2
+; GFX11-NEXT: s_cmp_lg_u32 s1, 0
+; GFX11-NEXT: s_cselect_b32 s0, 0x7fc00000, s0
+; GFX11-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
+; GFX11-NEXT: v_mov_b32_e32 v0, s0
; GFX11-NEXT: ; return to shader part epilog
%pow = call float @llvm.pow.f32(float %x, float %y)
ret float %pow
@@ -1752,116 +3841,195 @@ define float @v_pow_f32_fneg_lhs(float %x, float %y) {
; GFX6: ; %bb.0:
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX6-NEXT: v_mov_b32_e32 v2, 0x800000
-; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, -v0, v2
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
; GFX6-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
; GFX6-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX6-NEXT: v_ldexp_f32_e64 v0, -v0, v2
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_mov_b32_e32 v2, 0x42000000
-; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
-; GFX6-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX6-NEXT: v_mov_b32_e32 v2, 0x42800000
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
-; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
-; GFX6-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
-; GFX6-NEXT: v_not_b32_e32 v1, 63
-; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v1
+; GFX6-NEXT: v_ldexp_f32_e64 v2, |v0|, v2
+; GFX6-NEXT: v_log_f32_e32 v2, v2
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX6-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX6-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX6-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_exp_f32_e32 v2, v2
+; GFX6-NEXT: v_not_b32_e32 v4, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
+; GFX6-NEXT: v_xor_b32_e32 v3, 0x80000000, v0
+; GFX6-NEXT: v_ldexp_f32_e32 v2, v2, v4
+; GFX6-NEXT: v_trunc_f32_e32 v4, v1
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v4, v1
+; GFX6-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX6-NEXT: v_trunc_f32_e32 v4, v1
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v4, v1
+; GFX6-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX6-NEXT: v_and_b32_e32 v3, 0x80000000, v3
+; GFX6-NEXT: v_or_b32_e32 v1, v1, v3
+; GFX6-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], -v0, 24
+; GFX6-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX6-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX6-NEXT: s_setpc_b64 s[30:31]
;
; GFX8-LABEL: v_pow_f32_fneg_lhs:
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX8-NEXT: v_mov_b32_e32 v2, 0x800000
-; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, -v0, v2
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
; GFX8-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX8-NEXT: v_ldexp_f32 v0, -v0, v2
-; GFX8-NEXT: v_log_f32_e32 v0, v0
-; GFX8-NEXT: v_mov_b32_e32 v2, 0x42000000
-; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
-; GFX8-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX8-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX8-NEXT: v_mov_b32_e32 v2, 0x42800000
-; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
-; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
-; GFX8-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX8-NEXT: v_exp_f32_e32 v0, v0
-; GFX8-NEXT: v_not_b32_e32 v1, 63
-; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX8-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX8-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX8-NEXT: v_log_f32_e32 v2, v2
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX8-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX8-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX8-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_exp_f32_e32 v2, v2
+; GFX8-NEXT: v_not_b32_e32 v4, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
+; GFX8-NEXT: v_xor_b32_e32 v3, 0x80000000, v0
+; GFX8-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX8-NEXT: v_trunc_f32_e32 v4, v1
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v4, v1
+; GFX8-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v4, v1
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v4, v1
+; GFX8-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX8-NEXT: v_and_b32_e32 v3, 0x80000000, v3
+; GFX8-NEXT: v_or_b32_e32 v1, v1, v3
+; GFX8-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], -v0, 24
+; GFX8-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX8-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: v_pow_f32_fneg_lhs:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_mov_b32_e32 v2, 0x800000
-; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, -v0, v2
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
; GFX9-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
; GFX9-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX9-NEXT: v_ldexp_f32 v0, -v0, v2
-; GFX9-NEXT: v_log_f32_e32 v0, v0
-; GFX9-NEXT: v_mov_b32_e32 v2, 0x42000000
-; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
-; GFX9-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX9-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX9-NEXT: v_mov_b32_e32 v2, 0x42800000
-; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
-; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
-; GFX9-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX9-NEXT: v_exp_f32_e32 v0, v0
-; GFX9-NEXT: v_not_b32_e32 v1, 63
-; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX9-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX9-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX9-NEXT: v_log_f32_e32 v2, v2
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX9-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX9-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX9-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX9-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX9-NEXT: v_exp_f32_e32 v2, v2
+; GFX9-NEXT: v_not_b32_e32 v4, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
+; GFX9-NEXT: v_xor_b32_e32 v3, 0x80000000, v0
+; GFX9-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX9-NEXT: v_trunc_f32_e32 v4, v1
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v4, v1
+; GFX9-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX9-NEXT: v_trunc_f32_e32 v4, v1
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v4, v1
+; GFX9-NEXT: v_bfrev_b32_e32 v1, -2
+; GFX9-NEXT: v_and_b32_e32 v3, 0x80000000, v3
+; GFX9-NEXT: v_and_or_b32 v1, v2, v1, v3
+; GFX9-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX9-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], -v0, 24
+; GFX9-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX9-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_f32_fneg_lhs:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, -v0
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v0|
+; GFX10-NEXT: v_xor_b32_e32 v5, 0x80000000, v0
+; GFX10-NEXT: v_trunc_f32_e32 v6, v1
+; GFX10-NEXT: v_cmp_class_f32_e64 s6, -v0, 24
; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 1, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s4
; GFX10-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX10-NEXT: v_ldexp_f32 v0, -v0, v2
-; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s4
-; GFX10-NEXT: v_log_f32_e32 v0, v0
-; GFX10-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
-; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
-; GFX10-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, vcc_lo
-; GFX10-NEXT: v_exp_f32_e32 v0, v0
-; GFX10-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX10-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX10-NEXT: v_log_f32_e32 v2, v2
+; GFX10-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX10-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_cmp_eq_f32_e32 vcc_lo, v6, v1
+; GFX10-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX10-NEXT: v_mul_f32_e32 v3, 0.5, v1
+; GFX10-NEXT: v_exp_f32_e32 v2, v2
+; GFX10-NEXT: v_trunc_f32_e32 v7, v3
+; GFX10-NEXT: v_cmp_lg_f32_e64 s4, v7, v3
+; GFX10-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX10-NEXT: v_and_b32_e32 v4, 0x80000000, v5
+; GFX10-NEXT: s_and_b32 s4, vcc_lo, s4
+; GFX10-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v4
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v2, v1, s4
+; GFX10-NEXT: s_xor_b32 s4, vcc_lo, exec_lo
+; GFX10-NEXT: s_and_b32 s4, s6, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s4
; GFX10-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: v_pow_f32_fneg_lhs:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, -v0
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-NEXT: v_xor_b32_e32 v5, 0x80000000, v0
+; GFX11-NEXT: v_trunc_f32_e32 v6, v1
+; GFX11-NEXT: v_cmp_class_f32_e64 s2, -v0, 24
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(SKIP_1) | instid1(VALU_DEP_2)
; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 1, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s0
; GFX11-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
-; GFX11-NEXT: v_ldexp_f32 v0, -v0, v2
-; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s0
-; GFX11-NEXT: v_log_f32_e32 v0, v0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX11-NEXT: v_log_f32_e32 v2, v2
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_sub_f32_e32 v0, v0, v2
+; GFX11-NEXT: v_sub_f32_e32 v2, v2, v3
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, v0, v1
-; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
-; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
-; GFX11-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, vcc_lo
-; GFX11-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v2, v1, v2
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: v_cmp_eq_f32_e32 vcc_lo, v6, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_dual_add_f32 v2, v2, v3 :: v_dual_mul_f32 v3, 0.5, v1
+; GFX11-NEXT: v_exp_f32_e32 v2, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_trunc_f32_e32 v7, v3
+; GFX11-NEXT: v_cmp_lg_f32_e64 s0, v7, v3
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX11-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX11-NEXT: v_and_b32_e32 v4, 0x80000000, v5
+; GFX11-NEXT: s_and_b32 s0, vcc_lo, s0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v4
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v2, v1, s0
+; GFX11-NEXT: s_xor_b32 s0, vcc_lo, exec_lo
+; GFX11-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
+; GFX11-NEXT: s_and_b32 s0, s2, s0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
%neg.x = fneg float %x
%pow = call float @llvm.pow.f32(float %neg.x, float %y)
@@ -1873,17 +4041,335 @@ define float @v_pow_f32_fneg_rhs(float %x, float %y) {
; GFX6: ; %bb.0:
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX6-NEXT: v_mov_b32_e32 v2, 0x800000
-; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v2
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
; GFX6-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
; GFX6-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v2
+; GFX6-NEXT: v_ldexp_f32_e64 v2, |v0|, v2
+; GFX6-NEXT: v_log_f32_e32 v2, v2
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX6-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_mul_legacy_f32_e64 v2, -v1, v2
+; GFX6-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX6-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_exp_f32_e32 v2, v2
+; GFX6-NEXT: v_not_b32_e32 v3, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: v_cmp_class_f32_e64 s[8:9], v0, 24
+; GFX6-NEXT: v_ldexp_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_trunc_f32_e64 v3, -v1
+; GFX6-NEXT: v_cmp_eq_f32_e64 s[6:7], v3, -v1
+; GFX6-NEXT: v_mul_f32_e64 v1, -v1, 0.5
+; GFX6-NEXT: v_trunc_f32_e32 v3, v1
+; GFX6-NEXT: v_cmp_lg_f32_e32 vcc, v3, v1
+; GFX6-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX6-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX6-NEXT: v_or_b32_e32 v1, v1, v3
+; GFX6-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX6-NEXT: s_xor_b64 s[4:5], s[6:7], exec
+; GFX6-NEXT: v_cndmask_b32_e32 v1, v2, v1, vcc
+; GFX6-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX6-NEXT: s_and_b64 vcc, s[8:9], s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
+; GFX6-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX8-LABEL: v_pow_f32_fneg_rhs:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x800000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
+; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX8-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX8-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX8-NEXT: v_log_f32_e32 v2, v2
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX8-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_mul_legacy_f32_e64 v2, -v1, v2
+; GFX8-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX8-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_exp_f32_e32 v2, v2
+; GFX8-NEXT: v_not_b32_e32 v3, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 s[8:9], v0, 24
+; GFX8-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX8-NEXT: v_trunc_f32_e64 v3, -v1
+; GFX8-NEXT: v_cmp_eq_f32_e64 s[6:7], v3, -v1
+; GFX8-NEXT: v_mul_f32_e64 v1, -v1, 0.5
+; GFX8-NEXT: v_trunc_f32_e32 v3, v1
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v3, v1
+; GFX8-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX8-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX8-NEXT: v_or_b32_e32 v1, v1, v3
+; GFX8-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX8-NEXT: s_xor_b64 s[4:5], s[6:7], exec
+; GFX8-NEXT: v_cndmask_b32_e32 v1, v2, v1, vcc
+; GFX8-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[8:9], s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
+; GFX8-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: v_pow_f32_fneg_rhs:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x800000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
+; GFX9-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX9-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX9-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX9-NEXT: v_log_f32_e32 v2, v2
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX9-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX9-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX9-NEXT: v_mul_legacy_f32_e64 v2, -v1, v2
+; GFX9-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX9-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX9-NEXT: v_exp_f32_e32 v2, v2
+; GFX9-NEXT: v_not_b32_e32 v3, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX9-NEXT: v_cmp_class_f32_e64 s[8:9], v0, 24
+; GFX9-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX9-NEXT: v_trunc_f32_e64 v3, -v1
+; GFX9-NEXT: v_cmp_eq_f32_e64 s[6:7], v3, -v1
+; GFX9-NEXT: v_mul_f32_e64 v1, -v1, 0.5
+; GFX9-NEXT: v_trunc_f32_e32 v3, v1
+; GFX9-NEXT: v_cmp_lg_f32_e32 vcc, v3, v1
+; GFX9-NEXT: v_bfrev_b32_e32 v1, -2
+; GFX9-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX9-NEXT: v_and_or_b32 v1, v2, v1, v3
+; GFX9-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX9-NEXT: s_xor_b64 s[4:5], s[6:7], exec
+; GFX9-NEXT: v_cndmask_b32_e32 v1, v2, v1, vcc
+; GFX9-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX9-NEXT: s_and_b64 vcc, s[8:9], s[4:5]
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: v_pow_f32_fneg_rhs:
+; GFX10: ; %bb.0:
+; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT: v_cmp_gt_f32_e64 s5, 0x800000, |v0|
+; GFX10-NEXT: v_trunc_f32_e64 v5, -v1
+; GFX10-NEXT: v_cmp_class_f32_e64 s6, v0, 24
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 1, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s5
+; GFX10-NEXT: v_cmp_eq_f32_e64 s5, v5, -v1
+; GFX10-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX10-NEXT: s_xor_b32 s4, s5, exec_lo
+; GFX10-NEXT: s_and_b32 s4, s6, s4
+; GFX10-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX10-NEXT: v_log_f32_e32 v2, v2
+; GFX10-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX10-NEXT: v_mul_legacy_f32_e64 v2, -v1, v2
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX10-NEXT: v_mul_f32_e64 v3, -v1, 0.5
+; GFX10-NEXT: v_exp_f32_e32 v2, v2
+; GFX10-NEXT: v_trunc_f32_e32 v6, v3
+; GFX10-NEXT: v_cmp_lg_f32_e32 vcc_lo, v6, v3
+; GFX10-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX10-NEXT: v_and_b32_e32 v4, 0x80000000, v0
+; GFX10-NEXT: s_and_b32 vcc_lo, s5, vcc_lo
+; GFX10-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v4
+; GFX10-NEXT: v_cndmask_b32_e32 v0, v2, v1, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s4
+; GFX10-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: v_pow_f32_fneg_rhs:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v0|
+; GFX11-NEXT: v_trunc_f32_e64 v5, -v1
+; GFX11-NEXT: v_cmp_class_f32_e64 s2, v0, 24
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_4)
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 1, s1
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s1
+; GFX11-NEXT: v_cmp_eq_f32_e64 s1, v5, -v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX11-NEXT: s_xor_b32 s0, s1, exec_lo
+; GFX11-NEXT: s_and_b32 s0, s2, s0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX11-NEXT: v_log_f32_e32 v2, v2
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_mul_dx9_zero_f32_e64 v2, -v1, v2
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX11-NEXT: v_mul_f32_e64 v3, -v1, 0.5
+; GFX11-NEXT: v_exp_f32_e32 v2, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_trunc_f32_e32 v6, v3
+; GFX11-NEXT: v_cmp_lg_f32_e32 vcc_lo, v6, v3
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX11-NEXT: v_and_b32_e32 v4, 0x80000000, v0
+; GFX11-NEXT: s_and_b32 vcc_lo, s1, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v4
+; GFX11-NEXT: v_cndmask_b32_e32 v0, v2, v1, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
+; GFX11-NEXT: s_setpc_b64 s[30:31]
+ %neg.y = fneg float %y
+ %pow = call float @llvm.pow.f32(float %x, float %neg.y)
+ ret float %pow
+}
+
+define float @v_pow_f32_afn(float %x, float %y) {
+; GFX6-LABEL: v_pow_f32_afn:
+; GFX6: ; %bb.0:
+; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_mov_b32_e32 v2, 0x42000000
-; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
-; GFX6-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX6-NEXT: v_mul_legacy_f32_e64 v0, v0, -v1
-; GFX6-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
+; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX6-NEXT: v_exp_f32_e32 v0, v0
+; GFX6-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX8-LABEL: v_pow_f32_afn:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8-NEXT: v_log_f32_e32 v0, v0
+; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX8-NEXT: v_exp_f32_e32 v0, v0
+; GFX8-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: v_pow_f32_afn:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: v_log_f32_e32 v0, v0
+; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX9-NEXT: v_exp_f32_e32 v0, v0
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: v_pow_f32_afn:
+; GFX10: ; %bb.0:
+; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT: v_log_f32_e32 v0, v0
+; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX10-NEXT: v_exp_f32_e32 v0, v0
+; GFX10-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: v_pow_f32_afn:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: v_log_f32_e32 v0, v0
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-NEXT: s_setpc_b64 s[30:31]
+ %pow = call afn float @llvm.pow.f32(float %x, float %y)
+ ret float %pow
+}
+
+define half @v_pow_f16_afn(half %x, half %y) {
+; GFX6-LABEL: v_pow_f16_afn:
+; GFX6: ; %bb.0:
+; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v1
+; GFX6-NEXT: v_log_f32_e32 v0, v0
+; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX6-NEXT: v_exp_f32_e32 v0, v0
+; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GFX6-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX8-LABEL: v_pow_f16_afn:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX8-NEXT: v_cvt_f32_f16_e32 v1, v1
+; GFX8-NEXT: v_log_f32_e32 v0, v0
+; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX8-NEXT: v_exp_f32_e32 v0, v0
+; GFX8-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GFX8-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: v_pow_f16_afn:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX9-NEXT: v_cvt_f32_f16_e32 v1, v1
+; GFX9-NEXT: v_log_f32_e32 v0, v0
+; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX9-NEXT: v_exp_f32_e32 v0, v0
+; GFX9-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: v_pow_f16_afn:
+; GFX10: ; %bb.0:
+; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX10-NEXT: v_cvt_f32_f16_e32 v1, v1
+; GFX10-NEXT: v_log_f32_e32 v0, v0
+; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX10-NEXT: v_exp_f32_e32 v0, v0
+; GFX10-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GFX10-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-TRUE16-LABEL: v_pow_f16_afn:
+; GFX11-TRUE16: ; %bb.0:
+; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.l
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v1.l
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v0, v0
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v0
+; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-FAKE16-LABEL: v_pow_f16_afn:
+; GFX11-FAKE16: ; %bb.0:
+; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v1, v1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v0, v0
+; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
+ %pow = call afn half @llvm.pow.f16(half %x, half %y)
+ ret half %pow
+}
+
+define float @v_pow_f32_const_even_int(float %x) {
+; GFX6-LABEL: v_pow_f32_const_even_int:
+; GFX6: ; %bb.0:
+; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX6-NEXT: v_mov_b32_e32 v1, 0x800000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v1
+; GFX6-NEXT: v_cndmask_b32_e64 v1, 0, 1, vcc
+; GFX6-NEXT: v_lshlrev_b32_e32 v1, 5, v1
+; GFX6-NEXT: v_ldexp_f32_e64 v0, |v0|, v1
+; GFX6-NEXT: v_log_f32_e32 v0, v0
+; GFX6-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
; GFX6-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX6-NEXT: v_sub_f32_e32 v0, v0, v1
+; GFX6-NEXT: v_mul_legacy_f32_e32 v0, 2.0, v0
+; GFX6-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
; GFX6-NEXT: v_add_f32_e32 v0, v0, v1
@@ -1893,21 +4379,21 @@ define float @v_pow_f32_fneg_rhs(float %x, float %y) {
; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v1
; GFX6-NEXT: s_setpc_b64 s[30:31]
;
-; GFX8-LABEL: v_pow_f32_fneg_rhs:
+; GFX8-LABEL: v_pow_f32_const_even_int:
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX8-NEXT: v_mov_b32_e32 v2, 0x800000
-; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v0, v2
-; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
-; GFX8-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX8-NEXT: v_ldexp_f32 v0, v0, v2
+; GFX8-NEXT: v_mov_b32_e32 v1, 0x800000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v1
+; GFX8-NEXT: v_cndmask_b32_e64 v1, 0, 1, vcc
+; GFX8-NEXT: v_lshlrev_b32_e32 v1, 5, v1
+; GFX8-NEXT: v_ldexp_f32 v0, |v0|, v1
; GFX8-NEXT: v_log_f32_e32 v0, v0
-; GFX8-NEXT: v_mov_b32_e32 v2, 0x42000000
-; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
-; GFX8-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX8-NEXT: v_mul_legacy_f32_e64 v0, v0, -v1
-; GFX8-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
+; GFX8-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
; GFX8-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX8-NEXT: v_sub_f32_e32 v0, v0, v1
+; GFX8-NEXT: v_mul_legacy_f32_e32 v0, 2.0, v0
+; GFX8-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
; GFX8-NEXT: v_add_f32_e32 v0, v0, v1
@@ -1917,21 +4403,21 @@ define float @v_pow_f32_fneg_rhs(float %x, float %y) {
; GFX8-NEXT: v_ldexp_f32 v0, v0, v1
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
-; GFX9-LABEL: v_pow_f32_fneg_rhs:
+; GFX9-LABEL: v_pow_f32_const_even_int:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT: v_mov_b32_e32 v2, 0x800000
-; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v0, v2
-; GFX9-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
-; GFX9-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX9-NEXT: v_ldexp_f32 v0, v0, v2
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x800000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v1
+; GFX9-NEXT: v_cndmask_b32_e64 v1, 0, 1, vcc
+; GFX9-NEXT: v_lshlrev_b32_e32 v1, 5, v1
+; GFX9-NEXT: v_ldexp_f32 v0, |v0|, v1
; GFX9-NEXT: v_log_f32_e32 v0, v0
-; GFX9-NEXT: v_mov_b32_e32 v2, 0x42000000
-; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
-; GFX9-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX9-NEXT: v_mul_legacy_f32_e64 v0, v0, -v1
-; GFX9-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
; GFX9-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX9-NEXT: v_sub_f32_e32 v0, v0, v1
+; GFX9-NEXT: v_mul_legacy_f32_e32 v0, 2.0, v0
+; GFX9-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
; GFX9-NEXT: v_add_f32_e32 v0, v0, v1
@@ -1941,17 +4427,17 @@ define float @v_pow_f32_fneg_rhs(float %x, float %y) {
; GFX9-NEXT: v_ldexp_f32 v0, v0, v1
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
-; GFX10-LABEL: v_pow_f32_fneg_rhs:
+; GFX10-LABEL: v_pow_f32_const_even_int:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0x800000, v0
-; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc_lo
-; GFX10-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX10-NEXT: v_ldexp_f32 v0, v0, v2
-; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, vcc_lo
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v0|
+; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 1, s4
+; GFX10-NEXT: v_lshlrev_b32_e32 v1, 5, v1
+; GFX10-NEXT: v_ldexp_f32 v0, |v0|, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42000000, s4
; GFX10-NEXT: v_log_f32_e32 v0, v0
-; GFX10-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX10-NEXT: v_mul_legacy_f32_e64 v0, v0, -v1
+; GFX10-NEXT: v_sub_f32_e32 v0, v0, v1
+; GFX10-NEXT: v_mul_legacy_f32_e32 v0, 2.0, v0
; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
; GFX10-NEXT: v_add_f32_e32 v0, v0, v1
@@ -1960,32 +4446,589 @@ define float @v_pow_f32_fneg_rhs(float %x, float %y) {
; GFX10-NEXT: v_ldexp_f32 v0, v0, v1
; GFX10-NEXT: s_setpc_b64 s[30:31]
;
-; GFX11-LABEL: v_pow_f32_fneg_rhs:
+; GFX11-LABEL: v_pow_f32_const_even_int:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0x800000, v0
-; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc_lo
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX11-NEXT: v_ldexp_f32 v0, v0, v2
-; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, vcc_lo
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 1, s0
+; GFX11-NEXT: v_lshlrev_b32_e32 v1, 5, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_ldexp_f32 v0, |v0|, v1
+; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42000000, s0
; GFX11-NEXT: v_log_f32_e32 v0, v0
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX11-NEXT: v_mul_dx9_zero_f32_e64 v0, v0, -v1
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_sub_f32_e32 v0, v0, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, 2.0, v0
; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
; GFX11-NEXT: v_add_f32_e32 v0, v0, v1
; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, vcc_lo
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2)
; GFX11-NEXT: v_exp_f32_e32 v0, v0
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
; GFX11-NEXT: v_ldexp_f32 v0, v0, v1
; GFX11-NEXT: s_setpc_b64 s[30:31]
- %neg.y = fneg float %y
- %pow = call float @llvm.pow.f32(float %x, float %neg.y)
+ %pow = call float @llvm.pow.f32(float %x, float 2.0)
+ ret float %pow
+}
+
+define float @v_pow_f32_const_odd_int(float %x) {
+; GFX6-LABEL: v_pow_f32_const_odd_int:
+; GFX6: ; %bb.0:
+; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX6-NEXT: v_mov_b32_e32 v1, 0x800000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v1
+; GFX6-NEXT: v_cndmask_b32_e64 v1, 0, 1, vcc
+; GFX6-NEXT: v_lshlrev_b32_e32 v1, 5, v1
+; GFX6-NEXT: v_ldexp_f32_e64 v1, |v0|, v1
+; GFX6-NEXT: v_log_f32_e32 v1, v1
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX6-NEXT: v_sub_f32_e32 v1, v1, v2
+; GFX6-NEXT: v_mul_legacy_f32_e32 v1, 0x40400000, v1
+; GFX6-NEXT: v_mov_b32_e32 v2, 0xc2fc0000
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v1, v2
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v3, vcc
+; GFX6-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX6-NEXT: v_exp_f32_e32 v1, v1
+; GFX6-NEXT: v_not_b32_e32 v2, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: v_and_b32_e32 v0, 0x80000000, v0
+; GFX6-NEXT: v_ldexp_f32_e32 v1, v1, v2
+; GFX6-NEXT: v_and_b32_e32 v1, 0x7fffffff, v1
+; GFX6-NEXT: v_or_b32_e32 v0, v1, v0
+; GFX6-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX8-LABEL: v_pow_f32_const_odd_int:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8-NEXT: v_mov_b32_e32 v1, 0x800000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v1
+; GFX8-NEXT: v_cndmask_b32_e64 v1, 0, 1, vcc
+; GFX8-NEXT: v_lshlrev_b32_e32 v1, 5, v1
+; GFX8-NEXT: v_ldexp_f32 v1, |v0|, v1
+; GFX8-NEXT: v_log_f32_e32 v1, v1
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX8-NEXT: v_sub_f32_e32 v1, v1, v2
+; GFX8-NEXT: v_mul_legacy_f32_e32 v1, 0x40400000, v1
+; GFX8-NEXT: v_mov_b32_e32 v2, 0xc2fc0000
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v1, v2
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v3, vcc
+; GFX8-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX8-NEXT: v_exp_f32_e32 v1, v1
+; GFX8-NEXT: v_not_b32_e32 v2, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: v_and_b32_e32 v0, 0x80000000, v0
+; GFX8-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX8-NEXT: v_and_b32_e32 v1, 0x7fffffff, v1
+; GFX8-NEXT: v_or_b32_e32 v0, v1, v0
+; GFX8-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: v_pow_f32_const_odd_int:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x800000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v1
+; GFX9-NEXT: v_cndmask_b32_e64 v1, 0, 1, vcc
+; GFX9-NEXT: v_lshlrev_b32_e32 v1, 5, v1
+; GFX9-NEXT: v_ldexp_f32 v1, |v0|, v1
+; GFX9-NEXT: v_log_f32_e32 v1, v1
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX9-NEXT: v_sub_f32_e32 v1, v1, v2
+; GFX9-NEXT: v_mul_legacy_f32_e32 v1, 0x40400000, v1
+; GFX9-NEXT: v_mov_b32_e32 v2, 0xc2fc0000
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v1, v2
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v3, vcc
+; GFX9-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX9-NEXT: v_exp_f32_e32 v1, v1
+; GFX9-NEXT: v_not_b32_e32 v2, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: v_and_b32_e32 v0, 0x80000000, v0
+; GFX9-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX9-NEXT: v_bfrev_b32_e32 v2, -2
+; GFX9-NEXT: v_and_or_b32 v0, v1, v2, v0
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: v_pow_f32_const_odd_int:
+; GFX10: ; %bb.0:
+; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v0|
+; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 1, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s4
+; GFX10-NEXT: v_lshlrev_b32_e32 v1, 5, v1
+; GFX10-NEXT: v_ldexp_f32 v1, |v0|, v1
+; GFX10-NEXT: v_and_b32_e32 v0, 0x80000000, v0
+; GFX10-NEXT: v_log_f32_e32 v1, v1
+; GFX10-NEXT: v_sub_f32_e32 v1, v1, v2
+; GFX10-NEXT: v_mul_legacy_f32_e32 v1, 0x40400000, v1
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_exp_f32_e32 v1, v1
+; GFX10-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX10-NEXT: v_and_or_b32 v0, 0x7fffffff, v1, v0
+; GFX10-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: v_pow_f32_const_odd_int:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 1, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s0
+; GFX11-NEXT: v_lshlrev_b32_e32 v1, 5, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_ldexp_f32 v1, |v0|, v1
+; GFX11-NEXT: v_and_b32_e32 v0, 0x80000000, v0
+; GFX11-NEXT: v_log_f32_e32 v1, v1
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_sub_f32_e32 v1, v1, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v1, 0x40400000, v1
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v1
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: v_exp_f32_e32 v1, v1
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT: v_and_or_b32 v0, 0x7fffffff, v1, v0
+; GFX11-NEXT: s_setpc_b64 s[30:31]
+ %pow = call float @llvm.pow.f32(float %x, float 3.0)
+ ret float %pow
+}
+
+define float @v_pow_f32_const_non_int(float %x) {
+; GFX6-LABEL: v_pow_f32_const_non_int:
+; GFX6: ; %bb.0:
+; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX6-NEXT: v_mov_b32_e32 v1, 0x800000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v1
+; GFX6-NEXT: v_cndmask_b32_e64 v1, 0, 1, vcc
+; GFX6-NEXT: v_lshlrev_b32_e32 v1, 5, v1
+; GFX6-NEXT: v_ldexp_f32_e64 v1, |v0|, v1
+; GFX6-NEXT: v_log_f32_e32 v1, v1
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX6-NEXT: v_sub_f32_e32 v1, v1, v2
+; GFX6-NEXT: v_mul_legacy_f32_e32 v1, 0.5, v1
+; GFX6-NEXT: v_mov_b32_e32 v2, 0xc2fc0000
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v1, v2
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v3, vcc
+; GFX6-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX6-NEXT: v_exp_f32_e32 v1, v1
+; GFX6-NEXT: v_not_b32_e32 v2, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: v_cmp_class_f32_e64 vcc, v0, 24
+; GFX6-NEXT: v_ldexp_f32_e32 v1, v1, v2
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v1, v2, vcc
+; GFX6-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX8-LABEL: v_pow_f32_const_non_int:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8-NEXT: v_mov_b32_e32 v1, 0x800000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v1
+; GFX8-NEXT: v_cndmask_b32_e64 v1, 0, 1, vcc
+; GFX8-NEXT: v_lshlrev_b32_e32 v1, 5, v1
+; GFX8-NEXT: v_ldexp_f32 v1, |v0|, v1
+; GFX8-NEXT: v_log_f32_e32 v1, v1
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX8-NEXT: v_sub_f32_e32 v1, v1, v2
+; GFX8-NEXT: v_mul_legacy_f32_e32 v1, 0.5, v1
+; GFX8-NEXT: v_mov_b32_e32 v2, 0xc2fc0000
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v1, v2
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v3, vcc
+; GFX8-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX8-NEXT: v_exp_f32_e32 v1, v1
+; GFX8-NEXT: v_not_b32_e32 v2, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 vcc, v0, 24
+; GFX8-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v1, v2, vcc
+; GFX8-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: v_pow_f32_const_non_int:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x800000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v1
+; GFX9-NEXT: v_cndmask_b32_e64 v1, 0, 1, vcc
+; GFX9-NEXT: v_lshlrev_b32_e32 v1, 5, v1
+; GFX9-NEXT: v_ldexp_f32 v1, |v0|, v1
+; GFX9-NEXT: v_log_f32_e32 v1, v1
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX9-NEXT: v_sub_f32_e32 v1, v1, v2
+; GFX9-NEXT: v_mul_legacy_f32_e32 v1, 0.5, v1
+; GFX9-NEXT: v_mov_b32_e32 v2, 0xc2fc0000
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v1, v2
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v3, vcc
+; GFX9-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX9-NEXT: v_exp_f32_e32 v1, v1
+; GFX9-NEXT: v_not_b32_e32 v2, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: v_cmp_class_f32_e64 vcc, v0, 24
+; GFX9-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v1, v2, vcc
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: v_pow_f32_const_non_int:
+; GFX10: ; %bb.0:
+; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v0|
+; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 1, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s4
+; GFX10-NEXT: v_cmp_class_f32_e64 s4, v0, 24
+; GFX10-NEXT: v_lshlrev_b32_e32 v1, 5, v1
+; GFX10-NEXT: v_ldexp_f32 v1, |v0|, v1
+; GFX10-NEXT: v_log_f32_e32 v1, v1
+; GFX10-NEXT: v_sub_f32_e32 v1, v1, v2
+; GFX10-NEXT: v_mul_legacy_f32_e32 v1, 0.5, v1
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_exp_f32_e32 v1, v1
+; GFX10-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v1, 0x7fc00000, s4
+; GFX10-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: v_pow_f32_const_non_int:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_3)
+; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 1, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s0
+; GFX11-NEXT: v_cmp_class_f32_e64 s0, v0, 24
+; GFX11-NEXT: v_lshlrev_b32_e32 v1, 5, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_ldexp_f32 v1, |v0|, v1
+; GFX11-NEXT: v_log_f32_e32 v1, v1
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_sub_f32_e32 v1, v1, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v1, 0.5, v1
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v1
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: v_exp_f32_e32 v1, v1
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v1, 0x7fc00000, s0
+; GFX11-NEXT: s_setpc_b64 s[30:31]
+ %pow = call float @llvm.pow.f32(float %x, float 5.000000e-01)
+ ret float %pow
+}
+
+define float @v_pow_f32_nnan(float %x, float %y) {
+; GFX6-LABEL: v_pow_f32_nnan:
+; GFX6: ; %bb.0:
+; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x800000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
+; GFX6-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX6-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX6-NEXT: v_ldexp_f32_e64 v2, |v0|, v2
+; GFX6-NEXT: v_log_f32_e32 v2, v2
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX6-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX6-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX6-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX6-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_exp_f32_e32 v2, v2
+; GFX6-NEXT: v_not_b32_e32 v3, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: v_and_b32_e32 v0, 0x80000000, v0
+; GFX6-NEXT: v_ldexp_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_trunc_f32_e32 v3, v1
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v3, v1
+; GFX6-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX6-NEXT: v_trunc_f32_e32 v3, v1
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v3, v1
+; GFX6-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX6-NEXT: v_or_b32_e32 v0, v1, v0
+; GFX6-NEXT: s_and_b64 vcc, vcc, s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
+; GFX6-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX8-LABEL: v_pow_f32_nnan:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x800000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
+; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX8-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX8-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX8-NEXT: v_log_f32_e32 v2, v2
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX8-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX8-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX8-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_exp_f32_e32 v2, v2
+; GFX8-NEXT: v_not_b32_e32 v3, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_and_b32_e32 v0, 0x80000000, v0
+; GFX8-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX8-NEXT: v_trunc_f32_e32 v3, v1
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v3, v1
+; GFX8-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v3, v1
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v3, v1
+; GFX8-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX8-NEXT: v_or_b32_e32 v0, v1, v0
+; GFX8-NEXT: s_and_b64 vcc, vcc, s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
+; GFX8-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: v_pow_f32_nnan:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x800000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
+; GFX9-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX9-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX9-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX9-NEXT: v_log_f32_e32 v2, v2
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX9-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX9-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX9-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX9-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX9-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX9-NEXT: v_exp_f32_e32 v2, v2
+; GFX9-NEXT: v_not_b32_e32 v3, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX9-NEXT: v_and_b32_e32 v0, 0x80000000, v0
+; GFX9-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX9-NEXT: v_trunc_f32_e32 v3, v1
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v3, v1
+; GFX9-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX9-NEXT: v_trunc_f32_e32 v3, v1
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v3, v1
+; GFX9-NEXT: v_bfrev_b32_e32 v1, -2
+; GFX9-NEXT: v_and_or_b32 v0, v2, v1, v0
+; GFX9-NEXT: s_and_b64 vcc, vcc, s[4:5]
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: v_pow_f32_nnan:
+; GFX10: ; %bb.0:
+; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v0|
+; GFX10-NEXT: v_trunc_f32_e32 v5, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 1, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s4
+; GFX10-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX10-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX10-NEXT: v_and_b32_e32 v0, 0x80000000, v0
+; GFX10-NEXT: v_log_f32_e32 v2, v2
+; GFX10-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX10-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_cmp_eq_f32_e32 vcc_lo, v5, v1
+; GFX10-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX10-NEXT: v_mul_f32_e32 v3, 0.5, v1
+; GFX10-NEXT: v_exp_f32_e32 v2, v2
+; GFX10-NEXT: v_trunc_f32_e32 v6, v3
+; GFX10-NEXT: v_cmp_lg_f32_e64 s4, v6, v3
+; GFX10-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX10-NEXT: s_and_b32 vcc_lo, vcc_lo, s4
+; GFX10-NEXT: v_and_or_b32 v0, 0x7fffffff, v2, v0
+; GFX10-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc_lo
+; GFX10-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: v_pow_f32_nnan:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-NEXT: v_trunc_f32_e32 v5, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 1, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s0
+; GFX11-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX11-NEXT: v_and_b32_e32 v0, 0x80000000, v0
+; GFX11-NEXT: v_log_f32_e32 v2, v2
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v2, v1, v2
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: v_cmp_eq_f32_e32 vcc_lo, v5, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_dual_add_f32 v2, v2, v3 :: v_dual_mul_f32 v3, 0.5, v1
+; GFX11-NEXT: v_exp_f32_e32 v2, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_trunc_f32_e32 v6, v3
+; GFX11-NEXT: v_cmp_lg_f32_e64 s0, v6, v3
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX11-NEXT: s_and_b32 vcc_lo, vcc_lo, s0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_and_or_b32 v0, 0x7fffffff, v2, v0
+; GFX11-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc_lo
+; GFX11-NEXT: s_setpc_b64 s[30:31]
+ %pow = call nnan float @llvm.pow.f32(float %x, float %y)
+ ret float %pow
+}
+
+define float @v_pow_f32_daz(float %x, float %y) #0 {
+; GFX6-LABEL: v_pow_f32_daz:
+; GFX6: ; %bb.0:
+; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX6-NEXT: v_log_f32_e64 v2, |v0|
+; GFX6-NEXT: v_trunc_f32_e32 v3, v1
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v3, v1
+; GFX6-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX6-NEXT: v_exp_f32_e32 v2, v2
+; GFX6-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX6-NEXT: v_trunc_f32_e32 v3, v1
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v3, v1
+; GFX6-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX6-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX6-NEXT: v_or_b32_e32 v1, v1, v3
+; GFX6-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 8
+; GFX6-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
+; GFX6-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX8-LABEL: v_pow_f32_daz:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8-NEXT: v_log_f32_e64 v2, |v0|
+; GFX8-NEXT: v_trunc_f32_e32 v3, v1
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v3, v1
+; GFX8-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX8-NEXT: v_exp_f32_e32 v2, v2
+; GFX8-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v3, v1
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v3, v1
+; GFX8-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX8-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX8-NEXT: v_or_b32_e32 v1, v1, v3
+; GFX8-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 8
+; GFX8-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
+; GFX8-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: v_pow_f32_daz:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: v_log_f32_e64 v2, |v0|
+; GFX9-NEXT: v_trunc_f32_e32 v3, v1
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v3, v1
+; GFX9-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX9-NEXT: v_exp_f32_e32 v2, v2
+; GFX9-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX9-NEXT: v_trunc_f32_e32 v3, v1
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v3, v1
+; GFX9-NEXT: v_bfrev_b32_e32 v1, -2
+; GFX9-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX9-NEXT: v_and_or_b32 v1, v2, v1, v3
+; GFX9-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX9-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 8
+; GFX9-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: v_pow_f32_daz:
+; GFX10: ; %bb.0:
+; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT: v_log_f32_e64 v2, |v0|
+; GFX10-NEXT: v_mul_f32_e32 v3, 0.5, v1
+; GFX10-NEXT: v_trunc_f32_e32 v4, v1
+; GFX10-NEXT: v_and_b32_e32 v6, 0x80000000, v0
+; GFX10-NEXT: v_cmp_class_f32_e64 s6, v0, 8
+; GFX10-NEXT: v_trunc_f32_e32 v5, v3
+; GFX10-NEXT: v_cmp_eq_f32_e32 vcc_lo, v4, v1
+; GFX10-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX10-NEXT: v_cmp_lg_f32_e64 s4, v5, v3
+; GFX10-NEXT: v_exp_f32_e32 v2, v2
+; GFX10-NEXT: s_and_b32 s4, vcc_lo, s4
+; GFX10-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v6
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v2, v1, s4
+; GFX10-NEXT: s_xor_b32 s4, vcc_lo, exec_lo
+; GFX10-NEXT: s_and_b32 s4, s6, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s4
+; GFX10-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: v_pow_f32_daz:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: v_log_f32_e64 v2, |v0|
+; GFX11-NEXT: v_trunc_f32_e32 v4, v1
+; GFX11-NEXT: v_and_b32_e32 v6, 0x80000000, v0
+; GFX11-NEXT: v_cmp_class_f32_e64 s2, v0, 8
+; GFX11-NEXT: v_mul_f32_e32 v3, 0.5, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_cmp_eq_f32_e32 vcc_lo, v4, v1
+; GFX11-NEXT: v_trunc_f32_e32 v5, v3
+; GFX11-NEXT: s_delay_alu instid0(TRANS32_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v2, v1, v2
+; GFX11-NEXT: v_cmp_lg_f32_e64 s0, v5, v3
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_3) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_exp_f32_e32 v2, v2
+; GFX11-NEXT: s_and_b32 s0, vcc_lo, s0
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v6
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v2, v1, s0
+; GFX11-NEXT: s_xor_b32 s0, vcc_lo, exec_lo
+; GFX11-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
+; GFX11-NEXT: s_and_b32 s0, s2, s0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
+; GFX11-NEXT: s_setpc_b64 s[30:31]
+ %pow = call float @llvm.pow.f32(float %x, float %y)
ret float %pow
}
@@ -1998,3 +5041,5 @@ declare float @llvm.fabs.f32(float)
declare <2 x half> @llvm.pow.v2f16(<2 x half>, <2 x half>)
declare <2 x float> @llvm.pow.v2f32(<2 x float>, <2 x float>)
+
+attributes #0 = { denormal_fpenv(float:preservesign|preservesign) }
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-fpow.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-fpow.mir
index fa3d8377a5bd8..8fb41b0b6f6c8 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-fpow.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-fpow.mir
@@ -15,18 +15,19 @@ body: |
; GFX6-NEXT: {{ $}}
; GFX6-NEXT: [[COPY:%[0-9]+]]:_(f32) = COPY $vgpr0
; GFX6-NEXT: [[COPY1:%[0-9]+]]:_(f32) = COPY $vgpr1
+ ; GFX6-NEXT: [[FABS:%[0-9]+]]:_(f32) = G_FABS [[COPY]]
; GFX6-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
- ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[COPY]](f32), [[C]]
+ ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C]]
; GFX6-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
; GFX6-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
; GFX6-NEXT: [[SELECT:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C1]], [[C2]]
- ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[COPY]], [[SELECT]]
+ ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[FABS]], [[SELECT]]
; GFX6-NEXT: [[INT:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
; GFX6-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
; GFX6-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
; GFX6-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C3]], [[C4]]
; GFX6-NEXT: [[FSUB:%[0-9]+]]:_(f32) = G_FSUB [[INT]], [[SELECT1]]
- ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FSUB]](f32), [[COPY1]](f32)
+ ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[COPY1]](f32), [[FSUB]](f32)
; GFX6-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
; GFX6-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT1]](f32), [[C5]]
; GFX6-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
@@ -36,25 +37,48 @@ body: |
; GFX6-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
; GFX6-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = G_SELECT [[FCMP1]](s1), [[C7]], [[C2]]
; GFX6-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = G_FMUL [[INT2]], [[SELECT3]]
- ; GFX6-NEXT: $vgpr0 = COPY [[FMUL1]](f32)
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[COPY1]]
+ ; GFX6-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[COPY1]]
+ ; GFX6-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX6-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[COPY1]], [[C8]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX6-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX6-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX6-NEXT: [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX6-NEXT: [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[COPY]](f32)
+ ; GFX6-NEXT: [[C9:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX6-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX6-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST]], [[C10]]
+ ; GFX6-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST1]], [[C9]]
+ ; GFX6-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX6-NEXT: [[BITCAST2:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX6-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST2]], [[FMUL1]]
+ ; GFX6-NEXT: [[IS_FPCLASS:%[0-9]+]]:_(s1) = G_IS_FPCLASS [[COPY]](f32), 24
+ ; GFX6-NEXT: [[C11:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
+ ; GFX6-NEXT: [[XOR:%[0-9]+]]:_(s1) = G_XOR [[FCMP2]], [[C11]]
+ ; GFX6-NEXT: [[AND3:%[0-9]+]]:_(s1) = G_AND [[IS_FPCLASS]], [[XOR]]
+ ; GFX6-NEXT: [[C12:%[0-9]+]]:_(f32) = G_FCONSTANT float +qnan
+ ; GFX6-NEXT: [[SELECT5:%[0-9]+]]:_(f32) = G_SELECT [[AND3]](s1), [[C12]], [[SELECT4]]
+ ; GFX6-NEXT: $vgpr0 = COPY [[SELECT5]](f32)
;
; GFX9-LABEL: name: test_fpow_f32
; GFX9: liveins: $vgpr0, $vgpr1
; GFX9-NEXT: {{ $}}
; GFX9-NEXT: [[COPY:%[0-9]+]]:_(f32) = COPY $vgpr0
; GFX9-NEXT: [[COPY1:%[0-9]+]]:_(f32) = COPY $vgpr1
+ ; GFX9-NEXT: [[FABS:%[0-9]+]]:_(f32) = G_FABS [[COPY]]
; GFX9-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
- ; GFX9-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[COPY]](f32), [[C]]
+ ; GFX9-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C]]
; GFX9-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
; GFX9-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
; GFX9-NEXT: [[SELECT:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C1]], [[C2]]
- ; GFX9-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[COPY]], [[SELECT]]
+ ; GFX9-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[FABS]], [[SELECT]]
; GFX9-NEXT: [[INT:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
; GFX9-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
; GFX9-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
; GFX9-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C3]], [[C4]]
; GFX9-NEXT: [[FSUB:%[0-9]+]]:_(f32) = G_FSUB [[INT]], [[SELECT1]]
- ; GFX9-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FSUB]](f32), [[COPY1]](f32)
+ ; GFX9-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[COPY1]](f32), [[FSUB]](f32)
; GFX9-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
; GFX9-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT1]](f32), [[C5]]
; GFX9-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
@@ -64,7 +88,29 @@ body: |
; GFX9-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
; GFX9-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = G_SELECT [[FCMP1]](s1), [[C7]], [[C2]]
; GFX9-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = G_FMUL [[INT2]], [[SELECT3]]
- ; GFX9-NEXT: $vgpr0 = COPY [[FMUL1]](f32)
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[COPY1]]
+ ; GFX9-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[COPY1]]
+ ; GFX9-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX9-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[COPY1]], [[C8]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX9-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX9-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX9-NEXT: [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX9-NEXT: [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[COPY]](f32)
+ ; GFX9-NEXT: [[C9:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX9-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX9-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST]], [[C10]]
+ ; GFX9-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST1]], [[C9]]
+ ; GFX9-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX9-NEXT: [[BITCAST2:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX9-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST2]], [[FMUL1]]
+ ; GFX9-NEXT: [[IS_FPCLASS:%[0-9]+]]:_(s1) = G_IS_FPCLASS [[COPY]](f32), 24
+ ; GFX9-NEXT: [[C11:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
+ ; GFX9-NEXT: [[XOR:%[0-9]+]]:_(s1) = G_XOR [[FCMP2]], [[C11]]
+ ; GFX9-NEXT: [[AND3:%[0-9]+]]:_(s1) = G_AND [[IS_FPCLASS]], [[XOR]]
+ ; GFX9-NEXT: [[C12:%[0-9]+]]:_(f32) = G_FCONSTANT float +qnan
+ ; GFX9-NEXT: [[SELECT5:%[0-9]+]]:_(f32) = G_SELECT [[AND3]](s1), [[C12]], [[SELECT4]]
+ ; GFX9-NEXT: $vgpr0 = COPY [[SELECT5]](f32)
%0:_(f32) = COPY $vgpr0
%1:_(f32) = COPY $vgpr1
%2:_(f32) = G_FPOW %0, %1
@@ -84,18 +130,19 @@ body: |
; GFX6-NEXT: [[COPY1:%[0-9]+]]:_(<2 x f32>) = COPY $vgpr2_vgpr3
; GFX6-NEXT: [[UV:%[0-9]+]]:_(f32), [[UV1:%[0-9]+]]:_(f32) = G_UNMERGE_VALUES [[COPY]](<2 x f32>)
; GFX6-NEXT: [[UV2:%[0-9]+]]:_(f32), [[UV3:%[0-9]+]]:_(f32) = G_UNMERGE_VALUES [[COPY1]](<2 x f32>)
+ ; GFX6-NEXT: [[FABS:%[0-9]+]]:_(f32) = G_FABS [[UV]]
; GFX6-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
- ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[UV]](f32), [[C]]
+ ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C]]
; GFX6-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
; GFX6-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
; GFX6-NEXT: [[SELECT:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C1]], [[C2]]
- ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[UV]], [[SELECT]]
+ ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[FABS]], [[SELECT]]
; GFX6-NEXT: [[INT:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
; GFX6-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
; GFX6-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
; GFX6-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C3]], [[C4]]
; GFX6-NEXT: [[FSUB:%[0-9]+]]:_(f32) = G_FSUB [[INT]], [[SELECT1]]
- ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FSUB]](f32), [[UV2]](f32)
+ ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[UV2]](f32), [[FSUB]](f32)
; GFX6-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
; GFX6-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT1]](f32), [[C5]]
; GFX6-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
@@ -105,20 +152,60 @@ body: |
; GFX6-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
; GFX6-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = G_SELECT [[FCMP1]](s1), [[C7]], [[C2]]
; GFX6-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = G_FMUL [[INT2]], [[SELECT3]]
- ; GFX6-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[UV1]](f32), [[C]]
- ; GFX6-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[FCMP2]](s1), [[C1]], [[C2]]
- ; GFX6-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[UV1]], [[SELECT4]]
- ; GFX6-NEXT: [[INT3:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL2]](f32)
- ; GFX6-NEXT: [[SELECT5:%[0-9]+]]:_(f32) = G_SELECT [[FCMP2]](s1), [[C3]], [[C4]]
- ; GFX6-NEXT: [[FSUB1:%[0-9]+]]:_(f32) = G_FSUB [[INT3]], [[SELECT5]]
- ; GFX6-NEXT: [[INT4:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FSUB1]](f32), [[UV3]](f32)
- ; GFX6-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT4]](f32), [[C5]]
- ; GFX6-NEXT: [[SELECT6:%[0-9]+]]:_(f32) = G_SELECT [[FCMP3]](s1), [[C6]], [[C4]]
- ; GFX6-NEXT: [[FADD1:%[0-9]+]]:_(f32) = G_FADD [[INT4]], [[SELECT6]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[UV2]]
+ ; GFX6-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[UV2]]
+ ; GFX6-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX6-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[UV2]], [[C8]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX6-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX6-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX6-NEXT: [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX6-NEXT: [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[UV]](f32)
+ ; GFX6-NEXT: [[C9:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX6-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX6-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST]], [[C10]]
+ ; GFX6-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST1]], [[C9]]
+ ; GFX6-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX6-NEXT: [[BITCAST2:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX6-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST2]], [[FMUL1]]
+ ; GFX6-NEXT: [[IS_FPCLASS:%[0-9]+]]:_(s1) = G_IS_FPCLASS [[UV]](f32), 24
+ ; GFX6-NEXT: [[C11:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
+ ; GFX6-NEXT: [[XOR:%[0-9]+]]:_(s1) = G_XOR [[FCMP2]], [[C11]]
+ ; GFX6-NEXT: [[AND3:%[0-9]+]]:_(s1) = G_AND [[IS_FPCLASS]], [[XOR]]
+ ; GFX6-NEXT: [[C12:%[0-9]+]]:_(f32) = G_FCONSTANT float +qnan
+ ; GFX6-NEXT: [[SELECT5:%[0-9]+]]:_(f32) = G_SELECT [[AND3]](s1), [[C12]], [[SELECT4]]
+ ; GFX6-NEXT: [[FABS1:%[0-9]+]]:_(f32) = G_FABS [[UV1]]
+ ; GFX6-NEXT: [[FCMP4:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS1]](f32), [[C]]
+ ; GFX6-NEXT: [[SELECT6:%[0-9]+]]:_(f32) = G_SELECT [[FCMP4]](s1), [[C1]], [[C2]]
+ ; GFX6-NEXT: [[FMUL3:%[0-9]+]]:_(f32) = G_FMUL [[FABS1]], [[SELECT6]]
+ ; GFX6-NEXT: [[INT3:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL3]](f32)
+ ; GFX6-NEXT: [[SELECT7:%[0-9]+]]:_(f32) = G_SELECT [[FCMP4]](s1), [[C3]], [[C4]]
+ ; GFX6-NEXT: [[FSUB1:%[0-9]+]]:_(f32) = G_FSUB [[INT3]], [[SELECT7]]
+ ; GFX6-NEXT: [[INT4:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[UV3]](f32), [[FSUB1]](f32)
+ ; GFX6-NEXT: [[FCMP5:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT4]](f32), [[C5]]
+ ; GFX6-NEXT: [[SELECT8:%[0-9]+]]:_(f32) = G_SELECT [[FCMP5]](s1), [[C6]], [[C4]]
+ ; GFX6-NEXT: [[FADD1:%[0-9]+]]:_(f32) = G_FADD [[INT4]], [[SELECT8]]
; GFX6-NEXT: [[INT5:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD1]](f32)
- ; GFX6-NEXT: [[SELECT7:%[0-9]+]]:_(f32) = G_SELECT [[FCMP3]](s1), [[C7]], [[C2]]
- ; GFX6-NEXT: [[FMUL3:%[0-9]+]]:_(f32) = G_FMUL [[INT5]], [[SELECT7]]
- ; GFX6-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x f32>) = G_BUILD_VECTOR [[FMUL1]](f32), [[FMUL3]](f32)
+ ; GFX6-NEXT: [[SELECT9:%[0-9]+]]:_(f32) = G_SELECT [[FCMP5]](s1), [[C7]], [[C2]]
+ ; GFX6-NEXT: [[FMUL4:%[0-9]+]]:_(f32) = G_FMUL [[INT5]], [[SELECT9]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC2:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[UV3]]
+ ; GFX6-NEXT: [[FCMP6:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC2]](f32), [[UV3]]
+ ; GFX6-NEXT: [[FMUL5:%[0-9]+]]:_(f32) = G_FMUL [[UV3]], [[C8]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC3:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL5]]
+ ; GFX6-NEXT: [[FCMP7:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC3]](f32), [[FMUL5]]
+ ; GFX6-NEXT: [[AND4:%[0-9]+]]:_(s1) = G_AND [[FCMP6]], [[FCMP7]]
+ ; GFX6-NEXT: [[BITCAST3:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL4]](f32)
+ ; GFX6-NEXT: [[BITCAST4:%[0-9]+]]:_(i32) = G_BITCAST [[UV1]](f32)
+ ; GFX6-NEXT: [[AND5:%[0-9]+]]:_(i32) = G_AND [[BITCAST3]], [[C10]]
+ ; GFX6-NEXT: [[AND6:%[0-9]+]]:_(i32) = G_AND [[BITCAST4]], [[C9]]
+ ; GFX6-NEXT: [[OR1:%[0-9]+]]:_(i32) = disjoint G_OR [[AND5]], [[AND6]]
+ ; GFX6-NEXT: [[BITCAST5:%[0-9]+]]:_(f32) = G_BITCAST [[OR1]](i32)
+ ; GFX6-NEXT: [[SELECT10:%[0-9]+]]:_(f32) = G_SELECT [[AND4]](s1), [[BITCAST5]], [[FMUL4]]
+ ; GFX6-NEXT: [[IS_FPCLASS1:%[0-9]+]]:_(s1) = G_IS_FPCLASS [[UV1]](f32), 24
+ ; GFX6-NEXT: [[XOR1:%[0-9]+]]:_(s1) = G_XOR [[FCMP6]], [[C11]]
+ ; GFX6-NEXT: [[AND7:%[0-9]+]]:_(s1) = G_AND [[IS_FPCLASS1]], [[XOR1]]
+ ; GFX6-NEXT: [[SELECT11:%[0-9]+]]:_(f32) = G_SELECT [[AND7]](s1), [[C12]], [[SELECT10]]
+ ; GFX6-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x f32>) = G_BUILD_VECTOR [[SELECT5]](f32), [[SELECT11]](f32)
; GFX6-NEXT: $vgpr0_vgpr1 = COPY [[BUILD_VECTOR]](<2 x f32>)
;
; GFX9-LABEL: name: test_fpow_v2f32
@@ -128,18 +215,19 @@ body: |
; GFX9-NEXT: [[COPY1:%[0-9]+]]:_(<2 x f32>) = COPY $vgpr2_vgpr3
; GFX9-NEXT: [[UV:%[0-9]+]]:_(f32), [[UV1:%[0-9]+]]:_(f32) = G_UNMERGE_VALUES [[COPY]](<2 x f32>)
; GFX9-NEXT: [[UV2:%[0-9]+]]:_(f32), [[UV3:%[0-9]+]]:_(f32) = G_UNMERGE_VALUES [[COPY1]](<2 x f32>)
+ ; GFX9-NEXT: [[FABS:%[0-9]+]]:_(f32) = G_FABS [[UV]]
; GFX9-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
- ; GFX9-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[UV]](f32), [[C]]
+ ; GFX9-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C]]
; GFX9-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
; GFX9-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
; GFX9-NEXT: [[SELECT:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C1]], [[C2]]
- ; GFX9-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[UV]], [[SELECT]]
+ ; GFX9-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[FABS]], [[SELECT]]
; GFX9-NEXT: [[INT:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
; GFX9-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
; GFX9-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
; GFX9-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C3]], [[C4]]
; GFX9-NEXT: [[FSUB:%[0-9]+]]:_(f32) = G_FSUB [[INT]], [[SELECT1]]
- ; GFX9-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FSUB]](f32), [[UV2]](f32)
+ ; GFX9-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[UV2]](f32), [[FSUB]](f32)
; GFX9-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
; GFX9-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT1]](f32), [[C5]]
; GFX9-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
@@ -149,20 +237,60 @@ body: |
; GFX9-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
; GFX9-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = G_SELECT [[FCMP1]](s1), [[C7]], [[C2]]
; GFX9-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = G_FMUL [[INT2]], [[SELECT3]]
- ; GFX9-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[UV1]](f32), [[C]]
- ; GFX9-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[FCMP2]](s1), [[C1]], [[C2]]
- ; GFX9-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[UV1]], [[SELECT4]]
- ; GFX9-NEXT: [[INT3:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL2]](f32)
- ; GFX9-NEXT: [[SELECT5:%[0-9]+]]:_(f32) = G_SELECT [[FCMP2]](s1), [[C3]], [[C4]]
- ; GFX9-NEXT: [[FSUB1:%[0-9]+]]:_(f32) = G_FSUB [[INT3]], [[SELECT5]]
- ; GFX9-NEXT: [[INT4:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FSUB1]](f32), [[UV3]](f32)
- ; GFX9-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT4]](f32), [[C5]]
- ; GFX9-NEXT: [[SELECT6:%[0-9]+]]:_(f32) = G_SELECT [[FCMP3]](s1), [[C6]], [[C4]]
- ; GFX9-NEXT: [[FADD1:%[0-9]+]]:_(f32) = G_FADD [[INT4]], [[SELECT6]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[UV2]]
+ ; GFX9-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[UV2]]
+ ; GFX9-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX9-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[UV2]], [[C8]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX9-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX9-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX9-NEXT: [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX9-NEXT: [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[UV]](f32)
+ ; GFX9-NEXT: [[C9:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX9-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX9-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST]], [[C10]]
+ ; GFX9-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST1]], [[C9]]
+ ; GFX9-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX9-NEXT: [[BITCAST2:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX9-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST2]], [[FMUL1]]
+ ; GFX9-NEXT: [[IS_FPCLASS:%[0-9]+]]:_(s1) = G_IS_FPCLASS [[UV]](f32), 24
+ ; GFX9-NEXT: [[C11:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
+ ; GFX9-NEXT: [[XOR:%[0-9]+]]:_(s1) = G_XOR [[FCMP2]], [[C11]]
+ ; GFX9-NEXT: [[AND3:%[0-9]+]]:_(s1) = G_AND [[IS_FPCLASS]], [[XOR]]
+ ; GFX9-NEXT: [[C12:%[0-9]+]]:_(f32) = G_FCONSTANT float +qnan
+ ; GFX9-NEXT: [[SELECT5:%[0-9]+]]:_(f32) = G_SELECT [[AND3]](s1), [[C12]], [[SELECT4]]
+ ; GFX9-NEXT: [[FABS1:%[0-9]+]]:_(f32) = G_FABS [[UV1]]
+ ; GFX9-NEXT: [[FCMP4:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS1]](f32), [[C]]
+ ; GFX9-NEXT: [[SELECT6:%[0-9]+]]:_(f32) = G_SELECT [[FCMP4]](s1), [[C1]], [[C2]]
+ ; GFX9-NEXT: [[FMUL3:%[0-9]+]]:_(f32) = G_FMUL [[FABS1]], [[SELECT6]]
+ ; GFX9-NEXT: [[INT3:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL3]](f32)
+ ; GFX9-NEXT: [[SELECT7:%[0-9]+]]:_(f32) = G_SELECT [[FCMP4]](s1), [[C3]], [[C4]]
+ ; GFX9-NEXT: [[FSUB1:%[0-9]+]]:_(f32) = G_FSUB [[INT3]], [[SELECT7]]
+ ; GFX9-NEXT: [[INT4:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[UV3]](f32), [[FSUB1]](f32)
+ ; GFX9-NEXT: [[FCMP5:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT4]](f32), [[C5]]
+ ; GFX9-NEXT: [[SELECT8:%[0-9]+]]:_(f32) = G_SELECT [[FCMP5]](s1), [[C6]], [[C4]]
+ ; GFX9-NEXT: [[FADD1:%[0-9]+]]:_(f32) = G_FADD [[INT4]], [[SELECT8]]
; GFX9-NEXT: [[INT5:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD1]](f32)
- ; GFX9-NEXT: [[SELECT7:%[0-9]+]]:_(f32) = G_SELECT [[FCMP3]](s1), [[C7]], [[C2]]
- ; GFX9-NEXT: [[FMUL3:%[0-9]+]]:_(f32) = G_FMUL [[INT5]], [[SELECT7]]
- ; GFX9-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x f32>) = G_BUILD_VECTOR [[FMUL1]](f32), [[FMUL3]](f32)
+ ; GFX9-NEXT: [[SELECT9:%[0-9]+]]:_(f32) = G_SELECT [[FCMP5]](s1), [[C7]], [[C2]]
+ ; GFX9-NEXT: [[FMUL4:%[0-9]+]]:_(f32) = G_FMUL [[INT5]], [[SELECT9]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC2:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[UV3]]
+ ; GFX9-NEXT: [[FCMP6:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC2]](f32), [[UV3]]
+ ; GFX9-NEXT: [[FMUL5:%[0-9]+]]:_(f32) = G_FMUL [[UV3]], [[C8]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC3:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL5]]
+ ; GFX9-NEXT: [[FCMP7:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC3]](f32), [[FMUL5]]
+ ; GFX9-NEXT: [[AND4:%[0-9]+]]:_(s1) = G_AND [[FCMP6]], [[FCMP7]]
+ ; GFX9-NEXT: [[BITCAST3:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL4]](f32)
+ ; GFX9-NEXT: [[BITCAST4:%[0-9]+]]:_(i32) = G_BITCAST [[UV1]](f32)
+ ; GFX9-NEXT: [[AND5:%[0-9]+]]:_(i32) = G_AND [[BITCAST3]], [[C10]]
+ ; GFX9-NEXT: [[AND6:%[0-9]+]]:_(i32) = G_AND [[BITCAST4]], [[C9]]
+ ; GFX9-NEXT: [[OR1:%[0-9]+]]:_(i32) = disjoint G_OR [[AND5]], [[AND6]]
+ ; GFX9-NEXT: [[BITCAST5:%[0-9]+]]:_(f32) = G_BITCAST [[OR1]](i32)
+ ; GFX9-NEXT: [[SELECT10:%[0-9]+]]:_(f32) = G_SELECT [[AND4]](s1), [[BITCAST5]], [[FMUL4]]
+ ; GFX9-NEXT: [[IS_FPCLASS1:%[0-9]+]]:_(s1) = G_IS_FPCLASS [[UV1]](f32), 24
+ ; GFX9-NEXT: [[XOR1:%[0-9]+]]:_(s1) = G_XOR [[FCMP6]], [[C11]]
+ ; GFX9-NEXT: [[AND7:%[0-9]+]]:_(s1) = G_AND [[IS_FPCLASS1]], [[XOR1]]
+ ; GFX9-NEXT: [[SELECT11:%[0-9]+]]:_(f32) = G_SELECT [[AND7]](s1), [[C12]], [[SELECT10]]
+ ; GFX9-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x f32>) = G_BUILD_VECTOR [[SELECT5]](f32), [[SELECT11]](f32)
; GFX9-NEXT: $vgpr0_vgpr1 = COPY [[BUILD_VECTOR]](<2 x f32>)
%0:_(<2 x f32>) = COPY $vgpr0_vgpr1
%1:_(<2 x f32>) = COPY $vgpr2_vgpr3
@@ -183,18 +311,19 @@ body: |
; GFX6-NEXT: [[COPY1:%[0-9]+]]:_(<3 x f32>) = COPY $vgpr3_vgpr4_vgpr5
; GFX6-NEXT: [[UV:%[0-9]+]]:_(f32), [[UV1:%[0-9]+]]:_(f32), [[UV2:%[0-9]+]]:_(f32) = G_UNMERGE_VALUES [[COPY]](<3 x f32>)
; GFX6-NEXT: [[UV3:%[0-9]+]]:_(f32), [[UV4:%[0-9]+]]:_(f32), [[UV5:%[0-9]+]]:_(f32) = G_UNMERGE_VALUES [[COPY1]](<3 x f32>)
+ ; GFX6-NEXT: [[FABS:%[0-9]+]]:_(f32) = G_FABS [[UV]]
; GFX6-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
- ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[UV]](f32), [[C]]
+ ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C]]
; GFX6-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
; GFX6-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
; GFX6-NEXT: [[SELECT:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C1]], [[C2]]
- ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[UV]], [[SELECT]]
+ ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[FABS]], [[SELECT]]
; GFX6-NEXT: [[INT:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
; GFX6-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
; GFX6-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
; GFX6-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C3]], [[C4]]
; GFX6-NEXT: [[FSUB:%[0-9]+]]:_(f32) = G_FSUB [[INT]], [[SELECT1]]
- ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FSUB]](f32), [[UV3]](f32)
+ ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[UV3]](f32), [[FSUB]](f32)
; GFX6-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
; GFX6-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT1]](f32), [[C5]]
; GFX6-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
@@ -204,33 +333,91 @@ body: |
; GFX6-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
; GFX6-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = G_SELECT [[FCMP1]](s1), [[C7]], [[C2]]
; GFX6-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = G_FMUL [[INT2]], [[SELECT3]]
- ; GFX6-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[UV1]](f32), [[C]]
- ; GFX6-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[FCMP2]](s1), [[C1]], [[C2]]
- ; GFX6-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[UV1]], [[SELECT4]]
- ; GFX6-NEXT: [[INT3:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL2]](f32)
- ; GFX6-NEXT: [[SELECT5:%[0-9]+]]:_(f32) = G_SELECT [[FCMP2]](s1), [[C3]], [[C4]]
- ; GFX6-NEXT: [[FSUB1:%[0-9]+]]:_(f32) = G_FSUB [[INT3]], [[SELECT5]]
- ; GFX6-NEXT: [[INT4:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FSUB1]](f32), [[UV4]](f32)
- ; GFX6-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT4]](f32), [[C5]]
- ; GFX6-NEXT: [[SELECT6:%[0-9]+]]:_(f32) = G_SELECT [[FCMP3]](s1), [[C6]], [[C4]]
- ; GFX6-NEXT: [[FADD1:%[0-9]+]]:_(f32) = G_FADD [[INT4]], [[SELECT6]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[UV3]]
+ ; GFX6-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[UV3]]
+ ; GFX6-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX6-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[UV3]], [[C8]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX6-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX6-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX6-NEXT: [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX6-NEXT: [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[UV]](f32)
+ ; GFX6-NEXT: [[C9:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX6-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX6-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST]], [[C10]]
+ ; GFX6-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST1]], [[C9]]
+ ; GFX6-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX6-NEXT: [[BITCAST2:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX6-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST2]], [[FMUL1]]
+ ; GFX6-NEXT: [[IS_FPCLASS:%[0-9]+]]:_(s1) = G_IS_FPCLASS [[UV]](f32), 24
+ ; GFX6-NEXT: [[C11:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
+ ; GFX6-NEXT: [[XOR:%[0-9]+]]:_(s1) = G_XOR [[FCMP2]], [[C11]]
+ ; GFX6-NEXT: [[AND3:%[0-9]+]]:_(s1) = G_AND [[IS_FPCLASS]], [[XOR]]
+ ; GFX6-NEXT: [[C12:%[0-9]+]]:_(f32) = G_FCONSTANT float +qnan
+ ; GFX6-NEXT: [[SELECT5:%[0-9]+]]:_(f32) = G_SELECT [[AND3]](s1), [[C12]], [[SELECT4]]
+ ; GFX6-NEXT: [[FABS1:%[0-9]+]]:_(f32) = G_FABS [[UV1]]
+ ; GFX6-NEXT: [[FCMP4:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS1]](f32), [[C]]
+ ; GFX6-NEXT: [[SELECT6:%[0-9]+]]:_(f32) = G_SELECT [[FCMP4]](s1), [[C1]], [[C2]]
+ ; GFX6-NEXT: [[FMUL3:%[0-9]+]]:_(f32) = G_FMUL [[FABS1]], [[SELECT6]]
+ ; GFX6-NEXT: [[INT3:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL3]](f32)
+ ; GFX6-NEXT: [[SELECT7:%[0-9]+]]:_(f32) = G_SELECT [[FCMP4]](s1), [[C3]], [[C4]]
+ ; GFX6-NEXT: [[FSUB1:%[0-9]+]]:_(f32) = G_FSUB [[INT3]], [[SELECT7]]
+ ; GFX6-NEXT: [[INT4:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[UV4]](f32), [[FSUB1]](f32)
+ ; GFX6-NEXT: [[FCMP5:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT4]](f32), [[C5]]
+ ; GFX6-NEXT: [[SELECT8:%[0-9]+]]:_(f32) = G_SELECT [[FCMP5]](s1), [[C6]], [[C4]]
+ ; GFX6-NEXT: [[FADD1:%[0-9]+]]:_(f32) = G_FADD [[INT4]], [[SELECT8]]
; GFX6-NEXT: [[INT5:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD1]](f32)
- ; GFX6-NEXT: [[SELECT7:%[0-9]+]]:_(f32) = G_SELECT [[FCMP3]](s1), [[C7]], [[C2]]
- ; GFX6-NEXT: [[FMUL3:%[0-9]+]]:_(f32) = G_FMUL [[INT5]], [[SELECT7]]
- ; GFX6-NEXT: [[FCMP4:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[UV2]](f32), [[C]]
- ; GFX6-NEXT: [[SELECT8:%[0-9]+]]:_(f32) = G_SELECT [[FCMP4]](s1), [[C1]], [[C2]]
- ; GFX6-NEXT: [[FMUL4:%[0-9]+]]:_(f32) = G_FMUL [[UV2]], [[SELECT8]]
- ; GFX6-NEXT: [[INT6:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL4]](f32)
- ; GFX6-NEXT: [[SELECT9:%[0-9]+]]:_(f32) = G_SELECT [[FCMP4]](s1), [[C3]], [[C4]]
- ; GFX6-NEXT: [[FSUB2:%[0-9]+]]:_(f32) = G_FSUB [[INT6]], [[SELECT9]]
- ; GFX6-NEXT: [[INT7:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FSUB2]](f32), [[UV5]](f32)
- ; GFX6-NEXT: [[FCMP5:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT7]](f32), [[C5]]
- ; GFX6-NEXT: [[SELECT10:%[0-9]+]]:_(f32) = G_SELECT [[FCMP5]](s1), [[C6]], [[C4]]
- ; GFX6-NEXT: [[FADD2:%[0-9]+]]:_(f32) = G_FADD [[INT7]], [[SELECT10]]
+ ; GFX6-NEXT: [[SELECT9:%[0-9]+]]:_(f32) = G_SELECT [[FCMP5]](s1), [[C7]], [[C2]]
+ ; GFX6-NEXT: [[FMUL4:%[0-9]+]]:_(f32) = G_FMUL [[INT5]], [[SELECT9]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC2:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[UV4]]
+ ; GFX6-NEXT: [[FCMP6:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC2]](f32), [[UV4]]
+ ; GFX6-NEXT: [[FMUL5:%[0-9]+]]:_(f32) = G_FMUL [[UV4]], [[C8]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC3:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL5]]
+ ; GFX6-NEXT: [[FCMP7:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC3]](f32), [[FMUL5]]
+ ; GFX6-NEXT: [[AND4:%[0-9]+]]:_(s1) = G_AND [[FCMP6]], [[FCMP7]]
+ ; GFX6-NEXT: [[BITCAST3:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL4]](f32)
+ ; GFX6-NEXT: [[BITCAST4:%[0-9]+]]:_(i32) = G_BITCAST [[UV1]](f32)
+ ; GFX6-NEXT: [[AND5:%[0-9]+]]:_(i32) = G_AND [[BITCAST3]], [[C10]]
+ ; GFX6-NEXT: [[AND6:%[0-9]+]]:_(i32) = G_AND [[BITCAST4]], [[C9]]
+ ; GFX6-NEXT: [[OR1:%[0-9]+]]:_(i32) = disjoint G_OR [[AND5]], [[AND6]]
+ ; GFX6-NEXT: [[BITCAST5:%[0-9]+]]:_(f32) = G_BITCAST [[OR1]](i32)
+ ; GFX6-NEXT: [[SELECT10:%[0-9]+]]:_(f32) = G_SELECT [[AND4]](s1), [[BITCAST5]], [[FMUL4]]
+ ; GFX6-NEXT: [[IS_FPCLASS1:%[0-9]+]]:_(s1) = G_IS_FPCLASS [[UV1]](f32), 24
+ ; GFX6-NEXT: [[XOR1:%[0-9]+]]:_(s1) = G_XOR [[FCMP6]], [[C11]]
+ ; GFX6-NEXT: [[AND7:%[0-9]+]]:_(s1) = G_AND [[IS_FPCLASS1]], [[XOR1]]
+ ; GFX6-NEXT: [[SELECT11:%[0-9]+]]:_(f32) = G_SELECT [[AND7]](s1), [[C12]], [[SELECT10]]
+ ; GFX6-NEXT: [[FABS2:%[0-9]+]]:_(f32) = G_FABS [[UV2]]
+ ; GFX6-NEXT: [[FCMP8:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS2]](f32), [[C]]
+ ; GFX6-NEXT: [[SELECT12:%[0-9]+]]:_(f32) = G_SELECT [[FCMP8]](s1), [[C1]], [[C2]]
+ ; GFX6-NEXT: [[FMUL6:%[0-9]+]]:_(f32) = G_FMUL [[FABS2]], [[SELECT12]]
+ ; GFX6-NEXT: [[INT6:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL6]](f32)
+ ; GFX6-NEXT: [[SELECT13:%[0-9]+]]:_(f32) = G_SELECT [[FCMP8]](s1), [[C3]], [[C4]]
+ ; GFX6-NEXT: [[FSUB2:%[0-9]+]]:_(f32) = G_FSUB [[INT6]], [[SELECT13]]
+ ; GFX6-NEXT: [[INT7:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[UV5]](f32), [[FSUB2]](f32)
+ ; GFX6-NEXT: [[FCMP9:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT7]](f32), [[C5]]
+ ; GFX6-NEXT: [[SELECT14:%[0-9]+]]:_(f32) = G_SELECT [[FCMP9]](s1), [[C6]], [[C4]]
+ ; GFX6-NEXT: [[FADD2:%[0-9]+]]:_(f32) = G_FADD [[INT7]], [[SELECT14]]
; GFX6-NEXT: [[INT8:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD2]](f32)
- ; GFX6-NEXT: [[SELECT11:%[0-9]+]]:_(f32) = G_SELECT [[FCMP5]](s1), [[C7]], [[C2]]
- ; GFX6-NEXT: [[FMUL5:%[0-9]+]]:_(f32) = G_FMUL [[INT8]], [[SELECT11]]
- ; GFX6-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<3 x f32>) = G_BUILD_VECTOR [[FMUL1]](f32), [[FMUL3]](f32), [[FMUL5]](f32)
+ ; GFX6-NEXT: [[SELECT15:%[0-9]+]]:_(f32) = G_SELECT [[FCMP9]](s1), [[C7]], [[C2]]
+ ; GFX6-NEXT: [[FMUL7:%[0-9]+]]:_(f32) = G_FMUL [[INT8]], [[SELECT15]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC4:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[UV5]]
+ ; GFX6-NEXT: [[FCMP10:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC4]](f32), [[UV5]]
+ ; GFX6-NEXT: [[FMUL8:%[0-9]+]]:_(f32) = G_FMUL [[UV5]], [[C8]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC5:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL8]]
+ ; GFX6-NEXT: [[FCMP11:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC5]](f32), [[FMUL8]]
+ ; GFX6-NEXT: [[AND8:%[0-9]+]]:_(s1) = G_AND [[FCMP10]], [[FCMP11]]
+ ; GFX6-NEXT: [[BITCAST6:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL7]](f32)
+ ; GFX6-NEXT: [[BITCAST7:%[0-9]+]]:_(i32) = G_BITCAST [[UV2]](f32)
+ ; GFX6-NEXT: [[AND9:%[0-9]+]]:_(i32) = G_AND [[BITCAST6]], [[C10]]
+ ; GFX6-NEXT: [[AND10:%[0-9]+]]:_(i32) = G_AND [[BITCAST7]], [[C9]]
+ ; GFX6-NEXT: [[OR2:%[0-9]+]]:_(i32) = disjoint G_OR [[AND9]], [[AND10]]
+ ; GFX6-NEXT: [[BITCAST8:%[0-9]+]]:_(f32) = G_BITCAST [[OR2]](i32)
+ ; GFX6-NEXT: [[SELECT16:%[0-9]+]]:_(f32) = G_SELECT [[AND8]](s1), [[BITCAST8]], [[FMUL7]]
+ ; GFX6-NEXT: [[IS_FPCLASS2:%[0-9]+]]:_(s1) = G_IS_FPCLASS [[UV2]](f32), 24
+ ; GFX6-NEXT: [[XOR2:%[0-9]+]]:_(s1) = G_XOR [[FCMP10]], [[C11]]
+ ; GFX6-NEXT: [[AND11:%[0-9]+]]:_(s1) = G_AND [[IS_FPCLASS2]], [[XOR2]]
+ ; GFX6-NEXT: [[SELECT17:%[0-9]+]]:_(f32) = G_SELECT [[AND11]](s1), [[C12]], [[SELECT16]]
+ ; GFX6-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<3 x f32>) = G_BUILD_VECTOR [[SELECT5]](f32), [[SELECT11]](f32), [[SELECT17]](f32)
; GFX6-NEXT: $vgpr0_vgpr1_vgpr2 = COPY [[BUILD_VECTOR]](<3 x f32>)
;
; GFX9-LABEL: name: test_fpow_v3f32
@@ -240,18 +427,19 @@ body: |
; GFX9-NEXT: [[COPY1:%[0-9]+]]:_(<3 x f32>) = COPY $vgpr3_vgpr4_vgpr5
; GFX9-NEXT: [[UV:%[0-9]+]]:_(f32), [[UV1:%[0-9]+]]:_(f32), [[UV2:%[0-9]+]]:_(f32) = G_UNMERGE_VALUES [[COPY]](<3 x f32>)
; GFX9-NEXT: [[UV3:%[0-9]+]]:_(f32), [[UV4:%[0-9]+]]:_(f32), [[UV5:%[0-9]+]]:_(f32) = G_UNMERGE_VALUES [[COPY1]](<3 x f32>)
+ ; GFX9-NEXT: [[FABS:%[0-9]+]]:_(f32) = G_FABS [[UV]]
; GFX9-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
- ; GFX9-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[UV]](f32), [[C]]
+ ; GFX9-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C]]
; GFX9-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
; GFX9-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
; GFX9-NEXT: [[SELECT:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C1]], [[C2]]
- ; GFX9-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[UV]], [[SELECT]]
+ ; GFX9-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[FABS]], [[SELECT]]
; GFX9-NEXT: [[INT:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
; GFX9-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
; GFX9-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
; GFX9-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C3]], [[C4]]
; GFX9-NEXT: [[FSUB:%[0-9]+]]:_(f32) = G_FSUB [[INT]], [[SELECT1]]
- ; GFX9-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FSUB]](f32), [[UV3]](f32)
+ ; GFX9-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[UV3]](f32), [[FSUB]](f32)
; GFX9-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
; GFX9-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT1]](f32), [[C5]]
; GFX9-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
@@ -261,33 +449,91 @@ body: |
; GFX9-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
; GFX9-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = G_SELECT [[FCMP1]](s1), [[C7]], [[C2]]
; GFX9-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = G_FMUL [[INT2]], [[SELECT3]]
- ; GFX9-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[UV1]](f32), [[C]]
- ; GFX9-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[FCMP2]](s1), [[C1]], [[C2]]
- ; GFX9-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[UV1]], [[SELECT4]]
- ; GFX9-NEXT: [[INT3:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL2]](f32)
- ; GFX9-NEXT: [[SELECT5:%[0-9]+]]:_(f32) = G_SELECT [[FCMP2]](s1), [[C3]], [[C4]]
- ; GFX9-NEXT: [[FSUB1:%[0-9]+]]:_(f32) = G_FSUB [[INT3]], [[SELECT5]]
- ; GFX9-NEXT: [[INT4:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FSUB1]](f32), [[UV4]](f32)
- ; GFX9-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT4]](f32), [[C5]]
- ; GFX9-NEXT: [[SELECT6:%[0-9]+]]:_(f32) = G_SELECT [[FCMP3]](s1), [[C6]], [[C4]]
- ; GFX9-NEXT: [[FADD1:%[0-9]+]]:_(f32) = G_FADD [[INT4]], [[SELECT6]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[UV3]]
+ ; GFX9-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[UV3]]
+ ; GFX9-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX9-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[UV3]], [[C8]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX9-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX9-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX9-NEXT: [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX9-NEXT: [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[UV]](f32)
+ ; GFX9-NEXT: [[C9:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX9-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX9-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST]], [[C10]]
+ ; GFX9-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST1]], [[C9]]
+ ; GFX9-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX9-NEXT: [[BITCAST2:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX9-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST2]], [[FMUL1]]
+ ; GFX9-NEXT: [[IS_FPCLASS:%[0-9]+]]:_(s1) = G_IS_FPCLASS [[UV]](f32), 24
+ ; GFX9-NEXT: [[C11:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
+ ; GFX9-NEXT: [[XOR:%[0-9]+]]:_(s1) = G_XOR [[FCMP2]], [[C11]]
+ ; GFX9-NEXT: [[AND3:%[0-9]+]]:_(s1) = G_AND [[IS_FPCLASS]], [[XOR]]
+ ; GFX9-NEXT: [[C12:%[0-9]+]]:_(f32) = G_FCONSTANT float +qnan
+ ; GFX9-NEXT: [[SELECT5:%[0-9]+]]:_(f32) = G_SELECT [[AND3]](s1), [[C12]], [[SELECT4]]
+ ; GFX9-NEXT: [[FABS1:%[0-9]+]]:_(f32) = G_FABS [[UV1]]
+ ; GFX9-NEXT: [[FCMP4:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS1]](f32), [[C]]
+ ; GFX9-NEXT: [[SELECT6:%[0-9]+]]:_(f32) = G_SELECT [[FCMP4]](s1), [[C1]], [[C2]]
+ ; GFX9-NEXT: [[FMUL3:%[0-9]+]]:_(f32) = G_FMUL [[FABS1]], [[SELECT6]]
+ ; GFX9-NEXT: [[INT3:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL3]](f32)
+ ; GFX9-NEXT: [[SELECT7:%[0-9]+]]:_(f32) = G_SELECT [[FCMP4]](s1), [[C3]], [[C4]]
+ ; GFX9-NEXT: [[FSUB1:%[0-9]+]]:_(f32) = G_FSUB [[INT3]], [[SELECT7]]
+ ; GFX9-NEXT: [[INT4:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[UV4]](f32), [[FSUB1]](f32)
+ ; GFX9-NEXT: [[FCMP5:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT4]](f32), [[C5]]
+ ; GFX9-NEXT: [[SELECT8:%[0-9]+]]:_(f32) = G_SELECT [[FCMP5]](s1), [[C6]], [[C4]]
+ ; GFX9-NEXT: [[FADD1:%[0-9]+]]:_(f32) = G_FADD [[INT4]], [[SELECT8]]
; GFX9-NEXT: [[INT5:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD1]](f32)
- ; GFX9-NEXT: [[SELECT7:%[0-9]+]]:_(f32) = G_SELECT [[FCMP3]](s1), [[C7]], [[C2]]
- ; GFX9-NEXT: [[FMUL3:%[0-9]+]]:_(f32) = G_FMUL [[INT5]], [[SELECT7]]
- ; GFX9-NEXT: [[FCMP4:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[UV2]](f32), [[C]]
- ; GFX9-NEXT: [[SELECT8:%[0-9]+]]:_(f32) = G_SELECT [[FCMP4]](s1), [[C1]], [[C2]]
- ; GFX9-NEXT: [[FMUL4:%[0-9]+]]:_(f32) = G_FMUL [[UV2]], [[SELECT8]]
- ; GFX9-NEXT: [[INT6:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL4]](f32)
- ; GFX9-NEXT: [[SELECT9:%[0-9]+]]:_(f32) = G_SELECT [[FCMP4]](s1), [[C3]], [[C4]]
- ; GFX9-NEXT: [[FSUB2:%[0-9]+]]:_(f32) = G_FSUB [[INT6]], [[SELECT9]]
- ; GFX9-NEXT: [[INT7:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FSUB2]](f32), [[UV5]](f32)
- ; GFX9-NEXT: [[FCMP5:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT7]](f32), [[C5]]
- ; GFX9-NEXT: [[SELECT10:%[0-9]+]]:_(f32) = G_SELECT [[FCMP5]](s1), [[C6]], [[C4]]
- ; GFX9-NEXT: [[FADD2:%[0-9]+]]:_(f32) = G_FADD [[INT7]], [[SELECT10]]
+ ; GFX9-NEXT: [[SELECT9:%[0-9]+]]:_(f32) = G_SELECT [[FCMP5]](s1), [[C7]], [[C2]]
+ ; GFX9-NEXT: [[FMUL4:%[0-9]+]]:_(f32) = G_FMUL [[INT5]], [[SELECT9]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC2:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[UV4]]
+ ; GFX9-NEXT: [[FCMP6:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC2]](f32), [[UV4]]
+ ; GFX9-NEXT: [[FMUL5:%[0-9]+]]:_(f32) = G_FMUL [[UV4]], [[C8]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC3:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL5]]
+ ; GFX9-NEXT: [[FCMP7:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC3]](f32), [[FMUL5]]
+ ; GFX9-NEXT: [[AND4:%[0-9]+]]:_(s1) = G_AND [[FCMP6]], [[FCMP7]]
+ ; GFX9-NEXT: [[BITCAST3:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL4]](f32)
+ ; GFX9-NEXT: [[BITCAST4:%[0-9]+]]:_(i32) = G_BITCAST [[UV1]](f32)
+ ; GFX9-NEXT: [[AND5:%[0-9]+]]:_(i32) = G_AND [[BITCAST3]], [[C10]]
+ ; GFX9-NEXT: [[AND6:%[0-9]+]]:_(i32) = G_AND [[BITCAST4]], [[C9]]
+ ; GFX9-NEXT: [[OR1:%[0-9]+]]:_(i32) = disjoint G_OR [[AND5]], [[AND6]]
+ ; GFX9-NEXT: [[BITCAST5:%[0-9]+]]:_(f32) = G_BITCAST [[OR1]](i32)
+ ; GFX9-NEXT: [[SELECT10:%[0-9]+]]:_(f32) = G_SELECT [[AND4]](s1), [[BITCAST5]], [[FMUL4]]
+ ; GFX9-NEXT: [[IS_FPCLASS1:%[0-9]+]]:_(s1) = G_IS_FPCLASS [[UV1]](f32), 24
+ ; GFX9-NEXT: [[XOR1:%[0-9]+]]:_(s1) = G_XOR [[FCMP6]], [[C11]]
+ ; GFX9-NEXT: [[AND7:%[0-9]+]]:_(s1) = G_AND [[IS_FPCLASS1]], [[XOR1]]
+ ; GFX9-NEXT: [[SELECT11:%[0-9]+]]:_(f32) = G_SELECT [[AND7]](s1), [[C12]], [[SELECT10]]
+ ; GFX9-NEXT: [[FABS2:%[0-9]+]]:_(f32) = G_FABS [[UV2]]
+ ; GFX9-NEXT: [[FCMP8:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS2]](f32), [[C]]
+ ; GFX9-NEXT: [[SELECT12:%[0-9]+]]:_(f32) = G_SELECT [[FCMP8]](s1), [[C1]], [[C2]]
+ ; GFX9-NEXT: [[FMUL6:%[0-9]+]]:_(f32) = G_FMUL [[FABS2]], [[SELECT12]]
+ ; GFX9-NEXT: [[INT6:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL6]](f32)
+ ; GFX9-NEXT: [[SELECT13:%[0-9]+]]:_(f32) = G_SELECT [[FCMP8]](s1), [[C3]], [[C4]]
+ ; GFX9-NEXT: [[FSUB2:%[0-9]+]]:_(f32) = G_FSUB [[INT6]], [[SELECT13]]
+ ; GFX9-NEXT: [[INT7:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[UV5]](f32), [[FSUB2]](f32)
+ ; GFX9-NEXT: [[FCMP9:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT7]](f32), [[C5]]
+ ; GFX9-NEXT: [[SELECT14:%[0-9]+]]:_(f32) = G_SELECT [[FCMP9]](s1), [[C6]], [[C4]]
+ ; GFX9-NEXT: [[FADD2:%[0-9]+]]:_(f32) = G_FADD [[INT7]], [[SELECT14]]
; GFX9-NEXT: [[INT8:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD2]](f32)
- ; GFX9-NEXT: [[SELECT11:%[0-9]+]]:_(f32) = G_SELECT [[FCMP5]](s1), [[C7]], [[C2]]
- ; GFX9-NEXT: [[FMUL5:%[0-9]+]]:_(f32) = G_FMUL [[INT8]], [[SELECT11]]
- ; GFX9-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<3 x f32>) = G_BUILD_VECTOR [[FMUL1]](f32), [[FMUL3]](f32), [[FMUL5]](f32)
+ ; GFX9-NEXT: [[SELECT15:%[0-9]+]]:_(f32) = G_SELECT [[FCMP9]](s1), [[C7]], [[C2]]
+ ; GFX9-NEXT: [[FMUL7:%[0-9]+]]:_(f32) = G_FMUL [[INT8]], [[SELECT15]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC4:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[UV5]]
+ ; GFX9-NEXT: [[FCMP10:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC4]](f32), [[UV5]]
+ ; GFX9-NEXT: [[FMUL8:%[0-9]+]]:_(f32) = G_FMUL [[UV5]], [[C8]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC5:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL8]]
+ ; GFX9-NEXT: [[FCMP11:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC5]](f32), [[FMUL8]]
+ ; GFX9-NEXT: [[AND8:%[0-9]+]]:_(s1) = G_AND [[FCMP10]], [[FCMP11]]
+ ; GFX9-NEXT: [[BITCAST6:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL7]](f32)
+ ; GFX9-NEXT: [[BITCAST7:%[0-9]+]]:_(i32) = G_BITCAST [[UV2]](f32)
+ ; GFX9-NEXT: [[AND9:%[0-9]+]]:_(i32) = G_AND [[BITCAST6]], [[C10]]
+ ; GFX9-NEXT: [[AND10:%[0-9]+]]:_(i32) = G_AND [[BITCAST7]], [[C9]]
+ ; GFX9-NEXT: [[OR2:%[0-9]+]]:_(i32) = disjoint G_OR [[AND9]], [[AND10]]
+ ; GFX9-NEXT: [[BITCAST8:%[0-9]+]]:_(f32) = G_BITCAST [[OR2]](i32)
+ ; GFX9-NEXT: [[SELECT16:%[0-9]+]]:_(f32) = G_SELECT [[AND8]](s1), [[BITCAST8]], [[FMUL7]]
+ ; GFX9-NEXT: [[IS_FPCLASS2:%[0-9]+]]:_(s1) = G_IS_FPCLASS [[UV2]](f32), 24
+ ; GFX9-NEXT: [[XOR2:%[0-9]+]]:_(s1) = G_XOR [[FCMP10]], [[C11]]
+ ; GFX9-NEXT: [[AND11:%[0-9]+]]:_(s1) = G_AND [[IS_FPCLASS2]], [[XOR2]]
+ ; GFX9-NEXT: [[SELECT17:%[0-9]+]]:_(f32) = G_SELECT [[AND11]](s1), [[C12]], [[SELECT16]]
+ ; GFX9-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<3 x f32>) = G_BUILD_VECTOR [[SELECT5]](f32), [[SELECT11]](f32), [[SELECT17]](f32)
; GFX9-NEXT: $vgpr0_vgpr1_vgpr2 = COPY [[BUILD_VECTOR]](<3 x f32>)
%0:_(<3 x f32>) = COPY $vgpr0_vgpr1_vgpr2
%1:_(<3 x f32>) = COPY $vgpr3_vgpr4_vgpr5
@@ -306,18 +552,19 @@ body: |
; GFX6-NEXT: {{ $}}
; GFX6-NEXT: [[COPY:%[0-9]+]]:_(f32) = COPY $vgpr0
; GFX6-NEXT: [[COPY1:%[0-9]+]]:_(f32) = COPY $vgpr1
+ ; GFX6-NEXT: [[FABS:%[0-9]+]]:_(f32) = nnan nsz G_FABS [[COPY]]
; GFX6-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
- ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[COPY]](f32), [[C]]
+ ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C]]
; GFX6-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
; GFX6-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
; GFX6-NEXT: [[SELECT:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP]](s1), [[C1]], [[C2]]
- ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = nnan nsz G_FMUL [[COPY]], [[SELECT]]
+ ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = nnan nsz G_FMUL [[FABS]], [[SELECT]]
; GFX6-NEXT: [[INT:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
; GFX6-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
; GFX6-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
; GFX6-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP]](s1), [[C3]], [[C4]]
; GFX6-NEXT: [[FSUB:%[0-9]+]]:_(f32) = nnan nsz G_FSUB [[INT]], [[SELECT1]]
- ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FSUB]](f32), [[COPY1]](f32)
+ ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[COPY1]](f32), [[FSUB]](f32)
; GFX6-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
; GFX6-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = nnan nsz G_FCMP floatpred(olt), [[INT1]](f32), [[C5]]
; GFX6-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
@@ -327,25 +574,42 @@ body: |
; GFX6-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
; GFX6-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP1]](s1), [[C7]], [[C2]]
; GFX6-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = nnan nsz G_FMUL [[INT2]], [[SELECT3]]
- ; GFX6-NEXT: $vgpr0 = COPY [[FMUL1]](f32)
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[COPY1]]
+ ; GFX6-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[COPY1]]
+ ; GFX6-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX6-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[COPY1]], [[C8]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX6-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX6-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX6-NEXT: [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX6-NEXT: [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[COPY]](f32)
+ ; GFX6-NEXT: [[C9:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX6-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX6-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST]], [[C10]]
+ ; GFX6-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST1]], [[C9]]
+ ; GFX6-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX6-NEXT: [[BITCAST2:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX6-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST2]], [[FMUL1]]
+ ; GFX6-NEXT: $vgpr0 = COPY [[SELECT4]](f32)
;
; GFX9-LABEL: name: test_fpow_f32_flags
; GFX9: liveins: $vgpr0, $vgpr1
; GFX9-NEXT: {{ $}}
; GFX9-NEXT: [[COPY:%[0-9]+]]:_(f32) = COPY $vgpr0
; GFX9-NEXT: [[COPY1:%[0-9]+]]:_(f32) = COPY $vgpr1
+ ; GFX9-NEXT: [[FABS:%[0-9]+]]:_(f32) = nnan nsz G_FABS [[COPY]]
; GFX9-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
- ; GFX9-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[COPY]](f32), [[C]]
+ ; GFX9-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C]]
; GFX9-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
; GFX9-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
; GFX9-NEXT: [[SELECT:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP]](s1), [[C1]], [[C2]]
- ; GFX9-NEXT: [[FMUL:%[0-9]+]]:_(f32) = nnan nsz G_FMUL [[COPY]], [[SELECT]]
+ ; GFX9-NEXT: [[FMUL:%[0-9]+]]:_(f32) = nnan nsz G_FMUL [[FABS]], [[SELECT]]
; GFX9-NEXT: [[INT:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
; GFX9-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
; GFX9-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
; GFX9-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP]](s1), [[C3]], [[C4]]
; GFX9-NEXT: [[FSUB:%[0-9]+]]:_(f32) = nnan nsz G_FSUB [[INT]], [[SELECT1]]
- ; GFX9-NEXT: [[INT1:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FSUB]](f32), [[COPY1]](f32)
+ ; GFX9-NEXT: [[INT1:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[COPY1]](f32), [[FSUB]](f32)
; GFX9-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
; GFX9-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = nnan nsz G_FCMP floatpred(olt), [[INT1]](f32), [[C5]]
; GFX9-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
@@ -355,7 +619,23 @@ body: |
; GFX9-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
; GFX9-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP1]](s1), [[C7]], [[C2]]
; GFX9-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = nnan nsz G_FMUL [[INT2]], [[SELECT3]]
- ; GFX9-NEXT: $vgpr0 = COPY [[FMUL1]](f32)
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[COPY1]]
+ ; GFX9-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[COPY1]]
+ ; GFX9-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX9-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[COPY1]], [[C8]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX9-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX9-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX9-NEXT: [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX9-NEXT: [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[COPY]](f32)
+ ; GFX9-NEXT: [[C9:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX9-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX9-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST]], [[C10]]
+ ; GFX9-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST1]], [[C9]]
+ ; GFX9-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX9-NEXT: [[BITCAST2:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX9-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST2]], [[FMUL1]]
+ ; GFX9-NEXT: $vgpr0 = COPY [[SELECT4]](f32)
%0:_(f32) = COPY $vgpr0
%1:_(f32) = COPY $vgpr1
%2:_(f32) = nnan nsz G_FPOW %0, %1
@@ -377,20 +657,51 @@ body: |
; GFX6-NEXT: [[TRUNC1:%[0-9]+]]:_(f16) = G_TRUNC [[COPY1]](i32)
; GFX6-NEXT: [[FPEXT:%[0-9]+]]:_(f32) = G_FPEXT [[TRUNC]](f16)
; GFX6-NEXT: [[FPEXT1:%[0-9]+]]:_(f32) = G_FPEXT [[TRUNC1]](f16)
- ; GFX6-NEXT: [[INT:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FPEXT]](f32)
- ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[INT]](f32), [[FPEXT1]](f32)
- ; GFX6-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
- ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT1]](f32), [[C]]
- ; GFX6-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
- ; GFX6-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
+ ; GFX6-NEXT: [[FABS:%[0-9]+]]:_(f32) = G_FABS [[FPEXT]]
+ ; GFX6-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
+ ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C]]
+ ; GFX6-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
+ ; GFX6-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
; GFX6-NEXT: [[SELECT:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C1]], [[C2]]
- ; GFX6-NEXT: [[FADD:%[0-9]+]]:_(f32) = G_FADD [[INT1]], [[SELECT]]
- ; GFX6-NEXT: [[INT2:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD]](f32)
- ; GFX6-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
- ; GFX6-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
+ ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[FABS]], [[SELECT]]
+ ; GFX6-NEXT: [[INT:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
+ ; GFX6-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
+ ; GFX6-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
; GFX6-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C3]], [[C4]]
- ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[INT2]], [[SELECT1]]
- ; GFX6-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = G_FPTRUNC [[FMUL]](f32)
+ ; GFX6-NEXT: [[FSUB:%[0-9]+]]:_(f32) = G_FSUB [[INT]], [[SELECT1]]
+ ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT1]](f32), [[FSUB]](f32)
+ ; GFX6-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
+ ; GFX6-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT1]](f32), [[C5]]
+ ; GFX6-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
+ ; GFX6-NEXT: [[SELECT2:%[0-9]+]]:_(f32) = G_SELECT [[FCMP1]](s1), [[C6]], [[C4]]
+ ; GFX6-NEXT: [[FADD:%[0-9]+]]:_(f32) = G_FADD [[INT1]], [[SELECT2]]
+ ; GFX6-NEXT: [[INT2:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD]](f32)
+ ; GFX6-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
+ ; GFX6-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = G_SELECT [[FCMP1]](s1), [[C7]], [[C2]]
+ ; GFX6-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = G_FMUL [[INT2]], [[SELECT3]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FPEXT1]]
+ ; GFX6-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[FPEXT1]]
+ ; GFX6-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX6-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[FPEXT1]], [[C8]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX6-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX6-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX6-NEXT: [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX6-NEXT: [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[FPEXT]](f32)
+ ; GFX6-NEXT: [[C9:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX6-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX6-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST]], [[C10]]
+ ; GFX6-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST1]], [[C9]]
+ ; GFX6-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX6-NEXT: [[BITCAST2:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX6-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST2]], [[FMUL1]]
+ ; GFX6-NEXT: [[IS_FPCLASS:%[0-9]+]]:_(s1) = G_IS_FPCLASS [[FPEXT]](f32), 24
+ ; GFX6-NEXT: [[C11:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
+ ; GFX6-NEXT: [[XOR:%[0-9]+]]:_(s1) = G_XOR [[FCMP2]], [[C11]]
+ ; GFX6-NEXT: [[AND3:%[0-9]+]]:_(s1) = G_AND [[IS_FPCLASS]], [[XOR]]
+ ; GFX6-NEXT: [[C12:%[0-9]+]]:_(f32) = G_FCONSTANT float +qnan
+ ; GFX6-NEXT: [[SELECT5:%[0-9]+]]:_(f32) = G_SELECT [[AND3]](s1), [[C12]], [[SELECT4]]
+ ; GFX6-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = G_FPTRUNC [[SELECT5]](f32)
; GFX6-NEXT: [[ANYEXT:%[0-9]+]]:_(i32) = G_ANYEXT [[FPTRUNC]](f16)
; GFX6-NEXT: $vgpr0 = COPY [[ANYEXT]](i32)
;
@@ -401,13 +712,54 @@ body: |
; GFX9-NEXT: [[COPY1:%[0-9]+]]:_(i32) = COPY $vgpr1
; GFX9-NEXT: [[TRUNC:%[0-9]+]]:_(f16) = G_TRUNC [[COPY]](i32)
; GFX9-NEXT: [[TRUNC1:%[0-9]+]]:_(f16) = G_TRUNC [[COPY1]](i32)
- ; GFX9-NEXT: [[FLOG2_:%[0-9]+]]:_(f16) = G_FLOG2 [[TRUNC]]
- ; GFX9-NEXT: [[FPEXT:%[0-9]+]]:_(f32) = G_FPEXT [[FLOG2_]](f16)
+ ; GFX9-NEXT: [[FPEXT:%[0-9]+]]:_(f32) = G_FPEXT [[TRUNC]](f16)
; GFX9-NEXT: [[FPEXT1:%[0-9]+]]:_(f32) = G_FPEXT [[TRUNC1]](f16)
- ; GFX9-NEXT: [[INT:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT]](f32), [[FPEXT1]](f32)
- ; GFX9-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = G_FPTRUNC [[INT]](f32)
- ; GFX9-NEXT: [[FEXP2_:%[0-9]+]]:_(f16) = G_FEXP2 [[FPTRUNC]]
- ; GFX9-NEXT: [[ANYEXT:%[0-9]+]]:_(i32) = G_ANYEXT [[FEXP2_]](f16)
+ ; GFX9-NEXT: [[FABS:%[0-9]+]]:_(f32) = G_FABS [[FPEXT]]
+ ; GFX9-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
+ ; GFX9-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C]]
+ ; GFX9-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
+ ; GFX9-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
+ ; GFX9-NEXT: [[SELECT:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C1]], [[C2]]
+ ; GFX9-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[FABS]], [[SELECT]]
+ ; GFX9-NEXT: [[INT:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
+ ; GFX9-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
+ ; GFX9-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
+ ; GFX9-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C3]], [[C4]]
+ ; GFX9-NEXT: [[FSUB:%[0-9]+]]:_(f32) = G_FSUB [[INT]], [[SELECT1]]
+ ; GFX9-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT1]](f32), [[FSUB]](f32)
+ ; GFX9-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
+ ; GFX9-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT1]](f32), [[C5]]
+ ; GFX9-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
+ ; GFX9-NEXT: [[SELECT2:%[0-9]+]]:_(f32) = G_SELECT [[FCMP1]](s1), [[C6]], [[C4]]
+ ; GFX9-NEXT: [[FADD:%[0-9]+]]:_(f32) = G_FADD [[INT1]], [[SELECT2]]
+ ; GFX9-NEXT: [[INT2:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD]](f32)
+ ; GFX9-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
+ ; GFX9-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = G_SELECT [[FCMP1]](s1), [[C7]], [[C2]]
+ ; GFX9-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = G_FMUL [[INT2]], [[SELECT3]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FPEXT1]]
+ ; GFX9-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[FPEXT1]]
+ ; GFX9-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX9-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[FPEXT1]], [[C8]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX9-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX9-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX9-NEXT: [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX9-NEXT: [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[FPEXT]](f32)
+ ; GFX9-NEXT: [[C9:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX9-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX9-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST]], [[C10]]
+ ; GFX9-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST1]], [[C9]]
+ ; GFX9-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX9-NEXT: [[BITCAST2:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX9-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST2]], [[FMUL1]]
+ ; GFX9-NEXT: [[IS_FPCLASS:%[0-9]+]]:_(s1) = G_IS_FPCLASS [[FPEXT]](f32), 24
+ ; GFX9-NEXT: [[C11:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
+ ; GFX9-NEXT: [[XOR:%[0-9]+]]:_(s1) = G_XOR [[FCMP2]], [[C11]]
+ ; GFX9-NEXT: [[AND3:%[0-9]+]]:_(s1) = G_AND [[IS_FPCLASS]], [[XOR]]
+ ; GFX9-NEXT: [[C12:%[0-9]+]]:_(f32) = G_FCONSTANT float +qnan
+ ; GFX9-NEXT: [[SELECT5:%[0-9]+]]:_(f32) = G_SELECT [[AND3]](s1), [[C12]], [[SELECT4]]
+ ; GFX9-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = G_FPTRUNC [[SELECT5]](f32)
+ ; GFX9-NEXT: [[ANYEXT:%[0-9]+]]:_(i32) = G_ANYEXT [[FPTRUNC]](f16)
; GFX9-NEXT: $vgpr0 = COPY [[ANYEXT]](i32)
%0:_(i32) = COPY $vgpr0
%1:_(i32) = COPY $vgpr1
@@ -440,37 +792,91 @@ body: |
; GFX6-NEXT: [[TRUNC3:%[0-9]+]]:_(f16) = G_TRUNC [[LSHR1]](i32)
; GFX6-NEXT: [[FPEXT:%[0-9]+]]:_(f32) = G_FPEXT [[TRUNC]](f16)
; GFX6-NEXT: [[FPEXT1:%[0-9]+]]:_(f32) = G_FPEXT [[TRUNC2]](f16)
- ; GFX6-NEXT: [[INT:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FPEXT]](f32)
- ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[INT]](f32), [[FPEXT1]](f32)
- ; GFX6-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
- ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT1]](f32), [[C1]]
- ; GFX6-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
- ; GFX6-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
+ ; GFX6-NEXT: [[FABS:%[0-9]+]]:_(f32) = G_FABS [[FPEXT]]
+ ; GFX6-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
+ ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C1]]
+ ; GFX6-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
+ ; GFX6-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
; GFX6-NEXT: [[SELECT:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C2]], [[C3]]
- ; GFX6-NEXT: [[FADD:%[0-9]+]]:_(f32) = G_FADD [[INT1]], [[SELECT]]
- ; GFX6-NEXT: [[INT2:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD]](f32)
- ; GFX6-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
- ; GFX6-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
+ ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[FABS]], [[SELECT]]
+ ; GFX6-NEXT: [[INT:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
+ ; GFX6-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
+ ; GFX6-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
; GFX6-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C4]], [[C5]]
- ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[INT2]], [[SELECT1]]
- ; GFX6-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = G_FPTRUNC [[FMUL]](f32)
+ ; GFX6-NEXT: [[FSUB:%[0-9]+]]:_(f32) = G_FSUB [[INT]], [[SELECT1]]
+ ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT1]](f32), [[FSUB]](f32)
+ ; GFX6-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
+ ; GFX6-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT1]](f32), [[C6]]
+ ; GFX6-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
+ ; GFX6-NEXT: [[SELECT2:%[0-9]+]]:_(f32) = G_SELECT [[FCMP1]](s1), [[C7]], [[C5]]
+ ; GFX6-NEXT: [[FADD:%[0-9]+]]:_(f32) = G_FADD [[INT1]], [[SELECT2]]
+ ; GFX6-NEXT: [[INT2:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD]](f32)
+ ; GFX6-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
+ ; GFX6-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = G_SELECT [[FCMP1]](s1), [[C8]], [[C3]]
+ ; GFX6-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = G_FMUL [[INT2]], [[SELECT3]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FPEXT1]]
+ ; GFX6-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[FPEXT1]]
+ ; GFX6-NEXT: [[C9:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX6-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[FPEXT1]], [[C9]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX6-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX6-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX6-NEXT: [[BITCAST2:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX6-NEXT: [[BITCAST3:%[0-9]+]]:_(i32) = G_BITCAST [[FPEXT]](f32)
+ ; GFX6-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX6-NEXT: [[C11:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX6-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST2]], [[C11]]
+ ; GFX6-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST3]], [[C10]]
+ ; GFX6-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX6-NEXT: [[BITCAST4:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX6-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST4]], [[FMUL1]]
+ ; GFX6-NEXT: [[IS_FPCLASS:%[0-9]+]]:_(s1) = G_IS_FPCLASS [[FPEXT]](f32), 24
+ ; GFX6-NEXT: [[C12:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
+ ; GFX6-NEXT: [[XOR:%[0-9]+]]:_(s1) = G_XOR [[FCMP2]], [[C12]]
+ ; GFX6-NEXT: [[AND3:%[0-9]+]]:_(s1) = G_AND [[IS_FPCLASS]], [[XOR]]
+ ; GFX6-NEXT: [[C13:%[0-9]+]]:_(f32) = G_FCONSTANT float +qnan
+ ; GFX6-NEXT: [[SELECT5:%[0-9]+]]:_(f32) = G_SELECT [[AND3]](s1), [[C13]], [[SELECT4]]
+ ; GFX6-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = G_FPTRUNC [[SELECT5]](f32)
; GFX6-NEXT: [[FPEXT2:%[0-9]+]]:_(f32) = G_FPEXT [[TRUNC1]](f16)
; GFX6-NEXT: [[FPEXT3:%[0-9]+]]:_(f32) = G_FPEXT [[TRUNC3]](f16)
- ; GFX6-NEXT: [[INT3:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FPEXT2]](f32)
- ; GFX6-NEXT: [[INT4:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[INT3]](f32), [[FPEXT3]](f32)
- ; GFX6-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT4]](f32), [[C1]]
- ; GFX6-NEXT: [[SELECT2:%[0-9]+]]:_(f32) = G_SELECT [[FCMP1]](s1), [[C2]], [[C3]]
- ; GFX6-NEXT: [[FADD1:%[0-9]+]]:_(f32) = G_FADD [[INT4]], [[SELECT2]]
+ ; GFX6-NEXT: [[FABS1:%[0-9]+]]:_(f32) = G_FABS [[FPEXT2]]
+ ; GFX6-NEXT: [[FCMP4:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS1]](f32), [[C1]]
+ ; GFX6-NEXT: [[SELECT6:%[0-9]+]]:_(f32) = G_SELECT [[FCMP4]](s1), [[C2]], [[C3]]
+ ; GFX6-NEXT: [[FMUL3:%[0-9]+]]:_(f32) = G_FMUL [[FABS1]], [[SELECT6]]
+ ; GFX6-NEXT: [[INT3:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL3]](f32)
+ ; GFX6-NEXT: [[SELECT7:%[0-9]+]]:_(f32) = G_SELECT [[FCMP4]](s1), [[C4]], [[C5]]
+ ; GFX6-NEXT: [[FSUB1:%[0-9]+]]:_(f32) = G_FSUB [[INT3]], [[SELECT7]]
+ ; GFX6-NEXT: [[INT4:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT3]](f32), [[FSUB1]](f32)
+ ; GFX6-NEXT: [[FCMP5:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT4]](f32), [[C6]]
+ ; GFX6-NEXT: [[SELECT8:%[0-9]+]]:_(f32) = G_SELECT [[FCMP5]](s1), [[C7]], [[C5]]
+ ; GFX6-NEXT: [[FADD1:%[0-9]+]]:_(f32) = G_FADD [[INT4]], [[SELECT8]]
; GFX6-NEXT: [[INT5:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD1]](f32)
- ; GFX6-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = G_SELECT [[FCMP1]](s1), [[C4]], [[C5]]
- ; GFX6-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = G_FMUL [[INT5]], [[SELECT3]]
- ; GFX6-NEXT: [[FPTRUNC1:%[0-9]+]]:_(f16) = G_FPTRUNC [[FMUL1]](f32)
+ ; GFX6-NEXT: [[SELECT9:%[0-9]+]]:_(f32) = G_SELECT [[FCMP5]](s1), [[C8]], [[C3]]
+ ; GFX6-NEXT: [[FMUL4:%[0-9]+]]:_(f32) = G_FMUL [[INT5]], [[SELECT9]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC2:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FPEXT3]]
+ ; GFX6-NEXT: [[FCMP6:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC2]](f32), [[FPEXT3]]
+ ; GFX6-NEXT: [[FMUL5:%[0-9]+]]:_(f32) = G_FMUL [[FPEXT3]], [[C9]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC3:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL5]]
+ ; GFX6-NEXT: [[FCMP7:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC3]](f32), [[FMUL5]]
+ ; GFX6-NEXT: [[AND4:%[0-9]+]]:_(s1) = G_AND [[FCMP6]], [[FCMP7]]
+ ; GFX6-NEXT: [[BITCAST5:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL4]](f32)
+ ; GFX6-NEXT: [[BITCAST6:%[0-9]+]]:_(i32) = G_BITCAST [[FPEXT2]](f32)
+ ; GFX6-NEXT: [[AND5:%[0-9]+]]:_(i32) = G_AND [[BITCAST5]], [[C11]]
+ ; GFX6-NEXT: [[AND6:%[0-9]+]]:_(i32) = G_AND [[BITCAST6]], [[C10]]
+ ; GFX6-NEXT: [[OR1:%[0-9]+]]:_(i32) = disjoint G_OR [[AND5]], [[AND6]]
+ ; GFX6-NEXT: [[BITCAST7:%[0-9]+]]:_(f32) = G_BITCAST [[OR1]](i32)
+ ; GFX6-NEXT: [[SELECT10:%[0-9]+]]:_(f32) = G_SELECT [[AND4]](s1), [[BITCAST7]], [[FMUL4]]
+ ; GFX6-NEXT: [[IS_FPCLASS1:%[0-9]+]]:_(s1) = G_IS_FPCLASS [[FPEXT2]](f32), 24
+ ; GFX6-NEXT: [[XOR1:%[0-9]+]]:_(s1) = G_XOR [[FCMP6]], [[C12]]
+ ; GFX6-NEXT: [[AND7:%[0-9]+]]:_(s1) = G_AND [[IS_FPCLASS1]], [[XOR1]]
+ ; GFX6-NEXT: [[SELECT11:%[0-9]+]]:_(f32) = G_SELECT [[AND7]](s1), [[C13]], [[SELECT10]]
+ ; GFX6-NEXT: [[FPTRUNC1:%[0-9]+]]:_(f16) = G_FPTRUNC [[SELECT11]](f32)
; GFX6-NEXT: [[ZEXT:%[0-9]+]]:_(i32) = G_ZEXT [[FPTRUNC]](f16)
; GFX6-NEXT: [[ZEXT1:%[0-9]+]]:_(i32) = G_ZEXT [[FPTRUNC1]](f16)
; GFX6-NEXT: [[SHL:%[0-9]+]]:_(i32) = G_SHL [[ZEXT1]], [[C]](i32)
- ; GFX6-NEXT: [[OR:%[0-9]+]]:_(i32) = G_OR [[ZEXT]], [[SHL]]
- ; GFX6-NEXT: [[BITCAST2:%[0-9]+]]:_(<2 x f16>) = G_BITCAST [[OR]](i32)
- ; GFX6-NEXT: $vgpr0 = COPY [[BITCAST2]](<2 x f16>)
+ ; GFX6-NEXT: [[OR2:%[0-9]+]]:_(i32) = G_OR [[ZEXT]], [[SHL]]
+ ; GFX6-NEXT: [[BITCAST8:%[0-9]+]]:_(<2 x f16>) = G_BITCAST [[OR2]](i32)
+ ; GFX6-NEXT: $vgpr0 = COPY [[BITCAST8]](<2 x f16>)
;
; GFX9-LABEL: name: test_fpow_v2f16
; GFX9: liveins: $vgpr0, $vgpr1
@@ -486,19 +892,88 @@ body: |
; GFX9-NEXT: [[TRUNC2:%[0-9]+]]:_(f16) = G_TRUNC [[BITCAST1]](i32)
; GFX9-NEXT: [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST1]], [[C]](i32)
; GFX9-NEXT: [[TRUNC3:%[0-9]+]]:_(f16) = G_TRUNC [[LSHR1]](i32)
- ; GFX9-NEXT: [[FLOG2_:%[0-9]+]]:_(f16) = G_FLOG2 [[TRUNC]]
- ; GFX9-NEXT: [[FPEXT:%[0-9]+]]:_(f32) = G_FPEXT [[FLOG2_]](f16)
+ ; GFX9-NEXT: [[FPEXT:%[0-9]+]]:_(f32) = G_FPEXT [[TRUNC]](f16)
; GFX9-NEXT: [[FPEXT1:%[0-9]+]]:_(f32) = G_FPEXT [[TRUNC2]](f16)
- ; GFX9-NEXT: [[INT:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT]](f32), [[FPEXT1]](f32)
- ; GFX9-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = G_FPTRUNC [[INT]](f32)
- ; GFX9-NEXT: [[FEXP2_:%[0-9]+]]:_(f16) = G_FEXP2 [[FPTRUNC]]
- ; GFX9-NEXT: [[FLOG2_1:%[0-9]+]]:_(f16) = G_FLOG2 [[TRUNC1]]
- ; GFX9-NEXT: [[FPEXT2:%[0-9]+]]:_(f32) = G_FPEXT [[FLOG2_1]](f16)
+ ; GFX9-NEXT: [[FABS:%[0-9]+]]:_(f32) = G_FABS [[FPEXT]]
+ ; GFX9-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
+ ; GFX9-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C1]]
+ ; GFX9-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
+ ; GFX9-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
+ ; GFX9-NEXT: [[SELECT:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C2]], [[C3]]
+ ; GFX9-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[FABS]], [[SELECT]]
+ ; GFX9-NEXT: [[INT:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
+ ; GFX9-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
+ ; GFX9-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
+ ; GFX9-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = G_SELECT [[FCMP]](s1), [[C4]], [[C5]]
+ ; GFX9-NEXT: [[FSUB:%[0-9]+]]:_(f32) = G_FSUB [[INT]], [[SELECT1]]
+ ; GFX9-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT1]](f32), [[FSUB]](f32)
+ ; GFX9-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
+ ; GFX9-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT1]](f32), [[C6]]
+ ; GFX9-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
+ ; GFX9-NEXT: [[SELECT2:%[0-9]+]]:_(f32) = G_SELECT [[FCMP1]](s1), [[C7]], [[C5]]
+ ; GFX9-NEXT: [[FADD:%[0-9]+]]:_(f32) = G_FADD [[INT1]], [[SELECT2]]
+ ; GFX9-NEXT: [[INT2:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD]](f32)
+ ; GFX9-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
+ ; GFX9-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = G_SELECT [[FCMP1]](s1), [[C8]], [[C3]]
+ ; GFX9-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = G_FMUL [[INT2]], [[SELECT3]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FPEXT1]]
+ ; GFX9-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[FPEXT1]]
+ ; GFX9-NEXT: [[C9:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX9-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[FPEXT1]], [[C9]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX9-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX9-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX9-NEXT: [[BITCAST2:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX9-NEXT: [[BITCAST3:%[0-9]+]]:_(i32) = G_BITCAST [[FPEXT]](f32)
+ ; GFX9-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX9-NEXT: [[C11:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX9-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST2]], [[C11]]
+ ; GFX9-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST3]], [[C10]]
+ ; GFX9-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX9-NEXT: [[BITCAST4:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX9-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST4]], [[FMUL1]]
+ ; GFX9-NEXT: [[IS_FPCLASS:%[0-9]+]]:_(s1) = G_IS_FPCLASS [[FPEXT]](f32), 24
+ ; GFX9-NEXT: [[C12:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
+ ; GFX9-NEXT: [[XOR:%[0-9]+]]:_(s1) = G_XOR [[FCMP2]], [[C12]]
+ ; GFX9-NEXT: [[AND3:%[0-9]+]]:_(s1) = G_AND [[IS_FPCLASS]], [[XOR]]
+ ; GFX9-NEXT: [[C13:%[0-9]+]]:_(f32) = G_FCONSTANT float +qnan
+ ; GFX9-NEXT: [[SELECT5:%[0-9]+]]:_(f32) = G_SELECT [[AND3]](s1), [[C13]], [[SELECT4]]
+ ; GFX9-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = G_FPTRUNC [[SELECT5]](f32)
+ ; GFX9-NEXT: [[FPEXT2:%[0-9]+]]:_(f32) = G_FPEXT [[TRUNC1]](f16)
; GFX9-NEXT: [[FPEXT3:%[0-9]+]]:_(f32) = G_FPEXT [[TRUNC3]](f16)
- ; GFX9-NEXT: [[INT1:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT2]](f32), [[FPEXT3]](f32)
- ; GFX9-NEXT: [[FPTRUNC1:%[0-9]+]]:_(f16) = G_FPTRUNC [[INT1]](f32)
- ; GFX9-NEXT: [[FEXP2_1:%[0-9]+]]:_(f16) = G_FEXP2 [[FPTRUNC1]]
- ; GFX9-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x f16>) = G_BUILD_VECTOR [[FEXP2_]](f16), [[FEXP2_1]](f16)
+ ; GFX9-NEXT: [[FABS1:%[0-9]+]]:_(f32) = G_FABS [[FPEXT2]]
+ ; GFX9-NEXT: [[FCMP4:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS1]](f32), [[C1]]
+ ; GFX9-NEXT: [[SELECT6:%[0-9]+]]:_(f32) = G_SELECT [[FCMP4]](s1), [[C2]], [[C3]]
+ ; GFX9-NEXT: [[FMUL3:%[0-9]+]]:_(f32) = G_FMUL [[FABS1]], [[SELECT6]]
+ ; GFX9-NEXT: [[INT3:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL3]](f32)
+ ; GFX9-NEXT: [[SELECT7:%[0-9]+]]:_(f32) = G_SELECT [[FCMP4]](s1), [[C4]], [[C5]]
+ ; GFX9-NEXT: [[FSUB1:%[0-9]+]]:_(f32) = G_FSUB [[INT3]], [[SELECT7]]
+ ; GFX9-NEXT: [[INT4:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT3]](f32), [[FSUB1]](f32)
+ ; GFX9-NEXT: [[FCMP5:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[INT4]](f32), [[C6]]
+ ; GFX9-NEXT: [[SELECT8:%[0-9]+]]:_(f32) = G_SELECT [[FCMP5]](s1), [[C7]], [[C5]]
+ ; GFX9-NEXT: [[FADD1:%[0-9]+]]:_(f32) = G_FADD [[INT4]], [[SELECT8]]
+ ; GFX9-NEXT: [[INT5:%[0-9]+]]:_(f32) = G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD1]](f32)
+ ; GFX9-NEXT: [[SELECT9:%[0-9]+]]:_(f32) = G_SELECT [[FCMP5]](s1), [[C8]], [[C3]]
+ ; GFX9-NEXT: [[FMUL4:%[0-9]+]]:_(f32) = G_FMUL [[INT5]], [[SELECT9]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC2:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FPEXT3]]
+ ; GFX9-NEXT: [[FCMP6:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC2]](f32), [[FPEXT3]]
+ ; GFX9-NEXT: [[FMUL5:%[0-9]+]]:_(f32) = G_FMUL [[FPEXT3]], [[C9]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC3:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL5]]
+ ; GFX9-NEXT: [[FCMP7:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC3]](f32), [[FMUL5]]
+ ; GFX9-NEXT: [[AND4:%[0-9]+]]:_(s1) = G_AND [[FCMP6]], [[FCMP7]]
+ ; GFX9-NEXT: [[BITCAST5:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL4]](f32)
+ ; GFX9-NEXT: [[BITCAST6:%[0-9]+]]:_(i32) = G_BITCAST [[FPEXT2]](f32)
+ ; GFX9-NEXT: [[AND5:%[0-9]+]]:_(i32) = G_AND [[BITCAST5]], [[C11]]
+ ; GFX9-NEXT: [[AND6:%[0-9]+]]:_(i32) = G_AND [[BITCAST6]], [[C10]]
+ ; GFX9-NEXT: [[OR1:%[0-9]+]]:_(i32) = disjoint G_OR [[AND5]], [[AND6]]
+ ; GFX9-NEXT: [[BITCAST7:%[0-9]+]]:_(f32) = G_BITCAST [[OR1]](i32)
+ ; GFX9-NEXT: [[SELECT10:%[0-9]+]]:_(f32) = G_SELECT [[AND4]](s1), [[BITCAST7]], [[FMUL4]]
+ ; GFX9-NEXT: [[IS_FPCLASS1:%[0-9]+]]:_(s1) = G_IS_FPCLASS [[FPEXT2]](f32), 24
+ ; GFX9-NEXT: [[XOR1:%[0-9]+]]:_(s1) = G_XOR [[FCMP6]], [[C12]]
+ ; GFX9-NEXT: [[AND7:%[0-9]+]]:_(s1) = G_AND [[IS_FPCLASS1]], [[XOR1]]
+ ; GFX9-NEXT: [[SELECT11:%[0-9]+]]:_(f32) = G_SELECT [[AND7]](s1), [[C13]], [[SELECT10]]
+ ; GFX9-NEXT: [[FPTRUNC1:%[0-9]+]]:_(f16) = G_FPTRUNC [[SELECT11]](f32)
+ ; GFX9-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x f16>) = G_BUILD_VECTOR [[FPTRUNC]](f16), [[FPTRUNC1]](f16)
; GFX9-NEXT: $vgpr0 = COPY [[BUILD_VECTOR]](<2 x f16>)
%0:_(<2 x f16>) = COPY $vgpr0
%1:_(<2 x f16>) = COPY $vgpr1
@@ -528,37 +1003,81 @@ body: |
; GFX6-NEXT: [[TRUNC3:%[0-9]+]]:_(f16) = G_TRUNC [[LSHR1]](i32)
; GFX6-NEXT: [[FPEXT:%[0-9]+]]:_(f32) = nnan nsz G_FPEXT [[TRUNC]](f16)
; GFX6-NEXT: [[FPEXT1:%[0-9]+]]:_(f32) = nnan nsz G_FPEXT [[TRUNC2]](f16)
- ; GFX6-NEXT: [[INT:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FPEXT]](f32)
- ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[INT]](f32), [[FPEXT1]](f32)
- ; GFX6-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
- ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = nnan nsz G_FCMP floatpred(olt), [[INT1]](f32), [[C1]]
- ; GFX6-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
- ; GFX6-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
+ ; GFX6-NEXT: [[FABS:%[0-9]+]]:_(f32) = nnan nsz G_FABS [[FPEXT]]
+ ; GFX6-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
+ ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C1]]
+ ; GFX6-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
+ ; GFX6-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
; GFX6-NEXT: [[SELECT:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP]](s1), [[C2]], [[C3]]
- ; GFX6-NEXT: [[FADD:%[0-9]+]]:_(f32) = nnan nsz G_FADD [[INT1]], [[SELECT]]
- ; GFX6-NEXT: [[INT2:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD]](f32)
- ; GFX6-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
- ; GFX6-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
+ ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = nnan nsz G_FMUL [[FABS]], [[SELECT]]
+ ; GFX6-NEXT: [[INT:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
+ ; GFX6-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
+ ; GFX6-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
; GFX6-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP]](s1), [[C4]], [[C5]]
- ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = nnan nsz G_FMUL [[INT2]], [[SELECT1]]
- ; GFX6-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = nnan nsz G_FPTRUNC [[FMUL]](f32)
+ ; GFX6-NEXT: [[FSUB:%[0-9]+]]:_(f32) = nnan nsz G_FSUB [[INT]], [[SELECT1]]
+ ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT1]](f32), [[FSUB]](f32)
+ ; GFX6-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
+ ; GFX6-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = nnan nsz G_FCMP floatpred(olt), [[INT1]](f32), [[C6]]
+ ; GFX6-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
+ ; GFX6-NEXT: [[SELECT2:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP1]](s1), [[C7]], [[C5]]
+ ; GFX6-NEXT: [[FADD:%[0-9]+]]:_(f32) = nnan nsz G_FADD [[INT1]], [[SELECT2]]
+ ; GFX6-NEXT: [[INT2:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD]](f32)
+ ; GFX6-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
+ ; GFX6-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP1]](s1), [[C8]], [[C3]]
+ ; GFX6-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = nnan nsz G_FMUL [[INT2]], [[SELECT3]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FPEXT1]]
+ ; GFX6-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[FPEXT1]]
+ ; GFX6-NEXT: [[C9:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX6-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[FPEXT1]], [[C9]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX6-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX6-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX6-NEXT: [[BITCAST2:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX6-NEXT: [[BITCAST3:%[0-9]+]]:_(i32) = G_BITCAST [[FPEXT]](f32)
+ ; GFX6-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX6-NEXT: [[C11:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX6-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST2]], [[C11]]
+ ; GFX6-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST3]], [[C10]]
+ ; GFX6-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX6-NEXT: [[BITCAST4:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX6-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST4]], [[FMUL1]]
+ ; GFX6-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = nnan nsz G_FPTRUNC [[SELECT4]](f32)
; GFX6-NEXT: [[FPEXT2:%[0-9]+]]:_(f32) = nnan nsz G_FPEXT [[TRUNC1]](f16)
; GFX6-NEXT: [[FPEXT3:%[0-9]+]]:_(f32) = nnan nsz G_FPEXT [[TRUNC3]](f16)
- ; GFX6-NEXT: [[INT3:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FPEXT2]](f32)
- ; GFX6-NEXT: [[INT4:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[INT3]](f32), [[FPEXT3]](f32)
- ; GFX6-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = nnan nsz G_FCMP floatpred(olt), [[INT4]](f32), [[C1]]
- ; GFX6-NEXT: [[SELECT2:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP1]](s1), [[C2]], [[C3]]
- ; GFX6-NEXT: [[FADD1:%[0-9]+]]:_(f32) = nnan nsz G_FADD [[INT4]], [[SELECT2]]
+ ; GFX6-NEXT: [[FABS1:%[0-9]+]]:_(f32) = nnan nsz G_FABS [[FPEXT2]]
+ ; GFX6-NEXT: [[FCMP4:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS1]](f32), [[C1]]
+ ; GFX6-NEXT: [[SELECT5:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP4]](s1), [[C2]], [[C3]]
+ ; GFX6-NEXT: [[FMUL3:%[0-9]+]]:_(f32) = nnan nsz G_FMUL [[FABS1]], [[SELECT5]]
+ ; GFX6-NEXT: [[INT3:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL3]](f32)
+ ; GFX6-NEXT: [[SELECT6:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP4]](s1), [[C4]], [[C5]]
+ ; GFX6-NEXT: [[FSUB1:%[0-9]+]]:_(f32) = nnan nsz G_FSUB [[INT3]], [[SELECT6]]
+ ; GFX6-NEXT: [[INT4:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT3]](f32), [[FSUB1]](f32)
+ ; GFX6-NEXT: [[FCMP5:%[0-9]+]]:_(s1) = nnan nsz G_FCMP floatpred(olt), [[INT4]](f32), [[C6]]
+ ; GFX6-NEXT: [[SELECT7:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP5]](s1), [[C7]], [[C5]]
+ ; GFX6-NEXT: [[FADD1:%[0-9]+]]:_(f32) = nnan nsz G_FADD [[INT4]], [[SELECT7]]
; GFX6-NEXT: [[INT5:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD1]](f32)
- ; GFX6-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP1]](s1), [[C4]], [[C5]]
- ; GFX6-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = nnan nsz G_FMUL [[INT5]], [[SELECT3]]
- ; GFX6-NEXT: [[FPTRUNC1:%[0-9]+]]:_(f16) = nnan nsz G_FPTRUNC [[FMUL1]](f32)
+ ; GFX6-NEXT: [[SELECT8:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP5]](s1), [[C8]], [[C3]]
+ ; GFX6-NEXT: [[FMUL4:%[0-9]+]]:_(f32) = nnan nsz G_FMUL [[INT5]], [[SELECT8]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC2:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FPEXT3]]
+ ; GFX6-NEXT: [[FCMP6:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC2]](f32), [[FPEXT3]]
+ ; GFX6-NEXT: [[FMUL5:%[0-9]+]]:_(f32) = G_FMUL [[FPEXT3]], [[C9]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC3:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL5]]
+ ; GFX6-NEXT: [[FCMP7:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC3]](f32), [[FMUL5]]
+ ; GFX6-NEXT: [[AND3:%[0-9]+]]:_(s1) = G_AND [[FCMP6]], [[FCMP7]]
+ ; GFX6-NEXT: [[BITCAST5:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL4]](f32)
+ ; GFX6-NEXT: [[BITCAST6:%[0-9]+]]:_(i32) = G_BITCAST [[FPEXT2]](f32)
+ ; GFX6-NEXT: [[AND4:%[0-9]+]]:_(i32) = G_AND [[BITCAST5]], [[C11]]
+ ; GFX6-NEXT: [[AND5:%[0-9]+]]:_(i32) = G_AND [[BITCAST6]], [[C10]]
+ ; GFX6-NEXT: [[OR1:%[0-9]+]]:_(i32) = disjoint G_OR [[AND4]], [[AND5]]
+ ; GFX6-NEXT: [[BITCAST7:%[0-9]+]]:_(f32) = G_BITCAST [[OR1]](i32)
+ ; GFX6-NEXT: [[SELECT9:%[0-9]+]]:_(f32) = G_SELECT [[AND3]](s1), [[BITCAST7]], [[FMUL4]]
+ ; GFX6-NEXT: [[FPTRUNC1:%[0-9]+]]:_(f16) = nnan nsz G_FPTRUNC [[SELECT9]](f32)
; GFX6-NEXT: [[ZEXT:%[0-9]+]]:_(i32) = G_ZEXT [[FPTRUNC]](f16)
; GFX6-NEXT: [[ZEXT1:%[0-9]+]]:_(i32) = G_ZEXT [[FPTRUNC1]](f16)
; GFX6-NEXT: [[SHL:%[0-9]+]]:_(i32) = G_SHL [[ZEXT1]], [[C]](i32)
- ; GFX6-NEXT: [[OR:%[0-9]+]]:_(i32) = G_OR [[ZEXT]], [[SHL]]
- ; GFX6-NEXT: [[BITCAST2:%[0-9]+]]:_(<2 x f16>) = G_BITCAST [[OR]](i32)
- ; GFX6-NEXT: $vgpr0 = COPY [[BITCAST2]](<2 x f16>)
+ ; GFX6-NEXT: [[OR2:%[0-9]+]]:_(i32) = G_OR [[ZEXT]], [[SHL]]
+ ; GFX6-NEXT: [[BITCAST8:%[0-9]+]]:_(<2 x f16>) = G_BITCAST [[OR2]](i32)
+ ; GFX6-NEXT: $vgpr0 = COPY [[BITCAST8]](<2 x f16>)
;
; GFX9-LABEL: name: test_fpow_v2f16_flags
; GFX9: liveins: $vgpr0, $vgpr1
@@ -574,19 +1093,78 @@ body: |
; GFX9-NEXT: [[TRUNC2:%[0-9]+]]:_(f16) = G_TRUNC [[BITCAST1]](i32)
; GFX9-NEXT: [[LSHR1:%[0-9]+]]:_(i32) = G_LSHR [[BITCAST1]], [[C]](i32)
; GFX9-NEXT: [[TRUNC3:%[0-9]+]]:_(f16) = G_TRUNC [[LSHR1]](i32)
- ; GFX9-NEXT: [[FLOG2_:%[0-9]+]]:_(f16) = nnan nsz G_FLOG2 [[TRUNC]]
- ; GFX9-NEXT: [[FPEXT:%[0-9]+]]:_(f32) = nnan nsz G_FPEXT [[FLOG2_]](f16)
+ ; GFX9-NEXT: [[FPEXT:%[0-9]+]]:_(f32) = nnan nsz G_FPEXT [[TRUNC]](f16)
; GFX9-NEXT: [[FPEXT1:%[0-9]+]]:_(f32) = nnan nsz G_FPEXT [[TRUNC2]](f16)
- ; GFX9-NEXT: [[INT:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT]](f32), [[FPEXT1]](f32)
- ; GFX9-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = nnan nsz G_FPTRUNC [[INT]](f32)
- ; GFX9-NEXT: [[FEXP2_:%[0-9]+]]:_(f16) = nnan nsz G_FEXP2 [[FPTRUNC]]
- ; GFX9-NEXT: [[FLOG2_1:%[0-9]+]]:_(f16) = nnan nsz G_FLOG2 [[TRUNC1]]
- ; GFX9-NEXT: [[FPEXT2:%[0-9]+]]:_(f32) = nnan nsz G_FPEXT [[FLOG2_1]](f16)
+ ; GFX9-NEXT: [[FABS:%[0-9]+]]:_(f32) = nnan nsz G_FABS [[FPEXT]]
+ ; GFX9-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
+ ; GFX9-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C1]]
+ ; GFX9-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
+ ; GFX9-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
+ ; GFX9-NEXT: [[SELECT:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP]](s1), [[C2]], [[C3]]
+ ; GFX9-NEXT: [[FMUL:%[0-9]+]]:_(f32) = nnan nsz G_FMUL [[FABS]], [[SELECT]]
+ ; GFX9-NEXT: [[INT:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
+ ; GFX9-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
+ ; GFX9-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
+ ; GFX9-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP]](s1), [[C4]], [[C5]]
+ ; GFX9-NEXT: [[FSUB:%[0-9]+]]:_(f32) = nnan nsz G_FSUB [[INT]], [[SELECT1]]
+ ; GFX9-NEXT: [[INT1:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT1]](f32), [[FSUB]](f32)
+ ; GFX9-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
+ ; GFX9-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = nnan nsz G_FCMP floatpred(olt), [[INT1]](f32), [[C6]]
+ ; GFX9-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
+ ; GFX9-NEXT: [[SELECT2:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP1]](s1), [[C7]], [[C5]]
+ ; GFX9-NEXT: [[FADD:%[0-9]+]]:_(f32) = nnan nsz G_FADD [[INT1]], [[SELECT2]]
+ ; GFX9-NEXT: [[INT2:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD]](f32)
+ ; GFX9-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
+ ; GFX9-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP1]](s1), [[C8]], [[C3]]
+ ; GFX9-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = nnan nsz G_FMUL [[INT2]], [[SELECT3]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FPEXT1]]
+ ; GFX9-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[FPEXT1]]
+ ; GFX9-NEXT: [[C9:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX9-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[FPEXT1]], [[C9]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX9-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX9-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX9-NEXT: [[BITCAST2:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX9-NEXT: [[BITCAST3:%[0-9]+]]:_(i32) = G_BITCAST [[FPEXT]](f32)
+ ; GFX9-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX9-NEXT: [[C11:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX9-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST2]], [[C11]]
+ ; GFX9-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST3]], [[C10]]
+ ; GFX9-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX9-NEXT: [[BITCAST4:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX9-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST4]], [[FMUL1]]
+ ; GFX9-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = nnan nsz G_FPTRUNC [[SELECT4]](f32)
+ ; GFX9-NEXT: [[FPEXT2:%[0-9]+]]:_(f32) = nnan nsz G_FPEXT [[TRUNC1]](f16)
; GFX9-NEXT: [[FPEXT3:%[0-9]+]]:_(f32) = nnan nsz G_FPEXT [[TRUNC3]](f16)
- ; GFX9-NEXT: [[INT1:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT2]](f32), [[FPEXT3]](f32)
- ; GFX9-NEXT: [[FPTRUNC1:%[0-9]+]]:_(f16) = nnan nsz G_FPTRUNC [[INT1]](f32)
- ; GFX9-NEXT: [[FEXP2_1:%[0-9]+]]:_(f16) = nnan nsz G_FEXP2 [[FPTRUNC1]]
- ; GFX9-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x f16>) = G_BUILD_VECTOR [[FEXP2_]](f16), [[FEXP2_1]](f16)
+ ; GFX9-NEXT: [[FABS1:%[0-9]+]]:_(f32) = nnan nsz G_FABS [[FPEXT2]]
+ ; GFX9-NEXT: [[FCMP4:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS1]](f32), [[C1]]
+ ; GFX9-NEXT: [[SELECT5:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP4]](s1), [[C2]], [[C3]]
+ ; GFX9-NEXT: [[FMUL3:%[0-9]+]]:_(f32) = nnan nsz G_FMUL [[FABS1]], [[SELECT5]]
+ ; GFX9-NEXT: [[INT3:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL3]](f32)
+ ; GFX9-NEXT: [[SELECT6:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP4]](s1), [[C4]], [[C5]]
+ ; GFX9-NEXT: [[FSUB1:%[0-9]+]]:_(f32) = nnan nsz G_FSUB [[INT3]], [[SELECT6]]
+ ; GFX9-NEXT: [[INT4:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT3]](f32), [[FSUB1]](f32)
+ ; GFX9-NEXT: [[FCMP5:%[0-9]+]]:_(s1) = nnan nsz G_FCMP floatpred(olt), [[INT4]](f32), [[C6]]
+ ; GFX9-NEXT: [[SELECT7:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP5]](s1), [[C7]], [[C5]]
+ ; GFX9-NEXT: [[FADD1:%[0-9]+]]:_(f32) = nnan nsz G_FADD [[INT4]], [[SELECT7]]
+ ; GFX9-NEXT: [[INT5:%[0-9]+]]:_(f32) = nnan nsz G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD1]](f32)
+ ; GFX9-NEXT: [[SELECT8:%[0-9]+]]:_(f32) = nnan nsz G_SELECT [[FCMP5]](s1), [[C8]], [[C3]]
+ ; GFX9-NEXT: [[FMUL4:%[0-9]+]]:_(f32) = nnan nsz G_FMUL [[INT5]], [[SELECT8]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC2:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FPEXT3]]
+ ; GFX9-NEXT: [[FCMP6:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC2]](f32), [[FPEXT3]]
+ ; GFX9-NEXT: [[FMUL5:%[0-9]+]]:_(f32) = G_FMUL [[FPEXT3]], [[C9]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC3:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL5]]
+ ; GFX9-NEXT: [[FCMP7:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC3]](f32), [[FMUL5]]
+ ; GFX9-NEXT: [[AND3:%[0-9]+]]:_(s1) = G_AND [[FCMP6]], [[FCMP7]]
+ ; GFX9-NEXT: [[BITCAST5:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL4]](f32)
+ ; GFX9-NEXT: [[BITCAST6:%[0-9]+]]:_(i32) = G_BITCAST [[FPEXT2]](f32)
+ ; GFX9-NEXT: [[AND4:%[0-9]+]]:_(i32) = G_AND [[BITCAST5]], [[C11]]
+ ; GFX9-NEXT: [[AND5:%[0-9]+]]:_(i32) = G_AND [[BITCAST6]], [[C10]]
+ ; GFX9-NEXT: [[OR1:%[0-9]+]]:_(i32) = disjoint G_OR [[AND4]], [[AND5]]
+ ; GFX9-NEXT: [[BITCAST7:%[0-9]+]]:_(f32) = G_BITCAST [[OR1]](i32)
+ ; GFX9-NEXT: [[SELECT9:%[0-9]+]]:_(f32) = G_SELECT [[AND3]](s1), [[BITCAST7]], [[FMUL4]]
+ ; GFX9-NEXT: [[FPTRUNC1:%[0-9]+]]:_(f16) = nnan nsz G_FPTRUNC [[SELECT9]](f32)
+ ; GFX9-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x f16>) = G_BUILD_VECTOR [[FPTRUNC]](f16), [[FPTRUNC1]](f16)
; GFX9-NEXT: $vgpr0 = COPY [[BUILD_VECTOR]](<2 x f16>)
%0:_(<2 x f16>) = COPY $vgpr0
%1:_(<2 x f16>) = COPY $vgpr1
@@ -609,20 +1187,45 @@ body: |
; GFX6-NEXT: [[TRUNC1:%[0-9]+]]:_(f16) = G_TRUNC [[COPY1]](i32)
; GFX6-NEXT: [[FPEXT:%[0-9]+]]:_(f32) = nnan ninf G_FPEXT [[TRUNC]](f16)
; GFX6-NEXT: [[FPEXT1:%[0-9]+]]:_(f32) = nnan ninf G_FPEXT [[TRUNC1]](f16)
- ; GFX6-NEXT: [[INT:%[0-9]+]]:_(f32) = nnan ninf G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FPEXT]](f32)
- ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = nnan ninf G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[INT]](f32), [[FPEXT1]](f32)
- ; GFX6-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
- ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = nnan ninf G_FCMP floatpred(olt), [[INT1]](f32), [[C]]
- ; GFX6-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
- ; GFX6-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
- ; GFX6-NEXT: [[SELECT:%[0-9]+]]:_(f32) = nnan ninf G_SELECT [[FCMP]](s1), [[C1]], [[C2]]
- ; GFX6-NEXT: [[FADD:%[0-9]+]]:_(f32) = nnan ninf G_FADD [[INT1]], [[SELECT]]
- ; GFX6-NEXT: [[INT2:%[0-9]+]]:_(f32) = nnan ninf G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD]](f32)
- ; GFX6-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
- ; GFX6-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
- ; GFX6-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = nnan ninf G_SELECT [[FCMP]](s1), [[C3]], [[C4]]
- ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = nnan ninf G_FMUL [[INT2]], [[SELECT1]]
- ; GFX6-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = nnan ninf G_FPTRUNC [[FMUL]](f32)
+ ; GFX6-NEXT: [[FABS:%[0-9]+]]:_(f32) = nnan ninf G_FABS [[FPEXT]]
+ ; GFX6-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
+ ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C]]
+ ; GFX6-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
+ ; GFX6-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
+ ; GFX6-NEXT: [[SELECT:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP]](s1), [[C1]], [[C2]]
+ ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = nnan G_FMUL [[FABS]], [[SELECT]]
+ ; GFX6-NEXT: [[INT:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
+ ; GFX6-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
+ ; GFX6-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
+ ; GFX6-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP]](s1), [[C3]], [[C4]]
+ ; GFX6-NEXT: [[FSUB:%[0-9]+]]:_(f32) = nnan G_FSUB [[INT]], [[SELECT1]]
+ ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT1]](f32), [[FSUB]](f32)
+ ; GFX6-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
+ ; GFX6-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = nnan G_FCMP floatpred(olt), [[INT1]](f32), [[C5]]
+ ; GFX6-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
+ ; GFX6-NEXT: [[SELECT2:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP1]](s1), [[C6]], [[C4]]
+ ; GFX6-NEXT: [[FADD:%[0-9]+]]:_(f32) = nnan G_FADD [[INT1]], [[SELECT2]]
+ ; GFX6-NEXT: [[INT2:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD]](f32)
+ ; GFX6-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
+ ; GFX6-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP1]](s1), [[C7]], [[C2]]
+ ; GFX6-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = nnan G_FMUL [[INT2]], [[SELECT3]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FPEXT1]]
+ ; GFX6-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[FPEXT1]]
+ ; GFX6-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX6-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[FPEXT1]], [[C8]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX6-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX6-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX6-NEXT: [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX6-NEXT: [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[FPEXT]](f32)
+ ; GFX6-NEXT: [[C9:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX6-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX6-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST]], [[C10]]
+ ; GFX6-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST1]], [[C9]]
+ ; GFX6-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX6-NEXT: [[BITCAST2:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX6-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST2]], [[FMUL1]]
+ ; GFX6-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = nnan ninf G_FPTRUNC [[SELECT4]](f32)
; GFX6-NEXT: [[ANYEXT:%[0-9]+]]:_(i32) = G_ANYEXT [[FPTRUNC]](f16)
; GFX6-NEXT: $vgpr0 = COPY [[ANYEXT]](i32)
;
@@ -633,13 +1236,48 @@ body: |
; GFX9-NEXT: [[COPY1:%[0-9]+]]:_(i32) = COPY $vgpr1
; GFX9-NEXT: [[TRUNC:%[0-9]+]]:_(f16) = G_TRUNC [[COPY]](i32)
; GFX9-NEXT: [[TRUNC1:%[0-9]+]]:_(f16) = G_TRUNC [[COPY1]](i32)
- ; GFX9-NEXT: [[FLOG2_:%[0-9]+]]:_(f16) = nnan ninf G_FLOG2 [[TRUNC]]
- ; GFX9-NEXT: [[FPEXT:%[0-9]+]]:_(f32) = nnan ninf G_FPEXT [[FLOG2_]](f16)
+ ; GFX9-NEXT: [[FPEXT:%[0-9]+]]:_(f32) = nnan ninf G_FPEXT [[TRUNC]](f16)
; GFX9-NEXT: [[FPEXT1:%[0-9]+]]:_(f32) = nnan ninf G_FPEXT [[TRUNC1]](f16)
- ; GFX9-NEXT: [[INT:%[0-9]+]]:_(f32) = nnan ninf G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT]](f32), [[FPEXT1]](f32)
- ; GFX9-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = nnan G_FPTRUNC [[INT]](f32)
- ; GFX9-NEXT: [[FEXP2_:%[0-9]+]]:_(f16) = nnan G_FEXP2 [[FPTRUNC]]
- ; GFX9-NEXT: [[ANYEXT:%[0-9]+]]:_(i32) = G_ANYEXT [[FEXP2_]](f16)
+ ; GFX9-NEXT: [[FABS:%[0-9]+]]:_(f32) = nnan ninf G_FABS [[FPEXT]]
+ ; GFX9-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
+ ; GFX9-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C]]
+ ; GFX9-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
+ ; GFX9-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
+ ; GFX9-NEXT: [[SELECT:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP]](s1), [[C1]], [[C2]]
+ ; GFX9-NEXT: [[FMUL:%[0-9]+]]:_(f32) = nnan G_FMUL [[FABS]], [[SELECT]]
+ ; GFX9-NEXT: [[INT:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
+ ; GFX9-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
+ ; GFX9-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
+ ; GFX9-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP]](s1), [[C3]], [[C4]]
+ ; GFX9-NEXT: [[FSUB:%[0-9]+]]:_(f32) = nnan G_FSUB [[INT]], [[SELECT1]]
+ ; GFX9-NEXT: [[INT1:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT1]](f32), [[FSUB]](f32)
+ ; GFX9-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
+ ; GFX9-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = nnan G_FCMP floatpred(olt), [[INT1]](f32), [[C5]]
+ ; GFX9-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
+ ; GFX9-NEXT: [[SELECT2:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP1]](s1), [[C6]], [[C4]]
+ ; GFX9-NEXT: [[FADD:%[0-9]+]]:_(f32) = nnan G_FADD [[INT1]], [[SELECT2]]
+ ; GFX9-NEXT: [[INT2:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD]](f32)
+ ; GFX9-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
+ ; GFX9-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP1]](s1), [[C7]], [[C2]]
+ ; GFX9-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = nnan G_FMUL [[INT2]], [[SELECT3]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FPEXT1]]
+ ; GFX9-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[FPEXT1]]
+ ; GFX9-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX9-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[FPEXT1]], [[C8]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX9-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX9-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX9-NEXT: [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX9-NEXT: [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[FPEXT]](f32)
+ ; GFX9-NEXT: [[C9:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX9-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX9-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST]], [[C10]]
+ ; GFX9-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST1]], [[C9]]
+ ; GFX9-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX9-NEXT: [[BITCAST2:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX9-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST2]], [[FMUL1]]
+ ; GFX9-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = nnan ninf G_FPTRUNC [[SELECT4]](f32)
+ ; GFX9-NEXT: [[ANYEXT:%[0-9]+]]:_(i32) = G_ANYEXT [[FPTRUNC]](f16)
; GFX9-NEXT: $vgpr0 = COPY [[ANYEXT]](i32)
%0:_(i32) = COPY $vgpr0
%1:_(i32) = COPY $vgpr1
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-fpowi.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-fpowi.mir
index a7da86f5c4e28..8a5dcc4e2856e 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-fpowi.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-fpowi.mir
@@ -18,20 +18,45 @@ body: |
; GFX6-NEXT: [[TRUNC:%[0-9]+]]:_(f16) = G_TRUNC [[COPY]](i32)
; GFX6-NEXT: [[FPEXT:%[0-9]+]]:_(f32) = nnan G_FPEXT [[TRUNC]](f16)
; GFX6-NEXT: [[SITOFP:%[0-9]+]]:_(f32) = G_SITOFP [[COPY1]](i32)
- ; GFX6-NEXT: [[INT:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FPEXT]](f32)
- ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[INT]](f32), [[SITOFP]](f32)
- ; GFX6-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
- ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = nnan G_FCMP floatpred(olt), [[INT1]](f32), [[C]]
- ; GFX6-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
- ; GFX6-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
+ ; GFX6-NEXT: [[FABS:%[0-9]+]]:_(f32) = nnan G_FABS [[FPEXT]]
+ ; GFX6-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
+ ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C]]
+ ; GFX6-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
+ ; GFX6-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
; GFX6-NEXT: [[SELECT:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP]](s1), [[C1]], [[C2]]
- ; GFX6-NEXT: [[FADD:%[0-9]+]]:_(f32) = nnan G_FADD [[INT1]], [[SELECT]]
- ; GFX6-NEXT: [[INT2:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD]](f32)
- ; GFX6-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
- ; GFX6-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
+ ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = nnan G_FMUL [[FABS]], [[SELECT]]
+ ; GFX6-NEXT: [[INT:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
+ ; GFX6-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
+ ; GFX6-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
; GFX6-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP]](s1), [[C3]], [[C4]]
- ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = nnan G_FMUL [[INT2]], [[SELECT1]]
- ; GFX6-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = nnan G_FPTRUNC [[FMUL]](f32)
+ ; GFX6-NEXT: [[FSUB:%[0-9]+]]:_(f32) = nnan G_FSUB [[INT]], [[SELECT1]]
+ ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[SITOFP]](f32), [[FSUB]](f32)
+ ; GFX6-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
+ ; GFX6-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = nnan G_FCMP floatpred(olt), [[INT1]](f32), [[C5]]
+ ; GFX6-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
+ ; GFX6-NEXT: [[SELECT2:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP1]](s1), [[C6]], [[C4]]
+ ; GFX6-NEXT: [[FADD:%[0-9]+]]:_(f32) = nnan G_FADD [[INT1]], [[SELECT2]]
+ ; GFX6-NEXT: [[INT2:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD]](f32)
+ ; GFX6-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
+ ; GFX6-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP1]](s1), [[C7]], [[C2]]
+ ; GFX6-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = nnan G_FMUL [[INT2]], [[SELECT3]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[SITOFP]]
+ ; GFX6-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[SITOFP]]
+ ; GFX6-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX6-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[SITOFP]], [[C8]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX6-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX6-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX6-NEXT: [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX6-NEXT: [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[FPEXT]](f32)
+ ; GFX6-NEXT: [[C9:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX6-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX6-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST]], [[C10]]
+ ; GFX6-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST1]], [[C9]]
+ ; GFX6-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX6-NEXT: [[BITCAST2:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX6-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST2]], [[FMUL1]]
+ ; GFX6-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = nnan G_FPTRUNC [[SELECT4]](f32)
; GFX6-NEXT: [[ANYEXT:%[0-9]+]]:_(i32) = G_ANYEXT [[FPTRUNC]](f16)
; GFX6-NEXT: $vgpr0 = COPY [[ANYEXT]](i32)
;
@@ -41,15 +66,48 @@ body: |
; GFX9-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $vgpr0
; GFX9-NEXT: [[COPY1:%[0-9]+]]:_(i32) = COPY $vgpr1
; GFX9-NEXT: [[TRUNC:%[0-9]+]]:_(f16) = G_TRUNC [[COPY]](i32)
+ ; GFX9-NEXT: [[FPEXT:%[0-9]+]]:_(f32) = nnan G_FPEXT [[TRUNC]](f16)
; GFX9-NEXT: [[SITOFP:%[0-9]+]]:_(f32) = G_SITOFP [[COPY1]](i32)
- ; GFX9-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = G_FPTRUNC [[SITOFP]](f32)
- ; GFX9-NEXT: [[FLOG2_:%[0-9]+]]:_(f16) = nnan G_FLOG2 [[TRUNC]]
- ; GFX9-NEXT: [[FPEXT:%[0-9]+]]:_(f32) = nnan G_FPEXT [[FLOG2_]](f16)
- ; GFX9-NEXT: [[FPEXT1:%[0-9]+]]:_(f32) = nnan G_FPEXT [[FPTRUNC]](f16)
- ; GFX9-NEXT: [[INT:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FPEXT]](f32), [[FPEXT1]](f32)
- ; GFX9-NEXT: [[FPTRUNC1:%[0-9]+]]:_(f16) = nnan G_FPTRUNC [[INT]](f32)
- ; GFX9-NEXT: [[FEXP2_:%[0-9]+]]:_(f16) = nnan G_FEXP2 [[FPTRUNC1]]
- ; GFX9-NEXT: [[ANYEXT:%[0-9]+]]:_(i32) = G_ANYEXT [[FEXP2_]](f16)
+ ; GFX9-NEXT: [[FABS:%[0-9]+]]:_(f32) = nnan G_FABS [[FPEXT]]
+ ; GFX9-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
+ ; GFX9-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C]]
+ ; GFX9-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
+ ; GFX9-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
+ ; GFX9-NEXT: [[SELECT:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP]](s1), [[C1]], [[C2]]
+ ; GFX9-NEXT: [[FMUL:%[0-9]+]]:_(f32) = nnan G_FMUL [[FABS]], [[SELECT]]
+ ; GFX9-NEXT: [[INT:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
+ ; GFX9-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
+ ; GFX9-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
+ ; GFX9-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP]](s1), [[C3]], [[C4]]
+ ; GFX9-NEXT: [[FSUB:%[0-9]+]]:_(f32) = nnan G_FSUB [[INT]], [[SELECT1]]
+ ; GFX9-NEXT: [[INT1:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[SITOFP]](f32), [[FSUB]](f32)
+ ; GFX9-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
+ ; GFX9-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = nnan G_FCMP floatpred(olt), [[INT1]](f32), [[C5]]
+ ; GFX9-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
+ ; GFX9-NEXT: [[SELECT2:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP1]](s1), [[C6]], [[C4]]
+ ; GFX9-NEXT: [[FADD:%[0-9]+]]:_(f32) = nnan G_FADD [[INT1]], [[SELECT2]]
+ ; GFX9-NEXT: [[INT2:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.exp2), [[FADD]](f32)
+ ; GFX9-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
+ ; GFX9-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP1]](s1), [[C7]], [[C2]]
+ ; GFX9-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = nnan G_FMUL [[INT2]], [[SELECT3]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[SITOFP]]
+ ; GFX9-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[SITOFP]]
+ ; GFX9-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX9-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[SITOFP]], [[C8]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX9-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX9-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX9-NEXT: [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX9-NEXT: [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[FPEXT]](f32)
+ ; GFX9-NEXT: [[C9:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX9-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX9-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST]], [[C10]]
+ ; GFX9-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST1]], [[C9]]
+ ; GFX9-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX9-NEXT: [[BITCAST2:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX9-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST2]], [[FMUL1]]
+ ; GFX9-NEXT: [[FPTRUNC:%[0-9]+]]:_(f16) = nnan G_FPTRUNC [[SELECT4]](f32)
+ ; GFX9-NEXT: [[ANYEXT:%[0-9]+]]:_(i32) = G_ANYEXT [[FPTRUNC]](f16)
; GFX9-NEXT: $vgpr0 = COPY [[ANYEXT]](i32)
%0:_(i32) = COPY $vgpr0
%1:_(i32) = COPY $vgpr1
@@ -71,18 +129,19 @@ body: |
; GFX6-NEXT: [[COPY:%[0-9]+]]:_(f32) = COPY $vgpr0
; GFX6-NEXT: [[COPY1:%[0-9]+]]:_(i32) = COPY $vgpr1
; GFX6-NEXT: [[SITOFP:%[0-9]+]]:_(f32) = G_SITOFP [[COPY1]](i32)
+ ; GFX6-NEXT: [[FABS:%[0-9]+]]:_(f32) = nnan G_FABS [[COPY]]
; GFX6-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
- ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[COPY]](f32), [[C]]
+ ; GFX6-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C]]
; GFX6-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
; GFX6-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
; GFX6-NEXT: [[SELECT:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP]](s1), [[C1]], [[C2]]
- ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = nnan G_FMUL [[COPY]], [[SELECT]]
+ ; GFX6-NEXT: [[FMUL:%[0-9]+]]:_(f32) = nnan G_FMUL [[FABS]], [[SELECT]]
; GFX6-NEXT: [[INT:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
; GFX6-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
; GFX6-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
; GFX6-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP]](s1), [[C3]], [[C4]]
; GFX6-NEXT: [[FSUB:%[0-9]+]]:_(f32) = nnan G_FSUB [[INT]], [[SELECT1]]
- ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FSUB]](f32), [[SITOFP]](f32)
+ ; GFX6-NEXT: [[INT1:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[SITOFP]](f32), [[FSUB]](f32)
; GFX6-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
; GFX6-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = nnan G_FCMP floatpred(olt), [[INT1]](f32), [[C5]]
; GFX6-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
@@ -92,7 +151,23 @@ body: |
; GFX6-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
; GFX6-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP1]](s1), [[C7]], [[C2]]
; GFX6-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = nnan G_FMUL [[INT2]], [[SELECT3]]
- ; GFX6-NEXT: $vgpr0 = COPY [[FMUL1]](f32)
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[SITOFP]]
+ ; GFX6-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[SITOFP]]
+ ; GFX6-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX6-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[SITOFP]], [[C8]]
+ ; GFX6-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX6-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX6-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX6-NEXT: [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX6-NEXT: [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[COPY]](f32)
+ ; GFX6-NEXT: [[C9:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX6-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX6-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST]], [[C10]]
+ ; GFX6-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST1]], [[C9]]
+ ; GFX6-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX6-NEXT: [[BITCAST2:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX6-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST2]], [[FMUL1]]
+ ; GFX6-NEXT: $vgpr0 = COPY [[SELECT4]](f32)
;
; GFX9-LABEL: name: test_fpowi_f32_i32_flags
; GFX9: liveins: $vgpr0, $vgpr1
@@ -100,18 +175,19 @@ body: |
; GFX9-NEXT: [[COPY:%[0-9]+]]:_(f32) = COPY $vgpr0
; GFX9-NEXT: [[COPY1:%[0-9]+]]:_(i32) = COPY $vgpr1
; GFX9-NEXT: [[SITOFP:%[0-9]+]]:_(f32) = G_SITOFP [[COPY1]](i32)
+ ; GFX9-NEXT: [[FABS:%[0-9]+]]:_(f32) = nnan G_FABS [[COPY]]
; GFX9-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x00800000
- ; GFX9-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[COPY]](f32), [[C]]
+ ; GFX9-NEXT: [[FCMP:%[0-9]+]]:_(s1) = G_FCMP floatpred(olt), [[FABS]](f32), [[C]]
; GFX9-NEXT: [[C1:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x4F800000
; GFX9-NEXT: [[C2:%[0-9]+]]:_(f32) = G_FCONSTANT float 1.000000e+00
; GFX9-NEXT: [[SELECT:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP]](s1), [[C1]], [[C2]]
- ; GFX9-NEXT: [[FMUL:%[0-9]+]]:_(f32) = nnan G_FMUL [[COPY]], [[SELECT]]
+ ; GFX9-NEXT: [[FMUL:%[0-9]+]]:_(f32) = nnan G_FMUL [[FABS]], [[SELECT]]
; GFX9-NEXT: [[INT:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.log), [[FMUL]](f32)
; GFX9-NEXT: [[C3:%[0-9]+]]:_(f32) = G_FCONSTANT float 3.200000e+01
; GFX9-NEXT: [[C4:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
; GFX9-NEXT: [[SELECT1:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP]](s1), [[C3]], [[C4]]
; GFX9-NEXT: [[FSUB:%[0-9]+]]:_(f32) = nnan G_FSUB [[INT]], [[SELECT1]]
- ; GFX9-NEXT: [[INT1:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[FSUB]](f32), [[SITOFP]](f32)
+ ; GFX9-NEXT: [[INT1:%[0-9]+]]:_(f32) = nnan G_INTRINSIC intrinsic(@llvm.amdgcn.fmul.legacy), [[SITOFP]](f32), [[FSUB]](f32)
; GFX9-NEXT: [[C5:%[0-9]+]]:_(f32) = G_FCONSTANT float -1.260000e+02
; GFX9-NEXT: [[FCMP1:%[0-9]+]]:_(s1) = nnan G_FCMP floatpred(olt), [[INT1]](f32), [[C5]]
; GFX9-NEXT: [[C6:%[0-9]+]]:_(f32) = G_FCONSTANT float 6.400000e+01
@@ -121,7 +197,23 @@ body: |
; GFX9-NEXT: [[C7:%[0-9]+]]:_(f32) = G_FCONSTANT float f0x1F800000
; GFX9-NEXT: [[SELECT3:%[0-9]+]]:_(f32) = nnan G_SELECT [[FCMP1]](s1), [[C7]], [[C2]]
; GFX9-NEXT: [[FMUL1:%[0-9]+]]:_(f32) = nnan G_FMUL [[INT2]], [[SELECT3]]
- ; GFX9-NEXT: $vgpr0 = COPY [[FMUL1]](f32)
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[SITOFP]]
+ ; GFX9-NEXT: [[FCMP2:%[0-9]+]]:_(s1) = G_FCMP floatpred(oeq), [[INTRINSIC_TRUNC]](f32), [[SITOFP]]
+ ; GFX9-NEXT: [[C8:%[0-9]+]]:_(f32) = G_FCONSTANT float 5.000000e-01
+ ; GFX9-NEXT: [[FMUL2:%[0-9]+]]:_(f32) = G_FMUL [[SITOFP]], [[C8]]
+ ; GFX9-NEXT: [[INTRINSIC_TRUNC1:%[0-9]+]]:_(f32) = G_INTRINSIC_TRUNC [[FMUL2]]
+ ; GFX9-NEXT: [[FCMP3:%[0-9]+]]:_(s1) = G_FCMP floatpred(one), [[INTRINSIC_TRUNC1]](f32), [[FMUL2]]
+ ; GFX9-NEXT: [[AND:%[0-9]+]]:_(s1) = G_AND [[FCMP2]], [[FCMP3]]
+ ; GFX9-NEXT: [[BITCAST:%[0-9]+]]:_(i32) = G_BITCAST [[FMUL1]](f32)
+ ; GFX9-NEXT: [[BITCAST1:%[0-9]+]]:_(i32) = G_BITCAST [[COPY]](f32)
+ ; GFX9-NEXT: [[C9:%[0-9]+]]:_(i32) = G_CONSTANT i32 -2147483648
+ ; GFX9-NEXT: [[C10:%[0-9]+]]:_(i32) = G_CONSTANT i32 2147483647
+ ; GFX9-NEXT: [[AND1:%[0-9]+]]:_(i32) = G_AND [[BITCAST]], [[C10]]
+ ; GFX9-NEXT: [[AND2:%[0-9]+]]:_(i32) = G_AND [[BITCAST1]], [[C9]]
+ ; GFX9-NEXT: [[OR:%[0-9]+]]:_(i32) = disjoint G_OR [[AND1]], [[AND2]]
+ ; GFX9-NEXT: [[BITCAST2:%[0-9]+]]:_(f32) = G_BITCAST [[OR]](i32)
+ ; GFX9-NEXT: [[SELECT4:%[0-9]+]]:_(f32) = G_SELECT [[AND]](s1), [[BITCAST2]], [[FMUL1]]
+ ; GFX9-NEXT: $vgpr0 = COPY [[SELECT4]](f32)
%0:_(f32) = COPY $vgpr0
%1:_(i32) = COPY $vgpr1
%2:_(f32) = nnan G_FPOWI %0, %1
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.powi.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.powi.ll
index 6ac395372ddae..40678dbc7ff8d 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.powi.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.powi.ll
@@ -9,64 +9,176 @@ define i16 @v_powi_f16(i16 %l, i32 %r) {
; GFX7: ; %bb.0:
; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX7-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX7-NEXT: v_mov_b32_e32 v2, 0x800000
; GFX7-NEXT: v_cvt_f32_i32_e32 v1, v1
-; GFX7-NEXT: v_mov_b32_e32 v2, 0xc2fc0000
-; GFX7-NEXT: v_mov_b32_e32 v3, 0x42800000
-; GFX7-NEXT: v_log_f32_e32 v0, v0
-; GFX7-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX7-NEXT: v_cmp_lt_f32_e32 vcc, v0, v2
-; GFX7-NEXT: v_cndmask_b32_e32 v1, 0, v3, vcc
-; GFX7-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX7-NEXT: v_exp_f32_e32 v0, v0
-; GFX7-NEXT: v_not_b32_e32 v1, 63
-; GFX7-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX7-NEXT: v_ldexp_f32_e32 v0, v0, v1
+; GFX7-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX7-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
+; GFX7-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX7-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX7-NEXT: v_ldexp_f32_e64 v2, |v0|, v2
+; GFX7-NEXT: v_log_f32_e32 v2, v2
+; GFX7-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX7-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX7-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX7-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX7-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX7-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX7-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX7-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX7-NEXT: v_exp_f32_e32 v2, v2
+; GFX7-NEXT: v_not_b32_e32 v3, 63
+; GFX7-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX7-NEXT: v_ldexp_f32_e32 v2, v2, v3
+; GFX7-NEXT: v_trunc_f32_e32 v3, v1
+; GFX7-NEXT: v_cmp_eq_f32_e32 vcc, v3, v1
+; GFX7-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX7-NEXT: v_trunc_f32_e32 v3, v1
+; GFX7-NEXT: v_cmp_lg_f32_e64 s[4:5], v3, v1
+; GFX7-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX7-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX7-NEXT: v_or_b32_e32 v1, v1, v3
+; GFX7-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX7-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX7-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX7-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX7-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX7-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX7-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX7-NEXT: v_cvt_f16_f32_e32 v0, v0
; GFX7-NEXT: s_setpc_b64 s[30:31]
;
; GFX8-LABEL: v_powi_f16:
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX8-NEXT: v_cvt_f32_i32_e32 v1, v1
-; GFX8-NEXT: v_log_f16_e32 v0, v0
-; GFX8-NEXT: v_cvt_f16_f32_e32 v1, v1
; GFX8-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX8-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x800000
+; GFX8-NEXT: v_cvt_f32_i32_e32 v1, v1
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
+; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
+; GFX8-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX8-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX8-NEXT: v_log_f32_e32 v2, v2
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX8-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX8-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX8-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_exp_f32_e32 v2, v2
+; GFX8-NEXT: v_not_b32_e32 v3, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX8-NEXT: v_trunc_f32_e32 v3, v1
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v3, v1
+; GFX8-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v3, v1
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v3, v1
+; GFX8-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX8-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX8-NEXT: v_or_b32_e32 v1, v1, v3
+; GFX8-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX8-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX8-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX8-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX8-NEXT: v_exp_f16_e32 v0, v0
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-TRUE16-LABEL: v_powi_f16:
; GFX11-TRUE16: ; %bb.0:
; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-TRUE16-NEXT: v_log_f16_e32 v0.l, v0.l
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.l
; GFX11-TRUE16-NEXT: v_cvt_f32_i32_e32 v1, v1
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_3) | instid1(VALU_DEP_1)
-; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.h, v1
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v5, v1
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s2, v0, 24
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v2, 0, 1, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s0
+; GFX11-TRUE16-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v2, v2
; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v0.l
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.h
-; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
+; GFX11-TRUE16-NEXT: v_sub_f32_e32 v2, v2, v3
; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v2, v1, v2
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e32 vcc_lo, v5, v1
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_dual_add_f32 v2, v2, v3 :: v_dual_mul_f32 v3, 0.5, v1
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v2, v2
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v6, v3
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e64 s0, v6, v3
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX11-TRUE16-NEXT: v_and_b32_e32 v4, 0x80000000, v0
+; GFX11-TRUE16-NEXT: s_and_b32 s0, vcc_lo, s0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v4
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v0, v2, v1, s0
+; GFX11-TRUE16-NEXT: s_xor_b32 s0, vcc_lo, exec_lo
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
+; GFX11-TRUE16-NEXT: s_and_b32 s0, s2, s0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v0
-; GFX11-TRUE16-NEXT: v_exp_f16_e32 v0.l, v0.l
; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-FAKE16-LABEL: v_powi_f16:
; GFX11-FAKE16: ; %bb.0:
; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-FAKE16-NEXT: v_log_f16_e32 v0, v0
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v0
; GFX11-FAKE16-NEXT: v_cvt_f32_i32_e32 v1, v1
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_3) | instid1(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v5, v1
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s2, v0, 24
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v2, 0, 1, s0
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s0
+; GFX11-FAKE16-NEXT: v_lshlrev_b32_e32 v2, 5, v2
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v2, v2
; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v0, v1
+; GFX11-FAKE16-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v2, v1, v2
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e32 vcc_lo, v5, v1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_dual_add_f32 v2, v2, v3 :: v_dual_mul_f32 v3, 0.5, v1
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v2, v2
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v6, v3
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e64 s0, v6, v3
+; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX11-FAKE16-NEXT: v_and_b32_e32 v4, 0x80000000, v0
+; GFX11-FAKE16-NEXT: s_and_b32 s0, vcc_lo, s0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v4
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v0, v2, v1, s0
+; GFX11-FAKE16-NEXT: s_xor_b32 s0, vcc_lo, exec_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s2, s0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX11-FAKE16-NEXT: v_exp_f16_e32 v0, v0
; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
%l.cast = bitcast i16 %l to half
%res = call half @llvm.powi.f16.i32(half %l.cast, i32 %r)
@@ -79,76 +191,122 @@ define float @v_powi_f32(float %l, i32 %r) {
; GFX7: ; %bb.0:
; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX7-NEXT: v_mov_b32_e32 v2, 0x800000
-; GFX7-NEXT: v_cmp_lt_f32_e32 vcc, v0, v2
+; GFX7-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
; GFX7-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
; GFX7-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX7-NEXT: v_ldexp_f32_e32 v0, v0, v2
-; GFX7-NEXT: v_log_f32_e32 v0, v0
+; GFX7-NEXT: v_ldexp_f32_e64 v2, |v0|, v2
+; GFX7-NEXT: v_log_f32_e32 v2, v2
; GFX7-NEXT: v_cvt_f32_i32_e32 v1, v1
-; GFX7-NEXT: v_mov_b32_e32 v2, 0x42000000
-; GFX7-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
-; GFX7-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX7-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX7-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX7-NEXT: v_mov_b32_e32 v2, 0x42800000
-; GFX7-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
-; GFX7-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
-; GFX7-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX7-NEXT: v_exp_f32_e32 v0, v0
-; GFX7-NEXT: v_not_b32_e32 v1, 63
-; GFX7-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX7-NEXT: v_ldexp_f32_e32 v0, v0, v1
+; GFX7-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX7-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX7-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX7-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX7-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX7-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX7-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX7-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX7-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX7-NEXT: v_exp_f32_e32 v2, v2
+; GFX7-NEXT: v_not_b32_e32 v3, 63
+; GFX7-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX7-NEXT: v_ldexp_f32_e32 v2, v2, v3
+; GFX7-NEXT: v_trunc_f32_e32 v3, v1
+; GFX7-NEXT: v_cmp_eq_f32_e32 vcc, v3, v1
+; GFX7-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX7-NEXT: v_trunc_f32_e32 v3, v1
+; GFX7-NEXT: v_cmp_lg_f32_e64 s[4:5], v3, v1
+; GFX7-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX7-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX7-NEXT: v_or_b32_e32 v1, v1, v3
+; GFX7-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX7-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX7-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX7-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX7-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX7-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX7-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX7-NEXT: s_setpc_b64 s[30:31]
;
; GFX8-LABEL: v_powi_f32:
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX8-NEXT: v_mov_b32_e32 v2, 0x800000
-; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v0, v2
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, v2
; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc
; GFX8-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX8-NEXT: v_ldexp_f32 v0, v0, v2
-; GFX8-NEXT: v_log_f32_e32 v0, v0
+; GFX8-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX8-NEXT: v_log_f32_e32 v2, v2
; GFX8-NEXT: v_cvt_f32_i32_e32 v1, v1
-; GFX8-NEXT: v_mov_b32_e32 v2, 0x42000000
-; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
-; GFX8-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX8-NEXT: v_mov_b32_e32 v1, 0xc2fc0000
-; GFX8-NEXT: v_mov_b32_e32 v2, 0x42800000
-; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v0, v1
-; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
-; GFX8-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX8-NEXT: v_exp_f32_e32 v0, v0
-; GFX8-NEXT: v_not_b32_e32 v1, 63
-; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
-; GFX8-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX8-NEXT: v_mov_b32_e32 v3, 0xc2fc0000
+; GFX8-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX8-NEXT: v_cmp_lt_f32_e32 vcc, v2, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v4, vcc
+; GFX8-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_exp_f32_e32 v2, v2
+; GFX8-NEXT: v_not_b32_e32 v3, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX8-NEXT: v_trunc_f32_e32 v3, v1
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v3, v1
+; GFX8-NEXT: v_mul_f32_e32 v1, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v3, v1
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v3, v1
+; GFX8-NEXT: v_and_b32_e32 v1, 0x7fffffff, v2
+; GFX8-NEXT: v_and_b32_e32 v3, 0x80000000, v0
+; GFX8-NEXT: v_or_b32_e32 v1, v1, v3
+; GFX8-NEXT: s_and_b64 s[4:5], vcc, s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e64 v1, v2, v1, s[4:5]
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX8-NEXT: s_xor_b64 s[6:7], vcc, exec
+; GFX8-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: v_powi_f32:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0x800000, v0
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
; GFX11-NEXT: v_cvt_f32_i32_e32 v1, v1
-; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 1, vcc_lo
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_cmp_class_f32_e64 s2, v0, 24
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_4)
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 1, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s0
+; GFX11-NEXT: v_trunc_f32_e32 v5, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX11-NEXT: v_lshlrev_b32_e32 v2, 5, v2
-; GFX11-NEXT: v_ldexp_f32 v0, v0, v2
-; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, vcc_lo
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_1)
-; GFX11-NEXT: v_log_f32_e32 v0, v0
+; GFX11-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_log_f32_e32 v2, v2
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_sub_f32_e32 v0, v0, v2
-; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, v0, v1
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
-; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
-; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
-; GFX11-NEXT: v_add_f32_e32 v0, v0, v1
-; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, vcc_lo
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2)
-; GFX11-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-NEXT: v_sub_f32_e32 v2, v2, v3
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v2, v1, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_3) | instid1(VALU_DEP_3)
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: v_cmp_eq_f32_e32 vcc_lo, v5, v1
+; GFX11-NEXT: v_dual_add_f32 v2, v2, v3 :: v_dual_mul_f32 v3, 0.5, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_exp_f32_e32 v2, v2
+; GFX11-NEXT: v_trunc_f32_e32 v6, v3
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_4) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_cmp_lg_f32_e64 s0, v6, v3
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX11-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX11-NEXT: v_and_b32_e32 v4, 0x80000000, v0
+; GFX11-NEXT: s_and_b32 s0, vcc_lo, s0
+; GFX11-NEXT: v_and_or_b32 v1, 0x7fffffff, v2, v4
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v2, v1, s0
+; GFX11-NEXT: s_xor_b32 s0, vcc_lo, exec_lo
+; GFX11-NEXT: s_and_b32 s0, s2, s0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
%res = call float @llvm.powi.f32.i32(float %l, i32 %r)
ret float %res
diff --git a/llvm/test/CodeGen/AMDGPU/fpow.ll b/llvm/test/CodeGen/AMDGPU/fpow.ll
index b12bd73c8287a..3b2263fa47a30 100644
--- a/llvm/test/CodeGen/AMDGPU/fpow.ll
+++ b/llvm/test/CodeGen/AMDGPU/fpow.ll
@@ -11,51 +11,217 @@ define float @v_pow_f32(float %x, float %y) {
; GFX6-LABEL: v_pow_f32:
; GFX6: ; %bb.0:
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
+; GFX6-NEXT: s_mov_b32 s4, 0x800000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX6-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX6-NEXT: v_ldexp_f32_e64 v3, |v0|, v3
+; GFX6-NEXT: v_log_f32_e32 v3, v3
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX6-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX6-NEXT: v_cmp_gt_f32_e32 vcc, s4, v2
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_exp_f32_e32 v2, v2
+; GFX6-NEXT: v_not_b32_e32 v3, 63
+; GFX6-NEXT: v_mul_f32_e32 v4, 0.5, v1
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: v_trunc_f32_e32 v5, v4
+; GFX6-NEXT: v_ldexp_f32_e32 v2, v2, v3
+; GFX6-NEXT: s_brev_b32 s4, -2
+; GFX6-NEXT: v_cmp_lg_f32_e32 vcc, v5, v4
+; GFX6-NEXT: v_trunc_f32_e32 v4, v1
+; GFX6-NEXT: v_bfi_b32 v3, s4, v2, v0
+; GFX6-NEXT: v_cmp_eq_f32_e64 s[4:5], v4, v1
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v2, v2, v3, vcc
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX6-NEXT: v_cmp_neq_f32_e32 vcc, v4, v1
+; GFX6-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
; GFX6-NEXT: s_setpc_b64 s[30:31]
;
; GFX8-LABEL: v_pow_f32:
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX8-NEXT: v_log_f32_e32 v0, v0
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX8-NEXT: v_exp_f32_e32 v0, v0
+; GFX8-NEXT: s_mov_b32 s4, 0x800000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX8-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX8-NEXT: v_ldexp_f32 v3, |v0|, v3
+; GFX8-NEXT: v_log_f32_e32 v3, v3
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX8-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s4, v2
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_exp_f32_e32 v2, v2
+; GFX8-NEXT: v_not_b32_e32 v3, 63
+; GFX8-NEXT: v_mul_f32_e32 v4, 0.5, v1
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_trunc_f32_e32 v5, v4
+; GFX8-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX8-NEXT: s_brev_b32 s4, -2
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v5, v4
+; GFX8-NEXT: v_trunc_f32_e32 v4, v1
+; GFX8-NEXT: v_bfi_b32 v3, s4, v2, v0
+; GFX8-NEXT: v_cmp_eq_f32_e64 s[4:5], v4, v1
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v2, v2, v3, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX8-NEXT: v_cmp_neq_f32_e32 vcc, v4, v1
+; GFX8-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: v_pow_f32:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT: v_log_f32_e32 v0, v0
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX9-NEXT: v_exp_f32_e32 v0, v0
+; GFX9-NEXT: s_mov_b32 s4, 0x800000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX9-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX9-NEXT: v_ldexp_f32 v3, |v0|, v3
+; GFX9-NEXT: v_log_f32_e32 v3, v3
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX9-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, s4, v2
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX9-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX9-NEXT: v_exp_f32_e32 v2, v2
+; GFX9-NEXT: v_not_b32_e32 v3, 63
+; GFX9-NEXT: v_mul_f32_e32 v4, 0.5, v1
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX9-NEXT: v_trunc_f32_e32 v5, v4
+; GFX9-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX9-NEXT: s_brev_b32 s4, -2
+; GFX9-NEXT: v_cmp_lg_f32_e32 vcc, v5, v4
+; GFX9-NEXT: v_trunc_f32_e32 v4, v1
+; GFX9-NEXT: v_bfi_b32 v3, s4, v2, v0
+; GFX9-NEXT: v_cmp_eq_f32_e64 s[4:5], v4, v1
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v2, v2, v3, vcc
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX9-NEXT: v_cmp_neq_f32_e32 vcc, v4, v1
+; GFX9-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX90A-LABEL: v_pow_f32:
; GFX90A: ; %bb.0:
; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX90A-NEXT: v_log_f32_e32 v0, v0
-; GFX90A-NEXT: v_mul_legacy_f32 v0, v1, v0
-; GFX90A-NEXT: v_exp_f32_e32 v0, v0
+; GFX90A-NEXT: s_mov_b32 s4, 0x800000
+; GFX90A-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX90A-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX90A-NEXT: v_ldexp_f32 v3, |v0|, v3
+; GFX90A-NEXT: v_log_f32_e32 v3, v3
+; GFX90A-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX90A-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX90A-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX90A-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX90A-NEXT: v_mul_legacy_f32 v2, v1, v2
+; GFX90A-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX90A-NEXT: v_cmp_gt_f32_e32 vcc, s4, v2
+; GFX90A-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX90A-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX90A-NEXT: v_exp_f32_e32 v2, v2
+; GFX90A-NEXT: v_not_b32_e32 v3, 63
+; GFX90A-NEXT: v_mul_f32_e32 v4, 0.5, v1
+; GFX90A-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX90A-NEXT: v_trunc_f32_e32 v5, v4
+; GFX90A-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX90A-NEXT: s_brev_b32 s4, -2
+; GFX90A-NEXT: v_cmp_lg_f32_e32 vcc, v5, v4
+; GFX90A-NEXT: v_trunc_f32_e32 v4, v1
+; GFX90A-NEXT: v_bfi_b32 v3, s4, v2, v0
+; GFX90A-NEXT: v_cmp_eq_f32_e64 s[4:5], v4, v1
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v2, v2, v3, vcc
+; GFX90A-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX90A-NEXT: v_cmp_neq_f32_e32 vcc, v4, v1
+; GFX90A-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
; GFX90A-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_f32:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_log_f32_e32 v0, v0
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX10-NEXT: v_exp_f32_e32 v0, v0
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v0|
+; GFX10-NEXT: v_trunc_f32_e32 v6, v1
+; GFX10-NEXT: v_cmp_class_f32_e64 s6, v0, 24
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 32, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s4
+; GFX10-NEXT: v_cmp_eq_f32_e64 s4, v6, v1
+; GFX10-NEXT: v_cmp_neq_f32_e64 s5, v6, v1
+; GFX10-NEXT: v_ldexp_f32 v3, |v0|, v3
+; GFX10-NEXT: v_log_f32_e32 v3, v3
+; GFX10-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX10-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX10-NEXT: v_mul_f32_e32 v3, 0.5, v1
+; GFX10-NEXT: v_exp_f32_e32 v2, v2
+; GFX10-NEXT: v_trunc_f32_e32 v5, v3
+; GFX10-NEXT: v_cmp_lg_f32_e32 vcc_lo, v5, v3
+; GFX10-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX10-NEXT: s_and_b32 vcc_lo, s4, vcc_lo
+; GFX10-NEXT: s_and_b32 s4, s6, s5
+; GFX10-NEXT: v_bfi_b32 v3, 0x7fffffff, v2, v0
+; GFX10-NEXT: v_cndmask_b32_e32 v0, v2, v3, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s4
; GFX10-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: v_pow_f32:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT: v_log_f32_e32 v0, v0
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-NEXT: v_trunc_f32_e32 v6, v1
+; GFX11-NEXT: v_cmp_class_f32_e64 s2, v0, 24
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_4)
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 32, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s0
+; GFX11-NEXT: v_cmp_eq_f32_e64 s0, v6, v1
+; GFX11-NEXT: v_cmp_neq_f32_e64 s1, v6, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_ldexp_f32 v3, |v0|, v3
+; GFX11-NEXT: v_log_f32_e32 v3, v3
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
+; GFX11-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v2, v1, v2
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_dual_add_f32 v2, v2, v3 :: v_dual_mul_f32 v3, 0.5, v1
+; GFX11-NEXT: v_exp_f32_e32 v2, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_trunc_f32_e32 v5, v3
+; GFX11-NEXT: v_cmp_lg_f32_e32 vcc_lo, v5, v3
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX11-NEXT: s_and_b32 vcc_lo, s0, vcc_lo
+; GFX11-NEXT: s_and_b32 s0, s2, s1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_bfi_b32 v3, 0x7fffffff, v2, v0
+; GFX11-NEXT: v_cndmask_b32_e32 v0, v2, v3, vcc_lo
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
-; GFX11-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
%pow = call float @llvm.pow.f32(float %x, float %y)
ret float %pow
@@ -65,68 +231,367 @@ define <2 x float> @v_pow_v2f32(<2 x float> %x, <2 x float> %y) {
; GFX6-LABEL: v_pow_v2f32:
; GFX6: ; %bb.0:
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_log_f32_e32 v1, v1
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v2, v0
-; GFX6-NEXT: v_mul_legacy_f32_e32 v1, v3, v1
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
-; GFX6-NEXT: v_exp_f32_e32 v1, v1
+; GFX6-NEXT: s_mov_b32 s6, 0x800000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s6
+; GFX6-NEXT: v_cndmask_b32_e64 v6, 0, 32, vcc
+; GFX6-NEXT: v_ldexp_f32_e64 v6, |v0|, v6
+; GFX6-NEXT: v_log_f32_e32 v6, v6
+; GFX6-NEXT: v_mov_b32_e32 v4, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v5, 0, v4, vcc
+; GFX6-NEXT: s_mov_b32 s8, 0xc2fc0000
+; GFX6-NEXT: v_sub_f32_e32 v5, v6, v5
+; GFX6-NEXT: v_mul_legacy_f32_e32 v5, v2, v5
+; GFX6-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX6-NEXT: v_cmp_gt_f32_e32 vcc, s8, v5
+; GFX6-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX6-NEXT: v_add_f32_e32 v5, v5, v7
+; GFX6-NEXT: v_exp_f32_e32 v5, v5
+; GFX6-NEXT: v_mul_f32_e32 v9, 0.5, v2
+; GFX6-NEXT: v_not_b32_e32 v7, 63
+; GFX6-NEXT: v_trunc_f32_e32 v10, v9
+; GFX6-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX6-NEXT: v_cmp_lg_f32_e32 vcc, v10, v9
+; GFX6-NEXT: v_trunc_f32_e32 v9, v2
+; GFX6-NEXT: v_ldexp_f32_e32 v5, v5, v8
+; GFX6-NEXT: s_brev_b32 s9, -2
+; GFX6-NEXT: v_cmp_eq_f32_e64 s[4:5], v9, v2
+; GFX6-NEXT: v_bfi_b32 v8, s9, v5, v0
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v5, v5, v8, vcc
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v1|, s6
+; GFX6-NEXT: v_cndmask_b32_e64 v8, 0, 32, vcc
+; GFX6-NEXT: v_ldexp_f32_e64 v8, |v1|, v8
+; GFX6-NEXT: v_log_f32_e32 v8, v8
+; GFX6-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
+; GFX6-NEXT: v_cmp_class_f32_e64 s[6:7], v0, 24
+; GFX6-NEXT: v_cmp_neq_f32_e32 vcc, v9, v2
+; GFX6-NEXT: v_sub_f32_e32 v0, v8, v4
+; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v3, v0
+; GFX6-NEXT: v_cmp_gt_f32_e64 s[4:5], s8, v0
+; GFX6-NEXT: v_cndmask_b32_e64 v4, 0, v6, s[4:5]
+; GFX6-NEXT: v_add_f32_e32 v0, v0, v4
+; GFX6-NEXT: v_exp_f32_e32 v4, v0
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX6-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX6-NEXT: v_mul_f32_e32 v6, 0.5, v3
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v5, v2, vcc
+; GFX6-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX6-NEXT: v_trunc_f32_e32 v7, v6
+; GFX6-NEXT: v_cmp_lg_f32_e32 vcc, v7, v6
+; GFX6-NEXT: v_trunc_f32_e32 v6, v3
+; GFX6-NEXT: v_ldexp_f32_e32 v4, v4, v5
+; GFX6-NEXT: v_cmp_eq_f32_e64 s[4:5], v6, v3
+; GFX6-NEXT: v_bfi_b32 v5, s9, v4, v1
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v4, v4, v5, vcc
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v1, 24
+; GFX6-NEXT: v_cmp_neq_f32_e32 vcc, v6, v3
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v1, v4, v2, vcc
; GFX6-NEXT: s_setpc_b64 s[30:31]
;
; GFX8-LABEL: v_pow_v2f32:
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX8-NEXT: v_log_f32_e32 v0, v0
-; GFX8-NEXT: v_log_f32_e32 v1, v1
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v2, v0
-; GFX8-NEXT: v_mul_legacy_f32_e32 v1, v3, v1
-; GFX8-NEXT: v_exp_f32_e32 v0, v0
-; GFX8-NEXT: v_exp_f32_e32 v1, v1
+; GFX8-NEXT: s_mov_b32 s6, 0x800000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s6
+; GFX8-NEXT: v_cndmask_b32_e64 v6, 0, 32, vcc
+; GFX8-NEXT: v_ldexp_f32 v6, |v0|, v6
+; GFX8-NEXT: v_log_f32_e32 v6, v6
+; GFX8-NEXT: v_mov_b32_e32 v4, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v5, 0, v4, vcc
+; GFX8-NEXT: s_mov_b32 s8, 0xc2fc0000
+; GFX8-NEXT: v_sub_f32_e32 v5, v6, v5
+; GFX8-NEXT: v_mul_legacy_f32_e32 v5, v2, v5
+; GFX8-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s8, v5
+; GFX8-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX8-NEXT: v_add_f32_e32 v5, v5, v7
+; GFX8-NEXT: v_exp_f32_e32 v5, v5
+; GFX8-NEXT: v_mul_f32_e32 v9, 0.5, v2
+; GFX8-NEXT: v_not_b32_e32 v7, 63
+; GFX8-NEXT: v_trunc_f32_e32 v10, v9
+; GFX8-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v10, v9
+; GFX8-NEXT: v_trunc_f32_e32 v9, v2
+; GFX8-NEXT: v_ldexp_f32 v5, v5, v8
+; GFX8-NEXT: s_brev_b32 s9, -2
+; GFX8-NEXT: v_cmp_eq_f32_e64 s[4:5], v9, v2
+; GFX8-NEXT: v_bfi_b32 v8, s9, v5, v0
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v5, v5, v8, vcc
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v1|, s6
+; GFX8-NEXT: v_cndmask_b32_e64 v8, 0, 32, vcc
+; GFX8-NEXT: v_ldexp_f32 v8, |v1|, v8
+; GFX8-NEXT: v_log_f32_e32 v8, v8
+; GFX8-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 s[6:7], v0, 24
+; GFX8-NEXT: v_cmp_neq_f32_e32 vcc, v9, v2
+; GFX8-NEXT: v_sub_f32_e32 v0, v8, v4
+; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v3, v0
+; GFX8-NEXT: v_cmp_gt_f32_e64 s[4:5], s8, v0
+; GFX8-NEXT: v_cndmask_b32_e64 v4, 0, v6, s[4:5]
+; GFX8-NEXT: v_add_f32_e32 v0, v0, v4
+; GFX8-NEXT: v_exp_f32_e32 v4, v0
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX8-NEXT: v_mul_f32_e32 v6, 0.5, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v5, v2, vcc
+; GFX8-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX8-NEXT: v_trunc_f32_e32 v7, v6
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v7, v6
+; GFX8-NEXT: v_trunc_f32_e32 v6, v3
+; GFX8-NEXT: v_ldexp_f32 v4, v4, v5
+; GFX8-NEXT: v_cmp_eq_f32_e64 s[4:5], v6, v3
+; GFX8-NEXT: v_bfi_b32 v5, s9, v4, v1
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v4, v4, v5, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v1, 24
+; GFX8-NEXT: v_cmp_neq_f32_e32 vcc, v6, v3
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v1, v4, v2, vcc
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: v_pow_v2f32:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT: v_log_f32_e32 v0, v0
-; GFX9-NEXT: v_log_f32_e32 v1, v1
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v2, v0
-; GFX9-NEXT: v_mul_legacy_f32_e32 v1, v3, v1
-; GFX9-NEXT: v_exp_f32_e32 v0, v0
-; GFX9-NEXT: v_exp_f32_e32 v1, v1
+; GFX9-NEXT: s_mov_b32 s6, 0x800000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s6
+; GFX9-NEXT: v_cndmask_b32_e64 v6, 0, 32, vcc
+; GFX9-NEXT: v_ldexp_f32 v6, |v0|, v6
+; GFX9-NEXT: v_log_f32_e32 v6, v6
+; GFX9-NEXT: v_mov_b32_e32 v4, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v5, 0, v4, vcc
+; GFX9-NEXT: s_mov_b32 s8, 0xc2fc0000
+; GFX9-NEXT: v_sub_f32_e32 v5, v6, v5
+; GFX9-NEXT: v_mul_legacy_f32_e32 v5, v2, v5
+; GFX9-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, s8, v5
+; GFX9-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX9-NEXT: v_add_f32_e32 v5, v5, v7
+; GFX9-NEXT: v_exp_f32_e32 v5, v5
+; GFX9-NEXT: v_mul_f32_e32 v9, 0.5, v2
+; GFX9-NEXT: v_not_b32_e32 v7, 63
+; GFX9-NEXT: v_trunc_f32_e32 v10, v9
+; GFX9-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX9-NEXT: v_cmp_lg_f32_e32 vcc, v10, v9
+; GFX9-NEXT: v_trunc_f32_e32 v9, v2
+; GFX9-NEXT: v_ldexp_f32 v5, v5, v8
+; GFX9-NEXT: s_brev_b32 s9, -2
+; GFX9-NEXT: v_cmp_eq_f32_e64 s[4:5], v9, v2
+; GFX9-NEXT: v_bfi_b32 v8, s9, v5, v0
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v5, v5, v8, vcc
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v1|, s6
+; GFX9-NEXT: v_cndmask_b32_e64 v8, 0, 32, vcc
+; GFX9-NEXT: v_ldexp_f32 v8, |v1|, v8
+; GFX9-NEXT: v_log_f32_e32 v8, v8
+; GFX9-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
+; GFX9-NEXT: v_cmp_class_f32_e64 s[6:7], v0, 24
+; GFX9-NEXT: v_cmp_neq_f32_e32 vcc, v9, v2
+; GFX9-NEXT: v_sub_f32_e32 v0, v8, v4
+; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v3, v0
+; GFX9-NEXT: v_cmp_gt_f32_e64 s[4:5], s8, v0
+; GFX9-NEXT: v_cndmask_b32_e64 v4, 0, v6, s[4:5]
+; GFX9-NEXT: v_add_f32_e32 v0, v0, v4
+; GFX9-NEXT: v_exp_f32_e32 v4, v0
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX9-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX9-NEXT: v_mul_f32_e32 v6, 0.5, v3
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v5, v2, vcc
+; GFX9-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX9-NEXT: v_trunc_f32_e32 v7, v6
+; GFX9-NEXT: v_cmp_lg_f32_e32 vcc, v7, v6
+; GFX9-NEXT: v_trunc_f32_e32 v6, v3
+; GFX9-NEXT: v_ldexp_f32 v4, v4, v5
+; GFX9-NEXT: v_cmp_eq_f32_e64 s[4:5], v6, v3
+; GFX9-NEXT: v_bfi_b32 v5, s9, v4, v1
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v4, v4, v5, vcc
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v1, 24
+; GFX9-NEXT: v_cmp_neq_f32_e32 vcc, v6, v3
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v1, v4, v2, vcc
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX90A-LABEL: v_pow_v2f32:
; GFX90A: ; %bb.0:
; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX90A-NEXT: v_log_f32_e32 v0, v0
-; GFX90A-NEXT: v_log_f32_e32 v1, v1
-; GFX90A-NEXT: v_mul_legacy_f32 v0, v2, v0
-; GFX90A-NEXT: v_mul_legacy_f32 v1, v3, v1
-; GFX90A-NEXT: v_exp_f32_e32 v0, v0
-; GFX90A-NEXT: v_exp_f32_e32 v1, v1
+; GFX90A-NEXT: s_mov_b32 s6, 0x800000
+; GFX90A-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s6
+; GFX90A-NEXT: v_cndmask_b32_e64 v6, 0, 32, vcc
+; GFX90A-NEXT: v_ldexp_f32 v6, |v0|, v6
+; GFX90A-NEXT: v_log_f32_e32 v6, v6
+; GFX90A-NEXT: v_mov_b32_e32 v4, 0x42000000
+; GFX90A-NEXT: v_cndmask_b32_e32 v5, 0, v4, vcc
+; GFX90A-NEXT: s_mov_b32 s8, 0xc2fc0000
+; GFX90A-NEXT: v_sub_f32_e32 v5, v6, v5
+; GFX90A-NEXT: v_mul_legacy_f32 v5, v2, v5
+; GFX90A-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX90A-NEXT: v_cmp_gt_f32_e32 vcc, s8, v5
+; GFX90A-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX90A-NEXT: v_add_f32_e32 v5, v5, v7
+; GFX90A-NEXT: v_exp_f32_e32 v5, v5
+; GFX90A-NEXT: v_mul_f32_e32 v9, 0.5, v2
+; GFX90A-NEXT: v_not_b32_e32 v7, 63
+; GFX90A-NEXT: v_trunc_f32_e32 v10, v9
+; GFX90A-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX90A-NEXT: v_cmp_lg_f32_e32 vcc, v10, v9
+; GFX90A-NEXT: v_trunc_f32_e32 v9, v2
+; GFX90A-NEXT: v_ldexp_f32 v5, v5, v8
+; GFX90A-NEXT: s_brev_b32 s9, -2
+; GFX90A-NEXT: v_cmp_eq_f32_e64 s[4:5], v9, v2
+; GFX90A-NEXT: v_bfi_b32 v8, s9, v5, v0
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v5, v5, v8, vcc
+; GFX90A-NEXT: v_cmp_lt_f32_e64 vcc, |v1|, s6
+; GFX90A-NEXT: v_cndmask_b32_e64 v8, 0, 32, vcc
+; GFX90A-NEXT: v_ldexp_f32 v8, |v1|, v8
+; GFX90A-NEXT: v_log_f32_e32 v8, v8
+; GFX90A-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
+; GFX90A-NEXT: v_cmp_class_f32_e64 s[6:7], v0, 24
+; GFX90A-NEXT: v_cmp_neq_f32_e32 vcc, v9, v2
+; GFX90A-NEXT: v_sub_f32_e32 v0, v8, v4
+; GFX90A-NEXT: v_mul_legacy_f32 v0, v3, v0
+; GFX90A-NEXT: v_cmp_gt_f32_e64 s[4:5], s8, v0
+; GFX90A-NEXT: v_cndmask_b32_e64 v4, 0, v6, s[4:5]
+; GFX90A-NEXT: v_add_f32_e32 v0, v0, v4
+; GFX90A-NEXT: v_exp_f32_e32 v4, v0
+; GFX90A-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX90A-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX90A-NEXT: v_mul_f32_e32 v6, 0.5, v3
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v5, v2, vcc
+; GFX90A-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX90A-NEXT: v_trunc_f32_e32 v7, v6
+; GFX90A-NEXT: v_cmp_lg_f32_e32 vcc, v7, v6
+; GFX90A-NEXT: v_trunc_f32_e32 v6, v3
+; GFX90A-NEXT: v_ldexp_f32 v4, v4, v5
+; GFX90A-NEXT: v_cmp_eq_f32_e64 s[4:5], v6, v3
+; GFX90A-NEXT: v_bfi_b32 v5, s9, v4, v1
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v4, v4, v5, vcc
+; GFX90A-NEXT: v_cmp_class_f32_e64 s[4:5], v1, 24
+; GFX90A-NEXT: v_cmp_neq_f32_e32 vcc, v6, v3
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v1, v4, v2, vcc
; GFX90A-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_v2f32:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_log_f32_e32 v0, v0
-; GFX10-NEXT: v_log_f32_e32 v1, v1
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v2, v0
-; GFX10-NEXT: v_mul_legacy_f32_e32 v1, v3, v1
-; GFX10-NEXT: v_exp_f32_e32 v0, v0
-; GFX10-NEXT: v_exp_f32_e32 v1, v1
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v0|
+; GFX10-NEXT: v_cmp_gt_f32_e64 s5, 0x800000, |v1|
+; GFX10-NEXT: v_mul_f32_e32 v8, 0.5, v3
+; GFX10-NEXT: v_trunc_f32_e32 v9, v3
+; GFX10-NEXT: v_cmp_class_f32_e64 s9, v0, 24
+; GFX10-NEXT: v_cndmask_b32_e64 v5, 0, 32, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v7, 0, 32, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 0x42000000, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s5
+; GFX10-NEXT: v_cmp_eq_f32_e64 s5, v9, v3
+; GFX10-NEXT: v_ldexp_f32 v5, |v0|, v5
+; GFX10-NEXT: v_ldexp_f32 v7, |v1|, v7
+; GFX10-NEXT: v_cmp_class_f32_e64 s10, v1, 24
+; GFX10-NEXT: v_cmp_neq_f32_e64 s8, v9, v3
+; GFX10-NEXT: v_log_f32_e32 v5, v5
+; GFX10-NEXT: v_log_f32_e32 v7, v7
+; GFX10-NEXT: v_sub_f32_e32 v4, v5, v4
+; GFX10-NEXT: v_sub_f32_e32 v5, v7, v6
+; GFX10-NEXT: v_mul_legacy_f32_e32 v4, v2, v4
+; GFX10-NEXT: v_mul_legacy_f32_e32 v5, v3, v5
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v4
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0xc2fc0000, v5
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v7, 0, 0x42800000, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v10, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v12, 0, 0xffffffc0, s4
+; GFX10-NEXT: v_add_f32_e32 v4, v4, v6
+; GFX10-NEXT: v_add_f32_e32 v5, v5, v7
+; GFX10-NEXT: v_mul_f32_e32 v6, 0.5, v2
+; GFX10-NEXT: v_trunc_f32_e32 v7, v2
+; GFX10-NEXT: v_exp_f32_e32 v4, v4
+; GFX10-NEXT: v_exp_f32_e32 v5, v5
+; GFX10-NEXT: v_trunc_f32_e32 v11, v6
+; GFX10-NEXT: v_cmp_eq_f32_e32 vcc_lo, v7, v2
+; GFX10-NEXT: v_cmp_neq_f32_e64 s4, v7, v2
+; GFX10-NEXT: v_cmp_lg_f32_e64 s6, v11, v6
+; GFX10-NEXT: s_and_b32 s4, s9, s4
+; GFX10-NEXT: v_ldexp_f32 v2, v4, v10
+; GFX10-NEXT: v_trunc_f32_e32 v4, v8
+; GFX10-NEXT: v_ldexp_f32 v5, v5, v12
+; GFX10-NEXT: s_and_b32 vcc_lo, vcc_lo, s6
+; GFX10-NEXT: v_bfi_b32 v0, 0x7fffffff, v2, v0
+; GFX10-NEXT: v_cmp_lg_f32_e64 s7, v4, v8
+; GFX10-NEXT: v_bfi_b32 v1, 0x7fffffff, v5, v1
+; GFX10-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc_lo
+; GFX10-NEXT: s_and_b32 vcc_lo, s5, s7
+; GFX10-NEXT: v_cndmask_b32_e32 v1, v5, v1, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s4
+; GFX10-NEXT: s_and_b32 s4, s10, s8
+; GFX10-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s4
; GFX10-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: v_pow_v2f32:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT: v_log_f32_e32 v0, v0
-; GFX11-NEXT: v_log_f32_e32 v1, v1
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v1|
+; GFX11-NEXT: v_cmp_class_f32_e64 s6, v1, 24
+; GFX11-NEXT: v_mul_f32_e32 v8, 0.5, v3
+; GFX11-NEXT: v_trunc_f32_e32 v9, v3
+; GFX11-NEXT: v_cndmask_b32_e64 v5, 0, 32, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v7, 0, 32, s1
+; GFX11-NEXT: v_cndmask_b32_e64 v4, 0, 0x42000000, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s1
+; GFX11-NEXT: v_cmp_class_f32_e64 s5, v0, 24
+; GFX11-NEXT: v_ldexp_f32 v5, |v0|, v5
+; GFX11-NEXT: v_ldexp_f32 v7, |v1|, v7
+; GFX11-NEXT: v_cmp_eq_f32_e64 s1, v9, v3
+; GFX11-NEXT: v_cmp_neq_f32_e64 s4, v9, v3
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-NEXT: v_log_f32_e32 v5, v5
+; GFX11-NEXT: v_log_f32_e32 v7, v7
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_dual_mul_dx9_zero_f32 v0, v2, v0 :: v_dual_mul_dx9_zero_f32 v1, v3, v1
+; GFX11-NEXT: v_dual_sub_f32 v4, v5, v4 :: v_dual_sub_f32 v5, v7, v6
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-NEXT: v_exp_f32_e32 v0, v0
-; GFX11-NEXT: v_exp_f32_e32 v1, v1
+; GFX11-NEXT: v_dual_mul_dx9_zero_f32 v4, v2, v4 :: v_dual_mul_dx9_zero_f32 v5, v3, v5
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v4
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v5
+; GFX11-NEXT: v_cndmask_b32_e64 v6, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_cndmask_b32_e64 v7, 0, 0x42800000, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v12, 0, 0xffffffc0, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v10, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_dual_add_f32 v4, v4, v6 :: v_dual_add_f32 v5, v5, v7
+; GFX11-NEXT: v_trunc_f32_e32 v7, v2
+; GFX11-NEXT: v_exp_f32_e32 v4, v4
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_exp_f32_e32 v5, v5
+; GFX11-NEXT: v_cmp_eq_f32_e32 vcc_lo, v7, v2
+; GFX11-NEXT: v_cmp_neq_f32_e64 s0, v7, v2
+; GFX11-NEXT: s_and_b32 s0, s5, s0
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_ldexp_f32 v5, v5, v12
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_3) | instid1(VALU_DEP_3)
+; GFX11-NEXT: v_bfi_b32 v1, 0x7fffffff, v5, v1
+; GFX11-NEXT: v_mul_f32_e32 v6, 0.5, v2
+; GFX11-NEXT: v_ldexp_f32 v2, v4, v10
+; GFX11-NEXT: v_trunc_f32_e32 v4, v8
+; GFX11-NEXT: v_trunc_f32_e32 v11, v6
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-NEXT: v_bfi_b32 v0, 0x7fffffff, v2, v0
+; GFX11-NEXT: v_cmp_lg_f32_e64 s3, v4, v8
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_4) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_cmp_lg_f32_e64 s2, v11, v6
+; GFX11-NEXT: s_and_b32 vcc_lo, vcc_lo, s2
+; GFX11-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc_lo
+; GFX11-NEXT: s_and_b32 vcc_lo, s1, s3
+; GFX11-NEXT: v_cndmask_b32_e32 v1, v5, v1, vcc_lo
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
+; GFX11-NEXT: s_and_b32 s0, s6, s4
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
%pow = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> %y)
ret <2 x float> %pow
@@ -137,82 +602,289 @@ define half @v_pow_f16(half %x, half %y) {
; GFX6: ; %bb.0:
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX6-NEXT: s_mov_b32 s4, 0x800000
; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX6-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX6-NEXT: v_ldexp_f32_e64 v3, |v0|, v3
+; GFX6-NEXT: v_log_f32_e32 v3, v3
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX6-NEXT: v_mul_f32_e32 v4, 0.5, v1
+; GFX6-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX6-NEXT: v_cmp_gt_f32_e32 vcc, s4, v2
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_exp_f32_e32 v2, v2
+; GFX6-NEXT: v_not_b32_e32 v3, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: v_trunc_f32_e32 v5, v4
+; GFX6-NEXT: v_ldexp_f32_e32 v2, v2, v3
+; GFX6-NEXT: s_brev_b32 s4, -2
+; GFX6-NEXT: v_cmp_lg_f32_e32 vcc, v5, v4
+; GFX6-NEXT: v_trunc_f32_e32 v4, v1
+; GFX6-NEXT: v_bfi_b32 v3, s4, v2, v0
+; GFX6-NEXT: v_cmp_eq_f32_e64 s[4:5], v4, v1
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v2, v2, v3, vcc
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX6-NEXT: v_cmp_neq_f32_e32 vcc, v4, v1
+; GFX6-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v0
; GFX6-NEXT: s_setpc_b64 s[30:31]
;
; GFX8-LABEL: v_pow_f16:
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX8-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX8-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX8-NEXT: s_mov_b32 s4, 0x800000
; GFX8-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX8-NEXT: v_log_f32_e32 v0, v0
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX8-NEXT: v_exp_f32_e32 v0, v0
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s4
+; GFX8-NEXT: v_cndmask_b32_e64 v4, 0, 32, vcc
+; GFX8-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX8-NEXT: v_log_f32_e32 v4, v4
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX8-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX8-NEXT: v_sub_f32_e32 v3, v4, v3
+; GFX8-NEXT: v_mul_legacy_f32_e32 v3, v1, v3
+; GFX8-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s4, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
+; GFX8-NEXT: v_add_f32_e32 v3, v3, v4
+; GFX8-NEXT: v_exp_f32_e32 v3, v3
+; GFX8-NEXT: v_not_b32_e32 v4, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
+; GFX8-NEXT: s_brev_b32 s4, -2
+; GFX8-NEXT: v_ldexp_f32 v3, v3, v4
+; GFX8-NEXT: v_mul_f32_e32 v4, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v5, v4
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v5, v4
+; GFX8-NEXT: v_trunc_f32_e32 v4, v1
+; GFX8-NEXT: v_bfi_b32 v0, s4, v3, v0
+; GFX8-NEXT: v_cmp_eq_f32_e64 s[4:5], v4, v1
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v3, v0, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v2, 24
+; GFX8-NEXT: v_cmp_neq_f32_e32 vcc, v4, v1
+; GFX8-NEXT: v_mov_b32_e32 v1, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc
; GFX8-NEXT: v_cvt_f16_f32_e32 v0, v0
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: v_pow_f16:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX9-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX9-NEXT: s_mov_b32 s4, 0x800000
; GFX9-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX9-NEXT: v_log_f32_e32 v0, v0
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX9-NEXT: v_exp_f32_e32 v0, v0
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s4
+; GFX9-NEXT: v_cndmask_b32_e64 v4, 0, 32, vcc
+; GFX9-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX9-NEXT: v_log_f32_e32 v4, v4
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX9-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX9-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX9-NEXT: v_sub_f32_e32 v3, v4, v3
+; GFX9-NEXT: v_mul_legacy_f32_e32 v3, v1, v3
+; GFX9-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, s4, v3
+; GFX9-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
+; GFX9-NEXT: v_add_f32_e32 v3, v3, v4
+; GFX9-NEXT: v_exp_f32_e32 v3, v3
+; GFX9-NEXT: v_not_b32_e32 v4, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
+; GFX9-NEXT: s_brev_b32 s4, -2
+; GFX9-NEXT: v_ldexp_f32 v3, v3, v4
+; GFX9-NEXT: v_mul_f32_e32 v4, 0.5, v1
+; GFX9-NEXT: v_trunc_f32_e32 v5, v4
+; GFX9-NEXT: v_cmp_lg_f32_e32 vcc, v5, v4
+; GFX9-NEXT: v_trunc_f32_e32 v4, v1
+; GFX9-NEXT: v_bfi_b32 v0, s4, v3, v0
+; GFX9-NEXT: v_cmp_eq_f32_e64 s[4:5], v4, v1
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v3, v0, vcc
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v2, 24
+; GFX9-NEXT: v_cmp_neq_f32_e32 vcc, v4, v1
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x7fc00000
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc
; GFX9-NEXT: v_cvt_f16_f32_e32 v0, v0
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX90A-LABEL: v_pow_f16:
; GFX90A: ; %bb.0:
; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX90A-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX90A-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX90A-NEXT: v_log_f32_e32 v0, v0
-; GFX90A-NEXT: v_mul_legacy_f32 v0, v1, v0
-; GFX90A-NEXT: v_exp_f32_e32 v0, v0
+; GFX90A-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX90A-NEXT: s_mov_b32 s4, 0x800000
+; GFX90A-NEXT: v_cvt_f32_f16_e32 v5, v1
+; GFX90A-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX90A-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s4
+; GFX90A-NEXT: v_cndmask_b32_e64 v4, 0, 32, vcc
+; GFX90A-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX90A-NEXT: v_log_f32_e32 v4, v4
+; GFX90A-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX90A-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX90A-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX90A-NEXT: v_sub_f32_e32 v3, v4, v3
+; GFX90A-NEXT: v_mul_legacy_f32 v3, v5, v3
+; GFX90A-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX90A-NEXT: v_cmp_gt_f32_e32 vcc, s4, v3
+; GFX90A-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
+; GFX90A-NEXT: v_add_f32_e32 v3, v3, v4
+; GFX90A-NEXT: v_exp_f32_e32 v3, v3
+; GFX90A-NEXT: v_not_b32_e32 v4, 63
+; GFX90A-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
+; GFX90A-NEXT: s_brev_b32 s4, -2
+; GFX90A-NEXT: v_ldexp_f32 v3, v3, v4
+; GFX90A-NEXT: v_bfi_b32 v0, s4, v3, v0
+; GFX90A-NEXT: s_mov_b32 s4, 0.5
+; GFX90A-NEXT: v_fma_mix_f32 v1, v1, s4, neg(0) op_sel_hi:[1,0,0]
+; GFX90A-NEXT: v_trunc_f32_e32 v4, v1
+; GFX90A-NEXT: v_cmp_lg_f32_e32 vcc, v4, v1
+; GFX90A-NEXT: v_trunc_f32_e32 v1, v5
+; GFX90A-NEXT: v_cmp_eq_f32_e64 s[4:5], v1, v5
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v3, v0, vcc
+; GFX90A-NEXT: v_cmp_class_f32_e64 s[4:5], v2, 24
+; GFX90A-NEXT: v_cmp_neq_f32_e32 vcc, v1, v5
+; GFX90A-NEXT: v_mov_b32_e32 v1, 0x7fc00000
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc
; GFX90A-NEXT: v_cvt_f16_f32_e32 v0, v0
; GFX90A-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_f16:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX10-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX10-NEXT: v_log_f32_e32 v0, v0
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX10-NEXT: v_exp_f32_e32 v0, v0
+; GFX10-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX10-NEXT: v_cvt_f32_f16_e32 v5, v1
+; GFX10-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v2|
+; GFX10-NEXT: v_trunc_f32_e32 v7, v5
+; GFX10-NEXT: v_cmp_class_f32_e64 s6, v2, 24
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 32, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s4
+; GFX10-NEXT: s_mov_b32 s4, 0.5
+; GFX10-NEXT: v_cmp_neq_f32_e64 s5, v7, v5
+; GFX10-NEXT: v_fma_mix_f32 v1, v1, s4, neg(0) op_sel_hi:[1,0,0]
+; GFX10-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX10-NEXT: v_cmp_eq_f32_e64 s4, v7, v5
+; GFX10-NEXT: v_trunc_f32_e32 v6, v1
+; GFX10-NEXT: v_log_f32_e32 v4, v4
+; GFX10-NEXT: v_sub_f32_e32 v3, v4, v3
+; GFX10-NEXT: v_mul_legacy_f32_e32 v3, v5, v3
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v3
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v3, v3, v4
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_cmp_lg_f32_e32 vcc_lo, v6, v1
+; GFX10-NEXT: v_exp_f32_e32 v3, v3
+; GFX10-NEXT: s_and_b32 vcc_lo, s4, vcc_lo
+; GFX10-NEXT: s_and_b32 s4, s6, s5
+; GFX10-NEXT: v_ldexp_f32 v3, v3, v4
+; GFX10-NEXT: v_bfi_b32 v0, 0x7fffffff, v3, v0
+; GFX10-NEXT: v_cndmask_b32_e32 v0, v3, v0, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s4
; GFX10-NEXT: v_cvt_f16_f32_e32 v0, v0
; GFX10-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-TRUE16-LABEL: v_pow_f16:
; GFX11-TRUE16: ; %bb.0:
; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.l
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v1.l
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_1)
-; GFX11-TRUE16-NEXT: v_log_f32_e32 v0, v0
+; GFX11-TRUE16-NEXT: v_mov_b16_e32 v2.l, v0.l
+; GFX11-TRUE16-NEXT: v_mov_b16_e32 v0.h, v0.l
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v3, v2.l
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v3|
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s2, v3, 24
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v2, 0, 32, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v4, 0, 0x42000000, s0
+; GFX11-TRUE16-NEXT: s_mov_b32 s0, 0.5
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v2, |v3|, v2
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v5, v2
+; GFX11-TRUE16-NEXT: v_mov_b16_e32 v2.l, v1.l
+; GFX11-TRUE16-NEXT: v_fma_mix_f32 v1, v1, s0, neg(0) op_sel_hi:[1,0,0]
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v2, v2.l
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_3) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v6, v1
; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
-; GFX11-TRUE16-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-TRUE16-NEXT: v_sub_f32_e32 v4, v5, v4
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v7, v2
+; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v4, v2, v4
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_3)
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e64 s0, v7, v2
+; GFX11-TRUE16-NEXT: v_cmp_neq_f32_e64 s1, v7, v2
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v4
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v5, 0, 0x42800000, vcc_lo
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_3)
+; GFX11-TRUE16-NEXT: v_add_f32_e32 v4, v4, v5
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v5, 0, 0xffffffc0, vcc_lo
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e32 vcc_lo, v6, v1
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v4, v4
+; GFX11-TRUE16-NEXT: s_and_b32 vcc_lo, s0, vcc_lo
+; GFX11-TRUE16-NEXT: s_and_b32 s0, s2, s1
; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v4, v4, v5
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_bfi_b32 v0, 0x7fffffff, v4, v0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e32 v0, v4, v0, vcc_lo
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v0
; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-FAKE16-LABEL: v_pow_f16:
; GFX11-FAKE16: ; %bb.0:
; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_log_f32_e32 v0, v0
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v5, v1
+; GFX11-FAKE16-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v2|
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v7, v5
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s2, v2, 24
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v4, 0, 32, s0
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s0
+; GFX11-FAKE16-NEXT: s_mov_b32 s0, 0.5
+; GFX11-FAKE16-NEXT: v_cmp_neq_f32_e64 s1, v7, v5
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v1, v1, s0, neg(0) op_sel_hi:[1,0,0]
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e64 s0, v7, v5
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v6, v1
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v4, v4
; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
-; GFX11-FAKE16-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-FAKE16-NEXT: v_sub_f32_e32 v3, v4, v3
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v3, v5, v3
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v3
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v4, 0, 0x42800000, vcc_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_add_f32_e32 v3, v3, v4
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e32 vcc_lo, v6, v1
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v3, v3
+; GFX11-FAKE16-NEXT: s_and_b32 vcc_lo, s0, vcc_lo
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s2, s1
; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v3, v3, v4
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_bfi_b32 v0, 0x7fffffff, v3, v0
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e32 v0, v3, v0, vcc_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
%pow = call half @llvm.pow.f16(half %x, half %y)
@@ -225,19 +897,70 @@ define <2 x half> @v_pow_v2f16(<2 x half> %x, <2 x half> %y) {
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX6-NEXT: v_lshrrev_b32_e32 v2, 16, v0
; GFX6-NEXT: v_cvt_f32_f16_e32 v2, v2
-; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX6-NEXT: s_mov_b32 s6, 0x800000
; GFX6-NEXT: v_lshrrev_b32_e32 v3, 16, v1
; GFX6-NEXT: v_cvt_f32_f16_e32 v3, v3
-; GFX6-NEXT: v_log_f32_e32 v2, v2
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s6
+; GFX6-NEXT: v_cndmask_b32_e64 v4, 0, 32, vcc
+; GFX6-NEXT: v_ldexp_f32_e64 v4, |v2|, v4
+; GFX6-NEXT: v_log_f32_e32 v4, v4
+; GFX6-NEXT: v_mov_b32_e32 v5, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
+; GFX6-NEXT: s_mov_b32 s8, 0xc2fc0000
+; GFX6-NEXT: v_sub_f32_e32 v4, v4, v6
+; GFX6-NEXT: v_mul_legacy_f32_e32 v4, v3, v4
+; GFX6-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX6-NEXT: v_cmp_gt_f32_e32 vcc, s8, v4
+; GFX6-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX6-NEXT: v_add_f32_e32 v4, v4, v7
+; GFX6-NEXT: v_exp_f32_e32 v4, v4
+; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX6-NEXT: v_not_b32_e32 v7, 63
+; GFX6-NEXT: v_mul_f32_e32 v10, 0.5, v3
+; GFX6-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX6-NEXT: v_trunc_f32_e32 v9, v3
+; GFX6-NEXT: v_trunc_f32_e32 v11, v10
+; GFX6-NEXT: v_ldexp_f32_e32 v4, v4, v8
+; GFX6-NEXT: s_brev_b32 s9, -2
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v9, v3
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v11, v10
+; GFX6-NEXT: v_bfi_b32 v8, s9, v4, v2
+; GFX6-NEXT: s_and_b64 vcc, vcc, s[4:5]
+; GFX6-NEXT: v_cmp_lt_f32_e64 s[4:5], |v0|, s6
+; GFX6-NEXT: v_cndmask_b32_e32 v4, v4, v8, vcc
+; GFX6-NEXT: v_cmp_neq_f32_e32 vcc, v9, v3
+; GFX6-NEXT: v_cndmask_b32_e64 v3, 0, v5, s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e64 v5, 0, 32, s[4:5]
+; GFX6-NEXT: v_ldexp_f32_e64 v5, |v0|, v5
+; GFX6-NEXT: v_log_f32_e32 v5, v5
; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v3, v2
-; GFX6-NEXT: v_exp_f32_e32 v2, v2
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
-; GFX6-NEXT: v_cvt_f16_f32_e32 v1, v2
+; GFX6-NEXT: v_cmp_class_f32_e64 s[6:7], v2, 24
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX6-NEXT: v_sub_f32_e32 v3, v5, v3
+; GFX6-NEXT: v_mul_legacy_f32_e32 v3, v1, v3
+; GFX6-NEXT: v_cmp_gt_f32_e64 s[4:5], s8, v3
+; GFX6-NEXT: v_cndmask_b32_e64 v5, 0, v6, s[4:5]
+; GFX6-NEXT: v_add_f32_e32 v3, v3, v5
+; GFX6-NEXT: v_exp_f32_e32 v3, v3
+; GFX6-NEXT: v_mul_f32_e32 v6, 0.5, v1
+; GFX6-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX6-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX6-NEXT: v_trunc_f32_e32 v7, v6
+; GFX6-NEXT: v_cndmask_b32_e32 v4, v4, v2, vcc
+; GFX6-NEXT: v_cmp_lg_f32_e32 vcc, v7, v6
+; GFX6-NEXT: v_trunc_f32_e32 v6, v1
+; GFX6-NEXT: v_ldexp_f32_e32 v3, v3, v5
+; GFX6-NEXT: v_cmp_eq_f32_e64 s[4:5], v6, v1
+; GFX6-NEXT: v_bfi_b32 v5, s9, v3, v0
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v3, v3, v5, vcc
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX6-NEXT: v_cmp_neq_f32_e32 vcc, v6, v1
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX6-NEXT: v_cvt_f16_f32_e32 v4, v4
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v3, v2, vcc
; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX6-NEXT: v_lshlrev_b32_e32 v1, 16, v1
+; GFX6-NEXT: v_lshlrev_b32_e32 v1, 16, v4
; GFX6-NEXT: v_or_b32_e32 v0, v0, v1
; GFX6-NEXT: s_setpc_b64 s[30:31]
;
@@ -245,69 +968,280 @@ define <2 x half> @v_pow_v2f16(<2 x half> %x, <2 x half> %y) {
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX8-NEXT: v_cvt_f32_f16_sdwa v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX8-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX8-NEXT: v_cvt_f32_f16_sdwa v3, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX8-NEXT: s_mov_b32 s6, 0x800000
+; GFX8-NEXT: v_cvt_f32_f16_sdwa v4, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX8-NEXT: v_mov_b32_e32 v5, 0x42000000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s6
+; GFX8-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX8-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX8-NEXT: v_log_f32_e32 v3, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
+; GFX8-NEXT: s_mov_b32 s8, 0xc2fc0000
+; GFX8-NEXT: v_mul_f32_e32 v10, 0.5, v4
+; GFX8-NEXT: v_sub_f32_e32 v3, v3, v6
+; GFX8-NEXT: v_mul_legacy_f32_e32 v3, v4, v3
+; GFX8-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s8, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX8-NEXT: v_add_f32_e32 v3, v3, v7
+; GFX8-NEXT: v_exp_f32_e32 v3, v3
+; GFX8-NEXT: v_trunc_f32_e32 v11, v10
+; GFX8-NEXT: v_not_b32_e32 v7, 63
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v11, v10
+; GFX8-NEXT: v_cvt_f32_f16_e32 v10, v0
+; GFX8-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX8-NEXT: v_ldexp_f32 v3, v3, v8
+; GFX8-NEXT: v_mov_b32_e32 v8, 16
+; GFX8-NEXT: v_trunc_f32_e32 v9, v4
+; GFX8-NEXT: v_lshlrev_b32_sdwa v8, v8, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+; GFX8-NEXT: s_brev_b32 s9, -2
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v9, v4
+; GFX8-NEXT: v_bfi_b32 v8, s9, v3, v8
+; GFX8-NEXT: s_and_b64 vcc, vcc, s[4:5]
+; GFX8-NEXT: v_cmp_lt_f32_e64 s[4:5], |v10|, s6
+; GFX8-NEXT: v_cndmask_b32_e32 v3, v3, v8, vcc
+; GFX8-NEXT: v_cmp_neq_f32_e32 vcc, v9, v4
+; GFX8-NEXT: v_cndmask_b32_e64 v4, 0, v5, s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e64 v5, 0, 32, s[4:5]
+; GFX8-NEXT: v_ldexp_f32 v5, |v10|, v5
+; GFX8-NEXT: v_log_f32_e32 v5, v5
; GFX8-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX8-NEXT: v_log_f32_e32 v2, v2
-; GFX8-NEXT: v_log_f32_e32 v0, v0
-; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v3, v2
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX8-NEXT: v_exp_f32_e32 v1, v2
-; GFX8-NEXT: v_exp_f32_e32 v0, v0
-; GFX8-NEXT: v_cvt_f16_f32_sdwa v1, v1 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD
+; GFX8-NEXT: v_cmp_class_f32_e64 s[6:7], v2, 24
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX8-NEXT: v_sub_f32_e32 v4, v5, v4
+; GFX8-NEXT: v_mul_legacy_f32_e32 v4, v1, v4
+; GFX8-NEXT: v_cmp_gt_f32_e64 s[4:5], s8, v4
+; GFX8-NEXT: v_cndmask_b32_e64 v5, 0, v6, s[4:5]
+; GFX8-NEXT: v_add_f32_e32 v4, v4, v5
+; GFX8-NEXT: v_exp_f32_e32 v4, v4
+; GFX8-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX8-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v3, v3, v2, vcc
+; GFX8-NEXT: v_ldexp_f32 v4, v4, v5
+; GFX8-NEXT: v_mul_f32_e32 v5, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v6, v5
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v6, v5
+; GFX8-NEXT: v_trunc_f32_e32 v5, v1
+; GFX8-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX8-NEXT: v_cmp_eq_f32_e64 s[4:5], v5, v1
+; GFX8-NEXT: v_bfi_b32 v0, s9, v4, v0
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v4, v0, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v10, 24
+; GFX8-NEXT: v_cmp_neq_f32_e32 vcc, v5, v1
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc
+; GFX8-NEXT: v_cvt_f16_f32_sdwa v3, v3 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD
; GFX8-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX8-NEXT: v_or_b32_e32 v0, v0, v1
+; GFX8-NEXT: v_or_b32_e32 v0, v0, v3
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: v_pow_v2f16:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_cvt_f32_f16_sdwa v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX9-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX9-NEXT: v_cvt_f32_f16_sdwa v3, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX9-NEXT: s_mov_b32 s6, 0x800000
+; GFX9-NEXT: v_cvt_f32_f16_sdwa v4, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX9-NEXT: v_mov_b32_e32 v5, 0x42000000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s6
+; GFX9-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX9-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX9-NEXT: v_log_f32_e32 v3, v3
+; GFX9-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
+; GFX9-NEXT: s_mov_b32 s8, 0xc2fc0000
+; GFX9-NEXT: v_mul_f32_e32 v10, 0.5, v4
+; GFX9-NEXT: v_sub_f32_e32 v3, v3, v6
+; GFX9-NEXT: v_mul_legacy_f32_e32 v3, v4, v3
+; GFX9-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, s8, v3
+; GFX9-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX9-NEXT: v_add_f32_e32 v3, v3, v7
+; GFX9-NEXT: v_exp_f32_e32 v3, v3
+; GFX9-NEXT: v_trunc_f32_e32 v11, v10
+; GFX9-NEXT: v_not_b32_e32 v7, 63
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v11, v10
+; GFX9-NEXT: v_cvt_f32_f16_e32 v10, v0
+; GFX9-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX9-NEXT: v_ldexp_f32 v3, v3, v8
+; GFX9-NEXT: v_mov_b32_e32 v8, 16
+; GFX9-NEXT: v_trunc_f32_e32 v9, v4
+; GFX9-NEXT: v_lshlrev_b32_sdwa v8, v8, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+; GFX9-NEXT: s_brev_b32 s9, -2
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v9, v4
+; GFX9-NEXT: v_bfi_b32 v8, s9, v3, v8
+; GFX9-NEXT: s_and_b64 vcc, vcc, s[4:5]
+; GFX9-NEXT: v_cmp_lt_f32_e64 s[4:5], |v10|, s6
+; GFX9-NEXT: v_cndmask_b32_e32 v3, v3, v8, vcc
+; GFX9-NEXT: v_cmp_neq_f32_e32 vcc, v9, v4
+; GFX9-NEXT: v_cndmask_b32_e64 v4, 0, v5, s[4:5]
+; GFX9-NEXT: v_cndmask_b32_e64 v5, 0, 32, s[4:5]
+; GFX9-NEXT: v_ldexp_f32 v5, |v10|, v5
+; GFX9-NEXT: v_log_f32_e32 v5, v5
; GFX9-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX9-NEXT: v_log_f32_e32 v2, v2
-; GFX9-NEXT: v_log_f32_e32 v0, v0
-; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v3, v2
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX9-NEXT: v_exp_f32_e32 v1, v2
-; GFX9-NEXT: v_exp_f32_e32 v0, v0
-; GFX9-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX9-NEXT: v_cmp_class_f32_e64 s[6:7], v2, 24
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX9-NEXT: v_sub_f32_e32 v4, v5, v4
+; GFX9-NEXT: v_mul_legacy_f32_e32 v4, v1, v4
+; GFX9-NEXT: v_cmp_gt_f32_e64 s[4:5], s8, v4
+; GFX9-NEXT: v_cndmask_b32_e64 v5, 0, v6, s[4:5]
+; GFX9-NEXT: v_add_f32_e32 v4, v4, v5
+; GFX9-NEXT: v_exp_f32_e32 v4, v4
+; GFX9-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX9-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v3, v3, v2, vcc
+; GFX9-NEXT: v_ldexp_f32 v4, v4, v5
+; GFX9-NEXT: v_mul_f32_e32 v5, 0.5, v1
+; GFX9-NEXT: v_trunc_f32_e32 v6, v5
+; GFX9-NEXT: v_cmp_lg_f32_e32 vcc, v6, v5
+; GFX9-NEXT: v_trunc_f32_e32 v5, v1
+; GFX9-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX9-NEXT: v_cmp_eq_f32_e64 s[4:5], v5, v1
+; GFX9-NEXT: v_bfi_b32 v0, s9, v4, v0
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v4, v0, vcc
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v10, 24
+; GFX9-NEXT: v_cmp_neq_f32_e32 vcc, v5, v1
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc
+; GFX9-NEXT: v_cvt_f16_f32_e32 v3, v3
; GFX9-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX9-NEXT: v_pack_b32_f16 v0, v0, v1
+; GFX9-NEXT: v_pack_b32_f16 v0, v0, v3
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX90A-LABEL: v_pow_v2f16:
; GFX90A: ; %bb.0:
; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX90A-NEXT: v_cvt_f32_f16_sdwa v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX90A-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX90A-NEXT: v_cvt_f32_f16_sdwa v3, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX90A-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX90A-NEXT: v_log_f32_e32 v2, v2
-; GFX90A-NEXT: v_log_f32_e32 v0, v0
-; GFX90A-NEXT: v_mul_legacy_f32 v2, v3, v2
-; GFX90A-NEXT: v_mul_legacy_f32 v0, v1, v0
-; GFX90A-NEXT: v_exp_f32_e32 v1, v2
-; GFX90A-NEXT: v_exp_f32_e32 v0, v0
-; GFX90A-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX90A-NEXT: s_mov_b32 s6, 0x800000
+; GFX90A-NEXT: v_cvt_f32_f16_sdwa v4, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX90A-NEXT: v_mov_b32_e32 v5, 0x42000000
+; GFX90A-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s6
+; GFX90A-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX90A-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX90A-NEXT: v_log_f32_e32 v3, v3
+; GFX90A-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
+; GFX90A-NEXT: s_mov_b32 s8, 0xc2fc0000
+; GFX90A-NEXT: s_mov_b32 s10, 0.5
+; GFX90A-NEXT: v_sub_f32_e32 v3, v3, v6
+; GFX90A-NEXT: v_mul_legacy_f32 v3, v4, v3
+; GFX90A-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX90A-NEXT: v_cmp_gt_f32_e32 vcc, s8, v3
+; GFX90A-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX90A-NEXT: v_add_f32_e32 v3, v3, v7
+; GFX90A-NEXT: v_exp_f32_e32 v3, v3
+; GFX90A-NEXT: v_fma_mix_f32 v9, v1, s10, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX90A-NEXT: v_not_b32_e32 v7, 63
+; GFX90A-NEXT: v_trunc_f32_e32 v10, v9
+; GFX90A-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX90A-NEXT: v_cmp_lg_f32_e32 vcc, v10, v9
+; GFX90A-NEXT: v_cvt_f32_f16_e32 v10, v0
+; GFX90A-NEXT: v_ldexp_f32 v3, v3, v8
+; GFX90A-NEXT: v_mov_b32_e32 v8, 16
+; GFX90A-NEXT: v_trunc_f32_e32 v9, v4
+; GFX90A-NEXT: v_lshlrev_b32_sdwa v8, v8, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+; GFX90A-NEXT: s_brev_b32 s9, -2
+; GFX90A-NEXT: v_cmp_eq_f32_e64 s[4:5], v9, v4
+; GFX90A-NEXT: v_bfi_b32 v8, s9, v3, v8
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cmp_lt_f32_e64 s[4:5], |v10|, s6
+; GFX90A-NEXT: v_cndmask_b32_e32 v3, v3, v8, vcc
+; GFX90A-NEXT: v_cmp_neq_f32_e32 vcc, v9, v4
+; GFX90A-NEXT: v_cndmask_b32_e64 v4, 0, v5, s[4:5]
+; GFX90A-NEXT: v_cndmask_b32_e64 v5, 0, 32, s[4:5]
+; GFX90A-NEXT: v_ldexp_f32 v5, |v10|, v5
+; GFX90A-NEXT: v_log_f32_e32 v5, v5
+; GFX90A-NEXT: v_cvt_f32_f16_e32 v8, v1
+; GFX90A-NEXT: v_cmp_class_f32_e64 s[6:7], v2, 24
+; GFX90A-NEXT: v_fma_mix_f32 v1, v1, s10, neg(0) op_sel_hi:[1,0,0]
+; GFX90A-NEXT: v_sub_f32_e32 v4, v5, v4
+; GFX90A-NEXT: v_mul_legacy_f32 v4, v8, v4
+; GFX90A-NEXT: v_cmp_gt_f32_e64 s[4:5], s8, v4
+; GFX90A-NEXT: v_cndmask_b32_e64 v5, 0, v6, s[4:5]
+; GFX90A-NEXT: v_add_f32_e32 v4, v4, v5
+; GFX90A-NEXT: v_exp_f32_e32 v4, v4
+; GFX90A-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX90A-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX90A-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX90A-NEXT: v_ldexp_f32 v4, v4, v5
+; GFX90A-NEXT: v_trunc_f32_e32 v5, v1
+; GFX90A-NEXT: v_cndmask_b32_e32 v3, v3, v2, vcc
+; GFX90A-NEXT: v_cmp_lg_f32_e32 vcc, v5, v1
+; GFX90A-NEXT: v_trunc_f32_e32 v1, v8
+; GFX90A-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX90A-NEXT: v_cmp_eq_f32_e64 s[4:5], v1, v8
+; GFX90A-NEXT: v_bfi_b32 v0, s9, v4, v0
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v4, v0, vcc
+; GFX90A-NEXT: v_cmp_class_f32_e64 s[4:5], v10, 24
+; GFX90A-NEXT: v_cmp_neq_f32_e32 vcc, v1, v8
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc
+; GFX90A-NEXT: v_cvt_f16_f32_e32 v3, v3
; GFX90A-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX90A-NEXT: v_pack_b32_f16 v0, v0, v1
+; GFX90A-NEXT: v_pack_b32_f16 v0, v0, v3
; GFX90A-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_v2f16:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX10-NEXT: v_cvt_f32_f16_sdwa v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX10-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX10-NEXT: v_cvt_f32_f16_sdwa v3, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX10-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX10-NEXT: v_log_f32_e32 v2, v2
-; GFX10-NEXT: v_log_f32_e32 v0, v0
-; GFX10-NEXT: v_mul_legacy_f32_e32 v2, v3, v2
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX10-NEXT: v_exp_f32_e32 v1, v2
-; GFX10-NEXT: v_exp_f32_e32 v0, v0
+; GFX10-NEXT: v_cvt_f32_f16_e32 v3, v0
+; GFX10-NEXT: v_cvt_f32_f16_sdwa v8, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX10-NEXT: v_mov_b32_e32 v9, 16
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v2|
+; GFX10-NEXT: v_cmp_gt_f32_e64 s5, 0x800000, |v3|
+; GFX10-NEXT: v_trunc_f32_e32 v12, v8
+; GFX10-NEXT: v_lshlrev_b32_sdwa v9, v9, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+; GFX10-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 32, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 32, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v7, 0, 0x42000000, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v5, 0, 0x42000000, s5
+; GFX10-NEXT: s_mov_b32 s5, 0.5
+; GFX10-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX10-NEXT: v_ldexp_f32 v6, |v3|, v6
+; GFX10-NEXT: v_fma_mix_f32 v10, v1, s5, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX10-NEXT: v_cmp_class_f32_e64 s8, v2, 24
+; GFX10-NEXT: v_cmp_class_f32_e64 s9, v3, 24
+; GFX10-NEXT: v_log_f32_e32 v4, v4
+; GFX10-NEXT: v_log_f32_e32 v6, v6
+; GFX10-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX10-NEXT: v_cvt_f32_f16_e32 v7, v1
+; GFX10-NEXT: v_sub_f32_e32 v5, v6, v5
+; GFX10-NEXT: v_fma_mix_f32 v1, v1, s5, neg(0) op_sel_hi:[1,0,0]
+; GFX10-NEXT: v_cmp_neq_f32_e64 s5, v12, v8
+; GFX10-NEXT: v_mul_legacy_f32_e32 v4, v8, v4
+; GFX10-NEXT: v_trunc_f32_e32 v14, v7
+; GFX10-NEXT: v_mul_legacy_f32_e32 v5, v7, v5
+; GFX10-NEXT: v_trunc_f32_e32 v13, v1
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v4
+; GFX10-NEXT: v_cmp_eq_f32_e64 s7, v14, v7
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0xc2fc0000, v5
+; GFX10-NEXT: v_cmp_lg_f32_e64 s6, v13, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v11, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v4, v4, v6
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 0x42800000, s4
+; GFX10-NEXT: v_exp_f32_e32 v4, v4
+; GFX10-NEXT: v_add_f32_e32 v5, v5, v6
+; GFX10-NEXT: v_trunc_f32_e32 v6, v10
+; GFX10-NEXT: v_exp_f32_e32 v5, v5
+; GFX10-NEXT: v_cmp_lg_f32_e32 vcc_lo, v6, v10
+; GFX10-NEXT: v_ldexp_f32 v4, v4, v11
+; GFX10-NEXT: v_cndmask_b32_e64 v11, 0, 0xffffffc0, s4
+; GFX10-NEXT: v_cmp_eq_f32_e64 s4, v12, v8
+; GFX10-NEXT: v_bfi_b32 v6, 0x7fffffff, v4, v9
+; GFX10-NEXT: v_ldexp_f32 v5, v5, v11
+; GFX10-NEXT: s_and_b32 vcc_lo, s4, vcc_lo
+; GFX10-NEXT: s_and_b32 s4, s7, s6
+; GFX10-NEXT: v_cndmask_b32_e32 v1, v4, v6, vcc_lo
+; GFX10-NEXT: v_bfi_b32 v0, 0x7fffffff, v5, v0
+; GFX10-NEXT: v_cmp_neq_f32_e32 vcc_lo, v14, v7
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v5, v0, s4
+; GFX10-NEXT: s_and_b32 s4, s8, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s4
+; GFX10-NEXT: s_and_b32 s4, s9, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s4
; GFX10-NEXT: v_cvt_f16_f32_e32 v1, v1
; GFX10-NEXT: v_cvt_f16_f32_e32 v0, v0
; GFX10-NEXT: v_pack_b32_f16 v0, v0, v1
@@ -317,22 +1251,76 @@ define <2 x half> @v_pow_v2f16(<2 x half> %x, <2 x half> %y) {
; GFX11-TRUE16: ; %bb.0:
; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-TRUE16-NEXT: v_lshrrev_b32_e32 v2, 16, v0
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.l
-; GFX11-TRUE16-NEXT: v_lshrrev_b32_e32 v3, 16, v1
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v1.l
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v3, v0.l
+; GFX11-TRUE16-NEXT: v_lshrrev_b32_e32 v8, 16, v1
+; GFX11-TRUE16-NEXT: v_mov_b16_e32 v0.h, v0.l
; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v2, v2.l
-; GFX11-TRUE16-NEXT: v_log_f32_e32 v0, v0
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v3, v3.l
-; GFX11-TRUE16-NEXT: v_log_f32_e32 v2, v2
-; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
-; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v2, v3, v2
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-TRUE16-NEXT: v_exp_f32_e32 v1, v2
-; GFX11-TRUE16-NEXT: v_exp_f32_e32 v2, v0
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v4, v2.l
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v3|
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v8, v8.l
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s5, v3, 24
+; GFX11-TRUE16-NEXT: v_mov_b16_e32 v2.h, v2.l
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v4|
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v7, 0, 32, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s0
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s6, v4, 24
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v5, 0, 32, s1
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v7, |v3|, v7
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v9, 0, 0x42000000, s1
+; GFX11-TRUE16-NEXT: s_mov_b32 s1, 0.5
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_fma_mix_f32 v11, v1, s1, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v5, |v4|, v5
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v7, v7
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v5, v5
; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_dual_sub_f32 v6, v7, v6 :: v_dual_sub_f32 v5, v5, v9
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v9, v1.l
+; GFX11-TRUE16-NEXT: v_fma_mix_f32 v1, v1, s1, neg(0) op_sel_hi:[1,0,0]
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_dual_mul_dx9_zero_f32 v5, v8, v5 :: v_dual_mul_dx9_zero_f32 v6, v9, v6
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v12, v9
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v5
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v6
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e64 s1, v12, v9
+; GFX11-TRUE16-NEXT: v_cmp_neq_f32_e64 s3, v12, v9
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v7, 0, 0x42800000, vcc_lo
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v10, 0, 0x42800000, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v3, 0, 0xffffffc0, vcc_lo
+; GFX11-TRUE16-NEXT: v_dual_add_f32 v5, v5, v7 :: v_dual_add_f32 v6, v6, v10
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v7, v11
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v10, v1
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v5, v5
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v6, v6
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_3) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e32 vcc_lo, v7, v11
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v7, 0, 0xffffffc0, s0
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v11, v8
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e64 s0, v10, v1
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e64 s2, v11, v8
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(TRANS32_DEP_2) | instskip(NEXT) | instid1(TRANS32_DEP_1)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v3, v5, v3
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v1, v6, v7
+; GFX11-TRUE16-NEXT: v_cmp_neq_f32_e64 s4, v11, v8
+; GFX11-TRUE16-NEXT: s_and_b32 vcc_lo, s2, vcc_lo
+; GFX11-TRUE16-NEXT: v_bfi_b32 v2, 0x7fffffff, v3, v2
+; GFX11-TRUE16-NEXT: v_bfi_b32 v0, 0x7fffffff, v1, v0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e32 v2, v3, v2, vcc_lo
+; GFX11-TRUE16-NEXT: s_and_b32 vcc_lo, s1, s0
+; GFX11-TRUE16-NEXT: s_and_b32 s0, s6, s4
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc_lo
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v1, v2, 0x7fc00000, s0
+; GFX11-TRUE16-NEXT: s_and_b32 s0, s5, s3
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instid1(SALU_CYCLE_1)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v2, v0, 0x7fc00000, s0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.h, v1
; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v2
; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
@@ -341,24 +1329,78 @@ define <2 x half> @v_pow_v2f16(<2 x half> %x, <2 x half> %y) {
; GFX11-FAKE16: ; %bb.0:
; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v2, 16, v0
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v3, 16, v1
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v1, v1
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v3, v0
+; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v8, 16, v1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v4, v2
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v3|
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v8, v8
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s5, v3, 24
+; GFX11-FAKE16-NEXT: v_lshlrev_b32_e32 v2, 16, v2
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v4|
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v7, 0, 32, s0
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s0
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s6, v4, 24
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v2, v2
-; GFX11-FAKE16-NEXT: v_log_f32_e32 v0, v0
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v3, v3
-; GFX11-FAKE16-NEXT: v_log_f32_e32 v2, v2
-; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
-; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v2, v3, v2
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_exp_f32_e32 v0, v0
-; GFX11-FAKE16-NEXT: v_exp_f32_e32 v1, v2
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v5, 0, 32, s1
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v7, |v3|, v7
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v9, 0, 0x42000000, s1
+; GFX11-FAKE16-NEXT: s_mov_b32 s1, 0.5
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v11, v1, s1, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v5, |v4|, v5
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v7, v7
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v5, v5
; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GFX11-FAKE16-NEXT: v_dual_sub_f32 v6, v7, v6 :: v_dual_sub_f32 v5, v5, v9
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v9, v1
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v1, v1, s1, neg(0) op_sel_hi:[1,0,0]
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_dual_mul_dx9_zero_f32 v5, v8, v5 :: v_dual_mul_dx9_zero_f32 v6, v9, v6
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v12, v9
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v5
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v6
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e64 s1, v12, v9
+; GFX11-FAKE16-NEXT: v_cmp_neq_f32_e64 s3, v12, v9
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v7, 0, 0x42800000, vcc_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(SKIP_2) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v10, 0, 0x42800000, s0
+; GFX11-FAKE16-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v3, 0, 0xffffffc0, vcc_lo
+; GFX11-FAKE16-NEXT: v_dual_add_f32 v5, v5, v7 :: v_dual_add_f32 v6, v6, v10
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v7, v11
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v10, v1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v5, v5
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v6, v6
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_3) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e32 vcc_lo, v7, v11
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v7, 0, 0xffffffc0, s0
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v11, v8
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e64 s0, v10, v1
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e64 s2, v11, v8
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(TRANS32_DEP_2) | instskip(NEXT) | instid1(TRANS32_DEP_1)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v3, v5, v3
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v1, v6, v7
+; GFX11-FAKE16-NEXT: v_cmp_neq_f32_e64 s4, v11, v8
+; GFX11-FAKE16-NEXT: s_and_b32 vcc_lo, s2, vcc_lo
+; GFX11-FAKE16-NEXT: v_bfi_b32 v2, 0x7fffffff, v3, v2
+; GFX11-FAKE16-NEXT: v_bfi_b32 v0, 0x7fffffff, v1, v0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e32 v2, v3, v2, vcc_lo
+; GFX11-FAKE16-NEXT: s_and_b32 vcc_lo, s1, s0
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s6, s4
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v1, v2, 0x7fc00000, s0
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s5, s3
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instid1(SALU_CYCLE_1)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
; GFX11-FAKE16-NEXT: v_pack_b32_f16 v0, v0, v1
; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
@@ -373,19 +1415,70 @@ define <2 x half> @v_pow_v2f16_fneg_lhs(<2 x half> %x, <2 x half> %y) {
; GFX6-NEXT: v_xor_b32_e32 v0, 0x80008000, v0
; GFX6-NEXT: v_lshrrev_b32_e32 v2, 16, v0
; GFX6-NEXT: v_cvt_f32_f16_e32 v2, v2
-; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX6-NEXT: s_mov_b32 s8, 0x800000
; GFX6-NEXT: v_lshrrev_b32_e32 v3, 16, v1
; GFX6-NEXT: v_cvt_f32_f16_e32 v3, v3
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s8
+; GFX6-NEXT: v_cndmask_b32_e64 v4, 0, 32, vcc
+; GFX6-NEXT: v_ldexp_f32_e64 v4, |v2|, v4
+; GFX6-NEXT: v_log_f32_e32 v4, v4
+; GFX6-NEXT: v_mov_b32_e32 v5, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
+; GFX6-NEXT: s_mov_b32 s9, 0xc2fc0000
+; GFX6-NEXT: v_sub_f32_e32 v4, v4, v6
+; GFX6-NEXT: v_mul_legacy_f32_e32 v4, v3, v4
+; GFX6-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX6-NEXT: v_cmp_gt_f32_e32 vcc, s9, v4
+; GFX6-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX6-NEXT: v_add_f32_e32 v4, v4, v7
+; GFX6-NEXT: v_exp_f32_e32 v4, v4
+; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX6-NEXT: v_mul_f32_e32 v10, 0.5, v3
+; GFX6-NEXT: v_not_b32_e32 v7, 63
+; GFX6-NEXT: v_trunc_f32_e32 v9, v3
+; GFX6-NEXT: v_trunc_f32_e32 v11, v10
+; GFX6-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v9, v3
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v11, v10
+; GFX6-NEXT: v_ldexp_f32_e32 v4, v4, v8
+; GFX6-NEXT: s_brev_b32 s10, -2
+; GFX6-NEXT: s_and_b64 vcc, vcc, s[4:5]
+; GFX6-NEXT: v_cmp_lt_f32_e64 s[4:5], |v0|, s8
+; GFX6-NEXT: v_bfi_b32 v8, s10, v4, v2
+; GFX6-NEXT: v_cmp_class_f32_e64 s[6:7], v2, 24
+; GFX6-NEXT: v_cndmask_b32_e64 v2, 0, 32, s[4:5]
+; GFX6-NEXT: v_ldexp_f32_e64 v2, |v0|, v2
; GFX6-NEXT: v_log_f32_e32 v2, v2
; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v3, v2
+; GFX6-NEXT: v_cndmask_b32_e64 v5, 0, v5, s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e32 v4, v4, v8, vcc
+; GFX6-NEXT: v_sub_f32_e32 v2, v2, v5
+; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX6-NEXT: v_cmp_gt_f32_e64 s[4:5], s9, v2
+; GFX6-NEXT: v_cndmask_b32_e64 v5, 0, v6, s[4:5]
+; GFX6-NEXT: v_add_f32_e32 v2, v2, v5
; GFX6-NEXT: v_exp_f32_e32 v2, v2
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
-; GFX6-NEXT: v_cvt_f16_f32_e32 v1, v2
+; GFX6-NEXT: v_cmp_neq_f32_e32 vcc, v9, v3
+; GFX6-NEXT: v_mul_f32_e32 v6, 0.5, v1
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x7fc00000
+; GFX6-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX6-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX6-NEXT: v_trunc_f32_e32 v7, v6
+; GFX6-NEXT: v_cndmask_b32_e32 v4, v4, v3, vcc
+; GFX6-NEXT: v_cmp_lg_f32_e32 vcc, v7, v6
+; GFX6-NEXT: v_trunc_f32_e32 v6, v1
+; GFX6-NEXT: v_ldexp_f32_e32 v2, v2, v5
+; GFX6-NEXT: v_cmp_eq_f32_e64 s[4:5], v6, v1
+; GFX6-NEXT: v_bfi_b32 v5, s10, v2, v0
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v2, v2, v5, vcc
+; GFX6-NEXT: v_cmp_neq_f32_e32 vcc, v6, v1
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX6-NEXT: v_cvt_f16_f32_e32 v4, v4
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v2, v3, vcc
; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX6-NEXT: v_lshlrev_b32_e32 v1, 16, v1
+; GFX6-NEXT: v_lshlrev_b32_e32 v1, 16, v4
; GFX6-NEXT: v_or_b32_e32 v0, v0, v1
; GFX6-NEXT: s_setpc_b64 s[30:31]
;
@@ -393,69 +1486,280 @@ define <2 x half> @v_pow_v2f16_fneg_lhs(<2 x half> %x, <2 x half> %y) {
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX8-NEXT: v_cvt_f32_f16_sdwa v2, -v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX8-NEXT: v_cvt_f32_f16_e64 v0, -v0
-; GFX8-NEXT: v_cvt_f32_f16_sdwa v3, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX8-NEXT: s_mov_b32 s6, 0x800000
+; GFX8-NEXT: v_cvt_f32_f16_sdwa v4, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX8-NEXT: v_mov_b32_e32 v5, 0x42000000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s6
+; GFX8-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX8-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX8-NEXT: v_log_f32_e32 v3, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
+; GFX8-NEXT: s_mov_b32 s8, 0xc2fc0000
+; GFX8-NEXT: v_mul_f32_e32 v11, 0.5, v4
+; GFX8-NEXT: v_sub_f32_e32 v3, v3, v6
+; GFX8-NEXT: v_mul_legacy_f32_e32 v3, v4, v3
+; GFX8-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s8, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX8-NEXT: v_add_f32_e32 v3, v3, v7
+; GFX8-NEXT: v_exp_f32_e32 v3, v3
+; GFX8-NEXT: v_trunc_f32_e32 v12, v11
+; GFX8-NEXT: v_not_b32_e32 v7, 63
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v12, v11
+; GFX8-NEXT: v_cvt_f32_f16_e64 v11, -v0
+; GFX8-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX8-NEXT: v_ldexp_f32 v3, v3, v8
+; GFX8-NEXT: v_mov_b32_e32 v8, 0x8000
+; GFX8-NEXT: v_trunc_f32_e32 v10, v4
+; GFX8-NEXT: v_xor_b32_sdwa v9, v8, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+; GFX8-NEXT: s_brev_b32 s9, -2
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v10, v4
+; GFX8-NEXT: v_bfi_b32 v9, s9, v3, v9
+; GFX8-NEXT: s_and_b64 vcc, vcc, s[4:5]
+; GFX8-NEXT: v_cmp_lt_f32_e64 s[4:5], |v11|, s6
+; GFX8-NEXT: v_cndmask_b32_e32 v3, v3, v9, vcc
+; GFX8-NEXT: v_cmp_neq_f32_e32 vcc, v10, v4
+; GFX8-NEXT: v_cndmask_b32_e64 v4, 0, v5, s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e64 v5, 0, 32, s[4:5]
+; GFX8-NEXT: v_ldexp_f32 v5, |v11|, v5
+; GFX8-NEXT: v_log_f32_e32 v5, v5
; GFX8-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX8-NEXT: v_log_f32_e32 v2, v2
-; GFX8-NEXT: v_log_f32_e32 v0, v0
-; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v3, v2
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX8-NEXT: v_exp_f32_e32 v1, v2
-; GFX8-NEXT: v_exp_f32_e32 v0, v0
-; GFX8-NEXT: v_cvt_f16_f32_sdwa v1, v1 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD
+; GFX8-NEXT: v_cmp_class_f32_e64 s[6:7], v2, 24
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX8-NEXT: v_sub_f32_e32 v4, v5, v4
+; GFX8-NEXT: v_mul_legacy_f32_e32 v4, v1, v4
+; GFX8-NEXT: v_cmp_gt_f32_e64 s[4:5], s8, v4
+; GFX8-NEXT: v_cndmask_b32_e64 v5, 0, v6, s[4:5]
+; GFX8-NEXT: v_add_f32_e32 v4, v4, v5
+; GFX8-NEXT: v_exp_f32_e32 v4, v4
+; GFX8-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX8-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v3, v3, v2, vcc
+; GFX8-NEXT: v_ldexp_f32 v4, v4, v5
+; GFX8-NEXT: v_mul_f32_e32 v5, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v6, v5
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v6, v5
+; GFX8-NEXT: v_trunc_f32_e32 v5, v1
+; GFX8-NEXT: v_xor_b32_sdwa v0, v8, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; GFX8-NEXT: v_cmp_eq_f32_e64 s[4:5], v5, v1
+; GFX8-NEXT: v_bfi_b32 v0, s9, v4, v0
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v4, v0, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v11, 24
+; GFX8-NEXT: v_cmp_neq_f32_e32 vcc, v5, v1
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc
+; GFX8-NEXT: v_cvt_f16_f32_sdwa v3, v3 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD
; GFX8-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX8-NEXT: v_or_b32_e32 v0, v0, v1
+; GFX8-NEXT: v_or_b32_e32 v0, v0, v3
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: v_pow_v2f16_fneg_lhs:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_cvt_f32_f16_sdwa v2, -v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX9-NEXT: v_cvt_f32_f16_e64 v0, -v0
-; GFX9-NEXT: v_cvt_f32_f16_sdwa v3, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX9-NEXT: s_mov_b32 s6, 0x800000
+; GFX9-NEXT: v_cvt_f32_f16_sdwa v4, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX9-NEXT: v_mov_b32_e32 v5, 0x42000000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s6
+; GFX9-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX9-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX9-NEXT: v_log_f32_e32 v3, v3
+; GFX9-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
+; GFX9-NEXT: s_mov_b32 s8, 0xc2fc0000
+; GFX9-NEXT: v_mul_f32_e32 v10, 0.5, v4
+; GFX9-NEXT: v_sub_f32_e32 v3, v3, v6
+; GFX9-NEXT: v_mul_legacy_f32_e32 v3, v4, v3
+; GFX9-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, s8, v3
+; GFX9-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX9-NEXT: v_add_f32_e32 v3, v3, v7
+; GFX9-NEXT: v_exp_f32_e32 v3, v3
+; GFX9-NEXT: v_trunc_f32_e32 v11, v10
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v11, v10
+; GFX9-NEXT: v_cvt_f32_f16_e64 v10, -v0
+; GFX9-NEXT: v_not_b32_e32 v7, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX9-NEXT: s_mov_b32 s9, 0x8000
+; GFX9-NEXT: v_trunc_f32_e32 v9, v4
+; GFX9-NEXT: v_ldexp_f32 v3, v3, v8
+; GFX9-NEXT: v_xor_b32_sdwa v8, s9, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+; GFX9-NEXT: s_brev_b32 s10, -2
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v9, v4
+; GFX9-NEXT: v_bfi_b32 v8, s10, v3, v8
+; GFX9-NEXT: s_and_b64 vcc, vcc, s[4:5]
+; GFX9-NEXT: v_cmp_lt_f32_e64 s[4:5], |v10|, s6
+; GFX9-NEXT: v_cndmask_b32_e32 v3, v3, v8, vcc
+; GFX9-NEXT: v_cmp_neq_f32_e32 vcc, v9, v4
+; GFX9-NEXT: v_cndmask_b32_e64 v4, 0, v5, s[4:5]
+; GFX9-NEXT: v_cndmask_b32_e64 v5, 0, 32, s[4:5]
+; GFX9-NEXT: v_ldexp_f32 v5, |v10|, v5
+; GFX9-NEXT: v_log_f32_e32 v5, v5
; GFX9-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX9-NEXT: v_log_f32_e32 v2, v2
-; GFX9-NEXT: v_log_f32_e32 v0, v0
-; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v3, v2
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX9-NEXT: v_exp_f32_e32 v1, v2
-; GFX9-NEXT: v_exp_f32_e32 v0, v0
-; GFX9-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX9-NEXT: v_cmp_class_f32_e64 s[6:7], v2, 24
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX9-NEXT: v_sub_f32_e32 v4, v5, v4
+; GFX9-NEXT: v_mul_legacy_f32_e32 v4, v1, v4
+; GFX9-NEXT: v_cmp_gt_f32_e64 s[4:5], s8, v4
+; GFX9-NEXT: v_cndmask_b32_e64 v5, 0, v6, s[4:5]
+; GFX9-NEXT: v_add_f32_e32 v4, v4, v5
+; GFX9-NEXT: v_exp_f32_e32 v4, v4
+; GFX9-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX9-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v3, v3, v2, vcc
+; GFX9-NEXT: v_ldexp_f32 v4, v4, v5
+; GFX9-NEXT: v_mul_f32_e32 v5, 0.5, v1
+; GFX9-NEXT: v_trunc_f32_e32 v6, v5
+; GFX9-NEXT: v_cmp_lg_f32_e32 vcc, v6, v5
+; GFX9-NEXT: v_trunc_f32_e32 v5, v1
+; GFX9-NEXT: v_xor_b32_sdwa v0, s9, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; GFX9-NEXT: v_cmp_eq_f32_e64 s[4:5], v5, v1
+; GFX9-NEXT: v_bfi_b32 v0, s10, v4, v0
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v4, v0, vcc
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v10, 24
+; GFX9-NEXT: v_cmp_neq_f32_e32 vcc, v5, v1
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc
+; GFX9-NEXT: v_cvt_f16_f32_e32 v3, v3
; GFX9-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX9-NEXT: v_pack_b32_f16 v0, v0, v1
+; GFX9-NEXT: v_pack_b32_f16 v0, v0, v3
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX90A-LABEL: v_pow_v2f16_fneg_lhs:
; GFX90A: ; %bb.0:
; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX90A-NEXT: v_cvt_f32_f16_sdwa v2, -v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX90A-NEXT: v_cvt_f32_f16_e64 v0, -v0
-; GFX90A-NEXT: v_cvt_f32_f16_sdwa v3, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX90A-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX90A-NEXT: v_log_f32_e32 v2, v2
-; GFX90A-NEXT: v_log_f32_e32 v0, v0
-; GFX90A-NEXT: v_mul_legacy_f32 v2, v3, v2
-; GFX90A-NEXT: v_mul_legacy_f32 v0, v1, v0
-; GFX90A-NEXT: v_exp_f32_e32 v1, v2
-; GFX90A-NEXT: v_exp_f32_e32 v0, v0
-; GFX90A-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX90A-NEXT: s_mov_b32 s6, 0x800000
+; GFX90A-NEXT: v_cvt_f32_f16_sdwa v4, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX90A-NEXT: v_mov_b32_e32 v5, 0x42000000
+; GFX90A-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s6
+; GFX90A-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX90A-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX90A-NEXT: v_log_f32_e32 v3, v3
+; GFX90A-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
+; GFX90A-NEXT: s_mov_b32 s8, 0xc2fc0000
+; GFX90A-NEXT: s_mov_b32 s11, 0.5
+; GFX90A-NEXT: v_sub_f32_e32 v3, v3, v6
+; GFX90A-NEXT: v_mul_legacy_f32 v3, v4, v3
+; GFX90A-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX90A-NEXT: v_cmp_gt_f32_e32 vcc, s8, v3
+; GFX90A-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX90A-NEXT: v_add_f32_e32 v3, v3, v7
+; GFX90A-NEXT: v_fma_mix_f32 v9, v1, s11, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX90A-NEXT: v_exp_f32_e32 v3, v3
+; GFX90A-NEXT: v_not_b32_e32 v7, 63
+; GFX90A-NEXT: v_trunc_f32_e32 v10, v9
+; GFX90A-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX90A-NEXT: v_cmp_lg_f32_e32 vcc, v10, v9
+; GFX90A-NEXT: v_cvt_f32_f16_e64 v10, -v0
+; GFX90A-NEXT: s_mov_b32 s9, 0x8000
+; GFX90A-NEXT: v_trunc_f32_e32 v9, v4
+; GFX90A-NEXT: v_ldexp_f32 v3, v3, v8
+; GFX90A-NEXT: v_xor_b32_sdwa v8, s9, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+; GFX90A-NEXT: s_brev_b32 s10, -2
+; GFX90A-NEXT: v_cmp_eq_f32_e64 s[4:5], v9, v4
+; GFX90A-NEXT: v_bfi_b32 v8, s10, v3, v8
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cmp_lt_f32_e64 s[4:5], |v10|, s6
+; GFX90A-NEXT: v_cndmask_b32_e32 v3, v3, v8, vcc
+; GFX90A-NEXT: v_cmp_neq_f32_e32 vcc, v9, v4
+; GFX90A-NEXT: v_cndmask_b32_e64 v4, 0, v5, s[4:5]
+; GFX90A-NEXT: v_cndmask_b32_e64 v5, 0, 32, s[4:5]
+; GFX90A-NEXT: v_ldexp_f32 v5, |v10|, v5
+; GFX90A-NEXT: v_log_f32_e32 v5, v5
+; GFX90A-NEXT: v_cvt_f32_f16_e32 v8, v1
+; GFX90A-NEXT: v_cmp_class_f32_e64 s[6:7], v2, 24
+; GFX90A-NEXT: v_fma_mix_f32 v1, v1, s11, neg(0) op_sel_hi:[1,0,0]
+; GFX90A-NEXT: v_sub_f32_e32 v4, v5, v4
+; GFX90A-NEXT: v_mul_legacy_f32 v4, v8, v4
+; GFX90A-NEXT: v_cmp_gt_f32_e64 s[4:5], s8, v4
+; GFX90A-NEXT: v_cndmask_b32_e64 v5, 0, v6, s[4:5]
+; GFX90A-NEXT: v_add_f32_e32 v4, v4, v5
+; GFX90A-NEXT: v_exp_f32_e32 v4, v4
+; GFX90A-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX90A-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX90A-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX90A-NEXT: v_ldexp_f32 v4, v4, v5
+; GFX90A-NEXT: v_trunc_f32_e32 v5, v1
+; GFX90A-NEXT: v_cndmask_b32_e32 v3, v3, v2, vcc
+; GFX90A-NEXT: v_cmp_lg_f32_e32 vcc, v5, v1
+; GFX90A-NEXT: v_trunc_f32_e32 v1, v8
+; GFX90A-NEXT: v_xor_b32_sdwa v0, s9, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; GFX90A-NEXT: v_cmp_eq_f32_e64 s[4:5], v1, v8
+; GFX90A-NEXT: v_bfi_b32 v0, s10, v4, v0
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v4, v0, vcc
+; GFX90A-NEXT: v_cmp_class_f32_e64 s[4:5], v10, 24
+; GFX90A-NEXT: v_cmp_neq_f32_e32 vcc, v1, v8
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc
+; GFX90A-NEXT: v_cvt_f16_f32_e32 v3, v3
; GFX90A-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX90A-NEXT: v_pack_b32_f16 v0, v0, v1
+; GFX90A-NEXT: v_pack_b32_f16 v0, v0, v3
; GFX90A-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_v2f16_fneg_lhs:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX10-NEXT: v_cvt_f32_f16_sdwa v2, -v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX10-NEXT: v_cvt_f32_f16_e64 v0, -v0
-; GFX10-NEXT: v_cvt_f32_f16_sdwa v3, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX10-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX10-NEXT: v_log_f32_e32 v2, v2
-; GFX10-NEXT: v_log_f32_e32 v0, v0
-; GFX10-NEXT: v_mul_legacy_f32_e32 v2, v3, v2
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX10-NEXT: v_exp_f32_e32 v1, v2
-; GFX10-NEXT: v_exp_f32_e32 v0, v0
+; GFX10-NEXT: v_cvt_f32_f16_e64 v3, -v0
+; GFX10-NEXT: v_cvt_f32_f16_sdwa v8, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX10-NEXT: v_mov_b32_e32 v9, 0x8000
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v2|
+; GFX10-NEXT: v_cmp_gt_f32_e64 s5, 0x800000, |v3|
+; GFX10-NEXT: v_trunc_f32_e32 v12, v8
+; GFX10-NEXT: v_xor_b32_sdwa v10, v9, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+; GFX10-NEXT: v_xor_b32_sdwa v0, v9, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 32, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 32, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v7, 0, 0x42000000, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v5, 0, 0x42000000, s5
+; GFX10-NEXT: s_mov_b32 s5, 0.5
+; GFX10-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX10-NEXT: v_ldexp_f32 v6, |v3|, v6
+; GFX10-NEXT: v_fma_mix_f32 v11, v1, s5, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX10-NEXT: v_cmp_class_f32_e64 s8, v2, 24
+; GFX10-NEXT: v_cmp_class_f32_e64 s9, v3, 24
+; GFX10-NEXT: v_log_f32_e32 v4, v4
+; GFX10-NEXT: v_log_f32_e32 v6, v6
+; GFX10-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX10-NEXT: v_cvt_f32_f16_e32 v7, v1
+; GFX10-NEXT: v_sub_f32_e32 v5, v6, v5
+; GFX10-NEXT: v_fma_mix_f32 v1, v1, s5, neg(0) op_sel_hi:[1,0,0]
+; GFX10-NEXT: v_cmp_neq_f32_e64 s5, v12, v8
+; GFX10-NEXT: v_mul_legacy_f32_e32 v4, v8, v4
+; GFX10-NEXT: v_trunc_f32_e32 v14, v7
+; GFX10-NEXT: v_mul_legacy_f32_e32 v5, v7, v5
+; GFX10-NEXT: v_trunc_f32_e32 v13, v1
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v4
+; GFX10-NEXT: v_cmp_eq_f32_e64 s7, v14, v7
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0xc2fc0000, v5
+; GFX10-NEXT: v_cmp_lg_f32_e64 s6, v13, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v9, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v4, v4, v6
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 0x42800000, s4
+; GFX10-NEXT: v_exp_f32_e32 v4, v4
+; GFX10-NEXT: v_add_f32_e32 v5, v5, v6
+; GFX10-NEXT: v_trunc_f32_e32 v6, v11
+; GFX10-NEXT: v_exp_f32_e32 v5, v5
+; GFX10-NEXT: v_cmp_lg_f32_e32 vcc_lo, v6, v11
+; GFX10-NEXT: v_ldexp_f32 v4, v4, v9
+; GFX10-NEXT: v_cndmask_b32_e64 v9, 0, 0xffffffc0, s4
+; GFX10-NEXT: v_cmp_eq_f32_e64 s4, v12, v8
+; GFX10-NEXT: v_bfi_b32 v6, 0x7fffffff, v4, v10
+; GFX10-NEXT: v_ldexp_f32 v5, v5, v9
+; GFX10-NEXT: s_and_b32 vcc_lo, s4, vcc_lo
+; GFX10-NEXT: s_and_b32 s4, s7, s6
+; GFX10-NEXT: v_cndmask_b32_e32 v1, v4, v6, vcc_lo
+; GFX10-NEXT: v_bfi_b32 v0, 0x7fffffff, v5, v0
+; GFX10-NEXT: v_cmp_neq_f32_e32 vcc_lo, v14, v7
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v5, v0, s4
+; GFX10-NEXT: s_and_b32 s4, s8, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s4
+; GFX10-NEXT: s_and_b32 s4, s9, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s4
; GFX10-NEXT: v_cvt_f16_f32_e32 v1, v1
; GFX10-NEXT: v_cvt_f16_f32_e32 v0, v0
; GFX10-NEXT: v_pack_b32_f16 v0, v0, v1
@@ -465,22 +1769,76 @@ define <2 x half> @v_pow_v2f16_fneg_lhs(<2 x half> %x, <2 x half> %y) {
; GFX11-TRUE16: ; %bb.0:
; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-TRUE16-NEXT: v_lshrrev_b32_e32 v2, 16, v0
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e64 v0, -v0.l
-; GFX11-TRUE16-NEXT: v_lshrrev_b32_e32 v3, 16, v1
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v1.l
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e64 v3, -v0.l
+; GFX11-TRUE16-NEXT: v_lshrrev_b32_e32 v8, 16, v1
+; GFX11-TRUE16-NEXT: v_xor_b16 v0.h, 0x8000, v0.l
; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e64 v2, -v2.l
-; GFX11-TRUE16-NEXT: v_log_f32_e32 v0, v0
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v3, v3.l
-; GFX11-TRUE16-NEXT: v_log_f32_e32 v2, v2
-; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
-; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v2, v3, v2
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-TRUE16-NEXT: v_exp_f32_e32 v1, v2
-; GFX11-TRUE16-NEXT: v_exp_f32_e32 v2, v0
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e64 v4, -v2.l
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v3|
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v8, v8.l
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s5, v3, 24
+; GFX11-TRUE16-NEXT: v_xor_b16 v2.h, 0x8000, v2.l
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v4|
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v7, 0, 32, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s0
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s6, v4, 24
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v5, 0, 32, s1
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v7, |v3|, v7
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v9, 0, 0x42000000, s1
+; GFX11-TRUE16-NEXT: s_mov_b32 s1, 0.5
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_fma_mix_f32 v11, v1, s1, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v5, |v4|, v5
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v7, v7
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v5, v5
; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_dual_sub_f32 v6, v7, v6 :: v_dual_sub_f32 v5, v5, v9
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v9, v1.l
+; GFX11-TRUE16-NEXT: v_fma_mix_f32 v1, v1, s1, neg(0) op_sel_hi:[1,0,0]
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_dual_mul_dx9_zero_f32 v5, v8, v5 :: v_dual_mul_dx9_zero_f32 v6, v9, v6
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v12, v9
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v5
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v6
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e64 s1, v12, v9
+; GFX11-TRUE16-NEXT: v_cmp_neq_f32_e64 s3, v12, v9
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v7, 0, 0x42800000, vcc_lo
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v10, 0, 0x42800000, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v3, 0, 0xffffffc0, vcc_lo
+; GFX11-TRUE16-NEXT: v_dual_add_f32 v5, v5, v7 :: v_dual_add_f32 v6, v6, v10
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v7, v11
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v10, v1
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v5, v5
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v6, v6
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_3) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e32 vcc_lo, v7, v11
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v7, 0, 0xffffffc0, s0
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v11, v8
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e64 s0, v10, v1
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e64 s2, v11, v8
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(TRANS32_DEP_2) | instskip(NEXT) | instid1(TRANS32_DEP_1)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v3, v5, v3
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v1, v6, v7
+; GFX11-TRUE16-NEXT: v_cmp_neq_f32_e64 s4, v11, v8
+; GFX11-TRUE16-NEXT: s_and_b32 vcc_lo, s2, vcc_lo
+; GFX11-TRUE16-NEXT: v_bfi_b32 v2, 0x7fffffff, v3, v2
+; GFX11-TRUE16-NEXT: v_bfi_b32 v0, 0x7fffffff, v1, v0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e32 v2, v3, v2, vcc_lo
+; GFX11-TRUE16-NEXT: s_and_b32 vcc_lo, s1, s0
+; GFX11-TRUE16-NEXT: s_and_b32 s0, s6, s4
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc_lo
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v1, v2, 0x7fc00000, s0
+; GFX11-TRUE16-NEXT: s_and_b32 s0, s5, s3
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instid1(SALU_CYCLE_1)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v2, v0, 0x7fc00000, s0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.h, v1
; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v2
; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
@@ -489,24 +1847,80 @@ define <2 x half> @v_pow_v2f16_fneg_lhs(<2 x half> %x, <2 x half> %y) {
; GFX11-FAKE16: ; %bb.0:
; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v2, 16, v0
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e64 v0, -v0
-; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v3, 16, v1
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v1, v1
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e64 v3, -v0
+; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v8, 16, v1
+; GFX11-FAKE16-NEXT: v_xor_b32_e32 v0, 0x8000, v0
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e64 v2, -v2
-; GFX11-FAKE16-NEXT: v_log_f32_e32 v0, v0
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v3, v3
-; GFX11-FAKE16-NEXT: v_log_f32_e32 v2, v2
-; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
-; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v2, v3, v2
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_exp_f32_e32 v0, v0
-; GFX11-FAKE16-NEXT: v_exp_f32_e32 v1, v2
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e64 v4, -v2
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v3|
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4)
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v8, v8
+; GFX11-FAKE16-NEXT: v_xor_b32_e32 v2, 0x8000, v2
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s5, v3, 24
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v4|
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v7, 0, 32, s0
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s0
+; GFX11-FAKE16-NEXT: v_lshlrev_b32_e32 v2, 16, v2
+; GFX11-FAKE16-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v5, 0, 32, s1
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v7, |v3|, v7
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v9, 0, 0x42000000, s1
+; GFX11-FAKE16-NEXT: s_mov_b32 s1, 0.5
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s6, v4, 24
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v5, |v4|, v5
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v7, v7
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v5, v5
; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GFX11-FAKE16-NEXT: v_sub_f32_e32 v6, v7, v6
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v7, v1, s1, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX11-FAKE16-NEXT: v_sub_f32_e32 v5, v5, v9
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v9, v1
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v1, v1, s1, neg(0) op_sel_hi:[1,0,0]
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_dual_mul_dx9_zero_f32 v5, v8, v5 :: v_dual_mul_dx9_zero_f32 v6, v9, v6
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v12, v9
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v5
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v6
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e64 s1, v12, v9
+; GFX11-FAKE16-NEXT: v_cmp_neq_f32_e64 s3, v12, v9
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v10, 0, 0x42800000, vcc_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v11, 0, 0x42800000, s0
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v3, 0, 0xffffffc0, vcc_lo
+; GFX11-FAKE16-NEXT: v_dual_add_f32 v5, v5, v10 :: v_dual_add_f32 v6, v6, v11
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v10, v7
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v11, v1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v5, v5
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v6, v6
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_3) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e32 vcc_lo, v10, v7
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v7, 0, 0xffffffc0, s0
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v10, v8
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e64 s0, v11, v1
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e64 s2, v10, v8
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(TRANS32_DEP_2) | instskip(NEXT) | instid1(TRANS32_DEP_1)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v3, v5, v3
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v1, v6, v7
+; GFX11-FAKE16-NEXT: v_cmp_neq_f32_e64 s4, v10, v8
+; GFX11-FAKE16-NEXT: s_and_b32 vcc_lo, s2, vcc_lo
+; GFX11-FAKE16-NEXT: v_bfi_b32 v2, 0x7fffffff, v3, v2
+; GFX11-FAKE16-NEXT: v_bfi_b32 v0, 0x7fffffff, v1, v0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e32 v2, v3, v2, vcc_lo
+; GFX11-FAKE16-NEXT: s_and_b32 vcc_lo, s1, s0
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s6, s4
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v1, v2, 0x7fc00000, s0
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s5, s3
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instid1(SALU_CYCLE_1)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
; GFX11-FAKE16-NEXT: v_pack_b32_f16 v0, v0, v1
; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
@@ -521,20 +1935,71 @@ define <2 x half> @v_pow_v2f16_fneg_rhs(<2 x half> %x, <2 x half> %y) {
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX6-NEXT: v_lshrrev_b32_e32 v2, 16, v0
; GFX6-NEXT: v_cvt_f32_f16_e32 v2, v2
-; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX6-NEXT: s_mov_b32 s6, 0x800000
; GFX6-NEXT: v_xor_b32_e32 v1, 0x80008000, v1
; GFX6-NEXT: v_lshrrev_b32_e32 v3, 16, v1
-; GFX6-NEXT: v_log_f32_e32 v2, v2
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s6
+; GFX6-NEXT: v_cndmask_b32_e64 v4, 0, 32, vcc
+; GFX6-NEXT: v_ldexp_f32_e64 v4, |v2|, v4
+; GFX6-NEXT: v_log_f32_e32 v4, v4
; GFX6-NEXT: v_cvt_f32_f16_e32 v3, v3
+; GFX6-NEXT: v_mov_b32_e32 v5, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
+; GFX6-NEXT: v_sub_f32_e32 v4, v4, v6
+; GFX6-NEXT: v_mul_legacy_f32_e32 v4, v3, v4
+; GFX6-NEXT: s_mov_b32 s8, 0xc2fc0000
+; GFX6-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX6-NEXT: v_cmp_gt_f32_e32 vcc, s8, v4
+; GFX6-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX6-NEXT: v_add_f32_e32 v4, v4, v7
+; GFX6-NEXT: v_exp_f32_e32 v4, v4
+; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX6-NEXT: v_not_b32_e32 v7, 63
+; GFX6-NEXT: v_mul_f32_e32 v10, 0.5, v3
+; GFX6-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX6-NEXT: v_trunc_f32_e32 v9, v3
+; GFX6-NEXT: v_trunc_f32_e32 v11, v10
+; GFX6-NEXT: v_ldexp_f32_e32 v4, v4, v8
+; GFX6-NEXT: s_brev_b32 s9, -2
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v9, v3
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v11, v10
+; GFX6-NEXT: v_bfi_b32 v8, s9, v4, v2
+; GFX6-NEXT: s_and_b64 vcc, vcc, s[4:5]
+; GFX6-NEXT: v_cmp_lt_f32_e64 s[4:5], |v0|, s6
+; GFX6-NEXT: v_cndmask_b32_e32 v4, v4, v8, vcc
+; GFX6-NEXT: v_cmp_neq_f32_e32 vcc, v9, v3
+; GFX6-NEXT: v_cndmask_b32_e64 v3, 0, v5, s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e64 v5, 0, 32, s[4:5]
+; GFX6-NEXT: v_ldexp_f32_e64 v5, |v0|, v5
+; GFX6-NEXT: v_log_f32_e32 v5, v5
; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v3, v2
-; GFX6-NEXT: v_exp_f32_e32 v2, v2
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
-; GFX6-NEXT: v_cvt_f16_f32_e32 v1, v2
+; GFX6-NEXT: v_cmp_class_f32_e64 s[6:7], v2, 24
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX6-NEXT: v_sub_f32_e32 v3, v5, v3
+; GFX6-NEXT: v_mul_legacy_f32_e32 v3, v1, v3
+; GFX6-NEXT: v_cmp_gt_f32_e64 s[4:5], s8, v3
+; GFX6-NEXT: v_cndmask_b32_e64 v5, 0, v6, s[4:5]
+; GFX6-NEXT: v_add_f32_e32 v3, v3, v5
+; GFX6-NEXT: v_exp_f32_e32 v3, v3
+; GFX6-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX6-NEXT: v_mul_f32_e32 v7, 0.5, v1
+; GFX6-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX6-NEXT: v_trunc_f32_e32 v6, v1
+; GFX6-NEXT: v_trunc_f32_e32 v8, v7
+; GFX6-NEXT: v_cndmask_b32_e32 v4, v4, v2, vcc
+; GFX6-NEXT: v_ldexp_f32_e32 v3, v3, v5
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v6, v1
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v8, v7
+; GFX6-NEXT: v_bfi_b32 v5, s9, v3, v0
+; GFX6-NEXT: s_and_b64 vcc, vcc, s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e32 v3, v3, v5, vcc
+; GFX6-NEXT: v_cmp_neq_f32_e32 vcc, v6, v1
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX6-NEXT: v_cvt_f16_f32_e32 v4, v4
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v3, v2, vcc
; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX6-NEXT: v_lshlrev_b32_e32 v1, 16, v1
+; GFX6-NEXT: v_lshlrev_b32_e32 v1, 16, v4
; GFX6-NEXT: v_or_b32_e32 v0, v0, v1
; GFX6-NEXT: s_setpc_b64 s[30:31]
;
@@ -542,69 +2007,280 @@ define <2 x half> @v_pow_v2f16_fneg_rhs(<2 x half> %x, <2 x half> %y) {
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX8-NEXT: v_cvt_f32_f16_sdwa v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX8-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX8-NEXT: v_cvt_f32_f16_sdwa v3, -v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX8-NEXT: s_mov_b32 s6, 0x800000
+; GFX8-NEXT: v_cvt_f32_f16_sdwa v4, -v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX8-NEXT: v_mov_b32_e32 v5, 0x42000000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s6
+; GFX8-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX8-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX8-NEXT: v_log_f32_e32 v3, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
+; GFX8-NEXT: s_mov_b32 s8, 0xc2fc0000
+; GFX8-NEXT: v_mul_f32_e32 v10, 0.5, v4
+; GFX8-NEXT: v_sub_f32_e32 v3, v3, v6
+; GFX8-NEXT: v_mul_legacy_f32_e32 v3, v4, v3
+; GFX8-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s8, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX8-NEXT: v_add_f32_e32 v3, v3, v7
+; GFX8-NEXT: v_exp_f32_e32 v3, v3
+; GFX8-NEXT: v_trunc_f32_e32 v11, v10
+; GFX8-NEXT: v_not_b32_e32 v7, 63
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v11, v10
+; GFX8-NEXT: v_cvt_f32_f16_e32 v10, v0
+; GFX8-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX8-NEXT: v_ldexp_f32 v3, v3, v8
+; GFX8-NEXT: v_mov_b32_e32 v8, 16
+; GFX8-NEXT: v_trunc_f32_e32 v9, v4
+; GFX8-NEXT: v_lshlrev_b32_sdwa v8, v8, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+; GFX8-NEXT: s_brev_b32 s9, -2
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v9, v4
+; GFX8-NEXT: v_bfi_b32 v8, s9, v3, v8
+; GFX8-NEXT: s_and_b64 vcc, vcc, s[4:5]
+; GFX8-NEXT: v_cmp_lt_f32_e64 s[4:5], |v10|, s6
+; GFX8-NEXT: v_cndmask_b32_e32 v3, v3, v8, vcc
+; GFX8-NEXT: v_cmp_neq_f32_e32 vcc, v9, v4
+; GFX8-NEXT: v_cndmask_b32_e64 v4, 0, v5, s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e64 v5, 0, 32, s[4:5]
+; GFX8-NEXT: v_ldexp_f32 v5, |v10|, v5
+; GFX8-NEXT: v_log_f32_e32 v5, v5
; GFX8-NEXT: v_cvt_f32_f16_e64 v1, -v1
-; GFX8-NEXT: v_log_f32_e32 v2, v2
-; GFX8-NEXT: v_log_f32_e32 v0, v0
-; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v3, v2
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX8-NEXT: v_exp_f32_e32 v1, v2
-; GFX8-NEXT: v_exp_f32_e32 v0, v0
-; GFX8-NEXT: v_cvt_f16_f32_sdwa v1, v1 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD
+; GFX8-NEXT: v_cmp_class_f32_e64 s[6:7], v2, 24
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX8-NEXT: v_sub_f32_e32 v4, v5, v4
+; GFX8-NEXT: v_mul_legacy_f32_e32 v4, v1, v4
+; GFX8-NEXT: v_cmp_gt_f32_e64 s[4:5], s8, v4
+; GFX8-NEXT: v_cndmask_b32_e64 v5, 0, v6, s[4:5]
+; GFX8-NEXT: v_add_f32_e32 v4, v4, v5
+; GFX8-NEXT: v_exp_f32_e32 v4, v4
+; GFX8-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX8-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v3, v3, v2, vcc
+; GFX8-NEXT: v_ldexp_f32 v4, v4, v5
+; GFX8-NEXT: v_mul_f32_e32 v5, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v6, v5
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v6, v5
+; GFX8-NEXT: v_trunc_f32_e32 v5, v1
+; GFX8-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX8-NEXT: v_cmp_eq_f32_e64 s[4:5], v5, v1
+; GFX8-NEXT: v_bfi_b32 v0, s9, v4, v0
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v4, v0, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v10, 24
+; GFX8-NEXT: v_cmp_neq_f32_e32 vcc, v5, v1
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc
+; GFX8-NEXT: v_cvt_f16_f32_sdwa v3, v3 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD
; GFX8-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX8-NEXT: v_or_b32_e32 v0, v0, v1
+; GFX8-NEXT: v_or_b32_e32 v0, v0, v3
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: v_pow_v2f16_fneg_rhs:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_cvt_f32_f16_sdwa v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX9-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX9-NEXT: v_cvt_f32_f16_sdwa v3, -v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX9-NEXT: s_mov_b32 s6, 0x800000
+; GFX9-NEXT: v_cvt_f32_f16_sdwa v4, -v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX9-NEXT: v_mov_b32_e32 v5, 0x42000000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s6
+; GFX9-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX9-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX9-NEXT: v_log_f32_e32 v3, v3
+; GFX9-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
+; GFX9-NEXT: s_mov_b32 s8, 0xc2fc0000
+; GFX9-NEXT: v_mul_f32_e32 v10, 0.5, v4
+; GFX9-NEXT: v_sub_f32_e32 v3, v3, v6
+; GFX9-NEXT: v_mul_legacy_f32_e32 v3, v4, v3
+; GFX9-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, s8, v3
+; GFX9-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX9-NEXT: v_add_f32_e32 v3, v3, v7
+; GFX9-NEXT: v_exp_f32_e32 v3, v3
+; GFX9-NEXT: v_trunc_f32_e32 v11, v10
+; GFX9-NEXT: v_not_b32_e32 v7, 63
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v11, v10
+; GFX9-NEXT: v_cvt_f32_f16_e32 v10, v0
+; GFX9-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX9-NEXT: v_ldexp_f32 v3, v3, v8
+; GFX9-NEXT: v_mov_b32_e32 v8, 16
+; GFX9-NEXT: v_trunc_f32_e32 v9, v4
+; GFX9-NEXT: v_lshlrev_b32_sdwa v8, v8, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+; GFX9-NEXT: s_brev_b32 s9, -2
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v9, v4
+; GFX9-NEXT: v_bfi_b32 v8, s9, v3, v8
+; GFX9-NEXT: s_and_b64 vcc, vcc, s[4:5]
+; GFX9-NEXT: v_cmp_lt_f32_e64 s[4:5], |v10|, s6
+; GFX9-NEXT: v_cndmask_b32_e32 v3, v3, v8, vcc
+; GFX9-NEXT: v_cmp_neq_f32_e32 vcc, v9, v4
+; GFX9-NEXT: v_cndmask_b32_e64 v4, 0, v5, s[4:5]
+; GFX9-NEXT: v_cndmask_b32_e64 v5, 0, 32, s[4:5]
+; GFX9-NEXT: v_ldexp_f32 v5, |v10|, v5
+; GFX9-NEXT: v_log_f32_e32 v5, v5
; GFX9-NEXT: v_cvt_f32_f16_e64 v1, -v1
-; GFX9-NEXT: v_log_f32_e32 v2, v2
-; GFX9-NEXT: v_log_f32_e32 v0, v0
-; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v3, v2
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX9-NEXT: v_exp_f32_e32 v1, v2
-; GFX9-NEXT: v_exp_f32_e32 v0, v0
-; GFX9-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX9-NEXT: v_cmp_class_f32_e64 s[6:7], v2, 24
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX9-NEXT: v_sub_f32_e32 v4, v5, v4
+; GFX9-NEXT: v_mul_legacy_f32_e32 v4, v1, v4
+; GFX9-NEXT: v_cmp_gt_f32_e64 s[4:5], s8, v4
+; GFX9-NEXT: v_cndmask_b32_e64 v5, 0, v6, s[4:5]
+; GFX9-NEXT: v_add_f32_e32 v4, v4, v5
+; GFX9-NEXT: v_exp_f32_e32 v4, v4
+; GFX9-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX9-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v3, v3, v2, vcc
+; GFX9-NEXT: v_ldexp_f32 v4, v4, v5
+; GFX9-NEXT: v_mul_f32_e32 v5, 0.5, v1
+; GFX9-NEXT: v_trunc_f32_e32 v6, v5
+; GFX9-NEXT: v_cmp_lg_f32_e32 vcc, v6, v5
+; GFX9-NEXT: v_trunc_f32_e32 v5, v1
+; GFX9-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX9-NEXT: v_cmp_eq_f32_e64 s[4:5], v5, v1
+; GFX9-NEXT: v_bfi_b32 v0, s9, v4, v0
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v4, v0, vcc
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v10, 24
+; GFX9-NEXT: v_cmp_neq_f32_e32 vcc, v5, v1
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc
+; GFX9-NEXT: v_cvt_f16_f32_e32 v3, v3
; GFX9-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX9-NEXT: v_pack_b32_f16 v0, v0, v1
+; GFX9-NEXT: v_pack_b32_f16 v0, v0, v3
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX90A-LABEL: v_pow_v2f16_fneg_rhs:
; GFX90A: ; %bb.0:
; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX90A-NEXT: v_cvt_f32_f16_sdwa v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX90A-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX90A-NEXT: v_cvt_f32_f16_sdwa v3, -v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX90A-NEXT: v_cvt_f32_f16_e64 v1, -v1
-; GFX90A-NEXT: v_log_f32_e32 v2, v2
-; GFX90A-NEXT: v_log_f32_e32 v0, v0
-; GFX90A-NEXT: v_mul_legacy_f32 v2, v3, v2
-; GFX90A-NEXT: v_mul_legacy_f32 v0, v1, v0
-; GFX90A-NEXT: v_exp_f32_e32 v1, v2
-; GFX90A-NEXT: v_exp_f32_e32 v0, v0
-; GFX90A-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX90A-NEXT: s_mov_b32 s6, 0x800000
+; GFX90A-NEXT: v_cvt_f32_f16_sdwa v4, -v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX90A-NEXT: v_mov_b32_e32 v5, 0x42000000
+; GFX90A-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s6
+; GFX90A-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX90A-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX90A-NEXT: v_log_f32_e32 v3, v3
+; GFX90A-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
+; GFX90A-NEXT: s_mov_b32 s8, 0xc2fc0000
+; GFX90A-NEXT: s_mov_b32 s10, 0.5
+; GFX90A-NEXT: v_sub_f32_e32 v3, v3, v6
+; GFX90A-NEXT: v_mul_legacy_f32 v3, v4, v3
+; GFX90A-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX90A-NEXT: v_cmp_gt_f32_e32 vcc, s8, v3
+; GFX90A-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX90A-NEXT: v_add_f32_e32 v3, v3, v7
+; GFX90A-NEXT: v_exp_f32_e32 v3, v3
+; GFX90A-NEXT: v_fma_mix_f32 v9, -v1, s10, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX90A-NEXT: v_not_b32_e32 v7, 63
+; GFX90A-NEXT: v_trunc_f32_e32 v10, v9
+; GFX90A-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX90A-NEXT: v_cmp_lg_f32_e32 vcc, v10, v9
+; GFX90A-NEXT: v_cvt_f32_f16_e32 v10, v0
+; GFX90A-NEXT: v_ldexp_f32 v3, v3, v8
+; GFX90A-NEXT: v_mov_b32_e32 v8, 16
+; GFX90A-NEXT: v_trunc_f32_e32 v9, v4
+; GFX90A-NEXT: v_lshlrev_b32_sdwa v8, v8, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+; GFX90A-NEXT: s_brev_b32 s9, -2
+; GFX90A-NEXT: v_cmp_eq_f32_e64 s[4:5], v9, v4
+; GFX90A-NEXT: v_bfi_b32 v8, s9, v3, v8
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cmp_lt_f32_e64 s[4:5], |v10|, s6
+; GFX90A-NEXT: v_cndmask_b32_e32 v3, v3, v8, vcc
+; GFX90A-NEXT: v_cmp_neq_f32_e32 vcc, v9, v4
+; GFX90A-NEXT: v_cndmask_b32_e64 v4, 0, v5, s[4:5]
+; GFX90A-NEXT: v_cndmask_b32_e64 v5, 0, 32, s[4:5]
+; GFX90A-NEXT: v_ldexp_f32 v5, |v10|, v5
+; GFX90A-NEXT: v_log_f32_e32 v5, v5
+; GFX90A-NEXT: v_cvt_f32_f16_e64 v8, -v1
+; GFX90A-NEXT: v_cmp_class_f32_e64 s[6:7], v2, 24
+; GFX90A-NEXT: v_fma_mix_f32 v1, -v1, s10, neg(0) op_sel_hi:[1,0,0]
+; GFX90A-NEXT: v_sub_f32_e32 v4, v5, v4
+; GFX90A-NEXT: v_mul_legacy_f32 v4, v8, v4
+; GFX90A-NEXT: v_cmp_gt_f32_e64 s[4:5], s8, v4
+; GFX90A-NEXT: v_cndmask_b32_e64 v5, 0, v6, s[4:5]
+; GFX90A-NEXT: v_add_f32_e32 v4, v4, v5
+; GFX90A-NEXT: v_exp_f32_e32 v4, v4
+; GFX90A-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX90A-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX90A-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX90A-NEXT: v_ldexp_f32 v4, v4, v5
+; GFX90A-NEXT: v_trunc_f32_e32 v5, v1
+; GFX90A-NEXT: v_cndmask_b32_e32 v3, v3, v2, vcc
+; GFX90A-NEXT: v_cmp_lg_f32_e32 vcc, v5, v1
+; GFX90A-NEXT: v_trunc_f32_e32 v1, v8
+; GFX90A-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX90A-NEXT: v_cmp_eq_f32_e64 s[4:5], v1, v8
+; GFX90A-NEXT: v_bfi_b32 v0, s9, v4, v0
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v4, v0, vcc
+; GFX90A-NEXT: v_cmp_class_f32_e64 s[4:5], v10, 24
+; GFX90A-NEXT: v_cmp_neq_f32_e32 vcc, v1, v8
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc
+; GFX90A-NEXT: v_cvt_f16_f32_e32 v3, v3
; GFX90A-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX90A-NEXT: v_pack_b32_f16 v0, v0, v1
+; GFX90A-NEXT: v_pack_b32_f16 v0, v0, v3
; GFX90A-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_v2f16_fneg_rhs:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX10-NEXT: v_cvt_f32_f16_sdwa v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX10-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX10-NEXT: v_cvt_f32_f16_sdwa v3, -v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX10-NEXT: v_cvt_f32_f16_e64 v1, -v1
-; GFX10-NEXT: v_log_f32_e32 v2, v2
-; GFX10-NEXT: v_log_f32_e32 v0, v0
-; GFX10-NEXT: v_mul_legacy_f32_e32 v2, v3, v2
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX10-NEXT: v_exp_f32_e32 v1, v2
-; GFX10-NEXT: v_exp_f32_e32 v0, v0
+; GFX10-NEXT: v_cvt_f32_f16_e32 v3, v0
+; GFX10-NEXT: v_cvt_f32_f16_sdwa v8, -v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX10-NEXT: v_mov_b32_e32 v9, 16
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v2|
+; GFX10-NEXT: v_cmp_gt_f32_e64 s5, 0x800000, |v3|
+; GFX10-NEXT: v_trunc_f32_e32 v12, v8
+; GFX10-NEXT: v_lshlrev_b32_sdwa v9, v9, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+; GFX10-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 32, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 32, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v7, 0, 0x42000000, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v5, 0, 0x42000000, s5
+; GFX10-NEXT: s_mov_b32 s5, 0.5
+; GFX10-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX10-NEXT: v_ldexp_f32 v6, |v3|, v6
+; GFX10-NEXT: v_fma_mix_f32 v10, -v1, s5, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX10-NEXT: v_cmp_class_f32_e64 s8, v2, 24
+; GFX10-NEXT: v_cmp_class_f32_e64 s9, v3, 24
+; GFX10-NEXT: v_log_f32_e32 v4, v4
+; GFX10-NEXT: v_log_f32_e32 v6, v6
+; GFX10-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX10-NEXT: v_cvt_f32_f16_e64 v7, -v1
+; GFX10-NEXT: v_sub_f32_e32 v5, v6, v5
+; GFX10-NEXT: v_fma_mix_f32 v1, -v1, s5, neg(0) op_sel_hi:[1,0,0]
+; GFX10-NEXT: v_cmp_neq_f32_e64 s5, v12, v8
+; GFX10-NEXT: v_mul_legacy_f32_e32 v4, v8, v4
+; GFX10-NEXT: v_trunc_f32_e32 v14, v7
+; GFX10-NEXT: v_mul_legacy_f32_e32 v5, v7, v5
+; GFX10-NEXT: v_trunc_f32_e32 v13, v1
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v4
+; GFX10-NEXT: v_cmp_eq_f32_e64 s7, v14, v7
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0xc2fc0000, v5
+; GFX10-NEXT: v_cmp_lg_f32_e64 s6, v13, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v11, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v4, v4, v6
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 0x42800000, s4
+; GFX10-NEXT: v_exp_f32_e32 v4, v4
+; GFX10-NEXT: v_add_f32_e32 v5, v5, v6
+; GFX10-NEXT: v_trunc_f32_e32 v6, v10
+; GFX10-NEXT: v_exp_f32_e32 v5, v5
+; GFX10-NEXT: v_cmp_lg_f32_e32 vcc_lo, v6, v10
+; GFX10-NEXT: v_ldexp_f32 v4, v4, v11
+; GFX10-NEXT: v_cndmask_b32_e64 v11, 0, 0xffffffc0, s4
+; GFX10-NEXT: v_cmp_eq_f32_e64 s4, v12, v8
+; GFX10-NEXT: v_bfi_b32 v6, 0x7fffffff, v4, v9
+; GFX10-NEXT: v_ldexp_f32 v5, v5, v11
+; GFX10-NEXT: s_and_b32 vcc_lo, s4, vcc_lo
+; GFX10-NEXT: s_and_b32 s4, s7, s6
+; GFX10-NEXT: v_cndmask_b32_e32 v1, v4, v6, vcc_lo
+; GFX10-NEXT: v_bfi_b32 v0, 0x7fffffff, v5, v0
+; GFX10-NEXT: v_cmp_neq_f32_e32 vcc_lo, v14, v7
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v5, v0, s4
+; GFX10-NEXT: s_and_b32 s4, s8, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s4
+; GFX10-NEXT: s_and_b32 s4, s9, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s4
; GFX10-NEXT: v_cvt_f16_f32_e32 v1, v1
; GFX10-NEXT: v_cvt_f16_f32_e32 v0, v0
; GFX10-NEXT: v_pack_b32_f16 v0, v0, v1
@@ -614,22 +2290,76 @@ define <2 x half> @v_pow_v2f16_fneg_rhs(<2 x half> %x, <2 x half> %y) {
; GFX11-TRUE16: ; %bb.0:
; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-TRUE16-NEXT: v_lshrrev_b32_e32 v2, 16, v0
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.l
-; GFX11-TRUE16-NEXT: v_lshrrev_b32_e32 v3, 16, v1
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e64 v1, -v1.l
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v3, v0.l
+; GFX11-TRUE16-NEXT: v_lshrrev_b32_e32 v8, 16, v1
+; GFX11-TRUE16-NEXT: v_mov_b16_e32 v0.h, v0.l
; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v2, v2.l
-; GFX11-TRUE16-NEXT: v_log_f32_e32 v0, v0
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e64 v3, -v3.l
-; GFX11-TRUE16-NEXT: v_log_f32_e32 v2, v2
-; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
-; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v2, v3, v2
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-TRUE16-NEXT: v_exp_f32_e32 v1, v2
-; GFX11-TRUE16-NEXT: v_exp_f32_e32 v2, v0
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v4, v2.l
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v3|
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e64 v8, -v8.l
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s5, v3, 24
+; GFX11-TRUE16-NEXT: v_mov_b16_e32 v2.h, v2.l
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v4|
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v7, 0, 32, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s0
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s6, v4, 24
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v5, 0, 32, s1
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v7, |v3|, v7
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v9, 0, 0x42000000, s1
+; GFX11-TRUE16-NEXT: s_mov_b32 s1, 0.5
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_fma_mix_f32 v11, -v1, s1, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v5, |v4|, v5
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v7, v7
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v5, v5
; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_dual_sub_f32 v6, v7, v6 :: v_dual_sub_f32 v5, v5, v9
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e64 v9, -v1.l
+; GFX11-TRUE16-NEXT: v_fma_mix_f32 v1, -v1, s1, neg(0) op_sel_hi:[1,0,0]
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_dual_mul_dx9_zero_f32 v5, v8, v5 :: v_dual_mul_dx9_zero_f32 v6, v9, v6
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v12, v9
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v5
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v6
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e64 s1, v12, v9
+; GFX11-TRUE16-NEXT: v_cmp_neq_f32_e64 s3, v12, v9
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v7, 0, 0x42800000, vcc_lo
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v10, 0, 0x42800000, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v3, 0, 0xffffffc0, vcc_lo
+; GFX11-TRUE16-NEXT: v_dual_add_f32 v5, v5, v7 :: v_dual_add_f32 v6, v6, v10
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v7, v11
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v10, v1
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v5, v5
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v6, v6
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_3) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e32 vcc_lo, v7, v11
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v7, 0, 0xffffffc0, s0
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v11, v8
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e64 s0, v10, v1
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e64 s2, v11, v8
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(TRANS32_DEP_2) | instskip(NEXT) | instid1(TRANS32_DEP_1)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v3, v5, v3
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v1, v6, v7
+; GFX11-TRUE16-NEXT: v_cmp_neq_f32_e64 s4, v11, v8
+; GFX11-TRUE16-NEXT: s_and_b32 vcc_lo, s2, vcc_lo
+; GFX11-TRUE16-NEXT: v_bfi_b32 v2, 0x7fffffff, v3, v2
+; GFX11-TRUE16-NEXT: v_bfi_b32 v0, 0x7fffffff, v1, v0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e32 v2, v3, v2, vcc_lo
+; GFX11-TRUE16-NEXT: s_and_b32 vcc_lo, s1, s0
+; GFX11-TRUE16-NEXT: s_and_b32 s0, s6, s4
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc_lo
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v1, v2, 0x7fc00000, s0
+; GFX11-TRUE16-NEXT: s_and_b32 s0, s5, s3
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instid1(SALU_CYCLE_1)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v2, v0, 0x7fc00000, s0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.h, v1
; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v2
; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
@@ -638,24 +2368,78 @@ define <2 x half> @v_pow_v2f16_fneg_rhs(<2 x half> %x, <2 x half> %y) {
; GFX11-FAKE16: ; %bb.0:
; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v2, 16, v0
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v3, 16, v1
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e64 v1, -v1
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v3, v0
+; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v8, 16, v1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v4, v2
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v3|
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e64 v8, -v8
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s5, v3, 24
+; GFX11-FAKE16-NEXT: v_lshlrev_b32_e32 v2, 16, v2
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v4|
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v7, 0, 32, s0
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s0
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s6, v4, 24
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v2, v2
-; GFX11-FAKE16-NEXT: v_log_f32_e32 v0, v0
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e64 v3, -v3
-; GFX11-FAKE16-NEXT: v_log_f32_e32 v2, v2
-; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
-; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v2, v3, v2
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_exp_f32_e32 v0, v0
-; GFX11-FAKE16-NEXT: v_exp_f32_e32 v1, v2
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v5, 0, 32, s1
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v7, |v3|, v7
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v9, 0, 0x42000000, s1
+; GFX11-FAKE16-NEXT: s_mov_b32 s1, 0.5
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v11, -v1, s1, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v5, |v4|, v5
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v7, v7
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v5, v5
; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GFX11-FAKE16-NEXT: v_dual_sub_f32 v6, v7, v6 :: v_dual_sub_f32 v5, v5, v9
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e64 v9, -v1
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v1, -v1, s1, neg(0) op_sel_hi:[1,0,0]
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_dual_mul_dx9_zero_f32 v5, v8, v5 :: v_dual_mul_dx9_zero_f32 v6, v9, v6
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v12, v9
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v5
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v6
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e64 s1, v12, v9
+; GFX11-FAKE16-NEXT: v_cmp_neq_f32_e64 s3, v12, v9
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v7, 0, 0x42800000, vcc_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(SKIP_2) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v10, 0, 0x42800000, s0
+; GFX11-FAKE16-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v3, 0, 0xffffffc0, vcc_lo
+; GFX11-FAKE16-NEXT: v_dual_add_f32 v5, v5, v7 :: v_dual_add_f32 v6, v6, v10
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v7, v11
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v10, v1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v5, v5
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v6, v6
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_3) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e32 vcc_lo, v7, v11
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v7, 0, 0xffffffc0, s0
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v11, v8
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e64 s0, v10, v1
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e64 s2, v11, v8
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(TRANS32_DEP_2) | instskip(NEXT) | instid1(TRANS32_DEP_1)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v3, v5, v3
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v1, v6, v7
+; GFX11-FAKE16-NEXT: v_cmp_neq_f32_e64 s4, v11, v8
+; GFX11-FAKE16-NEXT: s_and_b32 vcc_lo, s2, vcc_lo
+; GFX11-FAKE16-NEXT: v_bfi_b32 v2, 0x7fffffff, v3, v2
+; GFX11-FAKE16-NEXT: v_bfi_b32 v0, 0x7fffffff, v1, v0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e32 v2, v3, v2, vcc_lo
+; GFX11-FAKE16-NEXT: s_and_b32 vcc_lo, s1, s0
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s6, s4
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v1, v2, 0x7fc00000, s0
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s5, s3
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instid1(SALU_CYCLE_1)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
; GFX11-FAKE16-NEXT: v_pack_b32_f16 v0, v0, v1
; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
@@ -671,20 +2455,71 @@ define <2 x half> @v_pow_v2f16_fneg_lhs_rhs(<2 x half> %x, <2 x half> %y) {
; GFX6-NEXT: v_xor_b32_e32 v0, 0x80008000, v0
; GFX6-NEXT: v_lshrrev_b32_e32 v2, 16, v0
; GFX6-NEXT: v_cvt_f32_f16_e32 v2, v2
-; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX6-NEXT: s_mov_b32 s8, 0x800000
; GFX6-NEXT: v_xor_b32_e32 v1, 0x80008000, v1
; GFX6-NEXT: v_lshrrev_b32_e32 v3, 16, v1
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s8
+; GFX6-NEXT: v_cndmask_b32_e64 v4, 0, 32, vcc
+; GFX6-NEXT: v_ldexp_f32_e64 v4, |v2|, v4
+; GFX6-NEXT: v_log_f32_e32 v4, v4
; GFX6-NEXT: v_cvt_f32_f16_e32 v3, v3
+; GFX6-NEXT: v_mov_b32_e32 v5, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
+; GFX6-NEXT: v_sub_f32_e32 v4, v4, v6
+; GFX6-NEXT: v_mul_legacy_f32_e32 v4, v3, v4
+; GFX6-NEXT: s_mov_b32 s9, 0xc2fc0000
+; GFX6-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX6-NEXT: v_cmp_gt_f32_e32 vcc, s9, v4
+; GFX6-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX6-NEXT: v_add_f32_e32 v4, v4, v7
+; GFX6-NEXT: v_exp_f32_e32 v4, v4
+; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX6-NEXT: v_mul_f32_e32 v10, 0.5, v3
+; GFX6-NEXT: v_not_b32_e32 v7, 63
+; GFX6-NEXT: v_trunc_f32_e32 v9, v3
+; GFX6-NEXT: v_trunc_f32_e32 v11, v10
+; GFX6-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v9, v3
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v11, v10
+; GFX6-NEXT: v_ldexp_f32_e32 v4, v4, v8
+; GFX6-NEXT: s_brev_b32 s10, -2
+; GFX6-NEXT: s_and_b64 vcc, vcc, s[4:5]
+; GFX6-NEXT: v_cmp_lt_f32_e64 s[4:5], |v0|, s8
+; GFX6-NEXT: v_bfi_b32 v8, s10, v4, v2
+; GFX6-NEXT: v_cmp_class_f32_e64 s[6:7], v2, 24
+; GFX6-NEXT: v_cndmask_b32_e64 v2, 0, 32, s[4:5]
+; GFX6-NEXT: v_ldexp_f32_e64 v2, |v0|, v2
; GFX6-NEXT: v_log_f32_e32 v2, v2
; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v1
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v3, v2
+; GFX6-NEXT: v_cndmask_b32_e64 v5, 0, v5, s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e32 v4, v4, v8, vcc
+; GFX6-NEXT: v_sub_f32_e32 v2, v2, v5
+; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX6-NEXT: v_cmp_gt_f32_e64 s[4:5], s9, v2
+; GFX6-NEXT: v_cndmask_b32_e64 v5, 0, v6, s[4:5]
+; GFX6-NEXT: v_add_f32_e32 v2, v2, v5
; GFX6-NEXT: v_exp_f32_e32 v2, v2
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
-; GFX6-NEXT: v_cvt_f16_f32_e32 v1, v2
+; GFX6-NEXT: v_cmp_neq_f32_e32 vcc, v9, v3
+; GFX6-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX6-NEXT: v_mul_f32_e32 v7, 0.5, v1
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x7fc00000
+; GFX6-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX6-NEXT: v_trunc_f32_e32 v6, v1
+; GFX6-NEXT: v_trunc_f32_e32 v8, v7
+; GFX6-NEXT: v_cndmask_b32_e32 v4, v4, v3, vcc
+; GFX6-NEXT: v_ldexp_f32_e32 v2, v2, v5
+; GFX6-NEXT: v_cmp_eq_f32_e32 vcc, v6, v1
+; GFX6-NEXT: v_cmp_lg_f32_e64 s[4:5], v8, v7
+; GFX6-NEXT: v_bfi_b32 v5, s10, v2, v0
+; GFX6-NEXT: s_and_b64 vcc, vcc, s[4:5]
+; GFX6-NEXT: v_cndmask_b32_e32 v2, v2, v5, vcc
+; GFX6-NEXT: v_cmp_neq_f32_e32 vcc, v6, v1
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX6-NEXT: v_cvt_f16_f32_e32 v4, v4
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v2, v3, vcc
; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX6-NEXT: v_lshlrev_b32_e32 v1, 16, v1
+; GFX6-NEXT: v_lshlrev_b32_e32 v1, 16, v4
; GFX6-NEXT: v_or_b32_e32 v0, v0, v1
; GFX6-NEXT: s_setpc_b64 s[30:31]
;
@@ -692,69 +2527,280 @@ define <2 x half> @v_pow_v2f16_fneg_lhs_rhs(<2 x half> %x, <2 x half> %y) {
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX8-NEXT: v_cvt_f32_f16_sdwa v2, -v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX8-NEXT: v_cvt_f32_f16_e64 v0, -v0
-; GFX8-NEXT: v_cvt_f32_f16_sdwa v3, -v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX8-NEXT: s_mov_b32 s6, 0x800000
+; GFX8-NEXT: v_cvt_f32_f16_sdwa v4, -v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX8-NEXT: v_mov_b32_e32 v5, 0x42000000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s6
+; GFX8-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX8-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX8-NEXT: v_log_f32_e32 v3, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
+; GFX8-NEXT: s_mov_b32 s8, 0xc2fc0000
+; GFX8-NEXT: v_mul_f32_e32 v11, 0.5, v4
+; GFX8-NEXT: v_sub_f32_e32 v3, v3, v6
+; GFX8-NEXT: v_mul_legacy_f32_e32 v3, v4, v3
+; GFX8-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s8, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX8-NEXT: v_add_f32_e32 v3, v3, v7
+; GFX8-NEXT: v_exp_f32_e32 v3, v3
+; GFX8-NEXT: v_trunc_f32_e32 v12, v11
+; GFX8-NEXT: v_not_b32_e32 v7, 63
+; GFX8-NEXT: v_cmp_lg_f32_e64 s[4:5], v12, v11
+; GFX8-NEXT: v_cvt_f32_f16_e64 v11, -v0
+; GFX8-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX8-NEXT: v_ldexp_f32 v3, v3, v8
+; GFX8-NEXT: v_mov_b32_e32 v8, 0x8000
+; GFX8-NEXT: v_trunc_f32_e32 v10, v4
+; GFX8-NEXT: v_xor_b32_sdwa v9, v8, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+; GFX8-NEXT: s_brev_b32 s9, -2
+; GFX8-NEXT: v_cmp_eq_f32_e32 vcc, v10, v4
+; GFX8-NEXT: v_bfi_b32 v9, s9, v3, v9
+; GFX8-NEXT: s_and_b64 vcc, vcc, s[4:5]
+; GFX8-NEXT: v_cmp_lt_f32_e64 s[4:5], |v11|, s6
+; GFX8-NEXT: v_cndmask_b32_e32 v3, v3, v9, vcc
+; GFX8-NEXT: v_cmp_neq_f32_e32 vcc, v10, v4
+; GFX8-NEXT: v_cndmask_b32_e64 v4, 0, v5, s[4:5]
+; GFX8-NEXT: v_cndmask_b32_e64 v5, 0, 32, s[4:5]
+; GFX8-NEXT: v_ldexp_f32 v5, |v11|, v5
+; GFX8-NEXT: v_log_f32_e32 v5, v5
; GFX8-NEXT: v_cvt_f32_f16_e64 v1, -v1
-; GFX8-NEXT: v_log_f32_e32 v2, v2
-; GFX8-NEXT: v_log_f32_e32 v0, v0
-; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v3, v2
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX8-NEXT: v_exp_f32_e32 v1, v2
-; GFX8-NEXT: v_exp_f32_e32 v0, v0
-; GFX8-NEXT: v_cvt_f16_f32_sdwa v1, v1 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD
+; GFX8-NEXT: v_cmp_class_f32_e64 s[6:7], v2, 24
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX8-NEXT: v_sub_f32_e32 v4, v5, v4
+; GFX8-NEXT: v_mul_legacy_f32_e32 v4, v1, v4
+; GFX8-NEXT: v_cmp_gt_f32_e64 s[4:5], s8, v4
+; GFX8-NEXT: v_cndmask_b32_e64 v5, 0, v6, s[4:5]
+; GFX8-NEXT: v_add_f32_e32 v4, v4, v5
+; GFX8-NEXT: v_exp_f32_e32 v4, v4
+; GFX8-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX8-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v3, v3, v2, vcc
+; GFX8-NEXT: v_ldexp_f32 v4, v4, v5
+; GFX8-NEXT: v_mul_f32_e32 v5, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v6, v5
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v6, v5
+; GFX8-NEXT: v_trunc_f32_e32 v5, v1
+; GFX8-NEXT: v_xor_b32_sdwa v0, v8, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; GFX8-NEXT: v_cmp_eq_f32_e64 s[4:5], v5, v1
+; GFX8-NEXT: v_bfi_b32 v0, s9, v4, v0
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v4, v0, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v11, 24
+; GFX8-NEXT: v_cmp_neq_f32_e32 vcc, v5, v1
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc
+; GFX8-NEXT: v_cvt_f16_f32_sdwa v3, v3 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD
; GFX8-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX8-NEXT: v_or_b32_e32 v0, v0, v1
+; GFX8-NEXT: v_or_b32_e32 v0, v0, v3
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: v_pow_v2f16_fneg_lhs_rhs:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_cvt_f32_f16_sdwa v2, -v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX9-NEXT: v_cvt_f32_f16_e64 v0, -v0
-; GFX9-NEXT: v_cvt_f32_f16_sdwa v3, -v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX9-NEXT: s_mov_b32 s6, 0x800000
+; GFX9-NEXT: v_cvt_f32_f16_sdwa v4, -v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX9-NEXT: v_mov_b32_e32 v5, 0x42000000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s6
+; GFX9-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX9-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX9-NEXT: v_log_f32_e32 v3, v3
+; GFX9-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
+; GFX9-NEXT: s_mov_b32 s8, 0xc2fc0000
+; GFX9-NEXT: v_mul_f32_e32 v10, 0.5, v4
+; GFX9-NEXT: v_sub_f32_e32 v3, v3, v6
+; GFX9-NEXT: v_mul_legacy_f32_e32 v3, v4, v3
+; GFX9-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, s8, v3
+; GFX9-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX9-NEXT: v_add_f32_e32 v3, v3, v7
+; GFX9-NEXT: v_exp_f32_e32 v3, v3
+; GFX9-NEXT: v_trunc_f32_e32 v11, v10
+; GFX9-NEXT: v_cmp_lg_f32_e64 s[4:5], v11, v10
+; GFX9-NEXT: v_cvt_f32_f16_e64 v10, -v0
+; GFX9-NEXT: v_not_b32_e32 v7, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX9-NEXT: s_mov_b32 s9, 0x8000
+; GFX9-NEXT: v_trunc_f32_e32 v9, v4
+; GFX9-NEXT: v_ldexp_f32 v3, v3, v8
+; GFX9-NEXT: v_xor_b32_sdwa v8, s9, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+; GFX9-NEXT: s_brev_b32 s10, -2
+; GFX9-NEXT: v_cmp_eq_f32_e32 vcc, v9, v4
+; GFX9-NEXT: v_bfi_b32 v8, s10, v3, v8
+; GFX9-NEXT: s_and_b64 vcc, vcc, s[4:5]
+; GFX9-NEXT: v_cmp_lt_f32_e64 s[4:5], |v10|, s6
+; GFX9-NEXT: v_cndmask_b32_e32 v3, v3, v8, vcc
+; GFX9-NEXT: v_cmp_neq_f32_e32 vcc, v9, v4
+; GFX9-NEXT: v_cndmask_b32_e64 v4, 0, v5, s[4:5]
+; GFX9-NEXT: v_cndmask_b32_e64 v5, 0, 32, s[4:5]
+; GFX9-NEXT: v_ldexp_f32 v5, |v10|, v5
+; GFX9-NEXT: v_log_f32_e32 v5, v5
; GFX9-NEXT: v_cvt_f32_f16_e64 v1, -v1
-; GFX9-NEXT: v_log_f32_e32 v2, v2
-; GFX9-NEXT: v_log_f32_e32 v0, v0
-; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v3, v2
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX9-NEXT: v_exp_f32_e32 v1, v2
-; GFX9-NEXT: v_exp_f32_e32 v0, v0
-; GFX9-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX9-NEXT: v_cmp_class_f32_e64 s[6:7], v2, 24
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX9-NEXT: v_sub_f32_e32 v4, v5, v4
+; GFX9-NEXT: v_mul_legacy_f32_e32 v4, v1, v4
+; GFX9-NEXT: v_cmp_gt_f32_e64 s[4:5], s8, v4
+; GFX9-NEXT: v_cndmask_b32_e64 v5, 0, v6, s[4:5]
+; GFX9-NEXT: v_add_f32_e32 v4, v4, v5
+; GFX9-NEXT: v_exp_f32_e32 v4, v4
+; GFX9-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX9-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v3, v3, v2, vcc
+; GFX9-NEXT: v_ldexp_f32 v4, v4, v5
+; GFX9-NEXT: v_mul_f32_e32 v5, 0.5, v1
+; GFX9-NEXT: v_trunc_f32_e32 v6, v5
+; GFX9-NEXT: v_cmp_lg_f32_e32 vcc, v6, v5
+; GFX9-NEXT: v_trunc_f32_e32 v5, v1
+; GFX9-NEXT: v_xor_b32_sdwa v0, s9, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; GFX9-NEXT: v_cmp_eq_f32_e64 s[4:5], v5, v1
+; GFX9-NEXT: v_bfi_b32 v0, s10, v4, v0
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v4, v0, vcc
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v10, 24
+; GFX9-NEXT: v_cmp_neq_f32_e32 vcc, v5, v1
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc
+; GFX9-NEXT: v_cvt_f16_f32_e32 v3, v3
; GFX9-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX9-NEXT: v_pack_b32_f16 v0, v0, v1
+; GFX9-NEXT: v_pack_b32_f16 v0, v0, v3
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX90A-LABEL: v_pow_v2f16_fneg_lhs_rhs:
; GFX90A: ; %bb.0:
; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX90A-NEXT: v_cvt_f32_f16_sdwa v2, -v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX90A-NEXT: v_cvt_f32_f16_e64 v0, -v0
-; GFX90A-NEXT: v_cvt_f32_f16_sdwa v3, -v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX90A-NEXT: v_cvt_f32_f16_e64 v1, -v1
-; GFX90A-NEXT: v_log_f32_e32 v2, v2
-; GFX90A-NEXT: v_log_f32_e32 v0, v0
-; GFX90A-NEXT: v_mul_legacy_f32 v2, v3, v2
-; GFX90A-NEXT: v_mul_legacy_f32 v0, v1, v0
-; GFX90A-NEXT: v_exp_f32_e32 v1, v2
-; GFX90A-NEXT: v_exp_f32_e32 v0, v0
-; GFX90A-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX90A-NEXT: s_mov_b32 s6, 0x800000
+; GFX90A-NEXT: v_cvt_f32_f16_sdwa v4, -v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX90A-NEXT: v_mov_b32_e32 v5, 0x42000000
+; GFX90A-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s6
+; GFX90A-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX90A-NEXT: v_ldexp_f32 v3, |v2|, v3
+; GFX90A-NEXT: v_log_f32_e32 v3, v3
+; GFX90A-NEXT: v_cndmask_b32_e32 v6, 0, v5, vcc
+; GFX90A-NEXT: s_mov_b32 s8, 0xc2fc0000
+; GFX90A-NEXT: s_mov_b32 s11, 0.5
+; GFX90A-NEXT: v_sub_f32_e32 v3, v3, v6
+; GFX90A-NEXT: v_mul_legacy_f32 v3, v4, v3
+; GFX90A-NEXT: v_mov_b32_e32 v6, 0x42800000
+; GFX90A-NEXT: v_cmp_gt_f32_e32 vcc, s8, v3
+; GFX90A-NEXT: v_cndmask_b32_e32 v7, 0, v6, vcc
+; GFX90A-NEXT: v_add_f32_e32 v3, v3, v7
+; GFX90A-NEXT: v_fma_mix_f32 v9, -v1, s11, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX90A-NEXT: v_exp_f32_e32 v3, v3
+; GFX90A-NEXT: v_not_b32_e32 v7, 63
+; GFX90A-NEXT: v_trunc_f32_e32 v10, v9
+; GFX90A-NEXT: v_cndmask_b32_e32 v8, 0, v7, vcc
+; GFX90A-NEXT: v_cmp_lg_f32_e32 vcc, v10, v9
+; GFX90A-NEXT: v_cvt_f32_f16_e64 v10, -v0
+; GFX90A-NEXT: s_mov_b32 s9, 0x8000
+; GFX90A-NEXT: v_trunc_f32_e32 v9, v4
+; GFX90A-NEXT: v_ldexp_f32 v3, v3, v8
+; GFX90A-NEXT: v_xor_b32_sdwa v8, s9, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+; GFX90A-NEXT: s_brev_b32 s10, -2
+; GFX90A-NEXT: v_cmp_eq_f32_e64 s[4:5], v9, v4
+; GFX90A-NEXT: v_bfi_b32 v8, s10, v3, v8
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cmp_lt_f32_e64 s[4:5], |v10|, s6
+; GFX90A-NEXT: v_cndmask_b32_e32 v3, v3, v8, vcc
+; GFX90A-NEXT: v_cmp_neq_f32_e32 vcc, v9, v4
+; GFX90A-NEXT: v_cndmask_b32_e64 v4, 0, v5, s[4:5]
+; GFX90A-NEXT: v_cndmask_b32_e64 v5, 0, 32, s[4:5]
+; GFX90A-NEXT: v_ldexp_f32 v5, |v10|, v5
+; GFX90A-NEXT: v_log_f32_e32 v5, v5
+; GFX90A-NEXT: v_cvt_f32_f16_e64 v8, -v1
+; GFX90A-NEXT: v_cmp_class_f32_e64 s[6:7], v2, 24
+; GFX90A-NEXT: v_fma_mix_f32 v1, -v1, s11, neg(0) op_sel_hi:[1,0,0]
+; GFX90A-NEXT: v_sub_f32_e32 v4, v5, v4
+; GFX90A-NEXT: v_mul_legacy_f32 v4, v8, v4
+; GFX90A-NEXT: v_cmp_gt_f32_e64 s[4:5], s8, v4
+; GFX90A-NEXT: v_cndmask_b32_e64 v5, 0, v6, s[4:5]
+; GFX90A-NEXT: v_add_f32_e32 v4, v4, v5
+; GFX90A-NEXT: v_exp_f32_e32 v4, v4
+; GFX90A-NEXT: v_cndmask_b32_e64 v5, 0, v7, s[4:5]
+; GFX90A-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX90A-NEXT: s_and_b64 vcc, s[6:7], vcc
+; GFX90A-NEXT: v_ldexp_f32 v4, v4, v5
+; GFX90A-NEXT: v_trunc_f32_e32 v5, v1
+; GFX90A-NEXT: v_cndmask_b32_e32 v3, v3, v2, vcc
+; GFX90A-NEXT: v_cmp_lg_f32_e32 vcc, v5, v1
+; GFX90A-NEXT: v_trunc_f32_e32 v1, v8
+; GFX90A-NEXT: v_xor_b32_sdwa v0, s9, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; GFX90A-NEXT: v_cmp_eq_f32_e64 s[4:5], v1, v8
+; GFX90A-NEXT: v_bfi_b32 v0, s10, v4, v0
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v4, v0, vcc
+; GFX90A-NEXT: v_cmp_class_f32_e64 s[4:5], v10, 24
+; GFX90A-NEXT: v_cmp_neq_f32_e32 vcc, v1, v8
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v0, v2, vcc
+; GFX90A-NEXT: v_cvt_f16_f32_e32 v3, v3
; GFX90A-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX90A-NEXT: v_pack_b32_f16 v0, v0, v1
+; GFX90A-NEXT: v_pack_b32_f16 v0, v0, v3
; GFX90A-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_v2f16_fneg_lhs_rhs:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX10-NEXT: v_cvt_f32_f16_sdwa v2, -v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX10-NEXT: v_cvt_f32_f16_e64 v0, -v0
-; GFX10-NEXT: v_cvt_f32_f16_sdwa v3, -v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
-; GFX10-NEXT: v_cvt_f32_f16_e64 v1, -v1
-; GFX10-NEXT: v_log_f32_e32 v2, v2
-; GFX10-NEXT: v_log_f32_e32 v0, v0
-; GFX10-NEXT: v_mul_legacy_f32_e32 v2, v3, v2
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX10-NEXT: v_exp_f32_e32 v1, v2
-; GFX10-NEXT: v_exp_f32_e32 v0, v0
+; GFX10-NEXT: v_cvt_f32_f16_e64 v3, -v0
+; GFX10-NEXT: v_cvt_f32_f16_sdwa v8, -v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
+; GFX10-NEXT: v_mov_b32_e32 v9, 0x8000
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v2|
+; GFX10-NEXT: v_cmp_gt_f32_e64 s5, 0x800000, |v3|
+; GFX10-NEXT: v_trunc_f32_e32 v12, v8
+; GFX10-NEXT: v_xor_b32_sdwa v10, v9, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
+; GFX10-NEXT: v_xor_b32_sdwa v0, v9, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:DWORD
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 32, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 32, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v7, 0, 0x42000000, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v5, 0, 0x42000000, s5
+; GFX10-NEXT: s_mov_b32 s5, 0.5
+; GFX10-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX10-NEXT: v_ldexp_f32 v6, |v3|, v6
+; GFX10-NEXT: v_fma_mix_f32 v11, -v1, s5, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX10-NEXT: v_cmp_class_f32_e64 s8, v2, 24
+; GFX10-NEXT: v_cmp_class_f32_e64 s9, v3, 24
+; GFX10-NEXT: v_log_f32_e32 v4, v4
+; GFX10-NEXT: v_log_f32_e32 v6, v6
+; GFX10-NEXT: v_sub_f32_e32 v4, v4, v7
+; GFX10-NEXT: v_cvt_f32_f16_e64 v7, -v1
+; GFX10-NEXT: v_sub_f32_e32 v5, v6, v5
+; GFX10-NEXT: v_fma_mix_f32 v1, -v1, s5, neg(0) op_sel_hi:[1,0,0]
+; GFX10-NEXT: v_cmp_neq_f32_e64 s5, v12, v8
+; GFX10-NEXT: v_mul_legacy_f32_e32 v4, v8, v4
+; GFX10-NEXT: v_trunc_f32_e32 v14, v7
+; GFX10-NEXT: v_mul_legacy_f32_e32 v5, v7, v5
+; GFX10-NEXT: v_trunc_f32_e32 v13, v1
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v4
+; GFX10-NEXT: v_cmp_eq_f32_e64 s7, v14, v7
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0xc2fc0000, v5
+; GFX10-NEXT: v_cmp_lg_f32_e64 s6, v13, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v9, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v4, v4, v6
+; GFX10-NEXT: v_cndmask_b32_e64 v6, 0, 0x42800000, s4
+; GFX10-NEXT: v_exp_f32_e32 v4, v4
+; GFX10-NEXT: v_add_f32_e32 v5, v5, v6
+; GFX10-NEXT: v_trunc_f32_e32 v6, v11
+; GFX10-NEXT: v_exp_f32_e32 v5, v5
+; GFX10-NEXT: v_cmp_lg_f32_e32 vcc_lo, v6, v11
+; GFX10-NEXT: v_ldexp_f32 v4, v4, v9
+; GFX10-NEXT: v_cndmask_b32_e64 v9, 0, 0xffffffc0, s4
+; GFX10-NEXT: v_cmp_eq_f32_e64 s4, v12, v8
+; GFX10-NEXT: v_bfi_b32 v6, 0x7fffffff, v4, v10
+; GFX10-NEXT: v_ldexp_f32 v5, v5, v9
+; GFX10-NEXT: s_and_b32 vcc_lo, s4, vcc_lo
+; GFX10-NEXT: s_and_b32 s4, s7, s6
+; GFX10-NEXT: v_cndmask_b32_e32 v1, v4, v6, vcc_lo
+; GFX10-NEXT: v_bfi_b32 v0, 0x7fffffff, v5, v0
+; GFX10-NEXT: v_cmp_neq_f32_e32 vcc_lo, v14, v7
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v5, v0, s4
+; GFX10-NEXT: s_and_b32 s4, s8, s5
+; GFX10-NEXT: v_cndmask_b32_e64 v1, v1, 0x7fc00000, s4
+; GFX10-NEXT: s_and_b32 s4, s9, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s4
; GFX10-NEXT: v_cvt_f16_f32_e32 v1, v1
; GFX10-NEXT: v_cvt_f16_f32_e32 v0, v0
; GFX10-NEXT: v_pack_b32_f16 v0, v0, v1
@@ -764,22 +2810,76 @@ define <2 x half> @v_pow_v2f16_fneg_lhs_rhs(<2 x half> %x, <2 x half> %y) {
; GFX11-TRUE16: ; %bb.0:
; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-TRUE16-NEXT: v_lshrrev_b32_e32 v2, 16, v0
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e64 v0, -v0.l
-; GFX11-TRUE16-NEXT: v_lshrrev_b32_e32 v3, 16, v1
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e64 v1, -v1.l
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e64 v3, -v0.l
+; GFX11-TRUE16-NEXT: v_lshrrev_b32_e32 v8, 16, v1
+; GFX11-TRUE16-NEXT: v_xor_b16 v0.h, 0x8000, v0.l
; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e64 v2, -v2.l
-; GFX11-TRUE16-NEXT: v_log_f32_e32 v0, v0
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e64 v3, -v3.l
-; GFX11-TRUE16-NEXT: v_log_f32_e32 v2, v2
-; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
-; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v2, v3, v2
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-TRUE16-NEXT: v_exp_f32_e32 v1, v2
-; GFX11-TRUE16-NEXT: v_exp_f32_e32 v2, v0
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e64 v4, -v2.l
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v3|
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e64 v8, -v8.l
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s5, v3, 24
+; GFX11-TRUE16-NEXT: v_xor_b16 v2.h, 0x8000, v2.l
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v4|
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v7, 0, 32, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s0
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s6, v4, 24
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v5, 0, 32, s1
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v7, |v3|, v7
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v9, 0, 0x42000000, s1
+; GFX11-TRUE16-NEXT: s_mov_b32 s1, 0.5
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(SALU_CYCLE_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_fma_mix_f32 v11, -v1, s1, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v5, |v4|, v5
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v7, v7
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v5, v5
; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_dual_sub_f32 v6, v7, v6 :: v_dual_sub_f32 v5, v5, v9
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e64 v9, -v1.l
+; GFX11-TRUE16-NEXT: v_fma_mix_f32 v1, -v1, s1, neg(0) op_sel_hi:[1,0,0]
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_dual_mul_dx9_zero_f32 v5, v8, v5 :: v_dual_mul_dx9_zero_f32 v6, v9, v6
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v12, v9
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v5
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v6
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e64 s1, v12, v9
+; GFX11-TRUE16-NEXT: v_cmp_neq_f32_e64 s3, v12, v9
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v7, 0, 0x42800000, vcc_lo
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v10, 0, 0x42800000, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v3, 0, 0xffffffc0, vcc_lo
+; GFX11-TRUE16-NEXT: v_dual_add_f32 v5, v5, v7 :: v_dual_add_f32 v6, v6, v10
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v7, v11
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v10, v1
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v5, v5
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v6, v6
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_3) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e32 vcc_lo, v7, v11
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v7, 0, 0xffffffc0, s0
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v11, v8
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e64 s0, v10, v1
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e64 s2, v11, v8
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(TRANS32_DEP_2) | instskip(NEXT) | instid1(TRANS32_DEP_1)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v3, v5, v3
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v1, v6, v7
+; GFX11-TRUE16-NEXT: v_cmp_neq_f32_e64 s4, v11, v8
+; GFX11-TRUE16-NEXT: s_and_b32 vcc_lo, s2, vcc_lo
+; GFX11-TRUE16-NEXT: v_bfi_b32 v2, 0x7fffffff, v3, v2
+; GFX11-TRUE16-NEXT: v_bfi_b32 v0, 0x7fffffff, v1, v0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e32 v2, v3, v2, vcc_lo
+; GFX11-TRUE16-NEXT: s_and_b32 vcc_lo, s1, s0
+; GFX11-TRUE16-NEXT: s_and_b32 s0, s6, s4
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc_lo
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v1, v2, 0x7fc00000, s0
+; GFX11-TRUE16-NEXT: s_and_b32 s0, s5, s3
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instid1(SALU_CYCLE_1)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v2, v0, 0x7fc00000, s0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.h, v1
; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v2
; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
@@ -788,24 +2888,80 @@ define <2 x half> @v_pow_v2f16_fneg_lhs_rhs(<2 x half> %x, <2 x half> %y) {
; GFX11-FAKE16: ; %bb.0:
; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v2, 16, v0
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e64 v0, -v0
-; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v3, 16, v1
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e64 v1, -v1
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e64 v3, -v0
+; GFX11-FAKE16-NEXT: v_lshrrev_b32_e32 v8, 16, v1
+; GFX11-FAKE16-NEXT: v_xor_b32_e32 v0, 0x8000, v0
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_4)
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e64 v2, -v2
-; GFX11-FAKE16-NEXT: v_log_f32_e32 v0, v0
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e64 v3, -v3
-; GFX11-FAKE16-NEXT: v_log_f32_e32 v2, v2
-; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
-; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v2, v3, v2
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_exp_f32_e32 v0, v0
-; GFX11-FAKE16-NEXT: v_exp_f32_e32 v1, v2
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e64 v4, -v2
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v3|
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4)
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e64 v8, -v8
+; GFX11-FAKE16-NEXT: v_xor_b32_e32 v2, 0x8000, v2
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s5, v3, 24
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v4|
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v7, 0, 32, s0
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v6, 0, 0x42000000, s0
+; GFX11-FAKE16-NEXT: v_lshlrev_b32_e32 v2, 16, v2
+; GFX11-FAKE16-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v5, 0, 32, s1
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v7, |v3|, v7
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v9, 0, 0x42000000, s1
+; GFX11-FAKE16-NEXT: s_mov_b32 s1, 0.5
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s6, v4, 24
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v5, |v4|, v5
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v7, v7
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v5, v5
; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GFX11-FAKE16-NEXT: v_sub_f32_e32 v6, v7, v6
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v7, -v1, s1, neg(0) op_sel:[1,0,0] op_sel_hi:[1,0,0]
+; GFX11-FAKE16-NEXT: v_sub_f32_e32 v5, v5, v9
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e64 v9, -v1
+; GFX11-FAKE16-NEXT: v_fma_mix_f32 v1, -v1, s1, neg(0) op_sel_hi:[1,0,0]
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_dual_mul_dx9_zero_f32 v5, v8, v5 :: v_dual_mul_dx9_zero_f32 v6, v9, v6
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v12, v9
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v5
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0xc2fc0000, v6
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e64 s1, v12, v9
+; GFX11-FAKE16-NEXT: v_cmp_neq_f32_e64 s3, v12, v9
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v10, 0, 0x42800000, vcc_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v11, 0, 0x42800000, s0
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v3, 0, 0xffffffc0, vcc_lo
+; GFX11-FAKE16-NEXT: v_dual_add_f32 v5, v5, v10 :: v_dual_add_f32 v6, v6, v11
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v10, v7
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v11, v1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v5, v5
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v6, v6
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_3) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e32 vcc_lo, v10, v7
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v7, 0, 0xffffffc0, s0
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v10, v8
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e64 s0, v11, v1
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e64 s2, v10, v8
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(TRANS32_DEP_2) | instskip(NEXT) | instid1(TRANS32_DEP_1)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v3, v5, v3
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v1, v6, v7
+; GFX11-FAKE16-NEXT: v_cmp_neq_f32_e64 s4, v10, v8
+; GFX11-FAKE16-NEXT: s_and_b32 vcc_lo, s2, vcc_lo
+; GFX11-FAKE16-NEXT: v_bfi_b32 v2, 0x7fffffff, v3, v2
+; GFX11-FAKE16-NEXT: v_bfi_b32 v0, 0x7fffffff, v1, v0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e32 v2, v3, v2, vcc_lo
+; GFX11-FAKE16-NEXT: s_and_b32 vcc_lo, s1, s0
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s6, s4
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v1, v2, 0x7fc00000, s0
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s5, s3
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instid1(SALU_CYCLE_1)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v1, v1
+; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
; GFX11-FAKE16-NEXT: v_pack_b32_f16 v0, v0, v1
; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
@@ -825,51 +2981,135 @@ define float @v_pow_f32_fabs_lhs(float %x, float %y) {
; GFX6-LABEL: v_pow_f32_fabs_lhs:
; GFX6: ; %bb.0:
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX6-NEXT: v_log_f32_e64 v0, |v0|
+; GFX6-NEXT: s_mov_b32 s4, 0x800000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX6-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX6-NEXT: v_ldexp_f32_e64 v0, |v0|, v3
+; GFX6-NEXT: v_log_f32_e32 v0, v0
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX6-NEXT: v_sub_f32_e32 v0, v0, v2
; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX6-NEXT: v_mov_b32_e32 v1, 0x42800000
+; GFX6-NEXT: v_cmp_gt_f32_e32 vcc, s4, v0
+; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX6-NEXT: v_add_f32_e32 v0, v0, v1
; GFX6-NEXT: v_exp_f32_e32 v0, v0
+; GFX6-NEXT: v_not_b32_e32 v1, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v1
; GFX6-NEXT: s_setpc_b64 s[30:31]
;
; GFX8-LABEL: v_pow_f32_fabs_lhs:
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX8-NEXT: v_log_f32_e64 v0, |v0|
+; GFX8-NEXT: s_mov_b32 s4, 0x800000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX8-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX8-NEXT: v_ldexp_f32 v0, |v0|, v3
+; GFX8-NEXT: v_log_f32_e32 v0, v0
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX8-NEXT: v_sub_f32_e32 v0, v0, v2
; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX8-NEXT: v_mov_b32_e32 v1, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s4, v0
+; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX8-NEXT: v_add_f32_e32 v0, v0, v1
; GFX8-NEXT: v_exp_f32_e32 v0, v0
+; GFX8-NEXT: v_not_b32_e32 v1, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX8-NEXT: v_ldexp_f32 v0, v0, v1
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: v_pow_f32_fabs_lhs:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT: v_log_f32_e64 v0, |v0|
+; GFX9-NEXT: s_mov_b32 s4, 0x800000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX9-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX9-NEXT: v_ldexp_f32 v0, |v0|, v3
+; GFX9-NEXT: v_log_f32_e32 v0, v0
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX9-NEXT: v_sub_f32_e32 v0, v0, v2
; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x42800000
+; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, s4, v0
+; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX9-NEXT: v_add_f32_e32 v0, v0, v1
; GFX9-NEXT: v_exp_f32_e32 v0, v0
+; GFX9-NEXT: v_not_b32_e32 v1, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX9-NEXT: v_ldexp_f32 v0, v0, v1
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX90A-LABEL: v_pow_f32_fabs_lhs:
; GFX90A: ; %bb.0:
; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX90A-NEXT: v_log_f32_e64 v0, |v0|
+; GFX90A-NEXT: s_mov_b32 s4, 0x800000
+; GFX90A-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX90A-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX90A-NEXT: v_ldexp_f32 v0, |v0|, v3
+; GFX90A-NEXT: v_log_f32_e32 v0, v0
+; GFX90A-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX90A-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX90A-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX90A-NEXT: v_sub_f32_e32 v0, v0, v2
; GFX90A-NEXT: v_mul_legacy_f32 v0, v1, v0
+; GFX90A-NEXT: v_mov_b32_e32 v1, 0x42800000
+; GFX90A-NEXT: v_cmp_gt_f32_e32 vcc, s4, v0
+; GFX90A-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX90A-NEXT: v_add_f32_e32 v0, v0, v1
; GFX90A-NEXT: v_exp_f32_e32 v0, v0
+; GFX90A-NEXT: v_not_b32_e32 v1, 63
+; GFX90A-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX90A-NEXT: v_ldexp_f32 v0, v0, v1
; GFX90A-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_f32_fabs_lhs:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_log_f32_e64 v0, |v0|
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v0|
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 32, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s4
+; GFX10-NEXT: v_ldexp_f32 v0, |v0|, v3
+; GFX10-NEXT: v_log_f32_e32 v0, v0
+; GFX10-NEXT: v_sub_f32_e32 v0, v0, v2
; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
+; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v0, v0, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, vcc_lo
; GFX10-NEXT: v_exp_f32_e32 v0, v0
+; GFX10-NEXT: v_ldexp_f32 v0, v0, v1
; GFX10-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: v_pow_f32_fabs_lhs:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT: v_log_f32_e64 v0, |v0|
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 32, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s0
+; GFX11-NEXT: v_ldexp_f32 v0, |v0|, v3
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_log_f32_e32 v0, v0
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_sub_f32_e32 v0, v0, v2
; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
+; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_add_f32_e32 v0, v0, v1
+; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2)
; GFX11-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_ldexp_f32 v0, v0, v1
; GFX11-NEXT: s_setpc_b64 s[30:31]
%fabs.x = call float @llvm.fabs.f32(float %x)
%pow = call float @llvm.pow.f32(float %fabs.x, float %y)
@@ -880,51 +3120,218 @@ define float @v_pow_f32_fabs_rhs(float %x, float %y) {
; GFX6-LABEL: v_pow_f32_fabs_rhs:
; GFX6: ; %bb.0:
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_mul_legacy_f32_e64 v0, |v1|, v0
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
+; GFX6-NEXT: s_mov_b32 s4, 0x800000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX6-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX6-NEXT: v_ldexp_f32_e64 v3, |v0|, v3
+; GFX6-NEXT: v_log_f32_e32 v3, v3
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX6-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX6-NEXT: v_mul_legacy_f32_e64 v2, |v1|, v2
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX6-NEXT: v_cmp_gt_f32_e32 vcc, s4, v2
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_exp_f32_e32 v2, v2
+; GFX6-NEXT: v_not_b32_e32 v3, 63
+; GFX6-NEXT: v_mul_f32_e64 v4, |v1|, 0.5
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: v_trunc_f32_e32 v5, v4
+; GFX6-NEXT: v_ldexp_f32_e32 v2, v2, v3
+; GFX6-NEXT: s_brev_b32 s4, -2
+; GFX6-NEXT: v_cmp_lg_f32_e32 vcc, v5, v4
+; GFX6-NEXT: v_trunc_f32_e64 v4, |v1|
+; GFX6-NEXT: v_bfi_b32 v3, s4, v2, v0
+; GFX6-NEXT: v_cmp_eq_f32_e64 s[4:5], v4, |v1|
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX6-NEXT: v_cmp_neq_f32_e64 s[6:7], v4, |v1|
+; GFX6-NEXT: v_cndmask_b32_e32 v2, v2, v3, vcc
+; GFX6-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
; GFX6-NEXT: s_setpc_b64 s[30:31]
;
; GFX8-LABEL: v_pow_f32_fabs_rhs:
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX8-NEXT: v_log_f32_e32 v0, v0
-; GFX8-NEXT: v_mul_legacy_f32_e64 v0, |v1|, v0
-; GFX8-NEXT: v_exp_f32_e32 v0, v0
+; GFX8-NEXT: s_mov_b32 s4, 0x800000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX8-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX8-NEXT: v_ldexp_f32 v3, |v0|, v3
+; GFX8-NEXT: v_log_f32_e32 v3, v3
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX8-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX8-NEXT: v_mul_legacy_f32_e64 v2, |v1|, v2
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s4, v2
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_exp_f32_e32 v2, v2
+; GFX8-NEXT: v_not_b32_e32 v3, 63
+; GFX8-NEXT: v_mul_f32_e64 v4, |v1|, 0.5
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_trunc_f32_e32 v5, v4
+; GFX8-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX8-NEXT: s_brev_b32 s4, -2
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v5, v4
+; GFX8-NEXT: v_trunc_f32_e64 v4, |v1|
+; GFX8-NEXT: v_bfi_b32 v3, s4, v2, v0
+; GFX8-NEXT: v_cmp_eq_f32_e64 s[4:5], v4, |v1|
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX8-NEXT: v_cmp_neq_f32_e64 s[6:7], v4, |v1|
+; GFX8-NEXT: v_cndmask_b32_e32 v2, v2, v3, vcc
+; GFX8-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: v_pow_f32_fabs_rhs:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT: v_log_f32_e32 v0, v0
-; GFX9-NEXT: v_mul_legacy_f32_e64 v0, |v1|, v0
-; GFX9-NEXT: v_exp_f32_e32 v0, v0
+; GFX9-NEXT: s_mov_b32 s4, 0x800000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX9-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX9-NEXT: v_ldexp_f32 v3, |v0|, v3
+; GFX9-NEXT: v_log_f32_e32 v3, v3
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX9-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX9-NEXT: v_mul_legacy_f32_e64 v2, |v1|, v2
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, s4, v2
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX9-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX9-NEXT: v_exp_f32_e32 v2, v2
+; GFX9-NEXT: v_not_b32_e32 v3, 63
+; GFX9-NEXT: v_mul_f32_e64 v4, |v1|, 0.5
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX9-NEXT: v_trunc_f32_e32 v5, v4
+; GFX9-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX9-NEXT: s_brev_b32 s4, -2
+; GFX9-NEXT: v_cmp_lg_f32_e32 vcc, v5, v4
+; GFX9-NEXT: v_trunc_f32_e64 v4, |v1|
+; GFX9-NEXT: v_bfi_b32 v3, s4, v2, v0
+; GFX9-NEXT: v_cmp_eq_f32_e64 s[4:5], v4, |v1|
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX9-NEXT: v_cmp_neq_f32_e64 s[6:7], v4, |v1|
+; GFX9-NEXT: v_cndmask_b32_e32 v2, v2, v3, vcc
+; GFX9-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX90A-LABEL: v_pow_f32_fabs_rhs:
; GFX90A: ; %bb.0:
; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX90A-NEXT: v_log_f32_e32 v0, v0
-; GFX90A-NEXT: v_mul_legacy_f32 v0, |v1|, v0
-; GFX90A-NEXT: v_exp_f32_e32 v0, v0
+; GFX90A-NEXT: s_mov_b32 s4, 0x800000
+; GFX90A-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX90A-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX90A-NEXT: v_ldexp_f32 v3, |v0|, v3
+; GFX90A-NEXT: v_log_f32_e32 v3, v3
+; GFX90A-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX90A-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX90A-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX90A-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX90A-NEXT: v_mul_legacy_f32 v2, |v1|, v2
+; GFX90A-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX90A-NEXT: v_cmp_gt_f32_e32 vcc, s4, v2
+; GFX90A-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX90A-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX90A-NEXT: v_exp_f32_e32 v2, v2
+; GFX90A-NEXT: v_not_b32_e32 v3, 63
+; GFX90A-NEXT: v_mul_f32_e64 v4, |v1|, 0.5
+; GFX90A-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX90A-NEXT: v_trunc_f32_e32 v5, v4
+; GFX90A-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX90A-NEXT: s_brev_b32 s4, -2
+; GFX90A-NEXT: v_cmp_lg_f32_e32 vcc, v5, v4
+; GFX90A-NEXT: v_trunc_f32_e64 v4, |v1|
+; GFX90A-NEXT: v_bfi_b32 v3, s4, v2, v0
+; GFX90A-NEXT: v_cmp_eq_f32_e64 s[4:5], v4, |v1|
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX90A-NEXT: v_cmp_neq_f32_e64 s[6:7], v4, |v1|
+; GFX90A-NEXT: v_cndmask_b32_e32 v2, v2, v3, vcc
+; GFX90A-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], s[6:7]
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
; GFX90A-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_f32_fabs_rhs:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_log_f32_e32 v0, v0
-; GFX10-NEXT: v_mul_legacy_f32_e64 v0, |v1|, v0
-; GFX10-NEXT: v_exp_f32_e32 v0, v0
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v0|
+; GFX10-NEXT: v_trunc_f32_e64 v6, |v1|
+; GFX10-NEXT: v_cmp_class_f32_e64 s5, v0, 24
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 32, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s4
+; GFX10-NEXT: v_cmp_eq_f32_e64 s4, v6, |v1|
+; GFX10-NEXT: v_cmp_neq_f32_e64 s6, v6, |v1|
+; GFX10-NEXT: v_ldexp_f32 v3, |v0|, v3
+; GFX10-NEXT: v_log_f32_e32 v3, v3
+; GFX10-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX10-NEXT: v_mul_legacy_f32_e64 v2, |v1|, v2
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX10-NEXT: v_mul_f32_e64 v3, |v1|, 0.5
+; GFX10-NEXT: v_exp_f32_e32 v2, v2
+; GFX10-NEXT: v_trunc_f32_e32 v5, v3
+; GFX10-NEXT: v_cmp_lg_f32_e32 vcc_lo, v5, v3
+; GFX10-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX10-NEXT: s_and_b32 vcc_lo, s4, vcc_lo
+; GFX10-NEXT: s_and_b32 s4, s5, s6
+; GFX10-NEXT: v_bfi_b32 v3, 0x7fffffff, v2, v0
+; GFX10-NEXT: v_cndmask_b32_e32 v0, v2, v3, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s4
; GFX10-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: v_pow_f32_fabs_rhs:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT: v_log_f32_e32 v0, v0
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-NEXT: v_trunc_f32_e64 v6, |v1|
+; GFX11-NEXT: v_cmp_class_f32_e64 s1, v0, 24
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_4)
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 32, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s0
+; GFX11-NEXT: v_cmp_eq_f32_e64 s0, v6, |v1|
+; GFX11-NEXT: v_cmp_neq_f32_e64 s2, v6, |v1|
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_ldexp_f32 v3, |v0|, v3
+; GFX11-NEXT: v_log_f32_e32 v3, v3
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_mul_dx9_zero_f32_e64 v0, |v1|, v0
+; GFX11-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_mul_dx9_zero_f32_e64 v2, |v1|, v2
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX11-NEXT: v_mul_f32_e64 v3, |v1|, 0.5
+; GFX11-NEXT: v_exp_f32_e32 v2, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_trunc_f32_e32 v5, v3
+; GFX11-NEXT: v_cmp_lg_f32_e32 vcc_lo, v5, v3
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX11-NEXT: s_and_b32 vcc_lo, s0, vcc_lo
+; GFX11-NEXT: s_and_b32 s0, s1, s2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_bfi_b32 v3, 0x7fffffff, v2, v0
+; GFX11-NEXT: v_cndmask_b32_e32 v0, v2, v3, vcc_lo
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
-; GFX11-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
%fabs.y = call float @llvm.fabs.f32(float %y)
%pow = call float @llvm.pow.f32(float %x, float %fabs.y)
@@ -935,51 +3342,135 @@ define float @v_pow_f32_fabs_lhs_rhs(float %x, float %y) {
; GFX6-LABEL: v_pow_f32_fabs_lhs_rhs:
; GFX6: ; %bb.0:
; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX6-NEXT: v_log_f32_e64 v0, |v0|
+; GFX6-NEXT: s_mov_b32 s4, 0x800000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX6-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX6-NEXT: v_ldexp_f32_e64 v0, |v0|, v3
+; GFX6-NEXT: v_log_f32_e32 v0, v0
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX6-NEXT: v_sub_f32_e32 v0, v0, v2
; GFX6-NEXT: v_mul_legacy_f32_e64 v0, |v1|, v0
+; GFX6-NEXT: v_mov_b32_e32 v1, 0x42800000
+; GFX6-NEXT: v_cmp_gt_f32_e32 vcc, s4, v0
+; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX6-NEXT: v_add_f32_e32 v0, v0, v1
; GFX6-NEXT: v_exp_f32_e32 v0, v0
+; GFX6-NEXT: v_not_b32_e32 v1, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v1
; GFX6-NEXT: s_setpc_b64 s[30:31]
;
; GFX8-LABEL: v_pow_f32_fabs_lhs_rhs:
; GFX8: ; %bb.0:
; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX8-NEXT: v_log_f32_e64 v0, |v0|
+; GFX8-NEXT: s_mov_b32 s4, 0x800000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX8-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX8-NEXT: v_ldexp_f32 v0, |v0|, v3
+; GFX8-NEXT: v_log_f32_e32 v0, v0
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX8-NEXT: v_sub_f32_e32 v0, v0, v2
; GFX8-NEXT: v_mul_legacy_f32_e64 v0, |v1|, v0
+; GFX8-NEXT: v_mov_b32_e32 v1, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s4, v0
+; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX8-NEXT: v_add_f32_e32 v0, v0, v1
; GFX8-NEXT: v_exp_f32_e32 v0, v0
+; GFX8-NEXT: v_not_b32_e32 v1, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX8-NEXT: v_ldexp_f32 v0, v0, v1
; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: v_pow_f32_fabs_lhs_rhs:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT: v_log_f32_e64 v0, |v0|
+; GFX9-NEXT: s_mov_b32 s4, 0x800000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX9-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX9-NEXT: v_ldexp_f32 v0, |v0|, v3
+; GFX9-NEXT: v_log_f32_e32 v0, v0
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX9-NEXT: v_sub_f32_e32 v0, v0, v2
; GFX9-NEXT: v_mul_legacy_f32_e64 v0, |v1|, v0
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x42800000
+; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, s4, v0
+; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX9-NEXT: v_add_f32_e32 v0, v0, v1
; GFX9-NEXT: v_exp_f32_e32 v0, v0
+; GFX9-NEXT: v_not_b32_e32 v1, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX9-NEXT: v_ldexp_f32 v0, v0, v1
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX90A-LABEL: v_pow_f32_fabs_lhs_rhs:
; GFX90A: ; %bb.0:
; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX90A-NEXT: v_log_f32_e64 v0, |v0|
+; GFX90A-NEXT: s_mov_b32 s4, 0x800000
+; GFX90A-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX90A-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX90A-NEXT: v_ldexp_f32 v0, |v0|, v3
+; GFX90A-NEXT: v_log_f32_e32 v0, v0
+; GFX90A-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX90A-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX90A-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX90A-NEXT: v_sub_f32_e32 v0, v0, v2
; GFX90A-NEXT: v_mul_legacy_f32 v0, |v1|, v0
+; GFX90A-NEXT: v_mov_b32_e32 v1, 0x42800000
+; GFX90A-NEXT: v_cmp_gt_f32_e32 vcc, s4, v0
+; GFX90A-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX90A-NEXT: v_add_f32_e32 v0, v0, v1
; GFX90A-NEXT: v_exp_f32_e32 v0, v0
+; GFX90A-NEXT: v_not_b32_e32 v1, 63
+; GFX90A-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX90A-NEXT: v_ldexp_f32 v0, v0, v1
; GFX90A-NEXT: s_setpc_b64 s[30:31]
;
; GFX10-LABEL: v_pow_f32_fabs_lhs_rhs:
; GFX10: ; %bb.0:
; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT: v_log_f32_e64 v0, |v0|
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v0|
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 32, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s4
+; GFX10-NEXT: v_ldexp_f32 v0, |v0|, v3
+; GFX10-NEXT: v_log_f32_e32 v0, v0
+; GFX10-NEXT: v_sub_f32_e32 v0, v0, v2
; GFX10-NEXT: v_mul_legacy_f32_e64 v0, |v1|, v0
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
+; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v0, v0, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, vcc_lo
; GFX10-NEXT: v_exp_f32_e32 v0, v0
+; GFX10-NEXT: v_ldexp_f32 v0, v0, v1
; GFX10-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: v_pow_f32_fabs_lhs_rhs:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT: v_log_f32_e64 v0, |v0|
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 32, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s0
+; GFX11-NEXT: v_ldexp_f32 v0, |v0|, v3
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_log_f32_e32 v0, v0
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_sub_f32_e32 v0, v0, v2
; GFX11-NEXT: v_mul_dx9_zero_f32_e64 v0, |v1|, v0
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
+; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_add_f32_e32 v0, v0, v1
+; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2)
; GFX11-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_ldexp_f32 v0, v0, v1
; GFX11-NEXT: s_setpc_b64 s[30:31]
%fabs.x = call float @llvm.fabs.f32(float %x)
%fabs.y = call float @llvm.fabs.f32(float %y)
@@ -990,46 +3481,226 @@ define float @v_pow_f32_fabs_lhs_rhs(float %x, float %y) {
define amdgpu_ps float @v_pow_f32_sgpr_vgpr(float inreg %x, float %y) {
; GFX6-LABEL: v_pow_f32_sgpr_vgpr:
; GFX6: ; %bb.0:
-; GFX6-NEXT: v_log_f32_e32 v1, s0
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
+; GFX6-NEXT: v_mov_b32_e32 v1, 0x800000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |s0|, v1
+; GFX6-NEXT: s_and_b64 s[2:3], vcc, exec
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX6-NEXT: s_cselect_b32 s1, 32, 0
+; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
+; GFX6-NEXT: v_mov_b32_e32 v2, s1
+; GFX6-NEXT: v_ldexp_f32_e64 v2, |s0|, v2
+; GFX6-NEXT: v_log_f32_e32 v2, v2
+; GFX6-NEXT: s_mov_b32 s1, 0xc2fc0000
+; GFX6-NEXT: v_mul_f32_e32 v3, 0.5, v0
+; GFX6-NEXT: v_trunc_f32_e32 v4, v3
+; GFX6-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX6-NEXT: v_mul_legacy_f32_e32 v1, v0, v1
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX6-NEXT: v_cmp_gt_f32_e32 vcc, s1, v1
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX6-NEXT: v_exp_f32_e32 v1, v1
+; GFX6-NEXT: v_not_b32_e32 v2, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: v_cmp_lg_f32_e32 vcc, v4, v3
+; GFX6-NEXT: v_trunc_f32_e32 v3, v0
+; GFX6-NEXT: v_ldexp_f32_e32 v1, v1, v2
+; GFX6-NEXT: s_brev_b32 s1, -2
+; GFX6-NEXT: v_mov_b32_e32 v2, s0
+; GFX6-NEXT: v_cmp_eq_f32_e64 s[2:3], v3, v0
+; GFX6-NEXT: v_bfi_b32 v2, s1, v1, v2
+; GFX6-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc
+; GFX6-NEXT: v_cmp_class_f32_e64 s[0:1], s0, 24
+; GFX6-NEXT: v_cmp_neq_f32_e32 vcc, v3, v0
+; GFX6-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX6-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX6-NEXT: ; return to shader part epilog
;
; GFX8-LABEL: v_pow_f32_sgpr_vgpr:
; GFX8: ; %bb.0:
-; GFX8-NEXT: v_log_f32_e32 v1, s0
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX8-NEXT: v_exp_f32_e32 v0, v0
+; GFX8-NEXT: v_mov_b32_e32 v1, 0x800000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |s0|, v1
+; GFX8-NEXT: s_and_b64 s[2:3], vcc, exec
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX8-NEXT: s_cselect_b32 s1, 32, 0
+; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
+; GFX8-NEXT: v_mov_b32_e32 v2, s1
+; GFX8-NEXT: v_ldexp_f32 v2, |s0|, v2
+; GFX8-NEXT: v_log_f32_e32 v2, v2
+; GFX8-NEXT: s_mov_b32 s1, 0xc2fc0000
+; GFX8-NEXT: v_mul_f32_e32 v3, 0.5, v0
+; GFX8-NEXT: v_trunc_f32_e32 v4, v3
+; GFX8-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX8-NEXT: v_mul_legacy_f32_e32 v1, v0, v1
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s1, v1
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX8-NEXT: v_exp_f32_e32 v1, v1
+; GFX8-NEXT: v_not_b32_e32 v2, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v4, v3
+; GFX8-NEXT: v_trunc_f32_e32 v3, v0
+; GFX8-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX8-NEXT: s_brev_b32 s1, -2
+; GFX8-NEXT: v_mov_b32_e32 v2, s0
+; GFX8-NEXT: v_cmp_eq_f32_e64 s[2:3], v3, v0
+; GFX8-NEXT: v_bfi_b32 v2, s1, v1, v2
+; GFX8-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 s[0:1], s0, 24
+; GFX8-NEXT: v_cmp_neq_f32_e32 vcc, v3, v0
+; GFX8-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX8-NEXT: ; return to shader part epilog
;
; GFX9-LABEL: v_pow_f32_sgpr_vgpr:
; GFX9: ; %bb.0:
-; GFX9-NEXT: v_log_f32_e32 v1, s0
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX9-NEXT: v_exp_f32_e32 v0, v0
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x800000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |s0|, v1
+; GFX9-NEXT: s_and_b64 s[2:3], vcc, exec
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX9-NEXT: s_cselect_b32 s1, 32, 0
+; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
+; GFX9-NEXT: v_mov_b32_e32 v2, s1
+; GFX9-NEXT: v_ldexp_f32 v2, |s0|, v2
+; GFX9-NEXT: v_log_f32_e32 v2, v2
+; GFX9-NEXT: s_mov_b32 s1, 0xc2fc0000
+; GFX9-NEXT: v_mul_f32_e32 v3, 0.5, v0
+; GFX9-NEXT: v_trunc_f32_e32 v4, v3
+; GFX9-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX9-NEXT: v_mul_legacy_f32_e32 v1, v0, v1
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, s1, v1
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX9-NEXT: v_exp_f32_e32 v1, v1
+; GFX9-NEXT: v_not_b32_e32 v2, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: v_cmp_lg_f32_e32 vcc, v4, v3
+; GFX9-NEXT: v_trunc_f32_e32 v3, v0
+; GFX9-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX9-NEXT: s_brev_b32 s1, -2
+; GFX9-NEXT: v_mov_b32_e32 v2, s0
+; GFX9-NEXT: v_cmp_eq_f32_e64 s[2:3], v3, v0
+; GFX9-NEXT: v_bfi_b32 v2, s1, v1, v2
+; GFX9-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc
+; GFX9-NEXT: v_cmp_class_f32_e64 s[0:1], s0, 24
+; GFX9-NEXT: v_cmp_neq_f32_e32 vcc, v3, v0
+; GFX9-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX9-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX9-NEXT: ; return to shader part epilog
;
; GFX90A-LABEL: v_pow_f32_sgpr_vgpr:
; GFX90A: ; %bb.0:
-; GFX90A-NEXT: v_log_f32_e32 v1, s0
-; GFX90A-NEXT: v_mul_legacy_f32 v0, v0, v1
-; GFX90A-NEXT: v_exp_f32_e32 v0, v0
+; GFX90A-NEXT: v_mov_b32_e32 v1, 0x800000
+; GFX90A-NEXT: v_cmp_lt_f32_e64 vcc, |s0|, v1
+; GFX90A-NEXT: s_and_b64 s[2:3], vcc, exec
+; GFX90A-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX90A-NEXT: s_cselect_b32 s1, 32, 0
+; GFX90A-NEXT: v_cndmask_b32_e32 v1, 0, v2, vcc
+; GFX90A-NEXT: v_mov_b32_e32 v2, s1
+; GFX90A-NEXT: v_ldexp_f32 v2, |s0|, v2
+; GFX90A-NEXT: v_log_f32_e32 v2, v2
+; GFX90A-NEXT: s_mov_b32 s1, 0xc2fc0000
+; GFX90A-NEXT: v_mul_f32_e32 v3, 0.5, v0
+; GFX90A-NEXT: v_trunc_f32_e32 v4, v3
+; GFX90A-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX90A-NEXT: v_mul_legacy_f32 v1, v0, v1
+; GFX90A-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX90A-NEXT: v_cmp_gt_f32_e32 vcc, s1, v1
+; GFX90A-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX90A-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX90A-NEXT: v_exp_f32_e32 v1, v1
+; GFX90A-NEXT: v_not_b32_e32 v2, 63
+; GFX90A-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX90A-NEXT: v_cmp_lg_f32_e32 vcc, v4, v3
+; GFX90A-NEXT: v_trunc_f32_e32 v3, v0
+; GFX90A-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX90A-NEXT: s_brev_b32 s1, -2
+; GFX90A-NEXT: v_mov_b32_e32 v2, s0
+; GFX90A-NEXT: v_cmp_eq_f32_e64 s[2:3], v3, v0
+; GFX90A-NEXT: v_bfi_b32 v2, s1, v1, v2
+; GFX90A-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc
+; GFX90A-NEXT: v_cmp_class_f32_e64 s[0:1], s0, 24
+; GFX90A-NEXT: v_cmp_neq_f32_e32 vcc, v3, v0
+; GFX90A-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX90A-NEXT: s_and_b64 vcc, s[0:1], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX90A-NEXT: ; return to shader part epilog
;
; GFX10-LABEL: v_pow_f32_sgpr_vgpr:
; GFX10: ; %bb.0:
-; GFX10-NEXT: v_log_f32_e32 v1, s0
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
-; GFX10-NEXT: v_exp_f32_e32 v0, v0
+; GFX10-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |s0|
+; GFX10-NEXT: v_trunc_f32_e32 v5, v0
+; GFX10-NEXT: v_cmp_class_f32_e64 s2, s0, 24
+; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42000000, s1
+; GFX10-NEXT: s_and_b32 s1, s1, exec_lo
+; GFX10-NEXT: s_cselect_b32 s1, 32, 0
+; GFX10-NEXT: v_ldexp_f32 v2, |s0|, s1
+; GFX10-NEXT: v_cmp_eq_f32_e64 s1, v5, v0
+; GFX10-NEXT: v_log_f32_e32 v2, v2
+; GFX10-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX10-NEXT: v_mul_legacy_f32_e32 v1, v0, v1
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX10-NEXT: v_mul_f32_e32 v2, 0.5, v0
+; GFX10-NEXT: v_exp_f32_e32 v1, v1
+; GFX10-NEXT: v_trunc_f32_e32 v4, v2
+; GFX10-NEXT: v_cmp_lg_f32_e32 vcc_lo, v4, v2
+; GFX10-NEXT: v_ldexp_f32 v1, v1, v3
+; GFX10-NEXT: s_and_b32 vcc_lo, s1, vcc_lo
+; GFX10-NEXT: v_bfi_b32 v2, 0x7fffffff, v1, s0
+; GFX10-NEXT: v_cmp_neq_f32_e64 s0, v5, v0
+; GFX10-NEXT: v_cndmask_b32_e32 v0, v1, v2, vcc_lo
+; GFX10-NEXT: s_and_b32 s0, s2, s0
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX10-NEXT: ; return to shader part epilog
;
; GFX11-LABEL: v_pow_f32_sgpr_vgpr:
; GFX11: ; %bb.0:
-; GFX11-NEXT: v_log_f32_e32 v1, s0
+; GFX11-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |s0|
+; GFX11-NEXT: v_trunc_f32_e32 v5, v0
+; GFX11-NEXT: v_cmp_class_f32_e64 s2, s0, 24
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_2) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42000000, s1
+; GFX11-NEXT: s_and_b32 s1, s1, exec_lo
+; GFX11-NEXT: s_cselect_b32 s1, 32, 0
+; GFX11-NEXT: v_ldexp_f32 v2, |s0|, s1
+; GFX11-NEXT: v_cmp_eq_f32_e64 s1, v5, v0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_log_f32_e32 v2, v2
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, v0, v1
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
-; GFX11-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v1, v0, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v1
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: v_dual_add_f32 v1, v1, v2 :: v_dual_mul_f32 v2, 0.5, v0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_exp_f32_e32 v1, v1
+; GFX11-NEXT: v_trunc_f32_e32 v4, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_3) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_cmp_lg_f32_e32 vcc_lo, v4, v2
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_ldexp_f32 v1, v1, v3
+; GFX11-NEXT: s_and_b32 vcc_lo, s1, vcc_lo
+; GFX11-NEXT: v_bfi_b32 v2, 0x7fffffff, v1, s0
+; GFX11-NEXT: v_cmp_neq_f32_e64 s0, v5, v0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2)
+; GFX11-NEXT: v_cndmask_b32_e32 v0, v1, v2, vcc_lo
+; GFX11-NEXT: s_and_b32 s0, s2, s0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX11-NEXT: ; return to shader part epilog
%pow = call float @llvm.pow.f32(float %x, float %y)
ret float %pow
@@ -1038,46 +3709,213 @@ define amdgpu_ps float @v_pow_f32_sgpr_vgpr(float inreg %x, float %y) {
define amdgpu_ps float @v_pow_f32_vgpr_sgpr(float %x, float inreg %y) {
; GFX6-LABEL: v_pow_f32_vgpr_sgpr:
; GFX6: ; %bb.0:
-; GFX6-NEXT: v_log_f32_e32 v0, v0
-; GFX6-NEXT: v_mul_legacy_f32_e32 v0, s0, v0
-; GFX6-NEXT: v_exp_f32_e32 v0, v0
+; GFX6-NEXT: s_mov_b32 s1, 0x800000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s1
+; GFX6-NEXT: v_cndmask_b32_e64 v2, 0, 32, vcc
+; GFX6-NEXT: v_ldexp_f32_e64 v2, |v0|, v2
+; GFX6-NEXT: v_log_f32_e32 v2, v2
+; GFX6-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX6-NEXT: s_mov_b32 s1, 0xc2fc0000
+; GFX6-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX6-NEXT: v_mul_legacy_f32_e32 v1, s0, v1
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX6-NEXT: v_cmp_gt_f32_e32 vcc, s1, v1
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX6-NEXT: v_exp_f32_e32 v1, v1
+; GFX6-NEXT: v_mul_f32_e64 v3, s0, 0.5
+; GFX6-NEXT: v_not_b32_e32 v2, 63
+; GFX6-NEXT: v_trunc_f32_e32 v4, v3
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: v_cmp_lg_f32_e32 vcc, v4, v3
+; GFX6-NEXT: v_trunc_f32_e32 v3, s0
+; GFX6-NEXT: v_ldexp_f32_e32 v1, v1, v2
+; GFX6-NEXT: s_brev_b32 s1, -2
+; GFX6-NEXT: v_cmp_eq_f32_e64 s[2:3], s0, v3
+; GFX6-NEXT: v_bfi_b32 v2, s1, v1, v0
+; GFX6-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc
+; GFX6-NEXT: v_cmp_class_f32_e64 s[2:3], v0, 24
+; GFX6-NEXT: v_cmp_neq_f32_e32 vcc, s0, v3
+; GFX6-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX6-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX6-NEXT: ; return to shader part epilog
;
; GFX8-LABEL: v_pow_f32_vgpr_sgpr:
; GFX8: ; %bb.0:
-; GFX8-NEXT: v_log_f32_e32 v0, v0
-; GFX8-NEXT: v_mul_legacy_f32_e32 v0, s0, v0
-; GFX8-NEXT: v_exp_f32_e32 v0, v0
+; GFX8-NEXT: s_mov_b32 s1, 0x800000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s1
+; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, 32, vcc
+; GFX8-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX8-NEXT: v_log_f32_e32 v2, v2
+; GFX8-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX8-NEXT: s_mov_b32 s1, 0xc2fc0000
+; GFX8-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX8-NEXT: v_mul_legacy_f32_e32 v1, s0, v1
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s1, v1
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX8-NEXT: v_exp_f32_e32 v1, v1
+; GFX8-NEXT: v_mul_f32_e64 v3, s0, 0.5
+; GFX8-NEXT: v_not_b32_e32 v2, 63
+; GFX8-NEXT: v_trunc_f32_e32 v4, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v4, v3
+; GFX8-NEXT: v_trunc_f32_e32 v3, s0
+; GFX8-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX8-NEXT: s_brev_b32 s1, -2
+; GFX8-NEXT: v_cmp_eq_f32_e64 s[2:3], s0, v3
+; GFX8-NEXT: v_bfi_b32 v2, s1, v1, v0
+; GFX8-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 s[2:3], v0, 24
+; GFX8-NEXT: v_cmp_neq_f32_e32 vcc, s0, v3
+; GFX8-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX8-NEXT: ; return to shader part epilog
;
; GFX9-LABEL: v_pow_f32_vgpr_sgpr:
; GFX9: ; %bb.0:
-; GFX9-NEXT: v_log_f32_e32 v0, v0
-; GFX9-NEXT: v_mul_legacy_f32_e32 v0, s0, v0
-; GFX9-NEXT: v_exp_f32_e32 v0, v0
+; GFX9-NEXT: s_mov_b32 s1, 0x800000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s1
+; GFX9-NEXT: v_cndmask_b32_e64 v2, 0, 32, vcc
+; GFX9-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX9-NEXT: v_log_f32_e32 v2, v2
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX9-NEXT: s_mov_b32 s1, 0xc2fc0000
+; GFX9-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX9-NEXT: v_mul_legacy_f32_e32 v1, s0, v1
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, s1, v1
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX9-NEXT: v_exp_f32_e32 v1, v1
+; GFX9-NEXT: v_mul_f32_e64 v3, s0, 0.5
+; GFX9-NEXT: v_not_b32_e32 v2, 63
+; GFX9-NEXT: v_trunc_f32_e32 v4, v3
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: v_cmp_lg_f32_e32 vcc, v4, v3
+; GFX9-NEXT: v_trunc_f32_e32 v3, s0
+; GFX9-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX9-NEXT: s_brev_b32 s1, -2
+; GFX9-NEXT: v_cmp_eq_f32_e64 s[2:3], s0, v3
+; GFX9-NEXT: v_bfi_b32 v2, s1, v1, v0
+; GFX9-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc
+; GFX9-NEXT: v_cmp_class_f32_e64 s[2:3], v0, 24
+; GFX9-NEXT: v_cmp_neq_f32_e32 vcc, s0, v3
+; GFX9-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX9-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX9-NEXT: ; return to shader part epilog
;
; GFX90A-LABEL: v_pow_f32_vgpr_sgpr:
; GFX90A: ; %bb.0:
-; GFX90A-NEXT: v_log_f32_e32 v0, v0
-; GFX90A-NEXT: v_mul_legacy_f32 v0, s0, v0
-; GFX90A-NEXT: v_exp_f32_e32 v0, v0
+; GFX90A-NEXT: s_mov_b32 s1, 0x800000
+; GFX90A-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s1
+; GFX90A-NEXT: v_cndmask_b32_e64 v2, 0, 32, vcc
+; GFX90A-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX90A-NEXT: v_log_f32_e32 v2, v2
+; GFX90A-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX90A-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX90A-NEXT: s_mov_b32 s1, 0xc2fc0000
+; GFX90A-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX90A-NEXT: v_mul_legacy_f32 v1, s0, v1
+; GFX90A-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX90A-NEXT: v_cmp_gt_f32_e32 vcc, s1, v1
+; GFX90A-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX90A-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX90A-NEXT: v_exp_f32_e32 v1, v1
+; GFX90A-NEXT: v_mul_f32_e64 v3, s0, 0.5
+; GFX90A-NEXT: v_not_b32_e32 v2, 63
+; GFX90A-NEXT: v_trunc_f32_e32 v4, v3
+; GFX90A-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX90A-NEXT: v_cmp_lg_f32_e32 vcc, v4, v3
+; GFX90A-NEXT: v_trunc_f32_e32 v3, s0
+; GFX90A-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX90A-NEXT: s_brev_b32 s1, -2
+; GFX90A-NEXT: v_cmp_eq_f32_e64 s[2:3], s0, v3
+; GFX90A-NEXT: v_bfi_b32 v2, s1, v1, v0
+; GFX90A-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc
+; GFX90A-NEXT: v_cmp_class_f32_e64 s[2:3], v0, 24
+; GFX90A-NEXT: v_cmp_neq_f32_e32 vcc, s0, v3
+; GFX90A-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX90A-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
; GFX90A-NEXT: ; return to shader part epilog
;
; GFX10-LABEL: v_pow_f32_vgpr_sgpr:
; GFX10: ; %bb.0:
-; GFX10-NEXT: v_log_f32_e32 v0, v0
-; GFX10-NEXT: v_mul_legacy_f32_e32 v0, s0, v0
-; GFX10-NEXT: v_exp_f32_e32 v0, v0
+; GFX10-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v0|
+; GFX10-NEXT: v_trunc_f32_e32 v5, s0
+; GFX10-NEXT: v_cmp_class_f32_e64 s2, v0, 24
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 32, s1
+; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42000000, s1
+; GFX10-NEXT: v_cmp_eq_f32_e64 s1, s0, v5
+; GFX10-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX10-NEXT: v_log_f32_e32 v2, v2
+; GFX10-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX10-NEXT: v_mul_legacy_f32_e32 v1, s0, v1
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX10-NEXT: v_mul_f32_e64 v2, s0, 0.5
+; GFX10-NEXT: v_cmp_neq_f32_e64 s0, s0, v5
+; GFX10-NEXT: v_exp_f32_e32 v1, v1
+; GFX10-NEXT: v_trunc_f32_e32 v4, v2
+; GFX10-NEXT: s_and_b32 s0, s2, s0
+; GFX10-NEXT: v_cmp_lg_f32_e32 vcc_lo, v4, v2
+; GFX10-NEXT: v_ldexp_f32 v1, v1, v3
+; GFX10-NEXT: s_and_b32 vcc_lo, s1, vcc_lo
+; GFX10-NEXT: v_bfi_b32 v2, 0x7fffffff, v1, v0
+; GFX10-NEXT: v_cndmask_b32_e32 v0, v1, v2, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX10-NEXT: ; return to shader part epilog
;
; GFX11-LABEL: v_pow_f32_vgpr_sgpr:
; GFX11: ; %bb.0:
-; GFX11-NEXT: v_log_f32_e32 v0, v0
+; GFX11-NEXT: v_cmp_gt_f32_e64 s1, 0x800000, |v0|
+; GFX11-NEXT: v_trunc_f32_e32 v5, s0
+; GFX11-NEXT: v_cmp_class_f32_e64 s2, v0, 24
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_4)
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 32, s1
+; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42000000, s1
+; GFX11-NEXT: v_cmp_eq_f32_e64 s1, s0, v5
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX11-NEXT: v_log_f32_e32 v2, v2
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v1, s0, v1
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v1
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_3)
+; GFX11-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX11-NEXT: v_mul_f32_e64 v2, s0, 0.5
+; GFX11-NEXT: v_cmp_neq_f32_e64 s0, s0, v5
+; GFX11-NEXT: v_exp_f32_e32 v1, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_trunc_f32_e32 v4, v2
+; GFX11-NEXT: s_and_b32 s0, s2, s0
+; GFX11-NEXT: v_cmp_lg_f32_e32 vcc_lo, v4, v2
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, s0, v0
+; GFX11-NEXT: v_ldexp_f32 v1, v1, v3
+; GFX11-NEXT: s_and_b32 vcc_lo, s1, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_bfi_b32 v2, 0x7fffffff, v1, v0
+; GFX11-NEXT: v_cndmask_b32_e32 v0, v1, v2, vcc_lo
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
-; GFX11-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX11-NEXT: ; return to shader part epilog
%pow = call float @llvm.pow.f32(float %x, float %y)
ret float %pow
@@ -1086,51 +3924,1143 @@ define amdgpu_ps float @v_pow_f32_vgpr_sgpr(float %x, float inreg %y) {
define amdgpu_ps float @v_pow_f32_sgpr_sgpr(float inreg %x, float inreg %y) {
; GFX6-LABEL: v_pow_f32_sgpr_sgpr:
; GFX6: ; %bb.0:
-; GFX6-NEXT: v_log_f32_e32 v0, s0
+; GFX6-NEXT: v_mov_b32_e32 v0, 0x800000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |s0|, v0
+; GFX6-NEXT: s_and_b64 s[2:3], vcc, exec
+; GFX6-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX6-NEXT: s_cselect_b32 s2, 32, 0
+; GFX6-NEXT: v_cndmask_b32_e32 v0, 0, v1, vcc
+; GFX6-NEXT: v_mov_b32_e32 v1, s2
+; GFX6-NEXT: v_ldexp_f32_e64 v1, |s0|, v1
+; GFX6-NEXT: v_log_f32_e32 v1, v1
+; GFX6-NEXT: s_mov_b32 s2, 0xc2fc0000
+; GFX6-NEXT: v_mul_f32_e64 v2, s1, 0.5
+; GFX6-NEXT: v_trunc_f32_e32 v3, v2
+; GFX6-NEXT: v_sub_f32_e32 v0, v1, v0
; GFX6-NEXT: v_mul_legacy_f32_e32 v0, s1, v0
+; GFX6-NEXT: v_mov_b32_e32 v1, 0x42800000
+; GFX6-NEXT: v_cmp_gt_f32_e32 vcc, s2, v0
+; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX6-NEXT: v_add_f32_e32 v0, v0, v1
; GFX6-NEXT: v_exp_f32_e32 v0, v0
+; GFX6-NEXT: s_and_b64 s[2:3], vcc, exec
+; GFX6-NEXT: s_cselect_b32 s2, 0xffffffc0, 0
+; GFX6-NEXT: v_mov_b32_e32 v1, s0
+; GFX6-NEXT: v_ldexp_f32_e64 v0, v0, s2
+; GFX6-NEXT: s_brev_b32 s2, -2
+; GFX6-NEXT: v_cmp_lg_f32_e32 vcc, v3, v2
+; GFX6-NEXT: v_trunc_f32_e32 v2, s1
+; GFX6-NEXT: v_bfi_b32 v1, s2, v0, v1
+; GFX6-NEXT: v_cmp_eq_f32_e64 s[2:3], s1, v2
+; GFX6-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc
+; GFX6-NEXT: v_cmp_class_f32_e64 s[2:3], s0, 24
+; GFX6-NEXT: v_cmp_neq_f32_e32 vcc, s1, v2
+; GFX6-NEXT: v_mov_b32_e32 v1, 0x7fc00000
+; GFX6-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc
; GFX6-NEXT: ; return to shader part epilog
;
; GFX8-LABEL: v_pow_f32_sgpr_sgpr:
; GFX8: ; %bb.0:
-; GFX8-NEXT: v_log_f32_e32 v0, s0
+; GFX8-NEXT: v_mov_b32_e32 v0, 0x800000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |s0|, v0
+; GFX8-NEXT: s_and_b64 s[2:3], vcc, exec
+; GFX8-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX8-NEXT: s_cselect_b32 s2, 32, 0
+; GFX8-NEXT: v_cndmask_b32_e32 v0, 0, v1, vcc
+; GFX8-NEXT: v_mov_b32_e32 v1, s2
+; GFX8-NEXT: v_ldexp_f32 v1, |s0|, v1
+; GFX8-NEXT: v_log_f32_e32 v1, v1
+; GFX8-NEXT: s_mov_b32 s2, 0xc2fc0000
+; GFX8-NEXT: v_mul_f32_e64 v2, s1, 0.5
+; GFX8-NEXT: v_trunc_f32_e32 v3, v2
+; GFX8-NEXT: v_sub_f32_e32 v0, v1, v0
; GFX8-NEXT: v_mul_legacy_f32_e32 v0, s1, v0
+; GFX8-NEXT: v_mov_b32_e32 v1, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s2, v0
+; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX8-NEXT: v_add_f32_e32 v0, v0, v1
; GFX8-NEXT: v_exp_f32_e32 v0, v0
+; GFX8-NEXT: s_and_b64 s[2:3], vcc, exec
+; GFX8-NEXT: s_cselect_b32 s2, 0xffffffc0, 0
+; GFX8-NEXT: v_mov_b32_e32 v1, s0
+; GFX8-NEXT: v_ldexp_f32 v0, v0, s2
+; GFX8-NEXT: s_brev_b32 s2, -2
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v3, v2
+; GFX8-NEXT: v_trunc_f32_e32 v2, s1
+; GFX8-NEXT: v_bfi_b32 v1, s2, v0, v1
+; GFX8-NEXT: v_cmp_eq_f32_e64 s[2:3], s1, v2
+; GFX8-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 s[2:3], s0, 24
+; GFX8-NEXT: v_cmp_neq_f32_e32 vcc, s1, v2
+; GFX8-NEXT: v_mov_b32_e32 v1, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc
; GFX8-NEXT: ; return to shader part epilog
;
; GFX9-LABEL: v_pow_f32_sgpr_sgpr:
; GFX9: ; %bb.0:
-; GFX9-NEXT: v_log_f32_e32 v0, s0
+; GFX9-NEXT: v_mov_b32_e32 v0, 0x800000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |s0|, v0
+; GFX9-NEXT: s_and_b64 s[2:3], vcc, exec
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX9-NEXT: s_cselect_b32 s2, 32, 0
+; GFX9-NEXT: v_cndmask_b32_e32 v0, 0, v1, vcc
+; GFX9-NEXT: v_mov_b32_e32 v1, s2
+; GFX9-NEXT: v_ldexp_f32 v1, |s0|, v1
+; GFX9-NEXT: v_log_f32_e32 v1, v1
+; GFX9-NEXT: s_mov_b32 s2, 0xc2fc0000
+; GFX9-NEXT: v_mul_f32_e64 v2, s1, 0.5
+; GFX9-NEXT: v_trunc_f32_e32 v3, v2
+; GFX9-NEXT: v_sub_f32_e32 v0, v1, v0
; GFX9-NEXT: v_mul_legacy_f32_e32 v0, s1, v0
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x42800000
+; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, s2, v0
+; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX9-NEXT: v_add_f32_e32 v0, v0, v1
; GFX9-NEXT: v_exp_f32_e32 v0, v0
+; GFX9-NEXT: s_and_b64 s[2:3], vcc, exec
+; GFX9-NEXT: s_cselect_b32 s2, 0xffffffc0, 0
+; GFX9-NEXT: v_mov_b32_e32 v1, s0
+; GFX9-NEXT: v_ldexp_f32 v0, v0, s2
+; GFX9-NEXT: s_brev_b32 s2, -2
+; GFX9-NEXT: v_cmp_lg_f32_e32 vcc, v3, v2
+; GFX9-NEXT: v_trunc_f32_e32 v2, s1
+; GFX9-NEXT: v_bfi_b32 v1, s2, v0, v1
+; GFX9-NEXT: v_cmp_eq_f32_e64 s[2:3], s1, v2
+; GFX9-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc
+; GFX9-NEXT: v_cmp_class_f32_e64 s[2:3], s0, 24
+; GFX9-NEXT: v_cmp_neq_f32_e32 vcc, s1, v2
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x7fc00000
+; GFX9-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc
; GFX9-NEXT: ; return to shader part epilog
;
; GFX90A-LABEL: v_pow_f32_sgpr_sgpr:
; GFX90A: ; %bb.0:
-; GFX90A-NEXT: v_log_f32_e32 v0, s0
+; GFX90A-NEXT: v_mov_b32_e32 v0, 0x800000
+; GFX90A-NEXT: v_cmp_lt_f32_e64 vcc, |s0|, v0
+; GFX90A-NEXT: s_and_b64 s[2:3], vcc, exec
+; GFX90A-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX90A-NEXT: s_cselect_b32 s2, 32, 0
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, 0, v1, vcc
+; GFX90A-NEXT: v_mov_b32_e32 v1, s2
+; GFX90A-NEXT: v_ldexp_f32 v1, |s0|, v1
+; GFX90A-NEXT: v_log_f32_e32 v1, v1
+; GFX90A-NEXT: s_mov_b32 s2, 0xc2fc0000
+; GFX90A-NEXT: v_mul_f32_e64 v2, s1, 0.5
+; GFX90A-NEXT: v_trunc_f32_e32 v3, v2
+; GFX90A-NEXT: v_sub_f32_e32 v0, v1, v0
; GFX90A-NEXT: v_mul_legacy_f32 v0, s1, v0
+; GFX90A-NEXT: v_mov_b32_e32 v1, 0x42800000
+; GFX90A-NEXT: v_cmp_gt_f32_e32 vcc, s2, v0
+; GFX90A-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX90A-NEXT: v_add_f32_e32 v0, v0, v1
; GFX90A-NEXT: v_exp_f32_e32 v0, v0
+; GFX90A-NEXT: s_and_b64 s[2:3], vcc, exec
+; GFX90A-NEXT: s_cselect_b32 s2, 0xffffffc0, 0
+; GFX90A-NEXT: v_mov_b32_e32 v1, s0
+; GFX90A-NEXT: v_ldexp_f32 v0, v0, s2
+; GFX90A-NEXT: s_brev_b32 s2, -2
+; GFX90A-NEXT: v_cmp_lg_f32_e32 vcc, v3, v2
+; GFX90A-NEXT: v_trunc_f32_e32 v2, s1
+; GFX90A-NEXT: v_bfi_b32 v1, s2, v0, v1
+; GFX90A-NEXT: v_cmp_eq_f32_e64 s[2:3], s1, v2
+; GFX90A-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc
+; GFX90A-NEXT: v_cmp_class_f32_e64 s[2:3], s0, 24
+; GFX90A-NEXT: v_cmp_neq_f32_e32 vcc, s1, v2
+; GFX90A-NEXT: v_mov_b32_e32 v1, 0x7fc00000
+; GFX90A-NEXT: s_and_b64 vcc, s[2:3], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc
; GFX90A-NEXT: ; return to shader part epilog
;
; GFX10-LABEL: v_pow_f32_sgpr_sgpr:
; GFX10: ; %bb.0:
-; GFX10-NEXT: v_log_f32_e32 v0, s0
+; GFX10-NEXT: v_cmp_gt_f32_e64 s2, 0x800000, |s0|
+; GFX10-NEXT: v_trunc_f32_e32 v3, s1
+; GFX10-NEXT: v_cmp_class_f32_e64 s3, s0, 24
+; GFX10-NEXT: v_cndmask_b32_e64 v0, 0, 0x42000000, s2
+; GFX10-NEXT: s_and_b32 s2, s2, exec_lo
+; GFX10-NEXT: s_cselect_b32 s2, 32, 0
+; GFX10-NEXT: v_ldexp_f32 v1, |s0|, s2
+; GFX10-NEXT: v_log_f32_e32 v1, v1
+; GFX10-NEXT: v_sub_f32_e32 v0, v1, v0
; GFX10-NEXT: v_mul_legacy_f32_e32 v0, s1, v0
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
+; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: s_and_b32 s2, vcc_lo, exec_lo
+; GFX10-NEXT: s_cselect_b32 s2, 0xffffffc0, 0
+; GFX10-NEXT: v_add_f32_e32 v0, v0, v1
+; GFX10-NEXT: v_mul_f32_e64 v1, s1, 0.5
; GFX10-NEXT: v_exp_f32_e32 v0, v0
+; GFX10-NEXT: v_trunc_f32_e32 v2, v1
+; GFX10-NEXT: v_cmp_lg_f32_e32 vcc_lo, v2, v1
+; GFX10-NEXT: v_ldexp_f32 v0, v0, s2
+; GFX10-NEXT: v_cmp_eq_f32_e64 s2, s1, v3
+; GFX10-NEXT: v_bfi_b32 v1, 0x7fffffff, v0, s0
+; GFX10-NEXT: v_cmp_neq_f32_e64 s0, s1, v3
+; GFX10-NEXT: s_and_b32 vcc_lo, s2, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc_lo
+; GFX10-NEXT: s_and_b32 s0, s3, s0
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX10-NEXT: ; return to shader part epilog
;
; GFX11-LABEL: v_pow_f32_sgpr_sgpr:
; GFX11: ; %bb.0:
-; GFX11-NEXT: v_log_f32_e32 v0, s0
+; GFX11-NEXT: v_cmp_gt_f32_e64 s2, 0x800000, |s0|
+; GFX11-NEXT: v_trunc_f32_e32 v3, s1
+; GFX11-NEXT: v_cmp_class_f32_e64 s3, s0, 24
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_2) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_cndmask_b32_e64 v0, 0, 0x42000000, s2
+; GFX11-NEXT: s_and_b32 s2, s2, exec_lo
+; GFX11-NEXT: s_cselect_b32 s2, 32, 0
+; GFX11-NEXT: v_ldexp_f32 v1, |s0|, s2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_log_f32_e32 v1, v1
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_sub_f32_e32 v0, v1, v0
; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, s1, v0
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_3) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
+; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: s_and_b32 s2, vcc_lo, exec_lo
+; GFX11-NEXT: s_cselect_b32 s2, 0xffffffc0, 0
+; GFX11-NEXT: v_add_f32_e32 v0, v0, v1
+; GFX11-NEXT: v_mul_f32_e64 v1, s1, 0.5
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX11-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-NEXT: v_trunc_f32_e32 v2, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_3) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_cmp_lg_f32_e32 vcc_lo, v2, v1
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_ldexp_f32 v0, v0, s2
+; GFX11-NEXT: v_cmp_eq_f32_e64 s2, s1, v3
+; GFX11-NEXT: v_bfi_b32 v1, 0x7fffffff, v0, s0
+; GFX11-NEXT: v_cmp_neq_f32_e64 s0, s1, v3
+; GFX11-NEXT: s_and_b32 vcc_lo, s2, vcc_lo
+; GFX11-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc_lo
+; GFX11-NEXT: s_and_b32 s0, s3, s0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX11-NEXT: ; return to shader part epilog
%pow = call float @llvm.pow.f32(float %x, float %y)
ret float %pow
}
+define float @v_pow_f32_afn(float %x, float %y) {
+; GFX6-LABEL: v_pow_f32_afn:
+; GFX6: ; %bb.0:
+; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX6-NEXT: v_log_f32_e32 v0, v0
+; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX6-NEXT: v_exp_f32_e32 v0, v0
+; GFX6-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX8-LABEL: v_pow_f32_afn:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8-NEXT: v_log_f32_e32 v0, v0
+; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX8-NEXT: v_exp_f32_e32 v0, v0
+; GFX8-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: v_pow_f32_afn:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: v_log_f32_e32 v0, v0
+; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX9-NEXT: v_exp_f32_e32 v0, v0
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX90A-LABEL: v_pow_f32_afn:
+; GFX90A: ; %bb.0:
+; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX90A-NEXT: v_log_f32_e32 v0, v0
+; GFX90A-NEXT: v_mul_legacy_f32 v0, v1, v0
+; GFX90A-NEXT: v_exp_f32_e32 v0, v0
+; GFX90A-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: v_pow_f32_afn:
+; GFX10: ; %bb.0:
+; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT: v_log_f32_e32 v0, v0
+; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX10-NEXT: v_exp_f32_e32 v0, v0
+; GFX10-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: v_pow_f32_afn:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: v_log_f32_e32 v0, v0
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-NEXT: s_setpc_b64 s[30:31]
+ %pow = call afn float @llvm.pow.f32(float %x, float %y)
+ ret float %pow
+}
+
+define half @v_pow_f16_afn(half %x, half %y) {
+; GFX6-LABEL: v_pow_f16_afn:
+; GFX6: ; %bb.0:
+; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX6-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX6-NEXT: v_cvt_f32_f16_e32 v1, v1
+; GFX6-NEXT: v_log_f32_e32 v0, v0
+; GFX6-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX6-NEXT: v_exp_f32_e32 v0, v0
+; GFX6-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GFX6-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX8-LABEL: v_pow_f16_afn:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX8-NEXT: v_cvt_f32_f16_e32 v1, v1
+; GFX8-NEXT: v_log_f32_e32 v0, v0
+; GFX8-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX8-NEXT: v_exp_f32_e32 v0, v0
+; GFX8-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GFX8-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: v_pow_f16_afn:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX9-NEXT: v_cvt_f32_f16_e32 v1, v1
+; GFX9-NEXT: v_log_f32_e32 v0, v0
+; GFX9-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX9-NEXT: v_exp_f32_e32 v0, v0
+; GFX9-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX90A-LABEL: v_pow_f16_afn:
+; GFX90A: ; %bb.0:
+; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX90A-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX90A-NEXT: v_cvt_f32_f16_e32 v1, v1
+; GFX90A-NEXT: v_log_f32_e32 v0, v0
+; GFX90A-NEXT: v_mul_legacy_f32 v0, v1, v0
+; GFX90A-NEXT: v_exp_f32_e32 v0, v0
+; GFX90A-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GFX90A-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: v_pow_f16_afn:
+; GFX10: ; %bb.0:
+; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX10-NEXT: v_cvt_f32_f16_e32 v1, v1
+; GFX10-NEXT: v_log_f32_e32 v0, v0
+; GFX10-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
+; GFX10-NEXT: v_exp_f32_e32 v0, v0
+; GFX10-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GFX10-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-TRUE16-LABEL: v_pow_f16_afn:
+; GFX11-TRUE16: ; %bb.0:
+; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.l
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v1, v1.l
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v0, v0
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v0
+; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-FAKE16-LABEL: v_pow_f16_afn:
+; GFX11-FAKE16: ; %bb.0:
+; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v1, v1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v0, v0
+; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
+ %pow = call afn half @llvm.pow.f16(half %x, half %y)
+ ret half %pow
+}
+
+define float @v_pow_f32_const_even_int(float %x) {
+; GFX6-LABEL: v_pow_f32_const_even_int:
+; GFX6: ; %bb.0:
+; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX6-NEXT: s_mov_b32 s4, 0x800000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX6-NEXT: v_cndmask_b32_e64 v2, 0, 32, vcc
+; GFX6-NEXT: v_ldexp_f32_e64 v0, |v0|, v2
+; GFX6-NEXT: v_log_f32_e32 v0, v0
+; GFX6-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX6-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX6-NEXT: v_sub_f32_e32 v0, v0, v1
+; GFX6-NEXT: v_mul_legacy_f32_e32 v0, 2.0, v0
+; GFX6-NEXT: v_mov_b32_e32 v1, 0x42800000
+; GFX6-NEXT: v_cmp_gt_f32_e32 vcc, s4, v0
+; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX6-NEXT: v_add_f32_e32 v0, v0, v1
+; GFX6-NEXT: v_exp_f32_e32 v0, v0
+; GFX6-NEXT: v_not_b32_e32 v1, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX6-NEXT: v_ldexp_f32_e32 v0, v0, v1
+; GFX6-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX8-LABEL: v_pow_f32_const_even_int:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8-NEXT: s_mov_b32 s4, 0x800000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, 32, vcc
+; GFX8-NEXT: v_ldexp_f32 v0, |v0|, v2
+; GFX8-NEXT: v_log_f32_e32 v0, v0
+; GFX8-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX8-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX8-NEXT: v_sub_f32_e32 v0, v0, v1
+; GFX8-NEXT: v_mul_legacy_f32_e32 v0, 2.0, v0
+; GFX8-NEXT: v_mov_b32_e32 v1, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s4, v0
+; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX8-NEXT: v_add_f32_e32 v0, v0, v1
+; GFX8-NEXT: v_exp_f32_e32 v0, v0
+; GFX8-NEXT: v_not_b32_e32 v1, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX8-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX8-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: v_pow_f32_const_even_int:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: s_mov_b32 s4, 0x800000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX9-NEXT: v_cndmask_b32_e64 v2, 0, 32, vcc
+; GFX9-NEXT: v_ldexp_f32 v0, |v0|, v2
+; GFX9-NEXT: v_log_f32_e32 v0, v0
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX9-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX9-NEXT: v_sub_f32_e32 v0, v0, v1
+; GFX9-NEXT: v_mul_legacy_f32_e32 v0, 2.0, v0
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x42800000
+; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, s4, v0
+; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX9-NEXT: v_add_f32_e32 v0, v0, v1
+; GFX9-NEXT: v_exp_f32_e32 v0, v0
+; GFX9-NEXT: v_not_b32_e32 v1, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX9-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX90A-LABEL: v_pow_f32_const_even_int:
+; GFX90A: ; %bb.0:
+; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX90A-NEXT: s_mov_b32 s4, 0x800000
+; GFX90A-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX90A-NEXT: v_cndmask_b32_e64 v2, 0, 32, vcc
+; GFX90A-NEXT: v_ldexp_f32 v0, |v0|, v2
+; GFX90A-NEXT: v_log_f32_e32 v0, v0
+; GFX90A-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX90A-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX90A-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX90A-NEXT: v_sub_f32_e32 v0, v0, v1
+; GFX90A-NEXT: v_mul_legacy_f32 v0, 2.0, v0
+; GFX90A-NEXT: v_mov_b32_e32 v1, 0x42800000
+; GFX90A-NEXT: v_cmp_gt_f32_e32 vcc, s4, v0
+; GFX90A-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX90A-NEXT: v_add_f32_e32 v0, v0, v1
+; GFX90A-NEXT: v_exp_f32_e32 v0, v0
+; GFX90A-NEXT: v_not_b32_e32 v1, 63
+; GFX90A-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX90A-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX90A-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: v_pow_f32_const_even_int:
+; GFX10: ; %bb.0:
+; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v0|
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 32, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42000000, s4
+; GFX10-NEXT: v_ldexp_f32 v0, |v0|, v2
+; GFX10-NEXT: v_log_f32_e32 v0, v0
+; GFX10-NEXT: v_sub_f32_e32 v0, v0, v1
+; GFX10-NEXT: v_mul_legacy_f32_e32 v0, 2.0, v0
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
+; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v0, v0, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_exp_f32_e32 v0, v0
+; GFX10-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX10-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: v_pow_f32_const_even_int:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 32, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42000000, s0
+; GFX11-NEXT: v_ldexp_f32 v0, |v0|, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_log_f32_e32 v0, v0
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_sub_f32_e32 v0, v0, v1
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, 2.0, v0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v0
+; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_add_f32_e32 v0, v0, v1
+; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2)
+; GFX11-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_ldexp_f32 v0, v0, v1
+; GFX11-NEXT: s_setpc_b64 s[30:31]
+ %pow = call float @llvm.pow.f32(float %x, float 2.0)
+ ret float %pow
+}
+
+define float @v_pow_f32_const_odd_int(float %x) {
+; GFX6-LABEL: v_pow_f32_const_odd_int:
+; GFX6: ; %bb.0:
+; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX6-NEXT: s_mov_b32 s4, 0x800000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX6-NEXT: v_cndmask_b32_e64 v2, 0, 32, vcc
+; GFX6-NEXT: v_ldexp_f32_e64 v2, |v0|, v2
+; GFX6-NEXT: v_log_f32_e32 v2, v2
+; GFX6-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX6-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX6-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX6-NEXT: v_mul_legacy_f32_e32 v1, 0x40400000, v1
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX6-NEXT: v_cmp_gt_f32_e32 vcc, s4, v1
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX6-NEXT: v_exp_f32_e32 v1, v1
+; GFX6-NEXT: v_not_b32_e32 v2, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: s_brev_b32 s4, -2
+; GFX6-NEXT: v_ldexp_f32_e32 v1, v1, v2
+; GFX6-NEXT: v_bfi_b32 v0, s4, v1, v0
+; GFX6-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX8-LABEL: v_pow_f32_const_odd_int:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8-NEXT: s_mov_b32 s4, 0x800000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, 32, vcc
+; GFX8-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX8-NEXT: v_log_f32_e32 v2, v2
+; GFX8-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX8-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX8-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX8-NEXT: v_mul_legacy_f32_e32 v1, 0x40400000, v1
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s4, v1
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX8-NEXT: v_exp_f32_e32 v1, v1
+; GFX8-NEXT: v_not_b32_e32 v2, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: s_brev_b32 s4, -2
+; GFX8-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX8-NEXT: v_bfi_b32 v0, s4, v1, v0
+; GFX8-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: v_pow_f32_const_odd_int:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: s_mov_b32 s4, 0x800000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX9-NEXT: v_cndmask_b32_e64 v2, 0, 32, vcc
+; GFX9-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX9-NEXT: v_log_f32_e32 v2, v2
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX9-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX9-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX9-NEXT: v_mul_legacy_f32_e32 v1, 0x40400000, v1
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, s4, v1
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX9-NEXT: v_exp_f32_e32 v1, v1
+; GFX9-NEXT: v_not_b32_e32 v2, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: s_brev_b32 s4, -2
+; GFX9-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX9-NEXT: v_bfi_b32 v0, s4, v1, v0
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX90A-LABEL: v_pow_f32_const_odd_int:
+; GFX90A: ; %bb.0:
+; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX90A-NEXT: s_mov_b32 s4, 0x800000
+; GFX90A-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX90A-NEXT: v_cndmask_b32_e64 v2, 0, 32, vcc
+; GFX90A-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX90A-NEXT: v_log_f32_e32 v2, v2
+; GFX90A-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX90A-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX90A-NEXT: s_mov_b32 s4, 0x40400000
+; GFX90A-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX90A-NEXT: v_mul_legacy_f32 v1, s4, v1
+; GFX90A-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX90A-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX90A-NEXT: v_cmp_gt_f32_e32 vcc, s4, v1
+; GFX90A-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX90A-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX90A-NEXT: v_exp_f32_e32 v1, v1
+; GFX90A-NEXT: v_not_b32_e32 v2, 63
+; GFX90A-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX90A-NEXT: s_brev_b32 s4, -2
+; GFX90A-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX90A-NEXT: v_bfi_b32 v0, s4, v1, v0
+; GFX90A-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: v_pow_f32_const_odd_int:
+; GFX10: ; %bb.0:
+; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v0|
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 32, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42000000, s4
+; GFX10-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX10-NEXT: v_log_f32_e32 v2, v2
+; GFX10-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX10-NEXT: v_mul_legacy_f32_e32 v1, 0x40400000, v1
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_exp_f32_e32 v1, v1
+; GFX10-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX10-NEXT: v_bfi_b32 v0, 0x7fffffff, v1, v0
+; GFX10-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: v_pow_f32_const_odd_int:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 32, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42000000, s0
+; GFX11-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_log_f32_e32 v2, v2
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v1, 0x40400000, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v1
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_exp_f32_e32 v1, v1
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX11-NEXT: v_bfi_b32 v0, 0x7fffffff, v1, v0
+; GFX11-NEXT: s_setpc_b64 s[30:31]
+ %pow = call float @llvm.pow.f32(float %x, float 3.0)
+ ret float %pow
+}
+
+define float @v_pow_f32_const_non_int(float %x) {
+; GFX6-LABEL: v_pow_f32_const_non_int:
+; GFX6: ; %bb.0:
+; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX6-NEXT: s_mov_b32 s4, 0x800000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX6-NEXT: v_cndmask_b32_e64 v2, 0, 32, vcc
+; GFX6-NEXT: v_ldexp_f32_e64 v2, |v0|, v2
+; GFX6-NEXT: v_log_f32_e32 v2, v2
+; GFX6-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX6-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX6-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX6-NEXT: v_mul_legacy_f32_e32 v1, 0.5, v1
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX6-NEXT: v_cmp_gt_f32_e32 vcc, s4, v1
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX6-NEXT: v_exp_f32_e32 v1, v1
+; GFX6-NEXT: v_not_b32_e32 v2, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: v_cmp_class_f32_e64 vcc, v0, 24
+; GFX6-NEXT: v_ldexp_f32_e32 v1, v1, v2
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v1, v2, vcc
+; GFX6-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX8-LABEL: v_pow_f32_const_non_int:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8-NEXT: s_mov_b32 s4, 0x800000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX8-NEXT: v_cndmask_b32_e64 v2, 0, 32, vcc
+; GFX8-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX8-NEXT: v_log_f32_e32 v2, v2
+; GFX8-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX8-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX8-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX8-NEXT: v_mul_legacy_f32_e32 v1, 0.5, v1
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s4, v1
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX8-NEXT: v_exp_f32_e32 v1, v1
+; GFX8-NEXT: v_not_b32_e32 v2, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 vcc, v0, 24
+; GFX8-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v1, v2, vcc
+; GFX8-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: v_pow_f32_const_non_int:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: s_mov_b32 s4, 0x800000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX9-NEXT: v_cndmask_b32_e64 v2, 0, 32, vcc
+; GFX9-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX9-NEXT: v_log_f32_e32 v2, v2
+; GFX9-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX9-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX9-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX9-NEXT: v_mul_legacy_f32_e32 v1, 0.5, v1
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, s4, v1
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX9-NEXT: v_exp_f32_e32 v1, v1
+; GFX9-NEXT: v_not_b32_e32 v2, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: v_cmp_class_f32_e64 vcc, v0, 24
+; GFX9-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v1, v2, vcc
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX90A-LABEL: v_pow_f32_const_non_int:
+; GFX90A: ; %bb.0:
+; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX90A-NEXT: s_mov_b32 s4, 0x800000
+; GFX90A-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX90A-NEXT: v_cndmask_b32_e64 v2, 0, 32, vcc
+; GFX90A-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX90A-NEXT: v_log_f32_e32 v2, v2
+; GFX90A-NEXT: v_mov_b32_e32 v1, 0x42000000
+; GFX90A-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
+; GFX90A-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX90A-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX90A-NEXT: v_mul_legacy_f32 v1, 0.5, v1
+; GFX90A-NEXT: v_mov_b32_e32 v2, 0x42800000
+; GFX90A-NEXT: v_cmp_gt_f32_e32 vcc, s4, v1
+; GFX90A-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX90A-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX90A-NEXT: v_exp_f32_e32 v1, v1
+; GFX90A-NEXT: v_not_b32_e32 v2, 63
+; GFX90A-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX90A-NEXT: v_cmp_class_f32_e64 vcc, v0, 24
+; GFX90A-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX90A-NEXT: v_mov_b32_e32 v2, 0x7fc00000
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v1, v2, vcc
+; GFX90A-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: v_pow_f32_const_non_int:
+; GFX10: ; %bb.0:
+; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v0|
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 32, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v1, 0, 0x42000000, s4
+; GFX10-NEXT: v_cmp_class_f32_e64 s4, v0, 24
+; GFX10-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX10-NEXT: v_log_f32_e32 v2, v2
+; GFX10-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX10-NEXT: v_mul_legacy_f32_e32 v1, 0.5, v1
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_exp_f32_e32 v1, v1
+; GFX10-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v1, 0x7fc00000, s4
+; GFX10-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: v_pow_f32_const_non_int:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_3)
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 32, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v1, 0, 0x42000000, s0
+; GFX11-NEXT: v_cmp_class_f32_e64 s0, v0, 24
+; GFX11-NEXT: v_ldexp_f32 v2, |v0|, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_log_f32_e32 v2, v2
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_sub_f32_e32 v1, v2, v1
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v1, 0.5, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v1
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_add_f32_e32 v1, v1, v2
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_exp_f32_e32 v1, v1
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_ldexp_f32 v1, v1, v2
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v1, 0x7fc00000, s0
+; GFX11-NEXT: s_setpc_b64 s[30:31]
+ %pow = call float @llvm.pow.f32(float %x, float 5.000000e-01)
+ ret float %pow
+}
+
+define float @v_pow_f32_nnan(float %x, float %y) {
+; GFX6-LABEL: v_pow_f32_nnan:
+; GFX6: ; %bb.0:
+; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX6-NEXT: s_mov_b32 s4, 0x800000
+; GFX6-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX6-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX6-NEXT: v_ldexp_f32_e64 v3, |v0|, v3
+; GFX6-NEXT: v_log_f32_e32 v3, v3
+; GFX6-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX6-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX6-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX6-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX6-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX6-NEXT: v_cmp_gt_f32_e32 vcc, s4, v2
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_exp_f32_e32 v2, v2
+; GFX6-NEXT: v_not_b32_e32 v3, 63
+; GFX6-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX6-NEXT: s_brev_b32 s4, -2
+; GFX6-NEXT: v_ldexp_f32_e32 v2, v2, v3
+; GFX6-NEXT: v_mul_f32_e32 v3, 0.5, v1
+; GFX6-NEXT: v_trunc_f32_e32 v4, v3
+; GFX6-NEXT: v_cmp_lg_f32_e32 vcc, v4, v3
+; GFX6-NEXT: v_trunc_f32_e32 v3, v1
+; GFX6-NEXT: v_bfi_b32 v0, s4, v2, v0
+; GFX6-NEXT: v_cmp_eq_f32_e64 s[4:5], v3, v1
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
+; GFX6-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX8-LABEL: v_pow_f32_nnan:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8-NEXT: s_mov_b32 s4, 0x800000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX8-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX8-NEXT: v_ldexp_f32 v3, |v0|, v3
+; GFX8-NEXT: v_log_f32_e32 v3, v3
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX8-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s4, v2
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_exp_f32_e32 v2, v2
+; GFX8-NEXT: v_not_b32_e32 v3, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: s_brev_b32 s4, -2
+; GFX8-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX8-NEXT: v_mul_f32_e32 v3, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v4, v3
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v4, v3
+; GFX8-NEXT: v_trunc_f32_e32 v3, v1
+; GFX8-NEXT: v_bfi_b32 v0, s4, v2, v0
+; GFX8-NEXT: v_cmp_eq_f32_e64 s[4:5], v3, v1
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
+; GFX8-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: v_pow_f32_nnan:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: s_mov_b32 s4, 0x800000
+; GFX9-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX9-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX9-NEXT: v_ldexp_f32 v3, |v0|, v3
+; GFX9-NEXT: v_log_f32_e32 v3, v3
+; GFX9-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX9-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX9-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX9-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX9-NEXT: v_cmp_gt_f32_e32 vcc, s4, v2
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX9-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX9-NEXT: v_exp_f32_e32 v2, v2
+; GFX9-NEXT: v_not_b32_e32 v3, 63
+; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX9-NEXT: s_brev_b32 s4, -2
+; GFX9-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX9-NEXT: v_mul_f32_e32 v3, 0.5, v1
+; GFX9-NEXT: v_trunc_f32_e32 v4, v3
+; GFX9-NEXT: v_cmp_lg_f32_e32 vcc, v4, v3
+; GFX9-NEXT: v_trunc_f32_e32 v3, v1
+; GFX9-NEXT: v_bfi_b32 v0, s4, v2, v0
+; GFX9-NEXT: v_cmp_eq_f32_e64 s[4:5], v3, v1
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX90A-LABEL: v_pow_f32_nnan:
+; GFX90A: ; %bb.0:
+; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX90A-NEXT: s_mov_b32 s4, 0x800000
+; GFX90A-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX90A-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX90A-NEXT: v_ldexp_f32 v3, |v0|, v3
+; GFX90A-NEXT: v_log_f32_e32 v3, v3
+; GFX90A-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX90A-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX90A-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX90A-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX90A-NEXT: v_mul_legacy_f32 v2, v1, v2
+; GFX90A-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX90A-NEXT: v_cmp_gt_f32_e32 vcc, s4, v2
+; GFX90A-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX90A-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX90A-NEXT: v_exp_f32_e32 v2, v2
+; GFX90A-NEXT: v_not_b32_e32 v3, 63
+; GFX90A-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX90A-NEXT: s_brev_b32 s4, -2
+; GFX90A-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX90A-NEXT: v_mul_f32_e32 v3, 0.5, v1
+; GFX90A-NEXT: v_trunc_f32_e32 v4, v3
+; GFX90A-NEXT: v_cmp_lg_f32_e32 vcc, v4, v3
+; GFX90A-NEXT: v_trunc_f32_e32 v3, v1
+; GFX90A-NEXT: v_bfi_b32 v0, s4, v2, v0
+; GFX90A-NEXT: v_cmp_eq_f32_e64 s[4:5], v3, v1
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
+; GFX90A-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: v_pow_f32_nnan:
+; GFX10: ; %bb.0:
+; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT: v_cmp_gt_f32_e64 s4, 0x800000, |v0|
+; GFX10-NEXT: v_trunc_f32_e32 v6, v1
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 32, s4
+; GFX10-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s4
+; GFX10-NEXT: v_cmp_eq_f32_e64 s4, v6, v1
+; GFX10-NEXT: v_ldexp_f32 v3, |v0|, v3
+; GFX10-NEXT: v_log_f32_e32 v3, v3
+; GFX10-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX10-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX10-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX10-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX10-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX10-NEXT: v_mul_f32_e32 v3, 0.5, v1
+; GFX10-NEXT: v_exp_f32_e32 v2, v2
+; GFX10-NEXT: v_trunc_f32_e32 v5, v3
+; GFX10-NEXT: v_cmp_lg_f32_e32 vcc_lo, v5, v3
+; GFX10-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX10-NEXT: s_and_b32 vcc_lo, s4, vcc_lo
+; GFX10-NEXT: v_bfi_b32 v0, 0x7fffffff, v2, v0
+; GFX10-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc_lo
+; GFX10-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: v_pow_f32_nnan:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
+; GFX11-NEXT: v_trunc_f32_e32 v6, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_3)
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 32, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s0
+; GFX11-NEXT: v_cmp_eq_f32_e64 s0, v6, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_ldexp_f32 v3, |v0|, v3
+; GFX11-NEXT: v_log_f32_e32 v3, v3
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v2, v1, v2
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_dual_add_f32 v2, v2, v3 :: v_dual_mul_f32 v3, 0.5, v1
+; GFX11-NEXT: v_exp_f32_e32 v2, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_trunc_f32_e32 v5, v3
+; GFX11-NEXT: v_cmp_lg_f32_e32 vcc_lo, v5, v3
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX11-NEXT: s_and_b32 vcc_lo, s0, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_bfi_b32 v0, 0x7fffffff, v2, v0
+; GFX11-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc_lo
+; GFX11-NEXT: s_setpc_b64 s[30:31]
+ %pow = call nnan float @llvm.pow.f32(float %x, float %y)
+ ret float %pow
+}
+
+define float @v_pow_f32_daz(float %x, float %y) #0 {
+; GFX6-LABEL: v_pow_f32_daz:
+; GFX6: ; %bb.0:
+; GFX6-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX6-NEXT: v_log_f32_e64 v2, |v0|
+; GFX6-NEXT: v_mul_f32_e32 v3, 0.5, v1
+; GFX6-NEXT: v_trunc_f32_e32 v4, v3
+; GFX6-NEXT: v_cmp_lg_f32_e32 vcc, v4, v3
+; GFX6-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX6-NEXT: v_exp_f32_e32 v2, v2
+; GFX6-NEXT: v_trunc_f32_e32 v3, v1
+; GFX6-NEXT: v_cmp_eq_f32_e64 s[4:5], v3, v1
+; GFX6-NEXT: s_brev_b32 s6, -2
+; GFX6-NEXT: v_bfi_b32 v4, s6, v2, v0
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v2, v2, v4, vcc
+; GFX6-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 8
+; GFX6-NEXT: v_cmp_neq_f32_e32 vcc, v3, v1
+; GFX6-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX6-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX6-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
+; GFX6-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX8-LABEL: v_pow_f32_daz:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8-NEXT: v_log_f32_e64 v2, |v0|
+; GFX8-NEXT: v_mul_f32_e32 v3, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v4, v3
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v4, v3
+; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX8-NEXT: v_exp_f32_e32 v2, v2
+; GFX8-NEXT: v_trunc_f32_e32 v3, v1
+; GFX8-NEXT: v_cmp_eq_f32_e64 s[4:5], v3, v1
+; GFX8-NEXT: s_brev_b32 s6, -2
+; GFX8-NEXT: v_bfi_b32 v4, s6, v2, v0
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v2, v2, v4, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 8
+; GFX8-NEXT: v_cmp_neq_f32_e32 vcc, v3, v1
+; GFX8-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
+; GFX8-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX9-LABEL: v_pow_f32_daz:
+; GFX9: ; %bb.0:
+; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT: v_log_f32_e64 v2, |v0|
+; GFX9-NEXT: v_mul_f32_e32 v3, 0.5, v1
+; GFX9-NEXT: v_trunc_f32_e32 v4, v3
+; GFX9-NEXT: v_cmp_lg_f32_e32 vcc, v4, v3
+; GFX9-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX9-NEXT: v_exp_f32_e32 v2, v2
+; GFX9-NEXT: v_trunc_f32_e32 v3, v1
+; GFX9-NEXT: v_cmp_eq_f32_e64 s[4:5], v3, v1
+; GFX9-NEXT: s_brev_b32 s6, -2
+; GFX9-NEXT: v_bfi_b32 v4, s6, v2, v0
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v2, v2, v4, vcc
+; GFX9-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 8
+; GFX9-NEXT: v_cmp_neq_f32_e32 vcc, v3, v1
+; GFX9-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX9-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX9-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
+; GFX9-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX90A-LABEL: v_pow_f32_daz:
+; GFX90A: ; %bb.0:
+; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX90A-NEXT: v_log_f32_e64 v2, |v0|
+; GFX90A-NEXT: v_mul_f32_e32 v3, 0.5, v1
+; GFX90A-NEXT: v_trunc_f32_e32 v4, v3
+; GFX90A-NEXT: v_cmp_lg_f32_e32 vcc, v4, v3
+; GFX90A-NEXT: v_mul_legacy_f32 v2, v1, v2
+; GFX90A-NEXT: v_exp_f32_e32 v2, v2
+; GFX90A-NEXT: v_trunc_f32_e32 v3, v1
+; GFX90A-NEXT: v_cmp_eq_f32_e64 s[4:5], v3, v1
+; GFX90A-NEXT: s_brev_b32 s6, -2
+; GFX90A-NEXT: v_bfi_b32 v4, s6, v2, v0
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v2, v2, v4, vcc
+; GFX90A-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 8
+; GFX90A-NEXT: v_cmp_neq_f32_e32 vcc, v3, v1
+; GFX90A-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX90A-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX90A-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
+; GFX90A-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: v_pow_f32_daz:
+; GFX10: ; %bb.0:
+; GFX10-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT: v_log_f32_e64 v2, |v0|
+; GFX10-NEXT: v_mul_f32_e32 v3, 0.5, v1
+; GFX10-NEXT: v_trunc_f32_e32 v5, v1
+; GFX10-NEXT: v_cmp_class_f32_e64 s6, v0, 8
+; GFX10-NEXT: v_trunc_f32_e32 v4, v3
+; GFX10-NEXT: v_cmp_eq_f32_e64 s4, v5, v1
+; GFX10-NEXT: v_cmp_neq_f32_e64 s5, v5, v1
+; GFX10-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX10-NEXT: v_cmp_lg_f32_e32 vcc_lo, v4, v3
+; GFX10-NEXT: v_exp_f32_e32 v2, v2
+; GFX10-NEXT: s_and_b32 vcc_lo, s4, vcc_lo
+; GFX10-NEXT: s_and_b32 s4, s6, s5
+; GFX10-NEXT: v_bfi_b32 v3, 0x7fffffff, v2, v0
+; GFX10-NEXT: v_cndmask_b32_e32 v0, v2, v3, vcc_lo
+; GFX10-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s4
+; GFX10-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: v_pow_f32_daz:
+; GFX11: ; %bb.0:
+; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT: v_log_f32_e64 v2, |v0|
+; GFX11-NEXT: v_trunc_f32_e32 v5, v1
+; GFX11-NEXT: v_cmp_class_f32_e64 s2, v0, 8
+; GFX11-NEXT: v_mul_f32_e32 v3, 0.5, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_3)
+; GFX11-NEXT: v_cmp_eq_f32_e64 s0, v5, v1
+; GFX11-NEXT: v_cmp_neq_f32_e64 s1, v5, v1
+; GFX11-NEXT: v_trunc_f32_e32 v4, v3
+; GFX11-NEXT: s_delay_alu instid0(TRANS32_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v2, v1, v2
+; GFX11-NEXT: v_cmp_lg_f32_e32 vcc_lo, v4, v3
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_4) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_exp_f32_e32 v2, v2
+; GFX11-NEXT: s_and_b32 vcc_lo, s0, vcc_lo
+; GFX11-NEXT: s_and_b32 s0, s2, s1
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_bfi_b32 v3, 0x7fffffff, v2, v0
+; GFX11-NEXT: v_cndmask_b32_e32 v0, v2, v3, vcc_lo
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
+; GFX11-NEXT: s_setpc_b64 s[30:31]
+ %pow = call float @llvm.pow.f32(float %x, float %y)
+ ret float %pow
+}
+
declare half @llvm.pow.f16(half, half)
declare float @llvm.pow.f32(float, float)
declare double @llvm.pow.f64(double, double)
@@ -1140,3 +5070,5 @@ declare float @llvm.fabs.f32(float)
declare <2 x half> @llvm.pow.v2f16(<2 x half>, <2 x half>)
declare <2 x float> @llvm.pow.v2f32(<2 x float>, <2 x float>)
+
+attributes #0 = { denormal_fpenv(float:preservesign|preservesign) }
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.powi.ll b/llvm/test/CodeGen/AMDGPU/llvm.powi.ll
index 9d4f22e5ea022..fd5ab9296cb7c 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.powi.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.powi.ll
@@ -5,42 +5,172 @@
; RUN: llc -mtriple=amdgpu11.00-mesa-mesa3d -mattr=-real-true16 < %s | FileCheck -check-prefixes=GFX11,GFX11-FAKE16 %s
define i16 @v_powi_f16(i16 %l, i32 %r) {
-; GFX78-LABEL: v_powi_f16:
-; GFX78: ; %bb.0:
-; GFX78-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX78-NEXT: v_cvt_f32_f16_e32 v0, v0
-; GFX78-NEXT: v_cvt_f32_i32_e32 v1, v1
-; GFX78-NEXT: v_log_f32_e32 v0, v0
-; GFX78-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX78-NEXT: v_exp_f32_e32 v0, v0
-; GFX78-NEXT: v_cvt_f16_f32_e32 v0, v0
-; GFX78-NEXT: s_setpc_b64 s[30:31]
+; GFX7-LABEL: v_powi_f16:
+; GFX7: ; %bb.0:
+; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX7-NEXT: s_mov_b32 s4, 0x800000
+; GFX7-NEXT: v_cvt_f32_i32_e32 v1, v1
+; GFX7-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX7-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX7-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX7-NEXT: v_ldexp_f32_e64 v3, |v0|, v3
+; GFX7-NEXT: v_log_f32_e32 v3, v3
+; GFX7-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX7-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX7-NEXT: v_mul_f32_e32 v4, 0.5, v1
+; GFX7-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX7-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX7-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX7-NEXT: v_cmp_gt_f32_e32 vcc, s4, v2
+; GFX7-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX7-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX7-NEXT: v_exp_f32_e32 v2, v2
+; GFX7-NEXT: v_not_b32_e32 v3, 63
+; GFX7-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX7-NEXT: v_trunc_f32_e32 v5, v4
+; GFX7-NEXT: v_ldexp_f32_e32 v2, v2, v3
+; GFX7-NEXT: s_brev_b32 s4, -2
+; GFX7-NEXT: v_cmp_lg_f32_e32 vcc, v5, v4
+; GFX7-NEXT: v_trunc_f32_e32 v4, v1
+; GFX7-NEXT: v_bfi_b32 v3, s4, v2, v0
+; GFX7-NEXT: v_cmp_eq_f32_e64 s[4:5], v4, v1
+; GFX7-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX7-NEXT: v_cndmask_b32_e32 v2, v2, v3, vcc
+; GFX7-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX7-NEXT: v_cmp_neq_f32_e32 vcc, v4, v1
+; GFX7-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX7-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX7-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
+; GFX7-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GFX7-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX8-LABEL: v_powi_f16:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8-NEXT: v_cvt_f32_f16_e32 v2, v0
+; GFX8-NEXT: s_mov_b32 s4, 0x800000
+; GFX8-NEXT: v_cvt_f32_i32_e32 v1, v1
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x42000000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v2|, s4
+; GFX8-NEXT: v_cndmask_b32_e64 v4, 0, 32, vcc
+; GFX8-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX8-NEXT: v_log_f32_e32 v4, v4
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX8-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX8-NEXT: v_sub_f32_e32 v3, v4, v3
+; GFX8-NEXT: v_mul_legacy_f32_e32 v3, v1, v3
+; GFX8-NEXT: v_mov_b32_e32 v4, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s4, v3
+; GFX8-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
+; GFX8-NEXT: v_add_f32_e32 v3, v3, v4
+; GFX8-NEXT: v_exp_f32_e32 v3, v3
+; GFX8-NEXT: v_not_b32_e32 v4, 63
+; GFX8-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
+; GFX8-NEXT: s_brev_b32 s4, -2
+; GFX8-NEXT: v_ldexp_f32 v3, v3, v4
+; GFX8-NEXT: v_mul_f32_e32 v4, 0.5, v1
+; GFX8-NEXT: v_trunc_f32_e32 v5, v4
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v5, v4
+; GFX8-NEXT: v_trunc_f32_e32 v4, v1
+; GFX8-NEXT: v_bfi_b32 v0, s4, v3, v0
+; GFX8-NEXT: v_cmp_eq_f32_e64 s[4:5], v4, v1
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v3, v0, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v2, 24
+; GFX8-NEXT: v_cmp_neq_f32_e32 vcc, v4, v1
+; GFX8-NEXT: v_mov_b32_e32 v1, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v0, v1, vcc
+; GFX8-NEXT: v_cvt_f16_f32_e32 v0, v0
+; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-TRUE16-LABEL: v_powi_f16:
; GFX11-TRUE16: ; %bb.0:
; GFX11-TRUE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v0, v0.l
+; GFX11-TRUE16-NEXT: v_mov_b16_e32 v2.l, v0.l
; GFX11-TRUE16-NEXT: v_cvt_f32_i32_e32 v1, v1
-; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_1)
-; GFX11-TRUE16-NEXT: v_log_f32_e32 v0, v0
+; GFX11-TRUE16-NEXT: v_mov_b16_e32 v0.h, v0.l
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-TRUE16-NEXT: v_cvt_f32_f16_e32 v2, v2.l
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v6, v1
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_3)
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v2|
+; GFX11-TRUE16-NEXT: v_cmp_class_f32_e64 s2, v2, 24
+; GFX11-TRUE16-NEXT: v_cmp_neq_f32_e64 s1, v6, v1
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_2) | instid1(VALU_DEP_3)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v4, 0, 32, s0
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s0
+; GFX11-TRUE16-NEXT: v_cmp_eq_f32_e64 s0, v6, v1
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_log_f32_e32 v4, v4
; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
-; GFX11-TRUE16-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-TRUE16-NEXT: v_sub_f32_e32 v3, v4, v3
+; GFX11-TRUE16-NEXT: v_mul_dx9_zero_f32_e32 v3, v1, v3
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_2)
+; GFX11-TRUE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v3
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v4, 0, 0x42800000, vcc_lo
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v5, 0, 0xffffffc0, vcc_lo
+; GFX11-TRUE16-NEXT: v_dual_add_f32 v3, v3, v4 :: v_dual_mul_f32 v4, 0.5, v1
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_exp_f32_e32 v3, v3
+; GFX11-TRUE16-NEXT: v_trunc_f32_e32 v7, v4
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_4) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_cmp_lg_f32_e32 vcc_lo, v7, v4
; GFX11-TRUE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-TRUE16-NEXT: v_ldexp_f32 v3, v3, v5
+; GFX11-TRUE16-NEXT: s_and_b32 vcc_lo, s0, vcc_lo
+; GFX11-TRUE16-NEXT: s_and_b32 s0, s2, s1
+; GFX11-TRUE16-NEXT: v_bfi_b32 v0, 0x7fffffff, v3, v0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e32 v0, v3, v0, vcc_lo
+; GFX11-TRUE16-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
+; GFX11-TRUE16-NEXT: s_delay_alu instid0(VALU_DEP_1)
; GFX11-TRUE16-NEXT: v_cvt_f16_f32_e32 v0.l, v0
; GFX11-TRUE16-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-FAKE16-LABEL: v_powi_f16:
; GFX11-FAKE16: ; %bb.0:
; GFX11-FAKE16-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v0, v0
+; GFX11-FAKE16-NEXT: v_cvt_f32_f16_e32 v2, v0
; GFX11-FAKE16-NEXT: v_cvt_f32_i32_e32 v1, v1
-; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_2) | instid1(VALU_DEP_1)
-; GFX11-FAKE16-NEXT: v_log_f32_e32 v0, v0
+; GFX11-FAKE16-NEXT: v_lshlrev_b32_e32 v0, 16, v0
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_3)
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v2|
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v6, v1
+; GFX11-FAKE16-NEXT: v_cmp_class_f32_e64 s2, v2, 24
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_4)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v4, 0, 32, s0
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v3, 0, 0x42000000, s0
+; GFX11-FAKE16-NEXT: v_cmp_eq_f32_e64 s0, v6, v1
+; GFX11-FAKE16-NEXT: v_cmp_neq_f32_e64 s1, v6, v1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_4) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v4, |v2|, v4
+; GFX11-FAKE16-NEXT: v_log_f32_e32 v4, v4
; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
-; GFX11-FAKE16-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-FAKE16-NEXT: v_sub_f32_e32 v3, v4, v3
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_mul_dx9_zero_f32_e32 v3, v1, v3
+; GFX11-FAKE16-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v3
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v4, 0, 0x42800000, vcc_lo
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v5, 0, 0xffffffc0, vcc_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_dual_add_f32 v3, v3, v4 :: v_dual_mul_f32 v4, 0.5, v1
+; GFX11-FAKE16-NEXT: v_exp_f32_e32 v3, v3
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_trunc_f32_e32 v7, v4
+; GFX11-FAKE16-NEXT: v_cmp_lg_f32_e32 vcc_lo, v7, v4
; GFX11-FAKE16-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-FAKE16-NEXT: v_ldexp_f32 v3, v3, v5
+; GFX11-FAKE16-NEXT: s_and_b32 vcc_lo, s0, vcc_lo
+; GFX11-FAKE16-NEXT: s_and_b32 s0, s2, s1
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_bfi_b32 v0, 0x7fffffff, v3, v0
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e32 v0, v3, v0, vcc_lo
+; GFX11-FAKE16-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-FAKE16-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX11-FAKE16-NEXT: v_cvt_f16_f32_e32 v0, v0
; GFX11-FAKE16-NEXT: s_setpc_b64 s[30:31]
%l.cast = bitcast i16 %l to half
@@ -50,24 +180,119 @@ define i16 @v_powi_f16(i16 %l, i32 %r) {
}
define float @v_powi_f32(float %l, i32 %r) {
-; GFX78-LABEL: v_powi_f32:
-; GFX78: ; %bb.0:
-; GFX78-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX78-NEXT: v_log_f32_e32 v0, v0
-; GFX78-NEXT: v_cvt_f32_i32_e32 v1, v1
-; GFX78-NEXT: v_mul_legacy_f32_e32 v0, v1, v0
-; GFX78-NEXT: v_exp_f32_e32 v0, v0
-; GFX78-NEXT: s_setpc_b64 s[30:31]
+; GFX7-LABEL: v_powi_f32:
+; GFX7: ; %bb.0:
+; GFX7-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7-NEXT: s_mov_b32 s4, 0x800000
+; GFX7-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX7-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX7-NEXT: v_ldexp_f32_e64 v3, |v0|, v3
+; GFX7-NEXT: v_log_f32_e32 v3, v3
+; GFX7-NEXT: v_cvt_f32_i32_e32 v1, v1
+; GFX7-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX7-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX7-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX7-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX7-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX7-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX7-NEXT: v_cmp_gt_f32_e32 vcc, s4, v2
+; GFX7-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX7-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX7-NEXT: v_exp_f32_e32 v2, v2
+; GFX7-NEXT: v_not_b32_e32 v3, 63
+; GFX7-NEXT: v_mul_f32_e32 v4, 0.5, v1
+; GFX7-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX7-NEXT: v_trunc_f32_e32 v5, v4
+; GFX7-NEXT: v_ldexp_f32_e32 v2, v2, v3
+; GFX7-NEXT: s_brev_b32 s4, -2
+; GFX7-NEXT: v_cmp_lg_f32_e32 vcc, v5, v4
+; GFX7-NEXT: v_trunc_f32_e32 v4, v1
+; GFX7-NEXT: v_bfi_b32 v3, s4, v2, v0
+; GFX7-NEXT: v_cmp_eq_f32_e64 s[4:5], v4, v1
+; GFX7-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX7-NEXT: v_cndmask_b32_e32 v2, v2, v3, vcc
+; GFX7-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX7-NEXT: v_cmp_neq_f32_e32 vcc, v4, v1
+; GFX7-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX7-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX7-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
+; GFX7-NEXT: s_setpc_b64 s[30:31]
+;
+; GFX8-LABEL: v_powi_f32:
+; GFX8: ; %bb.0:
+; GFX8-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8-NEXT: s_mov_b32 s4, 0x800000
+; GFX8-NEXT: v_cmp_lt_f32_e64 vcc, |v0|, s4
+; GFX8-NEXT: v_cndmask_b32_e64 v3, 0, 32, vcc
+; GFX8-NEXT: v_ldexp_f32 v3, |v0|, v3
+; GFX8-NEXT: v_log_f32_e32 v3, v3
+; GFX8-NEXT: v_cvt_f32_i32_e32 v1, v1
+; GFX8-NEXT: v_mov_b32_e32 v2, 0x42000000
+; GFX8-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
+; GFX8-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX8-NEXT: v_mul_legacy_f32_e32 v2, v1, v2
+; GFX8-NEXT: s_mov_b32 s4, 0xc2fc0000
+; GFX8-NEXT: v_mov_b32_e32 v3, 0x42800000
+; GFX8-NEXT: v_cmp_gt_f32_e32 vcc, s4, v2
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_add_f32_e32 v2, v2, v3
+; GFX8-NEXT: v_exp_f32_e32 v2, v2
+; GFX8-NEXT: v_not_b32_e32 v3, 63
+; GFX8-NEXT: v_mul_f32_e32 v4, 0.5, v1
+; GFX8-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
+; GFX8-NEXT: v_trunc_f32_e32 v5, v4
+; GFX8-NEXT: v_ldexp_f32 v2, v2, v3
+; GFX8-NEXT: s_brev_b32 s4, -2
+; GFX8-NEXT: v_cmp_lg_f32_e32 vcc, v5, v4
+; GFX8-NEXT: v_trunc_f32_e32 v4, v1
+; GFX8-NEXT: v_bfi_b32 v3, s4, v2, v0
+; GFX8-NEXT: v_cmp_eq_f32_e64 s[4:5], v4, v1
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v2, v2, v3, vcc
+; GFX8-NEXT: v_cmp_class_f32_e64 s[4:5], v0, 24
+; GFX8-NEXT: v_cmp_neq_f32_e32 vcc, v4, v1
+; GFX8-NEXT: v_mov_b32_e32 v0, 0x7fc00000
+; GFX8-NEXT: s_and_b64 vcc, s[4:5], vcc
+; GFX8-NEXT: v_cndmask_b32_e32 v0, v2, v0, vcc
+; GFX8-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: v_powi_f32:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-NEXT: v_log_f32_e32 v0, v0
+; GFX11-NEXT: v_cmp_gt_f32_e64 s0, 0x800000, |v0|
; GFX11-NEXT: v_cvt_f32_i32_e32 v1, v1
+; GFX11-NEXT: v_cmp_class_f32_e64 s2, v0, 24
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_4)
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 32, s0
+; GFX11-NEXT: v_cndmask_b32_e64 v2, 0, 0x42000000, s0
+; GFX11-NEXT: v_trunc_f32_e32 v6, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_ldexp_f32 v3, |v0|, v3
+; GFX11-NEXT: v_cmp_eq_f32_e64 s0, v6, v1
+; GFX11-NEXT: v_cmp_neq_f32_e64 s1, v6, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_2) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_log_f32_e32 v3, v3
; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
-; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v0, v1, v0
-; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
-; GFX11-NEXT: v_exp_f32_e32 v0, v0
+; GFX11-NEXT: v_sub_f32_e32 v2, v3, v2
+; GFX11-NEXT: v_mul_dx9_zero_f32_e32 v2, v1, v2
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_2)
+; GFX11-NEXT: v_cmp_gt_f32_e32 vcc_lo, 0xc2fc0000, v2
+; GFX11-NEXT: v_cndmask_b32_e64 v3, 0, 0x42800000, vcc_lo
+; GFX11-NEXT: v_cndmask_b32_e64 v4, 0, 0xffffffc0, vcc_lo
+; GFX11-NEXT: v_dual_add_f32 v2, v2, v3 :: v_dual_mul_f32 v3, 0.5, v1
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_exp_f32_e32 v2, v2
+; GFX11-NEXT: v_trunc_f32_e32 v5, v3
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_4) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_cmp_lg_f32_e32 vcc_lo, v5, v3
+; GFX11-NEXT: s_waitcnt_depctr depctr_va_vdst(0)
+; GFX11-NEXT: v_ldexp_f32 v2, v2, v4
+; GFX11-NEXT: s_and_b32 vcc_lo, s0, vcc_lo
+; GFX11-NEXT: s_and_b32 s0, s2, s1
+; GFX11-NEXT: v_bfi_b32 v3, 0x7fffffff, v2, v0
+; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT: v_cndmask_b32_e32 v0, v2, v3, vcc_lo
+; GFX11-NEXT: v_cndmask_b32_e64 v0, v0, 0x7fc00000, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
%res = call float @llvm.powi.f32.i32(float %l, i32 %r)
ret float %res
More information about the llvm-commits
mailing list