[AMDGPU][GlobalISel] Add lowering for G_FMODF (#180152)
Add generic expansion for G_FMODF matching the SelectionDAG implementation. Enable G_FMODF lowering for AMDGPU with tests. Related: #179434
This commit is contained in:
parent
9dd5542a34
commit
a947599991
@ -526,6 +526,7 @@ public:
|
||||
LLVM_ABI LegalizeResult lowerFPTRUNC_F64_TO_F16(MachineInstr &MI);
|
||||
LLVM_ABI LegalizeResult lowerFPTRUNC(MachineInstr &MI);
|
||||
LLVM_ABI LegalizeResult lowerFPOWI(MachineInstr &MI);
|
||||
LLVM_ABI LegalizeResult lowerFMODF(MachineInstr &MI);
|
||||
|
||||
LLVM_ABI LegalizeResult lowerISFPCLASS(MachineInstr &MI);
|
||||
|
||||
|
||||
@ -2202,9 +2202,10 @@ public:
|
||||
}
|
||||
|
||||
/// Build and insert \p Res = G_FCOPYSIGN \p Op0, \p Op1
|
||||
MachineInstrBuilder buildFCopysign(const DstOp &Dst, const SrcOp &Src0,
|
||||
const SrcOp &Src1) {
|
||||
return buildInstr(TargetOpcode::G_FCOPYSIGN, {Dst}, {Src0, Src1});
|
||||
MachineInstrBuilder
|
||||
buildFCopysign(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1,
|
||||
std::optional<unsigned> Flags = std::nullopt) {
|
||||
return buildInstr(TargetOpcode::G_FCOPYSIGN, {Dst}, {Src0, Src1}, Flags);
|
||||
}
|
||||
|
||||
/// Build and insert \p Res = G_UITOFP \p Src0
|
||||
|
||||
@ -4762,6 +4762,8 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
|
||||
return lowerFPTRUNC(MI);
|
||||
case G_FPOWI:
|
||||
return lowerFPOWI(MI);
|
||||
case G_FMODF:
|
||||
return lowerFMODF(MI);
|
||||
case G_SMIN:
|
||||
case G_SMAX:
|
||||
case G_UMIN:
|
||||
@ -8719,6 +8721,35 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerFPOWI(MachineInstr &MI) {
|
||||
return Legalized;
|
||||
}
|
||||
|
||||
LegalizerHelper::LegalizeResult LegalizerHelper::lowerFMODF(MachineInstr &MI) {
|
||||
auto [DstFrac, DstInt, Src] = MI.getFirst3Regs();
|
||||
LLT Ty = MRI.getType(Src);
|
||||
auto Flags = MI.getFlags();
|
||||
|
||||
auto IntPart = MIRBuilder.buildIntrinsicTrunc(Ty, Src, Flags);
|
||||
auto FracPart = MIRBuilder.buildFSub(Ty, Src, IntPart, Flags);
|
||||
|
||||
Register FracToUse;
|
||||
if (MI.getFlag(MachineInstr::FmNoInfs)) {
|
||||
FracToUse = FracPart.getReg(0);
|
||||
} else {
|
||||
auto Abs = MIRBuilder.buildFAbs(Ty, Src, Flags);
|
||||
const fltSemantics &Semantics = getFltSemanticForLLT(Ty.getScalarType());
|
||||
auto Inf = MIRBuilder.buildFConstant(Ty, APFloat::getInf(Semantics));
|
||||
auto IsInf = MIRBuilder.buildFCmp(CmpInst::FCMP_OEQ,
|
||||
Ty.changeElementSize(1), Abs, Inf);
|
||||
auto Zero = MIRBuilder.buildFConstant(Ty, 0.0);
|
||||
auto Select = MIRBuilder.buildSelect(Ty, IsInf, Zero, FracPart);
|
||||
FracToUse = Select.getReg(0);
|
||||
}
|
||||
|
||||
MIRBuilder.buildFCopysign(DstFrac, FracToUse, Src, Flags);
|
||||
MIRBuilder.buildCopy(DstInt, IntPart.getReg(0));
|
||||
|
||||
MI.eraseFromParent();
|
||||
return Legalized;
|
||||
}
|
||||
|
||||
static CmpInst::Predicate minMaxToCompare(unsigned Opc) {
|
||||
switch (Opc) {
|
||||
case TargetOpcode::G_SMIN:
|
||||
|
||||
@ -1057,6 +1057,11 @@ AMDGPULegalizerInfo::AMDGPULegalizerInfo(const GCNSubtarget &ST_,
|
||||
.customFor({{S32, S32}, {S64, S32}, {S16, S16}, {S16, S32}})
|
||||
.scalarize(0)
|
||||
.lower();
|
||||
|
||||
getActionDefinitionsBuilder(G_FMODF)
|
||||
.lowerFor({S16, S32, S64})
|
||||
.scalarize(0)
|
||||
.lower();
|
||||
} else {
|
||||
getActionDefinitionsBuilder(G_FSQRT)
|
||||
.customFor({S32, S64, S16})
|
||||
@ -1090,6 +1095,11 @@ AMDGPULegalizerInfo::AMDGPULegalizerInfo(const GCNSubtarget &ST_,
|
||||
.minScalar(0, S32)
|
||||
.clampScalar(1, S32, S32)
|
||||
.lower();
|
||||
|
||||
getActionDefinitionsBuilder(G_FMODF)
|
||||
.lowerFor({S32, S64})
|
||||
.scalarize(0)
|
||||
.lower();
|
||||
}
|
||||
|
||||
auto &FPTruncActions = getActionDefinitionsBuilder(G_FPTRUNC);
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
|
||||
; RUN: llc -mtriple=amdgcn -mcpu=gfx900 < %s | FileCheck -check-prefixes=GFX9 %s
|
||||
|
||||
; TODO: Add GlobalISel support
|
||||
; RUN: llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx900 < %s | FileCheck -check-prefixes=GFX9,GFX9-SDAG %s
|
||||
; RUN: llc -global-isel=1 -mtriple=amdgcn -mcpu=gfx900 < %s | FileCheck -check-prefixes=GFX9,GFX9-GISEL %s
|
||||
|
||||
declare { half, half } @llvm.modf.f16(half)
|
||||
declare { <2 x half>, <2 x half> } @llvm.modf.v2f16(<2 x half>)
|
||||
@ -13,33 +12,59 @@ declare { double, double } @llvm.modf.f64(double)
|
||||
declare { <2 x double>, <2 x double> } @llvm.modf.v2f64(<2 x double>)
|
||||
|
||||
define { half, half } @test_modf_f16(half %x) {
|
||||
; GFX9-LABEL: test_modf_f16:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: s_movk_i32 s4, 0x7c00
|
||||
; GFX9-NEXT: v_trunc_f16_e32 v1, v0
|
||||
; GFX9-NEXT: v_sub_f16_e32 v2, v0, v1
|
||||
; GFX9-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s4
|
||||
; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
|
||||
; GFX9-NEXT: s_movk_i32 s4, 0x7fff
|
||||
; GFX9-NEXT: v_bfi_b32 v0, s4, v2, v0
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
; GFX9-SDAG-LABEL: test_modf_f16:
|
||||
; GFX9-SDAG: ; %bb.0:
|
||||
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-SDAG-NEXT: s_movk_i32 s4, 0x7c00
|
||||
; GFX9-SDAG-NEXT: v_trunc_f16_e32 v1, v0
|
||||
; GFX9-SDAG-NEXT: v_sub_f16_e32 v2, v0, v1
|
||||
; GFX9-SDAG-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s4
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
|
||||
; GFX9-SDAG-NEXT: s_movk_i32 s4, 0x7fff
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v0, s4, v2, v0
|
||||
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
|
||||
;
|
||||
; GFX9-GISEL-LABEL: test_modf_f16:
|
||||
; GFX9-GISEL: ; %bb.0:
|
||||
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-GISEL-NEXT: v_trunc_f16_e32 v1, v0
|
||||
; GFX9-GISEL-NEXT: v_mov_b32_e32 v3, 0x7c00
|
||||
; GFX9-GISEL-NEXT: v_sub_f16_e32 v2, v0, v1
|
||||
; GFX9-GISEL-NEXT: v_cmp_eq_f16_e64 s[4:5], |v0|, v3
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v2, v2, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v2, 0x7fff, v2
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v0, 0xffff8000, v0
|
||||
; GFX9-GISEL-NEXT: v_or_b32_e32 v0, v2, v0
|
||||
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call { half, half } @llvm.modf.f16(half %x)
|
||||
ret { half, half } %result
|
||||
}
|
||||
|
||||
define half @test_modf_f16_only_use_fract(half %x) {
|
||||
; GFX9-LABEL: test_modf_f16_only_use_fract:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: s_movk_i32 s4, 0x7c00
|
||||
; GFX9-NEXT: v_trunc_f16_e32 v1, v0
|
||||
; GFX9-NEXT: v_sub_f16_e32 v1, v0, v1
|
||||
; GFX9-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s4
|
||||
; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
|
||||
; GFX9-NEXT: s_movk_i32 s4, 0x7fff
|
||||
; GFX9-NEXT: v_bfi_b32 v0, s4, v1, v0
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
; GFX9-SDAG-LABEL: test_modf_f16_only_use_fract:
|
||||
; GFX9-SDAG: ; %bb.0:
|
||||
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-SDAG-NEXT: s_movk_i32 s4, 0x7c00
|
||||
; GFX9-SDAG-NEXT: v_trunc_f16_e32 v1, v0
|
||||
; GFX9-SDAG-NEXT: v_sub_f16_e32 v1, v0, v1
|
||||
; GFX9-SDAG-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s4
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
|
||||
; GFX9-SDAG-NEXT: s_movk_i32 s4, 0x7fff
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v0, s4, v1, v0
|
||||
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
|
||||
;
|
||||
; GFX9-GISEL-LABEL: test_modf_f16_only_use_fract:
|
||||
; GFX9-GISEL: ; %bb.0:
|
||||
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-GISEL-NEXT: v_trunc_f16_e32 v1, v0
|
||||
; GFX9-GISEL-NEXT: v_mov_b32_e32 v2, 0x7c00
|
||||
; GFX9-GISEL-NEXT: v_sub_f16_e32 v1, v0, v1
|
||||
; GFX9-GISEL-NEXT: v_cmp_eq_f16_e64 s[4:5], |v0|, v2
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v1, v1, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v1, 0x7fff, v1
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v0, 0xffff8000, v0
|
||||
; GFX9-GISEL-NEXT: v_or_b32_e32 v0, v1, v0
|
||||
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call { half, half } @llvm.modf.f16(half %x)
|
||||
%result.0 = extractvalue { half, half } %result, 0
|
||||
ret half %result.0
|
||||
@ -57,94 +82,175 @@ define half @test_modf_f16_only_use_integer(half %x) {
|
||||
}
|
||||
|
||||
define { <2 x half>, <2 x half> } @test_modf_v2f16(<2 x half> %x) {
|
||||
; GFX9-LABEL: test_modf_v2f16:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: s_movk_i32 s4, 0x7c00
|
||||
; GFX9-NEXT: v_trunc_f16_e32 v1, v0
|
||||
; GFX9-NEXT: v_sub_f16_e32 v2, v0, v1
|
||||
; GFX9-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s4
|
||||
; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
|
||||
; GFX9-NEXT: s_movk_i32 s5, 0x7fff
|
||||
; GFX9-NEXT: v_bfi_b32 v2, s5, v2, v0
|
||||
; GFX9-NEXT: v_lshrrev_b32_e32 v0, 16, v0
|
||||
; GFX9-NEXT: v_trunc_f16_e32 v3, v0
|
||||
; GFX9-NEXT: v_sub_f16_e32 v4, v0, v3
|
||||
; GFX9-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s4
|
||||
; GFX9-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
|
||||
; GFX9-NEXT: v_bfi_b32 v0, s5, v4, v0
|
||||
; GFX9-NEXT: v_pack_b32_f16 v0, v2, v0
|
||||
; GFX9-NEXT: v_pack_b32_f16 v1, v1, v3
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
; GFX9-SDAG-LABEL: test_modf_v2f16:
|
||||
; GFX9-SDAG: ; %bb.0:
|
||||
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-SDAG-NEXT: s_movk_i32 s4, 0x7c00
|
||||
; GFX9-SDAG-NEXT: v_trunc_f16_e32 v1, v0
|
||||
; GFX9-SDAG-NEXT: v_sub_f16_e32 v2, v0, v1
|
||||
; GFX9-SDAG-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s4
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
|
||||
; GFX9-SDAG-NEXT: s_movk_i32 s5, 0x7fff
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v2, s5, v2, v0
|
||||
; GFX9-SDAG-NEXT: v_lshrrev_b32_e32 v0, 16, v0
|
||||
; GFX9-SDAG-NEXT: v_trunc_f16_e32 v3, v0
|
||||
; GFX9-SDAG-NEXT: v_sub_f16_e32 v4, v0, v3
|
||||
; GFX9-SDAG-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s4
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v0, s5, v4, v0
|
||||
; GFX9-SDAG-NEXT: v_pack_b32_f16 v0, v2, v0
|
||||
; GFX9-SDAG-NEXT: v_pack_b32_f16 v1, v1, v3
|
||||
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
|
||||
;
|
||||
; GFX9-GISEL-LABEL: test_modf_v2f16:
|
||||
; GFX9-GISEL: ; %bb.0:
|
||||
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-GISEL-NEXT: v_trunc_f16_e32 v1, v0
|
||||
; GFX9-GISEL-NEXT: v_mov_b32_e32 v3, 0x7c00
|
||||
; GFX9-GISEL-NEXT: v_sub_f16_e32 v2, v0, v1
|
||||
; GFX9-GISEL-NEXT: v_cmp_eq_f16_e64 s[4:5], |v0|, v3
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v2, v2, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v2, 0x7fff, v2
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v5, 0xffff8000, v0
|
||||
; GFX9-GISEL-NEXT: v_or_b32_e32 v2, v2, v5
|
||||
; GFX9-GISEL-NEXT: v_trunc_f16_sdwa v5, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
|
||||
; GFX9-GISEL-NEXT: v_sub_f16_sdwa v6, v0, v5 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
|
||||
; GFX9-GISEL-NEXT: v_cmp_eq_f16_sdwa s[4:5], |v0|, v3 src0_sel:WORD_1 src1_sel:DWORD
|
||||
; GFX9-GISEL-NEXT: v_mov_b32_e32 v4, 0xffff8000
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v3, v6, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v3, 0x7fff, v3
|
||||
; GFX9-GISEL-NEXT: v_and_b32_sdwa v0, v0, v4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
|
||||
; GFX9-GISEL-NEXT: v_or_b32_e32 v0, v3, v0
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2
|
||||
; GFX9-GISEL-NEXT: v_lshl_or_b32 v0, v0, 16, v2
|
||||
; GFX9-GISEL-NEXT: v_pack_b32_f16 v1, v1, v5
|
||||
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call { <2 x half>, <2 x half> } @llvm.modf.v2f16(<2 x half> %x)
|
||||
ret { <2 x half>, <2 x half> } %result
|
||||
}
|
||||
|
||||
define <2 x half> @test_modf_v2f16_only_use_fract(<2 x half> %x) {
|
||||
; GFX9-LABEL: test_modf_v2f16_only_use_fract:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: s_movk_i32 s4, 0x7c00
|
||||
; GFX9-NEXT: v_trunc_f16_e32 v1, v0
|
||||
; GFX9-NEXT: v_sub_f16_e32 v1, v0, v1
|
||||
; GFX9-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s4
|
||||
; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
|
||||
; GFX9-NEXT: s_movk_i32 s5, 0x7fff
|
||||
; GFX9-NEXT: v_bfi_b32 v1, s5, v1, v0
|
||||
; GFX9-NEXT: v_lshrrev_b32_e32 v0, 16, v0
|
||||
; GFX9-NEXT: v_trunc_f16_e32 v2, v0
|
||||
; GFX9-NEXT: v_sub_f16_e32 v2, v0, v2
|
||||
; GFX9-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s4
|
||||
; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
|
||||
; GFX9-NEXT: v_bfi_b32 v0, s5, v2, v0
|
||||
; GFX9-NEXT: v_pack_b32_f16 v0, v1, v0
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
; GFX9-SDAG-LABEL: test_modf_v2f16_only_use_fract:
|
||||
; GFX9-SDAG: ; %bb.0:
|
||||
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-SDAG-NEXT: s_movk_i32 s4, 0x7c00
|
||||
; GFX9-SDAG-NEXT: v_trunc_f16_e32 v1, v0
|
||||
; GFX9-SDAG-NEXT: v_sub_f16_e32 v1, v0, v1
|
||||
; GFX9-SDAG-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s4
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
|
||||
; GFX9-SDAG-NEXT: s_movk_i32 s5, 0x7fff
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v1, s5, v1, v0
|
||||
; GFX9-SDAG-NEXT: v_lshrrev_b32_e32 v0, 16, v0
|
||||
; GFX9-SDAG-NEXT: v_trunc_f16_e32 v2, v0
|
||||
; GFX9-SDAG-NEXT: v_sub_f16_e32 v2, v0, v2
|
||||
; GFX9-SDAG-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s4
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v0, s5, v2, v0
|
||||
; GFX9-SDAG-NEXT: v_pack_b32_f16 v0, v1, v0
|
||||
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
|
||||
;
|
||||
; GFX9-GISEL-LABEL: test_modf_v2f16_only_use_fract:
|
||||
; GFX9-GISEL: ; %bb.0:
|
||||
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-GISEL-NEXT: v_trunc_f16_e32 v1, v0
|
||||
; GFX9-GISEL-NEXT: v_mov_b32_e32 v2, 0x7c00
|
||||
; GFX9-GISEL-NEXT: v_sub_f16_e32 v1, v0, v1
|
||||
; GFX9-GISEL-NEXT: v_cmp_eq_f16_e64 s[4:5], |v0|, v2
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v1, v1, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v1, 0x7fff, v1
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v4, 0xffff8000, v0
|
||||
; GFX9-GISEL-NEXT: v_or_b32_e32 v1, v1, v4
|
||||
; GFX9-GISEL-NEXT: v_trunc_f16_sdwa v4, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
|
||||
; GFX9-GISEL-NEXT: v_sub_f16_sdwa v4, v0, v4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
|
||||
; GFX9-GISEL-NEXT: v_cmp_eq_f16_sdwa s[4:5], |v0|, v2 src0_sel:WORD_1 src1_sel:DWORD
|
||||
; GFX9-GISEL-NEXT: v_mov_b32_e32 v3, 0xffff8000
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v2, v4, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v2, 0x7fff, v2
|
||||
; GFX9-GISEL-NEXT: v_and_b32_sdwa v0, v0, v3 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
|
||||
; GFX9-GISEL-NEXT: v_or_b32_e32 v0, v2, v0
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v1, 0xffff, v1
|
||||
; GFX9-GISEL-NEXT: v_lshl_or_b32 v0, v0, 16, v1
|
||||
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call { <2 x half>, <2 x half> } @llvm.modf.v2f16(<2 x half> %x)
|
||||
%result.0 = extractvalue { <2 x half>, <2 x half> } %result, 0
|
||||
ret <2 x half> %result.0
|
||||
}
|
||||
|
||||
define <2 x half> @test_modf_v2f16_only_use_integer(<2 x half> %x) {
|
||||
; GFX9-LABEL: test_modf_v2f16_only_use_integer:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: v_trunc_f16_sdwa v1, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
|
||||
; GFX9-NEXT: v_trunc_f16_e32 v0, v0
|
||||
; GFX9-NEXT: v_pack_b32_f16 v0, v0, v1
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
; GFX9-SDAG-LABEL: test_modf_v2f16_only_use_integer:
|
||||
; GFX9-SDAG: ; %bb.0:
|
||||
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-SDAG-NEXT: v_trunc_f16_sdwa v1, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
|
||||
; GFX9-SDAG-NEXT: v_trunc_f16_e32 v0, v0
|
||||
; GFX9-SDAG-NEXT: v_pack_b32_f16 v0, v0, v1
|
||||
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
|
||||
;
|
||||
; GFX9-GISEL-LABEL: test_modf_v2f16_only_use_integer:
|
||||
; GFX9-GISEL: ; %bb.0:
|
||||
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-GISEL-NEXT: v_trunc_f16_e32 v1, v0
|
||||
; GFX9-GISEL-NEXT: v_trunc_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
|
||||
; GFX9-GISEL-NEXT: v_pack_b32_f16 v0, v1, v0
|
||||
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call { <2 x half>, <2 x half> } @llvm.modf.v2f16(<2 x half> %x)
|
||||
%result.1 = extractvalue { <2 x half>, <2 x half> } %result, 1
|
||||
ret <2 x half> %result.1
|
||||
}
|
||||
|
||||
define { float, float } @test_modf_f32(float %x) {
|
||||
; GFX9-LABEL: test_modf_f32:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: s_mov_b32 s4, 0x7f800000
|
||||
; GFX9-NEXT: v_trunc_f32_e32 v1, v0
|
||||
; GFX9-NEXT: v_sub_f32_e32 v2, v0, v1
|
||||
; GFX9-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s4
|
||||
; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
|
||||
; GFX9-NEXT: s_brev_b32 s4, -2
|
||||
; GFX9-NEXT: v_bfi_b32 v0, s4, v2, v0
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
; GFX9-SDAG-LABEL: test_modf_f32:
|
||||
; GFX9-SDAG: ; %bb.0:
|
||||
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-SDAG-NEXT: s_mov_b32 s4, 0x7f800000
|
||||
; GFX9-SDAG-NEXT: v_trunc_f32_e32 v1, v0
|
||||
; GFX9-SDAG-NEXT: v_sub_f32_e32 v2, v0, v1
|
||||
; GFX9-SDAG-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s4
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
|
||||
; GFX9-SDAG-NEXT: s_brev_b32 s4, -2
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v0, s4, v2, v0
|
||||
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
|
||||
;
|
||||
; GFX9-GISEL-LABEL: test_modf_f32:
|
||||
; GFX9-GISEL: ; %bb.0:
|
||||
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-GISEL-NEXT: v_trunc_f32_e32 v1, v0
|
||||
; GFX9-GISEL-NEXT: v_mov_b32_e32 v3, 0x7f800000
|
||||
; GFX9-GISEL-NEXT: v_sub_f32_e32 v2, v0, v1
|
||||
; GFX9-GISEL-NEXT: v_cmp_eq_f32_e64 s[4:5], |v0|, v3
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v2, v2, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_bfrev_b32_e32 v3, -2
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v0, 0x80000000, v0
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v0, v2, v3, v0
|
||||
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call { float, float } @llvm.modf.f32(float %x)
|
||||
ret { float, float } %result
|
||||
}
|
||||
|
||||
define float @test_modf_f32_only_use_fract(float %x) {
|
||||
; GFX9-LABEL: test_modf_f32_only_use_fract:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: s_mov_b32 s4, 0x7f800000
|
||||
; GFX9-NEXT: v_trunc_f32_e32 v1, v0
|
||||
; GFX9-NEXT: v_sub_f32_e32 v1, v0, v1
|
||||
; GFX9-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s4
|
||||
; GFX9-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
|
||||
; GFX9-NEXT: s_brev_b32 s4, -2
|
||||
; GFX9-NEXT: v_bfi_b32 v0, s4, v1, v0
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
; GFX9-SDAG-LABEL: test_modf_f32_only_use_fract:
|
||||
; GFX9-SDAG: ; %bb.0:
|
||||
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-SDAG-NEXT: s_mov_b32 s4, 0x7f800000
|
||||
; GFX9-SDAG-NEXT: v_trunc_f32_e32 v1, v0
|
||||
; GFX9-SDAG-NEXT: v_sub_f32_e32 v1, v0, v1
|
||||
; GFX9-SDAG-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s4
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
|
||||
; GFX9-SDAG-NEXT: s_brev_b32 s4, -2
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v0, s4, v1, v0
|
||||
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
|
||||
;
|
||||
; GFX9-GISEL-LABEL: test_modf_f32_only_use_fract:
|
||||
; GFX9-GISEL: ; %bb.0:
|
||||
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-GISEL-NEXT: v_trunc_f32_e32 v1, v0
|
||||
; GFX9-GISEL-NEXT: v_mov_b32_e32 v2, 0x7f800000
|
||||
; GFX9-GISEL-NEXT: v_sub_f32_e32 v1, v0, v1
|
||||
; GFX9-GISEL-NEXT: v_cmp_eq_f32_e64 s[4:5], |v0|, v2
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v1, v1, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_bfrev_b32_e32 v2, -2
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v0, 0x80000000, v0
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v0, v1, v2, v0
|
||||
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call { float, float } @llvm.modf.f32(float %x)
|
||||
%result.0 = extractvalue { float, float } %result, 0
|
||||
ret float %result.0
|
||||
@ -162,43 +268,81 @@ define float @test_modf_f32_only_use_integer(float %x) {
|
||||
}
|
||||
|
||||
define { <2 x float>, <2 x float> } @test_modf_v2f32(<2 x float> %x) {
|
||||
; GFX9-LABEL: test_modf_v2f32:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: s_mov_b32 s4, 0x7f800000
|
||||
; GFX9-NEXT: v_trunc_f32_e32 v2, v0
|
||||
; GFX9-NEXT: v_sub_f32_e32 v3, v0, v2
|
||||
; GFX9-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s4
|
||||
; GFX9-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
|
||||
; GFX9-NEXT: s_brev_b32 s5, -2
|
||||
; GFX9-NEXT: v_bfi_b32 v0, s5, v3, v0
|
||||
; GFX9-NEXT: v_trunc_f32_e32 v3, v1
|
||||
; GFX9-NEXT: v_sub_f32_e32 v4, v1, v3
|
||||
; GFX9-NEXT: v_cmp_neq_f32_e64 vcc, |v1|, s4
|
||||
; GFX9-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
|
||||
; GFX9-NEXT: v_bfi_b32 v1, s5, v4, v1
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
; GFX9-SDAG-LABEL: test_modf_v2f32:
|
||||
; GFX9-SDAG: ; %bb.0:
|
||||
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-SDAG-NEXT: s_mov_b32 s4, 0x7f800000
|
||||
; GFX9-SDAG-NEXT: v_trunc_f32_e32 v2, v0
|
||||
; GFX9-SDAG-NEXT: v_sub_f32_e32 v3, v0, v2
|
||||
; GFX9-SDAG-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s4
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
|
||||
; GFX9-SDAG-NEXT: s_brev_b32 s5, -2
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v0, s5, v3, v0
|
||||
; GFX9-SDAG-NEXT: v_trunc_f32_e32 v3, v1
|
||||
; GFX9-SDAG-NEXT: v_sub_f32_e32 v4, v1, v3
|
||||
; GFX9-SDAG-NEXT: v_cmp_neq_f32_e64 vcc, |v1|, s4
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v1, s5, v4, v1
|
||||
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
|
||||
;
|
||||
; GFX9-GISEL-LABEL: test_modf_v2f32:
|
||||
; GFX9-GISEL: ; %bb.0:
|
||||
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-GISEL-NEXT: v_trunc_f32_e32 v2, v0
|
||||
; GFX9-GISEL-NEXT: v_mov_b32_e32 v4, 0x7f800000
|
||||
; GFX9-GISEL-NEXT: v_sub_f32_e32 v3, v0, v2
|
||||
; GFX9-GISEL-NEXT: v_cmp_eq_f32_e64 s[4:5], |v0|, v4
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v3, v3, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_bfrev_b32_e32 v5, -2
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v0, 0x80000000, v0
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v0, v3, v5, v0
|
||||
; GFX9-GISEL-NEXT: v_trunc_f32_e32 v3, v1
|
||||
; GFX9-GISEL-NEXT: v_sub_f32_e32 v6, v1, v3
|
||||
; GFX9-GISEL-NEXT: v_cmp_eq_f32_e64 s[4:5], |v1|, v4
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v4, v6, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v1, 0x80000000, v1
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v1, v4, v5, v1
|
||||
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float> %x)
|
||||
ret { <2 x float>, <2 x float> } %result
|
||||
}
|
||||
|
||||
define <2 x float> @test_modf_v2f32_only_use_fract(<2 x float> %x) {
|
||||
; GFX9-LABEL: test_modf_v2f32_only_use_fract:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: s_mov_b32 s4, 0x7f800000
|
||||
; GFX9-NEXT: v_trunc_f32_e32 v2, v0
|
||||
; GFX9-NEXT: v_sub_f32_e32 v2, v0, v2
|
||||
; GFX9-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s4
|
||||
; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
|
||||
; GFX9-NEXT: s_brev_b32 s5, -2
|
||||
; GFX9-NEXT: v_bfi_b32 v0, s5, v2, v0
|
||||
; GFX9-NEXT: v_trunc_f32_e32 v2, v1
|
||||
; GFX9-NEXT: v_sub_f32_e32 v2, v1, v2
|
||||
; GFX9-NEXT: v_cmp_neq_f32_e64 vcc, |v1|, s4
|
||||
; GFX9-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
|
||||
; GFX9-NEXT: v_bfi_b32 v1, s5, v2, v1
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
; GFX9-SDAG-LABEL: test_modf_v2f32_only_use_fract:
|
||||
; GFX9-SDAG: ; %bb.0:
|
||||
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-SDAG-NEXT: s_mov_b32 s4, 0x7f800000
|
||||
; GFX9-SDAG-NEXT: v_trunc_f32_e32 v2, v0
|
||||
; GFX9-SDAG-NEXT: v_sub_f32_e32 v2, v0, v2
|
||||
; GFX9-SDAG-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s4
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
|
||||
; GFX9-SDAG-NEXT: s_brev_b32 s5, -2
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v0, s5, v2, v0
|
||||
; GFX9-SDAG-NEXT: v_trunc_f32_e32 v2, v1
|
||||
; GFX9-SDAG-NEXT: v_sub_f32_e32 v2, v1, v2
|
||||
; GFX9-SDAG-NEXT: v_cmp_neq_f32_e64 vcc, |v1|, s4
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v1, s5, v2, v1
|
||||
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
|
||||
;
|
||||
; GFX9-GISEL-LABEL: test_modf_v2f32_only_use_fract:
|
||||
; GFX9-GISEL: ; %bb.0:
|
||||
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-GISEL-NEXT: v_trunc_f32_e32 v2, v0
|
||||
; GFX9-GISEL-NEXT: v_mov_b32_e32 v3, 0x7f800000
|
||||
; GFX9-GISEL-NEXT: v_sub_f32_e32 v2, v0, v2
|
||||
; GFX9-GISEL-NEXT: v_cmp_eq_f32_e64 s[4:5], |v0|, v3
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v2, v2, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_bfrev_b32_e32 v4, -2
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v0, 0x80000000, v0
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v0, v2, v4, v0
|
||||
; GFX9-GISEL-NEXT: v_trunc_f32_e32 v2, v1
|
||||
; GFX9-GISEL-NEXT: v_sub_f32_e32 v2, v1, v2
|
||||
; GFX9-GISEL-NEXT: v_cmp_eq_f32_e64 s[4:5], |v1|, v3
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v2, v2, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v1, 0x80000000, v1
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v1, v2, v4, v1
|
||||
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float> %x)
|
||||
%result.0 = extractvalue { <2 x float>, <2 x float> } %result, 0
|
||||
ret <2 x float> %result.0
|
||||
@ -217,35 +361,67 @@ define <2 x float> @test_modf_v2f32_only_use_integer(<2 x float> %x) {
|
||||
}
|
||||
|
||||
define { double, double } @test_modf_f64(double %x) {
|
||||
; GFX9-LABEL: test_modf_f64:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: v_trunc_f64_e32 v[2:3], v[0:1]
|
||||
; GFX9-NEXT: s_movk_i32 s4, 0x204
|
||||
; GFX9-NEXT: v_cmp_class_f64_e64 s[4:5], v[0:1], s4
|
||||
; GFX9-NEXT: s_brev_b32 s6, -2
|
||||
; GFX9-NEXT: v_add_f64 v[4:5], v[0:1], -v[2:3]
|
||||
; GFX9-NEXT: v_cndmask_b32_e64 v0, v4, 0, s[4:5]
|
||||
; GFX9-NEXT: v_cndmask_b32_e64 v4, v5, 0, s[4:5]
|
||||
; GFX9-NEXT: v_bfi_b32 v1, s6, v4, v1
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
; GFX9-SDAG-LABEL: test_modf_f64:
|
||||
; GFX9-SDAG: ; %bb.0:
|
||||
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-SDAG-NEXT: v_trunc_f64_e32 v[2:3], v[0:1]
|
||||
; GFX9-SDAG-NEXT: s_movk_i32 s4, 0x204
|
||||
; GFX9-SDAG-NEXT: v_cmp_class_f64_e64 s[4:5], v[0:1], s4
|
||||
; GFX9-SDAG-NEXT: s_brev_b32 s6, -2
|
||||
; GFX9-SDAG-NEXT: v_add_f64 v[4:5], v[0:1], -v[2:3]
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v0, v4, 0, s[4:5]
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v4, v5, 0, s[4:5]
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v1, s6, v4, v1
|
||||
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
|
||||
;
|
||||
; GFX9-GISEL-LABEL: test_modf_f64:
|
||||
; GFX9-GISEL: ; %bb.0:
|
||||
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-GISEL-NEXT: v_trunc_f64_e32 v[2:3], v[0:1]
|
||||
; GFX9-GISEL-NEXT: v_mov_b32_e32 v4, 0
|
||||
; GFX9-GISEL-NEXT: v_mov_b32_e32 v5, 0x7ff00000
|
||||
; GFX9-GISEL-NEXT: v_cmp_eq_f64_e64 s[4:5], |v[0:1]|, v[4:5]
|
||||
; GFX9-GISEL-NEXT: v_bfrev_b32_e32 v4, -2
|
||||
; GFX9-GISEL-NEXT: v_add_f64 v[6:7], v[0:1], -v[2:3]
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v1, 0x80000000, v1
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v5, v6, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v6, v7, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v0, v0, 0, v5
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v1, v6, v4, v1
|
||||
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call { double, double } @llvm.modf.f64(double %x)
|
||||
ret { double, double } %result
|
||||
}
|
||||
|
||||
define double @test_modf_f64_only_use_fract(double %x) {
|
||||
; GFX9-LABEL: test_modf_f64_only_use_fract:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: v_trunc_f64_e32 v[2:3], v[0:1]
|
||||
; GFX9-NEXT: s_movk_i32 s4, 0x204
|
||||
; GFX9-NEXT: v_cmp_class_f64_e64 s[4:5], v[0:1], s4
|
||||
; GFX9-NEXT: s_brev_b32 s6, -2
|
||||
; GFX9-NEXT: v_add_f64 v[2:3], v[0:1], -v[2:3]
|
||||
; GFX9-NEXT: v_cndmask_b32_e64 v0, v2, 0, s[4:5]
|
||||
; GFX9-NEXT: v_cndmask_b32_e64 v2, v3, 0, s[4:5]
|
||||
; GFX9-NEXT: v_bfi_b32 v1, s6, v2, v1
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
; GFX9-SDAG-LABEL: test_modf_f64_only_use_fract:
|
||||
; GFX9-SDAG: ; %bb.0:
|
||||
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-SDAG-NEXT: v_trunc_f64_e32 v[2:3], v[0:1]
|
||||
; GFX9-SDAG-NEXT: s_movk_i32 s4, 0x204
|
||||
; GFX9-SDAG-NEXT: v_cmp_class_f64_e64 s[4:5], v[0:1], s4
|
||||
; GFX9-SDAG-NEXT: s_brev_b32 s6, -2
|
||||
; GFX9-SDAG-NEXT: v_add_f64 v[2:3], v[0:1], -v[2:3]
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v0, v2, 0, s[4:5]
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v2, v3, 0, s[4:5]
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v1, s6, v2, v1
|
||||
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
|
||||
;
|
||||
; GFX9-GISEL-LABEL: test_modf_f64_only_use_fract:
|
||||
; GFX9-GISEL: ; %bb.0:
|
||||
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-GISEL-NEXT: v_trunc_f64_e32 v[2:3], v[0:1]
|
||||
; GFX9-GISEL-NEXT: v_mov_b32_e32 v4, 0
|
||||
; GFX9-GISEL-NEXT: v_mov_b32_e32 v5, 0x7ff00000
|
||||
; GFX9-GISEL-NEXT: v_cmp_eq_f64_e64 s[4:5], |v[0:1]|, v[4:5]
|
||||
; GFX9-GISEL-NEXT: v_bfrev_b32_e32 v4, -2
|
||||
; GFX9-GISEL-NEXT: v_add_f64 v[2:3], v[0:1], -v[2:3]
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v1, 0x80000000, v1
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v2, v2, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v3, v3, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v0, v0, 0, v2
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v1, v3, v4, v1
|
||||
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call { double, double } @llvm.modf.f64(double %x)
|
||||
%result.0 = extractvalue { double, double } %result, 0
|
||||
ret double %result.0
|
||||
@ -263,47 +439,95 @@ define double @test_modf_f64_only_use_integer(double %x) {
|
||||
}
|
||||
|
||||
define { <2 x double>, <2 x double> } @test_modf_v2f64(<2 x double> %x) {
|
||||
; GFX9-LABEL: test_modf_v2f64:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: v_trunc_f64_e32 v[4:5], v[0:1]
|
||||
; GFX9-NEXT: v_trunc_f64_e32 v[6:7], v[2:3]
|
||||
; GFX9-NEXT: s_movk_i32 s6, 0x204
|
||||
; GFX9-NEXT: v_cmp_class_f64_e64 s[4:5], v[0:1], s6
|
||||
; GFX9-NEXT: v_cmp_class_f64_e64 s[6:7], v[2:3], s6
|
||||
; GFX9-NEXT: s_brev_b32 s8, -2
|
||||
; GFX9-NEXT: v_add_f64 v[8:9], v[0:1], -v[4:5]
|
||||
; GFX9-NEXT: v_add_f64 v[10:11], v[2:3], -v[6:7]
|
||||
; GFX9-NEXT: v_cndmask_b32_e64 v0, v8, 0, s[4:5]
|
||||
; GFX9-NEXT: v_cndmask_b32_e64 v8, v9, 0, s[4:5]
|
||||
; GFX9-NEXT: v_cndmask_b32_e64 v9, v11, 0, s[6:7]
|
||||
; GFX9-NEXT: v_cndmask_b32_e64 v2, v10, 0, s[6:7]
|
||||
; GFX9-NEXT: v_bfi_b32 v1, s8, v8, v1
|
||||
; GFX9-NEXT: v_bfi_b32 v3, s8, v9, v3
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
; GFX9-SDAG-LABEL: test_modf_v2f64:
|
||||
; GFX9-SDAG: ; %bb.0:
|
||||
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-SDAG-NEXT: v_trunc_f64_e32 v[4:5], v[0:1]
|
||||
; GFX9-SDAG-NEXT: v_trunc_f64_e32 v[6:7], v[2:3]
|
||||
; GFX9-SDAG-NEXT: s_movk_i32 s6, 0x204
|
||||
; GFX9-SDAG-NEXT: v_cmp_class_f64_e64 s[4:5], v[0:1], s6
|
||||
; GFX9-SDAG-NEXT: v_cmp_class_f64_e64 s[6:7], v[2:3], s6
|
||||
; GFX9-SDAG-NEXT: s_brev_b32 s8, -2
|
||||
; GFX9-SDAG-NEXT: v_add_f64 v[8:9], v[0:1], -v[4:5]
|
||||
; GFX9-SDAG-NEXT: v_add_f64 v[10:11], v[2:3], -v[6:7]
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v0, v8, 0, s[4:5]
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v8, v9, 0, s[4:5]
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v9, v11, 0, s[6:7]
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v2, v10, 0, s[6:7]
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v1, s8, v8, v1
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v3, s8, v9, v3
|
||||
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
|
||||
;
|
||||
; GFX9-GISEL-LABEL: test_modf_v2f64:
|
||||
; GFX9-GISEL: ; %bb.0:
|
||||
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-GISEL-NEXT: v_trunc_f64_e32 v[4:5], v[0:1]
|
||||
; GFX9-GISEL-NEXT: v_trunc_f64_e32 v[6:7], v[2:3]
|
||||
; GFX9-GISEL-NEXT: v_mov_b32_e32 v8, 0
|
||||
; GFX9-GISEL-NEXT: v_mov_b32_e32 v9, 0x7ff00000
|
||||
; GFX9-GISEL-NEXT: v_cmp_eq_f64_e64 s[4:5], |v[0:1]|, v[8:9]
|
||||
; GFX9-GISEL-NEXT: v_cmp_eq_f64_e64 s[6:7], |v[2:3]|, v[8:9]
|
||||
; GFX9-GISEL-NEXT: v_bfrev_b32_e32 v8, -2
|
||||
; GFX9-GISEL-NEXT: v_add_f64 v[10:11], v[0:1], -v[4:5]
|
||||
; GFX9-GISEL-NEXT: v_add_f64 v[12:13], v[2:3], -v[6:7]
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v1, 0x80000000, v1
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v3, 0x80000000, v3
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v9, v10, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v10, v11, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v11, v12, 0, s[6:7]
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v12, v13, 0, s[6:7]
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v0, v0, 0, v9
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v1, v10, v8, v1
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v2, v2, 0, v11
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v3, v12, v8, v3
|
||||
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call { <2 x double>, <2 x double> } @llvm.modf.v2f64(<2 x double> %x)
|
||||
ret { <2 x double>, <2 x double> } %result
|
||||
}
|
||||
|
||||
define <2 x double> @test_modf_v2f64_only_use_fract(<2 x double> %x) {
|
||||
; GFX9-LABEL: test_modf_v2f64_only_use_fract:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: v_trunc_f64_e32 v[4:5], v[0:1]
|
||||
; GFX9-NEXT: v_trunc_f64_e32 v[6:7], v[2:3]
|
||||
; GFX9-NEXT: s_movk_i32 s6, 0x204
|
||||
; GFX9-NEXT: v_cmp_class_f64_e64 s[4:5], v[0:1], s6
|
||||
; GFX9-NEXT: v_cmp_class_f64_e64 s[6:7], v[2:3], s6
|
||||
; GFX9-NEXT: s_brev_b32 s8, -2
|
||||
; GFX9-NEXT: v_add_f64 v[4:5], v[0:1], -v[4:5]
|
||||
; GFX9-NEXT: v_add_f64 v[6:7], v[2:3], -v[6:7]
|
||||
; GFX9-NEXT: v_cndmask_b32_e64 v0, v4, 0, s[4:5]
|
||||
; GFX9-NEXT: v_cndmask_b32_e64 v4, v5, 0, s[4:5]
|
||||
; GFX9-NEXT: v_cndmask_b32_e64 v5, v7, 0, s[6:7]
|
||||
; GFX9-NEXT: v_cndmask_b32_e64 v2, v6, 0, s[6:7]
|
||||
; GFX9-NEXT: v_bfi_b32 v1, s8, v4, v1
|
||||
; GFX9-NEXT: v_bfi_b32 v3, s8, v5, v3
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
; GFX9-SDAG-LABEL: test_modf_v2f64_only_use_fract:
|
||||
; GFX9-SDAG: ; %bb.0:
|
||||
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-SDAG-NEXT: v_trunc_f64_e32 v[4:5], v[0:1]
|
||||
; GFX9-SDAG-NEXT: v_trunc_f64_e32 v[6:7], v[2:3]
|
||||
; GFX9-SDAG-NEXT: s_movk_i32 s6, 0x204
|
||||
; GFX9-SDAG-NEXT: v_cmp_class_f64_e64 s[4:5], v[0:1], s6
|
||||
; GFX9-SDAG-NEXT: v_cmp_class_f64_e64 s[6:7], v[2:3], s6
|
||||
; GFX9-SDAG-NEXT: s_brev_b32 s8, -2
|
||||
; GFX9-SDAG-NEXT: v_add_f64 v[4:5], v[0:1], -v[4:5]
|
||||
; GFX9-SDAG-NEXT: v_add_f64 v[6:7], v[2:3], -v[6:7]
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v0, v4, 0, s[4:5]
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v4, v5, 0, s[4:5]
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v5, v7, 0, s[6:7]
|
||||
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v2, v6, 0, s[6:7]
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v1, s8, v4, v1
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v3, s8, v5, v3
|
||||
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
|
||||
;
|
||||
; GFX9-GISEL-LABEL: test_modf_v2f64_only_use_fract:
|
||||
; GFX9-GISEL: ; %bb.0:
|
||||
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-GISEL-NEXT: v_trunc_f64_e32 v[4:5], v[0:1]
|
||||
; GFX9-GISEL-NEXT: v_trunc_f64_e32 v[6:7], v[2:3]
|
||||
; GFX9-GISEL-NEXT: v_mov_b32_e32 v8, 0
|
||||
; GFX9-GISEL-NEXT: v_mov_b32_e32 v9, 0x7ff00000
|
||||
; GFX9-GISEL-NEXT: v_cmp_eq_f64_e64 s[4:5], |v[0:1]|, v[8:9]
|
||||
; GFX9-GISEL-NEXT: v_cmp_eq_f64_e64 s[6:7], |v[2:3]|, v[8:9]
|
||||
; GFX9-GISEL-NEXT: v_bfrev_b32_e32 v8, -2
|
||||
; GFX9-GISEL-NEXT: v_add_f64 v[4:5], v[0:1], -v[4:5]
|
||||
; GFX9-GISEL-NEXT: v_add_f64 v[6:7], v[2:3], -v[6:7]
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v1, 0x80000000, v1
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v3, 0x80000000, v3
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v4, v4, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v5, v5, 0, s[4:5]
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v6, v6, 0, s[6:7]
|
||||
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v7, v7, 0, s[6:7]
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v0, v0, 0, v4
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v1, v5, v8, v1
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v2, v2, 0, v6
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v3, v7, v8, v3
|
||||
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call { <2 x double>, <2 x double> } @llvm.modf.v2f64(<2 x double> %x)
|
||||
%result.0 = extractvalue { <2 x double>, <2 x double> } %result, 0
|
||||
ret <2 x double> %result.0
|
||||
@ -322,14 +546,24 @@ define <2 x double> @test_modf_v2f64_only_use_integer(<2 x double> %x) {
|
||||
}
|
||||
|
||||
define { float, float } @test_modf_ninf(float %x) {
|
||||
; GFX9-LABEL: test_modf_ninf:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: v_trunc_f32_e32 v1, v0
|
||||
; GFX9-NEXT: v_sub_f32_e32 v2, v0, v1
|
||||
; GFX9-NEXT: s_brev_b32 s4, -2
|
||||
; GFX9-NEXT: v_bfi_b32 v0, s4, v2, v0
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
; GFX9-SDAG-LABEL: test_modf_ninf:
|
||||
; GFX9-SDAG: ; %bb.0:
|
||||
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-SDAG-NEXT: v_trunc_f32_e32 v1, v0
|
||||
; GFX9-SDAG-NEXT: v_sub_f32_e32 v2, v0, v1
|
||||
; GFX9-SDAG-NEXT: s_brev_b32 s4, -2
|
||||
; GFX9-SDAG-NEXT: v_bfi_b32 v0, s4, v2, v0
|
||||
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
|
||||
;
|
||||
; GFX9-GISEL-LABEL: test_modf_ninf:
|
||||
; GFX9-GISEL: ; %bb.0:
|
||||
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-GISEL-NEXT: v_trunc_f32_e32 v1, v0
|
||||
; GFX9-GISEL-NEXT: v_sub_f32_e32 v2, v0, v1
|
||||
; GFX9-GISEL-NEXT: v_bfrev_b32_e32 v3, -2
|
||||
; GFX9-GISEL-NEXT: v_and_b32_e32 v0, 0x80000000, v0
|
||||
; GFX9-GISEL-NEXT: v_and_or_b32 v0, v2, v3, v0
|
||||
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call ninf { float, float } @llvm.modf.f32(float %x)
|
||||
ret { float, float } %result
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user