[SelectionDAG] Add expansion for llvm.modf intrinsic (#179434)
Targets without a `modf` libcall lower the intrinsic directly, matching the existing `llvm.frexp` expansion. Targets with an existing libcall are unchanged. Fixes #173021
This commit is contained in:
parent
639a8d1f1d
commit
b33a0e6101
@ -184,6 +184,7 @@ private:
|
||||
SDValue ExpandFNEG(SDNode *Node) const;
|
||||
SDValue expandLdexp(SDNode *Node) const;
|
||||
SDValue expandFrexp(SDNode *Node) const;
|
||||
SDValue expandModf(SDNode *Node) const;
|
||||
|
||||
SDValue ExpandLegalINT_TO_FP(SDNode *Node, SDValue &Chain);
|
||||
void PromoteLegalINT_TO_FP(SDNode *N, const SDLoc &dl,
|
||||
@ -2771,6 +2772,34 @@ SDValue SelectionDAGLegalize::expandFrexp(SDNode *Node) const {
|
||||
return DAG.getMergeValues({Result0, Result1}, dl);
|
||||
}
|
||||
|
||||
SDValue SelectionDAGLegalize::expandModf(SDNode *Node) const {
|
||||
SDLoc dl(Node);
|
||||
SDValue Val = Node->getOperand(0);
|
||||
EVT VT = Val.getValueType();
|
||||
SDNodeFlags Flags = Node->getFlags();
|
||||
|
||||
SDValue IntPart = DAG.getNode(ISD::FTRUNC, dl, VT, Val, Flags);
|
||||
SDValue FracPart = DAG.getNode(ISD::FSUB, dl, VT, Val, IntPart, Flags);
|
||||
|
||||
SDValue FracToUse;
|
||||
if (Flags.hasNoInfs()) {
|
||||
FracToUse = FracPart;
|
||||
} else {
|
||||
SDValue Abs = DAG.getNode(ISD::FABS, dl, VT, Val, Flags);
|
||||
SDValue Inf =
|
||||
DAG.getConstantFP(APFloat::getInf(VT.getFltSemantics()), dl, VT);
|
||||
EVT SetCCVT =
|
||||
TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
|
||||
SDValue IsInf = DAG.getSetCC(dl, SetCCVT, Abs, Inf, ISD::SETOEQ);
|
||||
SDValue Zero = DAG.getConstantFP(0.0, dl, VT);
|
||||
FracToUse = DAG.getSelect(dl, VT, IsInf, Zero, FracPart);
|
||||
}
|
||||
|
||||
SDValue ResultFrac =
|
||||
DAG.getNode(ISD::FCOPYSIGN, dl, VT, FracToUse, Val, Flags);
|
||||
return DAG.getMergeValues({ResultFrac, IntPart}, dl);
|
||||
}
|
||||
|
||||
/// This function is responsible for legalizing a
|
||||
/// INT_TO_FP operation of the specified operand when the target requests that
|
||||
/// we expand it. At this point, we know that the result and operand types are
|
||||
@ -3920,6 +3949,19 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ISD::FMODF: {
|
||||
RTLIB::Libcall LC = RTLIB::getMODF(Node->getValueType(0));
|
||||
// Use the LibCall instead, it is very likely faster
|
||||
// FIXME: Use separate LibCall action.
|
||||
if (DAG.getLibcalls().getLibcallImpl(LC) != RTLIB::Unsupported)
|
||||
break;
|
||||
|
||||
if (SDValue Expanded = expandModf(Node)) {
|
||||
Results.push_back(Expanded);
|
||||
Results.push_back(Expanded.getValue(1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ISD::FSINCOS: {
|
||||
if (isSinCosLibcallAvailable(Node, DAG.getLibcalls()))
|
||||
break;
|
||||
|
||||
335
llvm/test/CodeGen/AMDGPU/llvm.modf.ll
Normal file
335
llvm/test/CodeGen/AMDGPU/llvm.modf.ll
Normal file
@ -0,0 +1,335 @@
|
||||
; 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
|
||||
|
||||
declare { half, half } @llvm.modf.f16(half)
|
||||
declare { <2 x half>, <2 x half> } @llvm.modf.v2f16(<2 x half>)
|
||||
|
||||
declare { float, float } @llvm.modf.f32(float)
|
||||
declare { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float>)
|
||||
|
||||
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]
|
||||
%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]
|
||||
%result = call { half, half } @llvm.modf.f16(half %x)
|
||||
%result.0 = extractvalue { half, half } %result, 0
|
||||
ret half %result.0
|
||||
}
|
||||
|
||||
define half @test_modf_f16_only_use_integer(half %x) {
|
||||
; GFX9-LABEL: test_modf_f16_only_use_integer:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: v_trunc_f16_e32 v0, v0
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call { half, half } @llvm.modf.f16(half %x)
|
||||
%result.1 = extractvalue { half, half } %result, 1
|
||||
ret half %result.1
|
||||
}
|
||||
|
||||
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]
|
||||
%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]
|
||||
%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]
|
||||
%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]
|
||||
%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]
|
||||
%result = call { float, float } @llvm.modf.f32(float %x)
|
||||
%result.0 = extractvalue { float, float } %result, 0
|
||||
ret float %result.0
|
||||
}
|
||||
|
||||
define float @test_modf_f32_only_use_integer(float %x) {
|
||||
; GFX9-LABEL: test_modf_f32_only_use_integer:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: v_trunc_f32_e32 v0, v0
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call { float, float } @llvm.modf.f32(float %x)
|
||||
%result.1 = extractvalue { float, float } %result, 1
|
||||
ret float %result.1
|
||||
}
|
||||
|
||||
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]
|
||||
%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]
|
||||
%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
|
||||
}
|
||||
|
||||
define <2 x float> @test_modf_v2f32_only_use_integer(<2 x float> %x) {
|
||||
; GFX9-LABEL: test_modf_v2f32_only_use_integer:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: v_trunc_f32_e32 v0, v0
|
||||
; GFX9-NEXT: v_trunc_f32_e32 v1, v1
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float> %x)
|
||||
%result.1 = extractvalue { <2 x float>, <2 x float> } %result, 1
|
||||
ret <2 x float> %result.1
|
||||
}
|
||||
|
||||
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]
|
||||
%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]
|
||||
%result = call { double, double } @llvm.modf.f64(double %x)
|
||||
%result.0 = extractvalue { double, double } %result, 0
|
||||
ret double %result.0
|
||||
}
|
||||
|
||||
define double @test_modf_f64_only_use_integer(double %x) {
|
||||
; GFX9-LABEL: test_modf_f64_only_use_integer:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: v_trunc_f64_e32 v[0:1], v[0:1]
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call { double, double } @llvm.modf.f64(double %x)
|
||||
%result.1 = extractvalue { double, double } %result, 1
|
||||
ret double %result.1
|
||||
}
|
||||
|
||||
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]
|
||||
%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]
|
||||
%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
|
||||
}
|
||||
|
||||
define <2 x double> @test_modf_v2f64_only_use_integer(<2 x double> %x) {
|
||||
; GFX9-LABEL: test_modf_v2f64_only_use_integer:
|
||||
; GFX9: ; %bb.0:
|
||||
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; GFX9-NEXT: v_trunc_f64_e32 v[0:1], v[0:1]
|
||||
; GFX9-NEXT: v_trunc_f64_e32 v[2:3], v[2:3]
|
||||
; GFX9-NEXT: s_setpc_b64 s[30:31]
|
||||
%result = call { <2 x double>, <2 x double> } @llvm.modf.v2f64(<2 x double> %x)
|
||||
%result.1 = extractvalue { <2 x double>, <2 x double> } %result, 1
|
||||
ret <2 x double> %result.1
|
||||
}
|
||||
|
||||
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]
|
||||
%result = call ninf { float, float } @llvm.modf.f32(float %x)
|
||||
ret { float, float } %result
|
||||
}
|
||||
347
llvm/test/CodeGen/AMDGPU/modf-constant-fold.ll
Normal file
347
llvm/test/CodeGen/AMDGPU/modf-constant-fold.ll
Normal file
@ -0,0 +1,347 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
|
||||
; RUN: llc -mtriple=amdgcn -mcpu=gfx900 < %s | FileCheck %s
|
||||
|
||||
declare { float, float } @llvm.modf.f32(float)
|
||||
declare { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float>)
|
||||
declare { <4 x float>, <4 x float> } @llvm.modf.v4f32(<4 x float>)
|
||||
|
||||
define { float, float } @modf_3_25() {
|
||||
; CHECK-LABEL: modf_3_25:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_mov_b32_e32 v0, 0x3e800000
|
||||
; CHECK-NEXT: v_mov_b32_e32 v1, 0x40400000
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { float, float } @llvm.modf.f32(float 0x400A000000000000)
|
||||
ret { float, float } %ret
|
||||
}
|
||||
|
||||
define { float, float } @modf_neg_3_25() {
|
||||
; CHECK-LABEL: modf_neg_3_25:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_mov_b32_e32 v0, 0xbe800000
|
||||
; CHECK-NEXT: v_mov_b32_e32 v1, 0xc0400000
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { float, float } @llvm.modf.f32(float 0xC00A000000000000)
|
||||
ret { float, float } %ret
|
||||
}
|
||||
|
||||
define { float, float } @modf_integer() {
|
||||
; CHECK-LABEL: modf_integer:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_bfrev_b32_e32 v0, 1
|
||||
; CHECK-NEXT: v_mov_b32_e32 v1, 0xc2280000
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { float, float } @llvm.modf.f32(float -42.0)
|
||||
ret { float, float } %ret
|
||||
}
|
||||
|
||||
define { float, float } @modf_fraction() {
|
||||
; CHECK-LABEL: modf_fraction:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_mov_b32_e32 v0, 0.5
|
||||
; CHECK-NEXT: v_mov_b32_e32 v1, 0
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { float, float } @llvm.modf.f32(float 0.5)
|
||||
ret { float, float } %ret
|
||||
}
|
||||
|
||||
define { float, float } @modf_negfraction() {
|
||||
; CHECK-LABEL: modf_negfraction:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_mov_b32_e32 v0, -0.5
|
||||
; CHECK-NEXT: v_bfrev_b32_e32 v1, 1
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { float, float } @llvm.modf.f32(float -0.5)
|
||||
ret { float, float } %ret
|
||||
}
|
||||
|
||||
define { float, float } @modf_zero() {
|
||||
; CHECK-LABEL: modf_zero:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_mov_b32_e32 v0, 0
|
||||
; CHECK-NEXT: v_mov_b32_e32 v1, 0
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { float, float } @llvm.modf.f32(float 0.0)
|
||||
ret { float, float } %ret
|
||||
}
|
||||
|
||||
define { float, float } @modf_negzero() {
|
||||
; CHECK-LABEL: modf_negzero:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_bfrev_b32_e32 v0, 1
|
||||
; CHECK-NEXT: v_bfrev_b32_e32 v1, 1
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { float, float } @llvm.modf.f32(float -0.0)
|
||||
ret { float, float } %ret
|
||||
}
|
||||
|
||||
define { float, float } @modf_inf() {
|
||||
; CHECK-LABEL: modf_inf:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_mov_b32_e32 v0, 0
|
||||
; CHECK-NEXT: v_mov_b32_e32 v1, 0x7f800000
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { float, float } @llvm.modf.f32(float 0x7FF0000000000000)
|
||||
ret { float, float } %ret
|
||||
}
|
||||
|
||||
define { float, float } @modf_neginf() {
|
||||
; CHECK-LABEL: modf_neginf:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_bfrev_b32_e32 v0, 1
|
||||
; CHECK-NEXT: v_mov_b32_e32 v1, 0xff800000
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { float, float } @llvm.modf.f32(float 0xFFF0000000000000)
|
||||
ret { float, float } %ret
|
||||
}
|
||||
|
||||
define { float, float } @modf_qnan() {
|
||||
; CHECK-LABEL: modf_qnan:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_mov_b32_e32 v0, 0x7fc00000
|
||||
; CHECK-NEXT: v_mov_b32_e32 v1, 0x7fc00000
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { float, float } @llvm.modf.f32(float 0x7FF8000000000000)
|
||||
ret { float, float } %ret
|
||||
}
|
||||
|
||||
define { float, float } @modf_snan() {
|
||||
; CHECK-LABEL: modf_snan:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_trunc_f32_e32 v1, 0x7f800001
|
||||
; CHECK-NEXT: v_sub_f32_e32 v0, 0x7f800001, v1
|
||||
; CHECK-NEXT: v_and_b32_e32 v0, 0x7fffffff, v0
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { float, float } @llvm.modf.f32(float bitcast (i32 2139095041 to float))
|
||||
ret { float, float } %ret
|
||||
}
|
||||
|
||||
define { float, float } @modf_pos_denorm() {
|
||||
; CHECK-LABEL: modf_pos_denorm:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_mov_b32_e32 v0, 0x7fffff
|
||||
; CHECK-NEXT: v_mov_b32_e32 v1, 0
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { float, float } @llvm.modf.f32(float bitcast (i32 8388607 to float))
|
||||
ret { float, float } %ret
|
||||
}
|
||||
|
||||
define { float, float } @modf_neg_denorm() {
|
||||
; CHECK-LABEL: modf_neg_denorm:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_mov_b32_e32 v0, 0x807fffff
|
||||
; CHECK-NEXT: v_bfrev_b32_e32 v1, 1
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { float, float } @llvm.modf.f32(float bitcast (i32 -2139095041 to float))
|
||||
ret { float, float } %ret
|
||||
}
|
||||
|
||||
define { float, float } @modf_posion() {
|
||||
; CHECK-LABEL: modf_posion:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { float, float } @llvm.modf.f32(float poison)
|
||||
ret { float, float } %ret
|
||||
}
|
||||
|
||||
define { <2 x float>, <2 x float> } @modf_posion_vector() {
|
||||
; CHECK-LABEL: modf_posion_vector:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float> poison)
|
||||
ret { <2 x float>, <2 x float> } %ret
|
||||
}
|
||||
|
||||
define { <2 x float>, <2 x float> } @modf_zero_vector() {
|
||||
; CHECK-LABEL: modf_zero_vector:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_mov_b32_e32 v0, 0
|
||||
; CHECK-NEXT: v_mov_b32_e32 v1, 0
|
||||
; CHECK-NEXT: v_mov_b32_e32 v2, 0
|
||||
; CHECK-NEXT: v_mov_b32_e32 v3, 0
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float> zeroinitializer)
|
||||
ret { <2 x float>, <2 x float> } %ret
|
||||
}
|
||||
|
||||
define { <2 x float>, <2 x float> } @modf_zero_negzero_vector() {
|
||||
; CHECK-LABEL: modf_zero_negzero_vector:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_mov_b32_e32 v0, 0
|
||||
; CHECK-NEXT: v_bfrev_b32_e32 v1, 1
|
||||
; CHECK-NEXT: v_mov_b32_e32 v2, 0
|
||||
; CHECK-NEXT: v_bfrev_b32_e32 v3, 1
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float> <float 0.0, float -0.0>)
|
||||
ret { <2 x float>, <2 x float> } %ret
|
||||
}
|
||||
|
||||
define { float, float } @modf_modf(float %x) {
|
||||
; CHECK-LABEL: modf_modf:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: s_mov_b32 s4, 0x7f800000
|
||||
; CHECK-NEXT: v_trunc_f32_e32 v1, v0
|
||||
; CHECK-NEXT: v_sub_f32_e32 v1, v0, v1
|
||||
; CHECK-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s4
|
||||
; CHECK-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
|
||||
; CHECK-NEXT: s_brev_b32 s5, -2
|
||||
; CHECK-NEXT: v_bfi_b32 v0, s5, v1, v0
|
||||
; CHECK-NEXT: v_trunc_f32_e32 v1, v0
|
||||
; CHECK-NEXT: v_sub_f32_e32 v2, v0, v1
|
||||
; CHECK-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s4
|
||||
; CHECK-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
|
||||
; CHECK-NEXT: v_bfi_b32 v0, s5, v2, v0
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%modf0 = call { float, float } @llvm.modf.f32(float %x)
|
||||
%modf0.0 = extractvalue { float, float } %modf0, 0
|
||||
%modf1 = call { float, float } @llvm.modf.f32(float %modf0.0)
|
||||
ret { float, float } %modf1
|
||||
}
|
||||
|
||||
define { <2 x float>, <2 x float> } @modf_modf_vector(<2 x float> %x) {
|
||||
; CHECK-LABEL: modf_modf_vector:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: s_mov_b32 s4, 0x7f800000
|
||||
; CHECK-NEXT: v_trunc_f32_e32 v2, v1
|
||||
; CHECK-NEXT: v_sub_f32_e32 v2, v1, v2
|
||||
; CHECK-NEXT: v_cmp_neq_f32_e64 vcc, |v1|, s4
|
||||
; CHECK-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
|
||||
; CHECK-NEXT: s_brev_b32 s5, -2
|
||||
; CHECK-NEXT: v_bfi_b32 v1, s5, v2, v1
|
||||
; CHECK-NEXT: v_trunc_f32_e32 v2, v0
|
||||
; CHECK-NEXT: v_sub_f32_e32 v2, v0, v2
|
||||
; CHECK-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s4
|
||||
; CHECK-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
|
||||
; CHECK-NEXT: v_bfi_b32 v0, s5, v2, v0
|
||||
; CHECK-NEXT: v_trunc_f32_e32 v2, v0
|
||||
; CHECK-NEXT: v_sub_f32_e32 v3, v0, v2
|
||||
; CHECK-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s4
|
||||
; CHECK-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
|
||||
; CHECK-NEXT: v_bfi_b32 v0, s5, v3, v0
|
||||
; CHECK-NEXT: v_trunc_f32_e32 v3, v1
|
||||
; CHECK-NEXT: v_sub_f32_e32 v4, v1, v3
|
||||
; CHECK-NEXT: v_cmp_neq_f32_e64 vcc, |v1|, s4
|
||||
; CHECK-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
|
||||
; CHECK-NEXT: v_bfi_b32 v1, s5, v4, v1
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%modf0 = call { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float> %x)
|
||||
%modf0.0 = extractvalue { <2 x float>, <2 x float> } %modf0, 0
|
||||
%modf1 = call { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float> %modf0.0)
|
||||
ret { <2 x float>, <2 x float> } %modf1
|
||||
}
|
||||
|
||||
define { float, float } @modf_modf_const(float %x) {
|
||||
; CHECK-LABEL: modf_modf_const:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_mov_b32_e32 v0, 0x3e800000
|
||||
; CHECK-NEXT: v_mov_b32_e32 v1, 0
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%modf0 = call { float, float } @llvm.modf.f32(float 0x400A000000000000)
|
||||
%modf0.0 = extractvalue { float, float } %modf0, 0
|
||||
%modf1 = call { float, float } @llvm.modf.f32(float %modf0.0)
|
||||
ret { float, float } %modf1
|
||||
}
|
||||
|
||||
define { <4 x float>, <4 x float> } @modf_nonsplat_vector() {
|
||||
; CHECK-LABEL: modf_nonsplat_vector:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: s_and_b32 s4, 0x80000000, s4
|
||||
; CHECK-NEXT: v_trunc_f32_e32 v6, s4
|
||||
; CHECK-NEXT: v_mov_b32_e32 v0, 0x3e800000
|
||||
; CHECK-NEXT: v_bfrev_b32_e32 v1, 1
|
||||
; CHECK-NEXT: v_mov_b32_e32 v2, s4
|
||||
; CHECK-NEXT: v_mov_b32_e32 v3, 0
|
||||
; CHECK-NEXT: v_mov_b32_e32 v4, 0x40400000
|
||||
; CHECK-NEXT: v_mov_b32_e32 v5, 0xc2000000
|
||||
; CHECK-NEXT: v_mov_b32_e32 v7, 0x4479c000
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { <4 x float>, <4 x float> } @llvm.modf.v4f32(<4 x float> <float 0x400A000000000000, float -32.0, float poison, float 999.0>)
|
||||
ret { <4 x float>, <4 x float> } %ret
|
||||
}
|
||||
|
||||
define { <2 x float>, <2 x float> } @modf_splat_3_25() {
|
||||
; CHECK-LABEL: modf_splat_3_25:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_mov_b32_e32 v0, 0x3e800000
|
||||
; CHECK-NEXT: v_mov_b32_e32 v1, 0x3e800000
|
||||
; CHECK-NEXT: v_mov_b32_e32 v2, 0x40400000
|
||||
; CHECK-NEXT: v_mov_b32_e32 v3, 0x40400000
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float> <float 0x400A000000000000, float 0x400A000000000000>)
|
||||
ret { <2 x float>, <2 x float> } %ret
|
||||
}
|
||||
|
||||
define { <2 x float>, <2 x float> } @modf_splat_qnan() {
|
||||
; CHECK-LABEL: modf_splat_qnan:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_mov_b32_e32 v0, 0x7fc00000
|
||||
; CHECK-NEXT: v_mov_b32_e32 v1, 0x7fc00000
|
||||
; CHECK-NEXT: v_mov_b32_e32 v2, 0x7fc00000
|
||||
; CHECK-NEXT: v_mov_b32_e32 v3, 0x7fc00000
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>)
|
||||
ret { <2 x float>, <2 x float> } %ret
|
||||
}
|
||||
|
||||
define { <2 x float>, <2 x float> } @modf_splat_inf() {
|
||||
; CHECK-LABEL: modf_splat_inf:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_mov_b32_e32 v0, 0
|
||||
; CHECK-NEXT: v_mov_b32_e32 v1, 0
|
||||
; CHECK-NEXT: v_mov_b32_e32 v2, 0x7f800000
|
||||
; CHECK-NEXT: v_mov_b32_e32 v3, 0x7f800000
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000>)
|
||||
ret { <2 x float>, <2 x float> } %ret
|
||||
}
|
||||
|
||||
define { <2 x float>, <2 x float> } @modf_splat_neginf() {
|
||||
; CHECK-LABEL: modf_splat_neginf:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: v_bfrev_b32_e32 v0, 1
|
||||
; CHECK-NEXT: v_bfrev_b32_e32 v1, 1
|
||||
; CHECK-NEXT: v_mov_b32_e32 v2, 0xff800000
|
||||
; CHECK-NEXT: v_mov_b32_e32 v3, 0xff800000
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float> <float 0xFFF0000000000000, float 0xFFF0000000000000>)
|
||||
ret { <2 x float>, <2 x float> } %ret
|
||||
}
|
||||
|
||||
define { <2 x float>, <2 x float> } @modf_splat_poison_inf() {
|
||||
; CHECK-LABEL: modf_splat_poison_inf:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
|
||||
; CHECK-NEXT: s_and_b32 s4, 0x80000000, s4
|
||||
; CHECK-NEXT: v_trunc_f32_e32 v2, s4
|
||||
; CHECK-NEXT: v_mov_b32_e32 v0, s4
|
||||
; CHECK-NEXT: v_mov_b32_e32 v1, 0
|
||||
; CHECK-NEXT: v_mov_b32_e32 v3, 0x7f800000
|
||||
; CHECK-NEXT: s_setpc_b64 s[30:31]
|
||||
%ret = call { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float> <float poison, float 0x7FF0000000000000>)
|
||||
ret { <2 x float>, <2 x float> } %ret
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user