llvm.org GIT mirror llvm / 7166ee5
DAG: Enhance isKnownNeverNaN Add a parameter for testing specifically for sNaNs - at least one instruction pattern on AMDGPU needs to check specifically for this. Also handle more cases, and add a target hook for custom nodes, similar to the hooks for known bits. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338910 91177308-0d34-0410-b5e6-96231b3b80d8 Matt Arsenault 1 year, 6 months ago
12 changed file(s) with 892 addition(s) and 87 deletion(s). Raw diff Collapse all Expand all
14831483 /// X|Cst == X+Cst iff X&Cst = 0.
14841484 bool isBaseWithConstantOffset(SDValue Op) const;
14851485
1486 /// Test whether the given SDValue is known to never be NaN.
1487 bool isKnownNeverNaN(SDValue Op) const;
1486 /// Test whether the given SDValue is known to never be NaN. If \p SNaN is
1487 /// true, returns if \p Op is known to never be a signaling NaN (it may still
1488 /// be a qNaN).
1489 bool isKnownNeverNaN(SDValue Op, bool SNaN = false, unsigned Depth = 0) const;
1490
1491 /// \returns true if \p Op is known to never be a signaling NaN.
1492 bool isKnownNeverSNaN(SDValue Op, unsigned Depth = 0) const {
1493 return isKnownNeverNaN(Op, true, Depth);
1494 }
14881495
14891496 /// Test whether the given floating point SDValue is known to never be
14901497 /// positive or negative zero.
28672867 SDValue Op, const APInt &DemandedElts, APInt &KnownUndef,
28682868 APInt &KnownZero, TargetLoweringOpt &TLO, unsigned Depth = 0) const;
28692869
2870 /// If \p SNaN is false, \returns true if \p Op is known to never be any
2871 /// NaN. If \p sNaN is true, returns if \p Op is known to never be a signaling
2872 /// NaN.
2873 virtual bool isKnownNeverNaNForTargetNode(SDValue Op,
2874 const SelectionDAG &DAG,
2875 bool SNaN = false,
2876 unsigned Depth = 0) const;
28702877 struct DAGCombinerInfo {
28712878 void *DC; // The DAG Combiner object.
28722879 CombineLevel Level;
36213621 return true;
36223622 }
36233623
3624 bool SelectionDAG::isKnownNeverNaN(SDValue Op) const {
3624 bool SelectionDAG::isKnownNeverNaN(SDValue Op, bool SNaN, unsigned Depth) const {
36253625 // If we're told that NaNs won't happen, assume they won't.
3626 if (getTarget().Options.NoNaNsFPMath)
3626 if (getTarget().Options.NoNaNsFPMath || Op->getFlags().hasNoNaNs())
36273627 return true;
36283628
3629 if (Op->getFlags().hasNoNaNs())
3629 if (Depth == 6)
3630 return false; // Limit search depth.
3631
3632 // TODO: Handle vectors.
3633 // If the value is a constant, we can obviously see if it is a NaN or not.
3634 if (const ConstantFPSDNode *C = dyn_cast(Op)) {
3635 return !C->getValueAPF().isNaN() ||
3636 (SNaN && !C->getValueAPF().isSignaling());
3637 }
3638
3639 unsigned Opcode = Op.getOpcode();
3640 switch (Opcode) {
3641 case ISD::FADD:
3642 case ISD::FSUB:
3643 case ISD::FMUL: {
3644 if (SNaN)
3645 return true;
3646 return isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1) &&
3647 isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1);
3648 }
3649 case ISD::FCANONICALIZE:
3650 case ISD::FEXP:
3651 case ISD::FEXP2:
3652 case ISD::FTRUNC:
3653 case ISD::FFLOOR:
3654 case ISD::FCEIL:
3655 case ISD::FROUND:
3656 case ISD::FRINT:
3657 case ISD::FNEARBYINT: {
3658 if (SNaN)
3659 return true;
3660 return isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1);
3661 }
3662 case ISD::FABS:
3663 case ISD::FNEG:
3664 case ISD::FCOPYSIGN: {
3665 return isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1);
3666 }
3667 case ISD::SELECT:
3668 return isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1) &&
3669 isKnownNeverNaN(Op.getOperand(2), SNaN, Depth + 1);
3670 case ISD::FDIV:
3671 case ISD::FREM:
3672 case ISD::FSIN:
3673 case ISD::FCOS: {
3674 if (SNaN)
3675 return true;
3676 // TODO: Need isKnownNeverInfinity
3677 return false;
3678 }
3679 case ISD::FP_EXTEND:
3680 case ISD::FP_ROUND: {
3681 if (SNaN)
3682 return true;
3683 return isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1);
3684 }
3685 case ISD::SINT_TO_FP:
3686 case ISD::UINT_TO_FP:
36303687 return true;
3631
3632 // If the value is a constant, we can obviously see if it is a NaN or not.
3633 if (const ConstantFPSDNode *C = dyn_cast(Op))
3634 return !C->getValueAPF().isNaN();
3635
3636 // TODO: Recognize more cases here.
3637
3638 return false;
3688 case ISD::FMA:
3689 case ISD::FMAD: {
3690 if (SNaN)
3691 return true;
3692 return isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1) &&
3693 isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1) &&
3694 isKnownNeverNaN(Op.getOperand(2), SNaN, Depth + 1);
3695 }
3696 case ISD::FSQRT: // Need is known positive
3697 case ISD::FLOG:
3698 case ISD::FLOG2:
3699 case ISD::FLOG10:
3700 case ISD::FPOWI:
3701 case ISD::FPOW: {
3702 if (SNaN)
3703 return true;
3704 // TODO: Refine on operand
3705 return false;
3706 }
3707
3708 // TODO: Handle FMINNUM/FMAXNUM/FMINNAN/FMAXNAN when there is an agreement on
3709 // what they should do.
3710 default:
3711 if (Opcode >= ISD::BUILTIN_OP_END ||
3712 Opcode == ISD::INTRINSIC_WO_CHAIN ||
3713 Opcode == ISD::INTRINSIC_W_CHAIN ||
3714 Opcode == ISD::INTRINSIC_VOID) {
3715 return TLI->isKnownNeverNaNForTargetNode(Op, *this, SNaN, Depth);
3716 }
3717
3718 return false;
3719 }
36393720 }
36403721
36413722 bool SelectionDAG::isKnownNeverZeroFloat(SDValue Op) const {
17101710 return false;
17111711 }
17121712
1713 bool TargetLowering::isKnownNeverNaNForTargetNode(SDValue Op,
1714 const SelectionDAG &DAG,
1715 bool SNaN,
1716 unsigned Depth) const {
1717 assert((Op.getOpcode() >= ISD::BUILTIN_OP_END ||
1718 Op.getOpcode() == ISD::INTRINSIC_WO_CHAIN ||
1719 Op.getOpcode() == ISD::INTRINSIC_W_CHAIN ||
1720 Op.getOpcode() == ISD::INTRINSIC_VOID) &&
1721 "Should use isKnownNeverNaN if you don't know whether Op"
1722 " is a target node!");
1723 return false;
1724 }
1725
17131726 // FIXME: Ideally, this would use ISD::isConstantSplatVector(), but that must
17141727 // work with truncating build vectors and vectors with elements of less than
17151728 // 8 bits.
43194319 return 1;
43204320 }
43214321 }
4322
4323 bool AMDGPUTargetLowering::isKnownNeverNaNForTargetNode(SDValue Op,
4324 const SelectionDAG &DAG,
4325 bool SNaN,
4326 unsigned Depth) const {
4327 unsigned Opcode = Op.getOpcode();
4328 switch (Opcode) {
4329 case AMDGPUISD::FMIN_LEGACY:
4330 case AMDGPUISD::FMAX_LEGACY: {
4331 if (SNaN)
4332 return true;
4333
4334 // TODO: Can check no nans on one of the operands for each one, but which
4335 // one?
4336 return false;
4337 }
4338 case AMDGPUISD::FMUL_LEGACY: {
4339 if (SNaN)
4340 return true;
4341 return DAG.isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1) &&
4342 DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1);
4343 }
4344 case AMDGPUISD::FMED3:
4345 case AMDGPUISD::FMIN3:
4346 case AMDGPUISD::FMAX3:
4347 case AMDGPUISD::FMAD_FTZ: {
4348 if (SNaN)
4349 return true;
4350 return DAG.isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1) &&
4351 DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1) &&
4352 DAG.isKnownNeverNaN(Op.getOperand(2), SNaN, Depth + 1);
4353 }
4354 case AMDGPUISD::CVT_F32_UBYTE0:
4355 case AMDGPUISD::CVT_F32_UBYTE1:
4356 case AMDGPUISD::CVT_F32_UBYTE2:
4357 case AMDGPUISD::CVT_F32_UBYTE3:
4358 return true;
4359
4360 case AMDGPUISD::RCP:
4361 case AMDGPUISD::RSQ:
4362 case AMDGPUISD::RCP_LEGACY:
4363 case AMDGPUISD::RSQ_LEGACY:
4364 case AMDGPUISD::RSQ_CLAMP: {
4365 if (SNaN)
4366 return true;
4367
4368 // TODO: Need is known positive check.
4369 return false;
4370 }
4371 case AMDGPUISD::LDEXP: {
4372 if (SNaN)
4373 return true;
4374 return DAG.isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1);
4375 }
4376 case AMDGPUISD::DIV_SCALE:
4377 case AMDGPUISD::DIV_FMAS:
4378 case AMDGPUISD::DIV_FIXUP:
4379 case AMDGPUISD::TRIG_PREOP:
4380 // TODO: Refine on operands.
4381 return SNaN;
4382 case AMDGPUISD::SIN_HW:
4383 case AMDGPUISD::COS_HW: {
4384 // TODO: Need check for infinity
4385 return SNaN;
4386 }
4387 case ISD::INTRINSIC_WO_CHAIN: {
4388 unsigned IntrinsicID
4389 = cast(Op.getOperand(0))->getZExtValue();
4390 // TODO: Handle more intrinsics
4391 switch (IntrinsicID) {
4392 case Intrinsic::amdgcn_cubeid:
4393 return true;
4394
4395 case Intrinsic::amdgcn_frexp_mant:
4396 return DAG.isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1);
4397 default:
4398 return false;
4399 }
4400 }
4401 default:
4402 return false;
4403 }
4404 }
244244 unsigned ComputeNumSignBitsForTargetNode(SDValue Op, const APInt &DemandedElts,
245245 const SelectionDAG &DAG,
246246 unsigned Depth = 0) const override;
247
248 bool isKnownNeverNaNForTargetNode(SDValue Op,
249 const SelectionDAG &DAG,
250 bool SNaN = false,
251 unsigned Depth = 0) const override;
247252
248253 /// Helper function that adds Reg to the LiveIn list of the DAG's
249254 /// MachineFunction.
67446744 return AMDGPUTargetLowering::performRcpCombine(N, DCI);
67456745 }
67466746
6747 static bool isKnownNeverSNan(SelectionDAG &DAG, SDValue Op) {
6748 if (!DAG.getTargetLoweringInfo().hasFloatingPointExceptions())
6749 return true;
6750
6751 return DAG.isKnownNeverNaN(Op);
6752 }
6753
67546747 static bool isCanonicalized(SelectionDAG &DAG, SDValue Op,
67556748 const GCNSubtarget *ST, unsigned MaxDepth=5) {
67566749 // If source is a result of another standard FP operation it is already in
68456838
68466839 bool IsIEEEMode = Subtarget->enableIEEEBit(DAG.getMachineFunction());
68476840
6848 if ((IsIEEEMode || isKnownNeverSNan(DAG, N0)) &&
6841 if ((IsIEEEMode || DAG.isKnownNeverSNaN(N0)) &&
68496842 isCanonicalized(DAG, N0, ST))
68506843 return N0;
68516844
69906983 // then give the other result, which is different from med3 with a NaN
69916984 // input.
69926985 SDValue Var = Op0.getOperand(0);
6993 if (!isKnownNeverSNan(DAG, Var))
6986 if (!DAG.isKnownNeverSNaN(Var))
69946987 return SDValue();
69956988
69966989 return DAG.getNode(AMDGPUISD::FMED3, SL, K0->getValueType(0),
5252
5353 ; GCN-LABEL: {{^}}v_clamp_negzero_f32:
5454 ; GCN-DAG: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
55 ; GCN-DAG: v_add_f32_e32 [[ADD:v[0-9]+]], 0.5, [[A]]
5556 ; GCN-DAG: v_bfrev_b32_e32 [[SIGNBIT:v[0-9]+]], 1
56 ; GCN: v_med3_f32 v{{[0-9]+}}, [[A]], [[SIGNBIT]], 1.0
57 ; GCN: v_med3_f32 v{{[0-9]+}}, [[ADD]], [[SIGNBIT]], 1.0
5758 define amdgpu_kernel void @v_clamp_negzero_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 {
59 %tid = call i32 @llvm.amdgcn.workitem.id.x()
60 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
61 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
62 %a = load float, float addrspace(1)* %gep0
63 %add = fadd nnan float %a, 0.5
64 %max = call float @llvm.maxnum.f32(float %add, float -0.0)
65 %med = call float @llvm.minnum.f32(float %max, float 1.0)
66
67 store float %med, float addrspace(1)* %out.gep
68 ret void
69 }
70
71 ; FIXME: Weird inconsistency in how -0.0 is treated. Accepted if clamp
72 ; matched through med3, not if directly. Is this correct?
73
74 ; GCN-LABEL: {{^}}v_clamp_negzero_maybe_snan_f32:
75 ; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
76 ; GCN: v_max_f32_e32 [[MAX:v[0-9]+]], 0x80000000, [[A]]
77 ; GCN: v_min_f32_e32 [[MIN:v[0-9]+]], 1.0, [[MAX]]
78 define amdgpu_kernel void @v_clamp_negzero_maybe_snan_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #0 {
5879 %tid = call i32 @llvm.amdgcn.workitem.id.x()
5980 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
6081 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
351372
352373 ; GCN-LABEL: {{^}}v_clamp_f32_no_dx10_clamp:
353374 ; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
354 ; GCN: v_med3_f32 v{{[0-9]+}}, [[A]], 0, 1.0
375 ; GCN: v_add_f32_e32 [[ADD:v[0-9]+]], 0.5, [[A]]
376 ; GCN: v_med3_f32 v{{[0-9]+}}, [[ADD]], 0, 1.0
355377 define amdgpu_kernel void @v_clamp_f32_no_dx10_clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #2 {
356378 %tid = call i32 @llvm.amdgcn.workitem.id.x()
357379 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
358380 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
359381 %a = load float, float addrspace(1)* %gep0
360 %max = call float @llvm.maxnum.f32(float %a, float 0.0)
382 %a.nnan = fadd nnan float %a, 0.5
383 %max = call float @llvm.maxnum.f32(float %a.nnan, float 0.0)
361384 %med = call float @llvm.minnum.f32(float %max, float 1.0)
362385
363386 store float %med, float addrspace(1)* %out.gep
366389
367390 ; GCN-LABEL: {{^}}v_clamp_f32_snan_dx10clamp:
368391 ; GCN: {{buffer|flat|global}}_load_dword [[A:v[0-9]+]]
369 ; GCN: v_max_f32_e64 v{{[0-9]+}}, [[A]], [[A]] clamp{{$}}
392 ; GCN: v_add_f32_e64 [[ADD:v[0-9]+]], [[A]], 0.5 clamp{{$}}
370393 define amdgpu_kernel void @v_clamp_f32_snan_dx10clamp(float addrspace(1)* %out, float addrspace(1)* %aptr) #3 {
371394 %tid = call i32 @llvm.amdgcn.workitem.id.x()
372395 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
373396 %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
374397 %a = load float, float addrspace(1)* %gep0
375 %max = call float @llvm.maxnum.f32(float %a, float 0.0)
398 %add = fadd float %a, 0.5
399 %max = call float @llvm.maxnum.f32(float %add, float 0.0)
376400 %med = call float @llvm.minnum.f32(float %max, float 1.0)
377401
378402 store float %med, float addrspace(1)* %out.gep
457457 }
458458
459459 ; GCN-LABEL: test_no_fold_canonicalize_fmul_value_f32_no_ieee:
460 ; GCN-EXCEPT: v_mul_f32_e32 v{{[0-9]+}}, 1.0, v{{[0-9]+}}
460 ; GCN: v_mul_f32_e32 [[V:v[0-9]+]], 0x41700000, v{{[0-9]+}}
461 ; GCN-NOT: v_mul
462 ; GCN-NOT: v_max
463 ; GCN-NEXT: ; return
461464 define amdgpu_ps float @test_no_fold_canonicalize_fmul_value_f32_no_ieee(float %arg) {
462465 entry:
463466 %v = fmul float %arg, 15.0
None ; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=NOSNAN -check-prefix=GCN -check-prefix=SI %s
1 ; RUN: llc -march=amdgcn -mattr=+fp-exceptions -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=SNAN -check-prefix=GCN -check-prefix=SI %s
2 ; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=NOSNAN -check-prefix=GCN -check-prefix=VI -check-prefix=GFX89 %s
3 ; RUN: llc -march=amdgcn -mcpu=tonga -mattr=+fp-exceptions -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=SNAN -check-prefix=GCN -check-prefix=VI -check-prefix=GFX89 %s
4 ; RUN: llc -march=amdgcn -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=NOSNAN -check-prefix=GCN -check-prefix=GFX9 -check-prefix=GFX89 %s
5 ; RUN: llc -march=amdgcn -mcpu=gfx900 -mattr=+fp-exceptions -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=SNAN -check-prefix=GCN -check-prefix=GFX9 -check-prefix=GFX89 %s
0 ; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=GCN -check-prefix=SI %s
1 ; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=GCN -check-prefix=VI -check-prefix=GFX89 %s
2 ; RUN: llc -march=amdgcn -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=GCN -check-prefix=GFX9 -check-prefix=GFX89 %s
63
74
85 ; GCN-LABEL: {{^}}v_test_nnan_input_fmed3_r_i_i_f32:
2118 ret void
2219 }
2320
24 ; GCN-LABEL: {{^}}v_test_fmed3_r_i_i_f32:
25 ; NOSNAN: v_med3_f32 v{{[0-9]+}}, v{{[0-9]+}}, 2.0, 4.0
26
27 ; SNAN: v_max_f32_e32 v{{[0-9]+}}, 2.0, v{{[0-9]+}}
28 ; SNAN: v_min_f32_e32 v{{[0-9]+}}, 4.0, v{{[0-9]+}}
29 define amdgpu_kernel void @v_test_fmed3_r_i_i_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #1 {
21 ; GCN-LABEL: {{^}}v_test_fmed3_nnan_r_i_i_f32:
22 ; GCN: v_med3_f32 v{{[0-9]+}}, v{{[0-9]+}}, 2.0, 4.0
23 define amdgpu_kernel void @v_test_fmed3_nnan_r_i_i_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #1 {
3024 %tid = call i32 @llvm.amdgcn.workitem.id.x()
3125 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
3226 %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid
3327 %a = load float, float addrspace(1)* %gep0
34
35 %max = call float @llvm.maxnum.f32(float %a, float 2.0)
28 %a.add = fadd nnan float %a, 1.0
29
30 %max = call float @llvm.maxnum.f32(float %a.add, float 2.0)
3631 %med = call float @llvm.minnum.f32(float %max, float 4.0)
3732
3833 store float %med, float addrspace(1)* %outgep
3934 ret void
4035 }
4136
42 ; GCN-LABEL: {{^}}v_test_fmed3_r_i_i_commute0_f32:
43 ; NOSNAN: v_med3_f32 v{{[0-9]+}}, v{{[0-9]+}}, 2.0, 4.0
44
45 ; SNAN: v_max_f32_e32 v{{[0-9]+}}, 2.0, v{{[0-9]+}}
46 ; SNAN: v_min_f32_e32 v{{[0-9]+}}, 4.0, v{{[0-9]+}}
47 define amdgpu_kernel void @v_test_fmed3_r_i_i_commute0_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #1 {
37 ; GCN-LABEL: {{^}}v_test_fmed3_nnan_r_i_i_commute0_f32:
38 ; GCN: v_med3_f32 v{{[0-9]+}}, v{{[0-9]+}}, 2.0, 4.0
39 define amdgpu_kernel void @v_test_fmed3_nnan_r_i_i_commute0_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #1 {
4840 %tid = call i32 @llvm.amdgcn.workitem.id.x()
4941 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
5042 %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid
5143 %a = load float, float addrspace(1)* %gep0
52
53 %max = call float @llvm.maxnum.f32(float 2.0, float %a)
44 %a.add = fadd nnan float %a, 1.0
45
46 %max = call float @llvm.maxnum.f32(float 2.0, float %a.add)
5447 %med = call float @llvm.minnum.f32(float 4.0, float %max)
5548
5649 store float %med, float addrspace(1)* %outgep
5750 ret void
5851 }
5952
60 ; GCN-LABEL: {{^}}v_test_fmed3_r_i_i_commute1_f32:
61 ; NOSNAN: v_med3_f32 v{{[0-9]+}}, v{{[0-9]+}}, 2.0, 4.0
62
63 ; SNAN: v_max_f32_e32 v{{[0-9]+}}, 2.0, v{{[0-9]+}}
64 ; SNAN: v_min_f32_e32 v{{[0-9]+}}, 4.0, v{{[0-9]+}}
65 define amdgpu_kernel void @v_test_fmed3_r_i_i_commute1_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #1 {
53 ; GCN-LABEL: {{^}}v_test_fmed3_nnan_r_i_i_commute1_f32:
54 ; GCN: v_med3_f32 v{{[0-9]+}}, v{{[0-9]+}}, 2.0, 4.0
55 define amdgpu_kernel void @v_test_fmed3_nnan_r_i_i_commute1_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #1 {
6656 %tid = call i32 @llvm.amdgcn.workitem.id.x()
6757 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
6858 %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid
6959 %a = load float, float addrspace(1)* %gep0
70
71 %max = call float @llvm.maxnum.f32(float %a, float 2.0)
60 %a.add = fadd nnan float %a, 1.0
61
62 %max = call float @llvm.maxnum.f32(float %a.add, float 2.0)
7263 %med = call float @llvm.minnum.f32(float 4.0, float %max)
7364
7465 store float %med, float addrspace(1)* %outgep
7566 ret void
7667 }
7768
78 ; GCN-LABEL: {{^}}v_test_fmed3_r_i_i_constant_order_f32:
69 ; GCN-LABEL: {{^}}v_test_fmed3_nnan_r_i_i_constant_order_f32:
7970 ; GCN: v_max_f32_e32 v{{[0-9]+}}, 4.0, v{{[0-9]+}}
8071 ; GCN: v_min_f32_e32 v{{[0-9]+}}, 2.0, v{{[0-9]+}}
81 define amdgpu_kernel void @v_test_fmed3_r_i_i_constant_order_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #1 {
72 define amdgpu_kernel void @v_test_fmed3_nnan_r_i_i_constant_order_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #1 {
8273 %tid = call i32 @llvm.amdgcn.workitem.id.x()
8374 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
8475 %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid
8576 %a = load float, float addrspace(1)* %gep0
86
87 %max = call float @llvm.maxnum.f32(float %a, float 4.0)
77 %a.add = fadd nnan float %a, 1.0
78
79 %max = call float @llvm.maxnum.f32(float %a.add, float 4.0)
8880 %med = call float @llvm.minnum.f32(float %max, float 2.0)
8981
9082 store float %med, float addrspace(1)* %outgep
9183 ret void
9284 }
9385
94
95 ; GCN-LABEL: {{^}}v_test_fmed3_r_i_i_multi_use_f32:
86 ; GCN-LABEL: {{^}}v_test_fmed3_nnan_r_i_i_multi_use_f32:
9687 ; GCN: v_max_f32_e32 v{{[0-9]+}}, 2.0, v{{[0-9]+}}
9788 ; GCN: v_min_f32_e32 v{{[0-9]+}}, 4.0, v{{[0-9]+}}
98 define amdgpu_kernel void @v_test_fmed3_r_i_i_multi_use_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #1 {
89 define amdgpu_kernel void @v_test_fmed3_nnan_r_i_i_multi_use_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #1 {
9990 %tid = call i32 @llvm.amdgcn.workitem.id.x()
10091 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
10192 %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid
10293 %a = load float, float addrspace(1)* %gep0
103
104 %max = call float @llvm.maxnum.f32(float %a, float 2.0)
94 %a.add = fadd nnan float %a, 1.0
95
96 %max = call float @llvm.maxnum.f32(float %a.add, float 2.0)
10597 %med = call float @llvm.minnum.f32(float %max, float 4.0)
10698
10799 store volatile float %med, float addrspace(1)* %outgep
117109 %gep0 = getelementptr double, double addrspace(1)* %aptr, i32 %tid
118110 %outgep = getelementptr double, double addrspace(1)* %out, i32 %tid
119111 %a = load double, double addrspace(1)* %gep0
120
121 %max = call double @llvm.maxnum.f64(double %a, double 2.0)
112 %a.add = fadd nnan double %a, 1.0
113
114 %max = call double @llvm.maxnum.f64(double %a.add, double 2.0)
122115 %med = call double @llvm.minnum.f64(double %max, double 4.0)
123116
124117 store double %med, double addrspace(1)* %outgep
141134 }
142135
143136 ; GCN-LABEL: {{^}}v_test_legacy_fmed3_r_i_i_f32:
144 ; NOSNAN: v_med3_f32 v{{[0-9]+}}, v{{[0-9]+}}, 2.0, 4.0
145
146 ; SNAN: v_max_f32_e32 v{{[0-9]+}}, 2.0, v{{[0-9]+}}
147 ; SNAN: v_min_f32_e32 v{{[0-9]+}}, 4.0, v{{[0-9]+}}
137 ; GCN: v_med3_f32 v{{[0-9]+}}, v{{[0-9]+}}, 2.0, 4.0
148138 define amdgpu_kernel void @v_test_legacy_fmed3_r_i_i_f32(float addrspace(1)* %out, float addrspace(1)* %aptr) #1 {
149139 %tid = call i32 @llvm.amdgcn.workitem.id.x()
150140 %gep0 = getelementptr float, float addrspace(1)* %aptr, i32 %tid
151141 %outgep = getelementptr float, float addrspace(1)* %out, i32 %tid
152142 %a = load float, float addrspace(1)* %gep0
143 %a.nnan = fadd nnan float %a, 1.0
153144
154145 ; fmax_legacy
155 %cmp0 = fcmp ule float %a, 2.0
156 %max = select i1 %cmp0, float 2.0, float %a
146 %cmp0 = fcmp ule float %a.nnan, 2.0
147 %max = select i1 %cmp0, float 2.0, float %a.nnan
157148
158149 ; fmin_legacy
159150 %cmp1 = fcmp uge float %max, 4.0
2323 ; VI: v_mul_f32_e32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
2424 ; VI: v_mad_f32 v{{[0-9]+}}, -v{{[0-9]+}}, v{{[0-9]+}}, 1.0
2525 define amdgpu_kernel void @multiple_fadd_use_test_f32(float addrspace(1)* %out, float %x, float %y, float %z) #0 {
26 %a11 = fadd fast float %y, -1.0
26 %a11 = fadd float %y, -1.0
2727 %a12 = call float @llvm.fabs.f32(float %a11)
28 %a13 = fadd fast float %x, -1.0
28 %a13 = fadd float %x, -1.0
2929 %a14 = call float @llvm.fabs.f32(float %a13)
3030 %a15 = fcmp ogt float %a12, %a14
3131 %a16 = select i1 %a15, float %a12, float %a14
32 %a17 = fmul fast float %a16, 2.0
33 %a18 = fmul fast float %a17, %a17
34 %a19 = fmul fast float %a18, %a17
35 %a20 = fsub fast float 1.0, %a19
32 %a17 = fmul float %a16, 2.0
33 %a18 = fmul float %a17, %a17
34 %a19 = fmul float %a18, %a17
35 %a20 = fsub float 1.0, %a19
3636 store float %a20, float addrspace(1)* %out
3737 ret void
3838 }
122122 %x = bitcast i16 %x.arg to half
123123 %y = bitcast i16 %y.arg to half
124124 %z = bitcast i16 %z.arg to half
125 %a11 = fadd fast half %y, -1.0
125 %a11 = fadd half %y, -1.0
126126 %a12 = call half @llvm.fabs.f16(half %a11)
127 %a13 = fadd fast half %x, -1.0
127 %a13 = fadd half %x, -1.0
128128 %a14 = call half @llvm.fabs.f16(half %a13)
129129 %a15 = fcmp ogt half %a12, %a14
130130 %a16 = select i1 %a15, half %a12, half %a14
131 %a17 = fmul fast half %a16, 2.0
132 %a18 = fmul fast half %a17, %a17
133 %a19 = fmul fast half %a18, %a17
134 %a20 = fsub fast half 1.0, %a19
131 %a17 = fmul half %a16, 2.0
132 %a18 = fmul half %a17, %a17
133 %a19 = fmul half %a18, %a17
134 %a20 = fsub half 1.0, %a19
135135 store half %a20, half addrspace(1)* %out
136136 ret void
137137 }
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=fiji -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=GCN %s
2
3 ; Mostly overlaps with fmed3.ll to stress specific cases of
4 ; isKnownNeverSNaN.
5
6 define float @v_test_known_not_snan_fabs_input_fmed3_r_i_i_f32(float %a) #0 {
7 ; GCN-LABEL: v_test_known_not_snan_fabs_input_fmed3_r_i_i_f32:
8 ; GCN: ; %bb.0:
9 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
10 ; GCN-NEXT: v_rcp_f32_e32 v0, v0
11 ; GCN-NEXT: v_med3_f32 v0, |v0|, 2.0, 4.0
12 ; GCN-NEXT: s_setpc_b64 s[30:31]
13 %a.nnan.add = fdiv nnan float 1.0, %a
14 %known.not.snan = call float @llvm.fabs.f32(float %a.nnan.add)
15 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
16 %med = call float @llvm.minnum.f32(float %max, float 4.0)
17 ret float %med
18 }
19
20 define float @v_test_known_not_snan_fneg_input_fmed3_r_i_i_f32(float %a) #0 {
21 ; GCN-LABEL: v_test_known_not_snan_fneg_input_fmed3_r_i_i_f32:
22 ; GCN: ; %bb.0:
23 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
24 ; GCN-NEXT: v_rcp_f32_e64 v0, -v0
25 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
26 ; GCN-NEXT: s_setpc_b64 s[30:31]
27 %a.nnan.add = fdiv nnan float 1.0, %a
28 %known.not.snan = fsub float -0.0, %a.nnan.add
29 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
30 %med = call float @llvm.minnum.f32(float %max, float 4.0)
31 ret float %med
32 }
33
34 define float @v_test_known_not_snan_fpext_input_fmed3_r_i_i_f32(half %a) #0 {
35 ; GCN-LABEL: v_test_known_not_snan_fpext_input_fmed3_r_i_i_f32:
36 ; GCN: ; %bb.0:
37 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
38 ; GCN-NEXT: v_add_f16_e32 v0, 1.0, v0
39 ; GCN-NEXT: v_cvt_f32_f16_e32 v0, v0
40 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
41 ; GCN-NEXT: s_setpc_b64 s[30:31]
42 %a.nnan.add = fadd nnan half %a, 1.0
43 %known.not.snan = fpext half %a.nnan.add to float
44 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
45 %med = call float @llvm.minnum.f32(float %max, float 4.0)
46 ret float %med
47 }
48
49 define float @v_test_known_not_snan_fptrunc_input_fmed3_r_i_i_f32(double %a) #0 {
50 ; GCN-LABEL: v_test_known_not_snan_fptrunc_input_fmed3_r_i_i_f32:
51 ; GCN: ; %bb.0:
52 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
53 ; GCN-NEXT: v_add_f64 v[0:1], v[0:1], 1.0
54 ; GCN-NEXT: v_cvt_f32_f64_e32 v0, v[0:1]
55 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
56 ; GCN-NEXT: s_setpc_b64 s[30:31]
57 %a.nnan.add = fadd nnan double %a, 1.0
58 %known.not.snan = fptrunc double %a.nnan.add to float
59 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
60 %med = call float @llvm.minnum.f32(float %max, float 4.0)
61 ret float %med
62 }
63
64 define float @v_test_known_not_snan_copysign_input_fmed3_r_i_i_f32(float %a, float %sign) #0 {
65 ; GCN-LABEL: v_test_known_not_snan_copysign_input_fmed3_r_i_i_f32:
66 ; GCN: ; %bb.0:
67 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
68 ; GCN-NEXT: v_rcp_f32_e32 v0, v0
69 ; GCN-NEXT: s_brev_b32 s6, -2
70 ; GCN-NEXT: v_bfi_b32 v0, s6, v0, v1
71 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
72 ; GCN-NEXT: s_setpc_b64 s[30:31]
73 %a.nnan.add = fdiv nnan float 1.0, %a
74 %known.not.snan = call float @llvm.copysign.f32(float %a.nnan.add, float %sign)
75 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
76 %med = call float @llvm.minnum.f32(float %max, float 4.0)
77 ret float %med
78 }
79
80 ; Canonicalize always quiets, so nothing is necessary.
81 define float @v_test_known_canonicalize_input_fmed3_r_i_i_f32(float %a) #0 {
82 ; GCN-LABEL: v_test_known_canonicalize_input_fmed3_r_i_i_f32:
83 ; GCN: ; %bb.0:
84 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
85 ; GCN-NEXT: v_mul_f32_e32 v0, 1.0, v0
86 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
87 ; GCN-NEXT: s_setpc_b64 s[30:31]
88 %known.not.snan = call float @llvm.canonicalize.f32(float %a)
89 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
90 %med = call float @llvm.minnum.f32(float %max, float 4.0)
91 ret float %med
92 }
93
94 define float @v_test_known_not_snan_minnum_input_fmed3_r_i_i_f32(float %a, float %b) #0 {
95 ; GCN-LABEL: v_test_known_not_snan_minnum_input_fmed3_r_i_i_f32:
96 ; GCN: ; %bb.0:
97 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
98 ; GCN-NEXT: v_rcp_f32_e32 v0, v0
99 ; GCN-NEXT: v_add_f32_e32 v1, 1.0, v1
100 ; GCN-NEXT: v_min_f32_e32 v0, v0, v1
101 ; GCN-NEXT: v_max_f32_e32 v0, 2.0, v0
102 ; GCN-NEXT: v_min_f32_e32 v0, 4.0, v0
103 ; GCN-NEXT: s_setpc_b64 s[30:31]
104 %a.nnan.add = fdiv nnan float 1.0, %a
105 %b.nnan.add = fadd nnan float %b, 1.0
106 %known.not.snan = call float @llvm.minnum.f32(float %a.nnan.add, float %b.nnan.add)
107 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
108 %med = call float @llvm.minnum.f32(float %max, float 4.0)
109 ret float %med
110 }
111
112 define float @v_minnum_possible_nan_lhs_input_fmed3_r_i_i_f32(float %a, float %b) #0 {
113 ; GCN-LABEL: v_minnum_possible_nan_lhs_input_fmed3_r_i_i_f32:
114 ; GCN: ; %bb.0:
115 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
116 ; GCN-NEXT: v_add_f32_e32 v1, 1.0, v1
117 ; GCN-NEXT: v_min_f32_e32 v0, v0, v1
118 ; GCN-NEXT: v_max_f32_e32 v0, 2.0, v0
119 ; GCN-NEXT: v_min_f32_e32 v0, 4.0, v0
120 ; GCN-NEXT: s_setpc_b64 s[30:31]
121 %b.nnan.add = fadd nnan float %b, 1.0
122 %known.not.snan = call float @llvm.minnum.f32(float %a, float %b.nnan.add)
123 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
124 %med = call float @llvm.minnum.f32(float %max, float 4.0)
125 ret float %med
126 }
127
128 define float @v_minnum_possible_nan_rhs_input_fmed3_r_i_i_f32(float %a, float %b) #0 {
129 ; GCN-LABEL: v_minnum_possible_nan_rhs_input_fmed3_r_i_i_f32:
130 ; GCN: ; %bb.0:
131 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
132 ; GCN-NEXT: v_rcp_f32_e32 v0, v0
133 ; GCN-NEXT: v_min_f32_e32 v0, v0, v1
134 ; GCN-NEXT: v_max_f32_e32 v0, 2.0, v0
135 ; GCN-NEXT: v_min_f32_e32 v0, 4.0, v0
136 ; GCN-NEXT: s_setpc_b64 s[30:31]
137 %a.nnan.add = fdiv nnan float 1.0, %a
138 %known.not.snan = call float @llvm.minnum.f32(float %a.nnan.add, float %b)
139 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
140 %med = call float @llvm.minnum.f32(float %max, float 4.0)
141 ret float %med
142 }
143
144 define float @v_test_known_not_snan_maxnum_input_fmed3_r_i_i_f32(float %a, float %b) #0 {
145 ; GCN-LABEL: v_test_known_not_snan_maxnum_input_fmed3_r_i_i_f32:
146 ; GCN: ; %bb.0:
147 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
148 ; GCN-NEXT: v_rcp_f32_e32 v0, v0
149 ; GCN-NEXT: v_add_f32_e32 v1, 1.0, v1
150 ; GCN-NEXT: v_max3_f32 v0, v0, v1, 2.0
151 ; GCN-NEXT: v_min_f32_e32 v0, 4.0, v0
152 ; GCN-NEXT: s_setpc_b64 s[30:31]
153 %a.nnan.add = fdiv nnan float 1.0, %a
154 %b.nnan.add = fadd nnan float %b, 1.0
155 %known.not.snan = call float @llvm.maxnum.f32(float %a.nnan.add, float %b.nnan.add)
156 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
157 %med = call float @llvm.minnum.f32(float %max, float 4.0)
158 ret float %med
159 }
160
161 define float @v_maxnum_possible_nan_lhs_input_fmed3_r_i_i_f32(float %a, float %b) #0 {
162 ; GCN-LABEL: v_maxnum_possible_nan_lhs_input_fmed3_r_i_i_f32:
163 ; GCN: ; %bb.0:
164 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
165 ; GCN-NEXT: v_add_f32_e32 v1, 1.0, v1
166 ; GCN-NEXT: v_max3_f32 v0, v0, v1, 2.0
167 ; GCN-NEXT: v_min_f32_e32 v0, 4.0, v0
168 ; GCN-NEXT: s_setpc_b64 s[30:31]
169 %b.nnan.add = fadd nnan float %b, 1.0
170 %known.not.snan = call float @llvm.maxnum.f32(float %a, float %b.nnan.add)
171 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
172 %med = call float @llvm.minnum.f32(float %max, float 4.0)
173 ret float %med
174 }
175
176 define float @v_maxnum_possible_nan_rhs_input_fmed3_r_i_i_f32(float %a, float %b) #0 {
177 ; GCN-LABEL: v_maxnum_possible_nan_rhs_input_fmed3_r_i_i_f32:
178 ; GCN: ; %bb.0:
179 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
180 ; GCN-NEXT: v_rcp_f32_e32 v0, v0
181 ; GCN-NEXT: v_max3_f32 v0, v0, v1, 2.0
182 ; GCN-NEXT: v_min_f32_e32 v0, 4.0, v0
183 ; GCN-NEXT: s_setpc_b64 s[30:31]
184 %a.nnan.add = fdiv nnan float 1.0, %a
185 %known.not.snan = call float @llvm.maxnum.f32(float %a.nnan.add, float %b)
186 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
187 %med = call float @llvm.minnum.f32(float %max, float 4.0)
188 ret float %med
189 }
190
191 define float @v_test_known_not_snan_select_input_fmed3_r_i_i_f32(float %a, float %b, i32 %c) #0 {
192 ; GCN-LABEL: v_test_known_not_snan_select_input_fmed3_r_i_i_f32:
193 ; GCN: ; %bb.0:
194 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
195 ; GCN-NEXT: v_rcp_f32_e32 v0, v0
196 ; GCN-NEXT: v_add_f32_e32 v1, 1.0, v1
197 ; GCN-NEXT: v_cmp_eq_u32_e32 vcc, 0, v2
198 ; GCN-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
199 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
200 ; GCN-NEXT: s_setpc_b64 s[30:31]
201 %a.nnan.add = fdiv nnan float 1.0, %a
202 %b.nnan.add = fadd nnan float %b, 1.0
203 %cmp = icmp eq i32 %c, 0
204 %known.not.snan = select i1 %cmp, float %a.nnan.add, float %b.nnan.add
205 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
206 %med = call float @llvm.minnum.f32(float %max, float 4.0)
207 ret float %med
208 }
209
210 define float @v_select_possible_nan_lhs_input_fmed3_r_i_i_f32(float %a, float %b, i32 %c) #0 {
211 ; GCN-LABEL: v_select_possible_nan_lhs_input_fmed3_r_i_i_f32:
212 ; GCN: ; %bb.0:
213 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
214 ; GCN-NEXT: v_add_f32_e32 v1, 1.0, v1
215 ; GCN-NEXT: v_cmp_eq_u32_e32 vcc, 0, v2
216 ; GCN-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
217 ; GCN-NEXT: v_max_f32_e32 v0, 2.0, v0
218 ; GCN-NEXT: v_min_f32_e32 v0, 4.0, v0
219 ; GCN-NEXT: s_setpc_b64 s[30:31]
220 %b.nnan.add = fadd nnan float %b, 1.0
221 %cmp = icmp eq i32 %c, 0
222 %known.not.snan = select i1 %cmp, float %a, float %b.nnan.add
223 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
224 %med = call float @llvm.minnum.f32(float %max, float 4.0)
225 ret float %med
226 }
227
228 define float @v_select_possible_nan_rhs_input_fmed3_r_i_i_f32(float %a, float %b, i32 %c) #0 {
229 ; GCN-LABEL: v_select_possible_nan_rhs_input_fmed3_r_i_i_f32:
230 ; GCN: ; %bb.0:
231 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
232 ; GCN-NEXT: v_rcp_f32_e32 v0, v0
233 ; GCN-NEXT: v_cmp_eq_u32_e32 vcc, 0, v2
234 ; GCN-NEXT: v_cndmask_b32_e32 v0, v1, v0, vcc
235 ; GCN-NEXT: v_max_f32_e32 v0, 2.0, v0
236 ; GCN-NEXT: v_min_f32_e32 v0, 4.0, v0
237 ; GCN-NEXT: s_setpc_b64 s[30:31]
238 %a.nnan.add = fdiv nnan float 1.0, %a
239 %cmp = icmp eq i32 %c, 0
240 %known.not.snan = select i1 %cmp, float %a.nnan.add, float %b
241 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
242 %med = call float @llvm.minnum.f32(float %max, float 4.0)
243 ret float %med
244 }
245
246 define float @v_test_known_not_snan_fadd_input_fmed3_r_i_i_f32(float %a, float %b) #0 {
247 ; GCN-LABEL: v_test_known_not_snan_fadd_input_fmed3_r_i_i_f32:
248 ; GCN: ; %bb.0:
249 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
250 ; GCN-NEXT: v_add_f32_e32 v0, v0, v1
251 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
252 ; GCN-NEXT: s_setpc_b64 s[30:31]
253 %known.not.snan = fadd float %a, %b
254 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
255 %med = call float @llvm.minnum.f32(float %max, float 4.0)
256 ret float %med
257 }
258
259 define float @v_test_known_not_snan_fsub_input_fmed3_r_i_i_f32(float %a, float %b) #0 {
260 ; GCN-LABEL: v_test_known_not_snan_fsub_input_fmed3_r_i_i_f32:
261 ; GCN: ; %bb.0:
262 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
263 ; GCN-NEXT: v_sub_f32_e32 v0, v0, v1
264 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
265 ; GCN-NEXT: s_setpc_b64 s[30:31]
266 %known.not.snan = fsub float %a, %b
267 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
268 %med = call float @llvm.minnum.f32(float %max, float 4.0)
269 ret float %med
270 }
271
272 define float @v_test_known_not_snan_fmul_input_fmed3_r_i_i_f32(float %a, float %b) #0 {
273 ; GCN-LABEL: v_test_known_not_snan_fmul_input_fmed3_r_i_i_f32:
274 ; GCN: ; %bb.0:
275 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
276 ; GCN-NEXT: v_mul_f32_e32 v0, v0, v1
277 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
278 ; GCN-NEXT: s_setpc_b64 s[30:31]
279 %known.not.snan = fmul float %a, %b
280 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
281 %med = call float @llvm.minnum.f32(float %max, float 4.0)
282 ret float %med
283 }
284
285 define float @v_test_known_not_snan_uint_to_fp_input_fmed3_r_i_i_f32(i32 %a) #0 {
286 ; GCN-LABEL: v_test_known_not_snan_uint_to_fp_input_fmed3_r_i_i_f32:
287 ; GCN: ; %bb.0:
288 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
289 ; GCN-NEXT: v_cvt_f32_u32_e32 v0, v0
290 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
291 ; GCN-NEXT: s_setpc_b64 s[30:31]
292 %known.not.snan = uitofp i32 %a to float
293 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
294 %med = call float @llvm.minnum.f32(float %max, float 4.0)
295 ret float %med
296 }
297
298 define float @v_test_known_not_snan_sint_to_fp_input_fmed3_r_i_i_f32(i32 %a) #0 {
299 ; GCN-LABEL: v_test_known_not_snan_sint_to_fp_input_fmed3_r_i_i_f32:
300 ; GCN: ; %bb.0:
301 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
302 ; GCN-NEXT: v_cvt_f32_i32_e32 v0, v0
303 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
304 ; GCN-NEXT: s_setpc_b64 s[30:31]
305 %known.not.snan = sitofp i32 %a to float
306 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
307 %med = call float @llvm.minnum.f32(float %max, float 4.0)
308 ret float %med
309 }
310
311 define float @v_test_known_not_snan_fma_input_fmed3_r_i_i_f32(float %a, float %b, float %c) #0 {
312 ; GCN-LABEL: v_test_known_not_snan_fma_input_fmed3_r_i_i_f32:
313 ; GCN: ; %bb.0:
314 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
315 ; GCN-NEXT: v_fma_f32 v0, v0, v1, v2
316 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
317 ; GCN-NEXT: s_setpc_b64 s[30:31]
318 %known.not.snan = call float @llvm.fma.f32(float %a, float %b, float %c)
319 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
320 %med = call float @llvm.minnum.f32(float %max, float 4.0)
321 ret float %med
322 }
323
324 define float @v_test_known_not_snan_fmad_input_fmed3_r_i_i_f32(float %a, float %b, float %c) #0 {
325 ; GCN-LABEL: v_test_known_not_snan_fmad_input_fmed3_r_i_i_f32:
326 ; GCN: ; %bb.0:
327 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
328 ; GCN-NEXT: v_mac_f32_e32 v2, v0, v1
329 ; GCN-NEXT: v_med3_f32 v0, v2, 2.0, 4.0
330 ; GCN-NEXT: s_setpc_b64 s[30:31]
331 %known.not.snan = call float @llvm.fmuladd.f32(float %a, float %b, float %c)
332 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
333 %med = call float @llvm.minnum.f32(float %max, float 4.0)
334 ret float %med
335 }
336
337
338 define float @v_test_known_not_snan_sin_input_fmed3_r_i_i_f32(float %a) #0 {
339 ; GCN-LABEL: v_test_known_not_snan_sin_input_fmed3_r_i_i_f32:
340 ; GCN: ; %bb.0:
341 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
342 ; GCN-NEXT: v_mul_f32_e32 v0, 0.15915494, v0
343 ; GCN-NEXT: v_fract_f32_e32 v0, v0
344 ; GCN-NEXT: v_sin_f32_e32 v0, v0
345 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
346 ; GCN-NEXT: s_setpc_b64 s[30:31]
347 %known.not.snan = call float @llvm.sin.f32(float %a)
348 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
349 %med = call float @llvm.minnum.f32(float %max, float 4.0)
350 ret float %med
351 }
352
353 define float @v_test_known_not_snan_cos_input_fmed3_r_i_i_f32(float %a) #0 {
354 ; GCN-LABEL: v_test_known_not_snan_cos_input_fmed3_r_i_i_f32:
355 ; GCN: ; %bb.0:
356 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
357 ; GCN-NEXT: v_mul_f32_e32 v0, 0.15915494, v0
358 ; GCN-NEXT: v_fract_f32_e32 v0, v0
359 ; GCN-NEXT: v_cos_f32_e32 v0, v0
360 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
361 ; GCN-NEXT: s_setpc_b64 s[30:31]
362 %known.not.snan = call float @llvm.cos.f32(float %a)
363 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
364 %med = call float @llvm.minnum.f32(float %max, float 4.0)
365 ret float %med
366 }
367
368 define float @v_test_known_not_snan_exp2_input_fmed3_r_i_i_f32(float %a) #0 {
369 ; GCN-LABEL: v_test_known_not_snan_exp2_input_fmed3_r_i_i_f32:
370 ; GCN: ; %bb.0:
371 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
372 ; GCN-NEXT: v_exp_f32_e32 v0, v0
373 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
374 ; GCN-NEXT: s_setpc_b64 s[30:31]
375 %known.not.snan = call float @llvm.exp2.f32(float %a)
376 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
377 %med = call float @llvm.minnum.f32(float %max, float 4.0)
378 ret float %med
379 }
380
381 define float @v_test_known_not_snan_trunc_input_fmed3_r_i_i_f32(float %a) #0 {
382 ; GCN-LABEL: v_test_known_not_snan_trunc_input_fmed3_r_i_i_f32:
383 ; GCN: ; %bb.0:
384 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
385 ; GCN-NEXT: v_trunc_f32_e32 v0, v0
386 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
387 ; GCN-NEXT: s_setpc_b64 s[30:31]
388 %known.not.snan = call float @llvm.trunc.f32(float %a)
389 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
390 %med = call float @llvm.minnum.f32(float %max, float 4.0)
391 ret float %med
392 }
393
394 define float @v_test_known_not_snan_floor_input_fmed3_r_i_i_f32(float %a) #0 {
395 ; GCN-LABEL: v_test_known_not_snan_floor_input_fmed3_r_i_i_f32:
396 ; GCN: ; %bb.0:
397 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
398 ; GCN-NEXT: v_floor_f32_e32 v0, v0
399 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
400 ; GCN-NEXT: s_setpc_b64 s[30:31]
401 %known.not.snan = call float @llvm.floor.f32(float %a)
402 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
403 %med = call float @llvm.minnum.f32(float %max, float 4.0)
404 ret float %med
405 }
406
407 define float @v_test_known_not_snan_ceil_input_fmed3_r_i_i_f32(float %a) #0 {
408 ; GCN-LABEL: v_test_known_not_snan_ceil_input_fmed3_r_i_i_f32:
409 ; GCN: ; %bb.0:
410 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
411 ; GCN-NEXT: v_floor_f32_e32 v0, v0
412 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
413 ; GCN-NEXT: s_setpc_b64 s[30:31]
414 %known.not.snan = call float @llvm.floor.f32(float %a)
415 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
416 %med = call float @llvm.minnum.f32(float %max, float 4.0)
417 ret float %med
418 }
419
420 define float @v_test_known_not_snan_round_input_fmed3_r_i_i_f32(float %a) #0 {
421 ; GCN-LABEL: v_test_known_not_snan_round_input_fmed3_r_i_i_f32:
422 ; GCN: ; %bb.0:
423 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
424 ; GCN-NEXT: s_brev_b32 s6, -2
425 ; GCN-NEXT: v_trunc_f32_e32 v2, v0
426 ; GCN-NEXT: v_bfi_b32 v1, s6, 1.0, v0
427 ; GCN-NEXT: v_sub_f32_e32 v0, v0, v2
428 ; GCN-NEXT: v_cmp_ge_f32_e64 vcc, |v0|, 0.5
429 ; GCN-NEXT: v_cndmask_b32_e32 v0, 0, v1, vcc
430 ; GCN-NEXT: v_add_f32_e32 v0, v2, v0
431 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
432 ; GCN-NEXT: s_setpc_b64 s[30:31]
433 %known.not.snan = call float @llvm.round.f32(float %a)
434 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
435 %med = call float @llvm.minnum.f32(float %max, float 4.0)
436 ret float %med
437 }
438
439 define float @v_test_known_not_snan_rint_input_fmed3_r_i_i_f32(float %a) #0 {
440 ; GCN-LABEL: v_test_known_not_snan_rint_input_fmed3_r_i_i_f32:
441 ; GCN: ; %bb.0:
442 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
443 ; GCN-NEXT: v_rndne_f32_e32 v0, v0
444 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
445 ; GCN-NEXT: s_setpc_b64 s[30:31]
446 %known.not.snan = call float @llvm.rint.f32(float %a)
447 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
448 %med = call float @llvm.minnum.f32(float %max, float 4.0)
449 ret float %med
450 }
451
452 define float @v_test_known_not_snan_nearbyint_input_fmed3_r_i_i_f32(float %a) #0 {
453 ; GCN-LABEL: v_test_known_not_snan_nearbyint_input_fmed3_r_i_i_f32:
454 ; GCN: ; %bb.0:
455 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
456 ; GCN-NEXT: v_rndne_f32_e32 v0, v0
457 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
458 ; GCN-NEXT: s_setpc_b64 s[30:31]
459 %known.not.snan = call float @llvm.nearbyint.f32(float %a)
460 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
461 %med = call float @llvm.minnum.f32(float %max, float 4.0)
462 ret float %med
463 }
464
465 define float @v_test_known_not_snan_fmul_legacy_input_fmed3_r_i_i_f32(float %a, float %b) #0 {
466 ; GCN-LABEL: v_test_known_not_snan_fmul_legacy_input_fmed3_r_i_i_f32:
467 ; GCN: ; %bb.0:
468 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
469 ; GCN-NEXT: v_mul_legacy_f32_e32 v0, v0, v1
470 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
471 ; GCN-NEXT: s_setpc_b64 s[30:31]
472 %known.not.snan = call float @llvm.amdgcn.fmul.legacy(float %a, float %b)
473 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
474 %med = call float @llvm.minnum.f32(float %max, float 4.0)
475 ret float %med
476 }
477
478 define float @v_test_known_not_snan_ldexp_input_fmed3_r_i_i_f32(float %a, i32 %b) #0 {
479 ; GCN-LABEL: v_test_known_not_snan_ldexp_input_fmed3_r_i_i_f32:
480 ; GCN: ; %bb.0:
481 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
482 ; GCN-NEXT: v_ldexp_f32 v0, v0, v1
483 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
484 ; GCN-NEXT: s_setpc_b64 s[30:31]
485 %known.not.snan = call float @llvm.amdgcn.ldexp.f32(float %a, i32 %b)
486 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
487 %med = call float @llvm.minnum.f32(float %max, float 4.0)
488 ret float %med
489 }
490
491 define float @v_test_known_not_snan_fmed3_input_fmed3_r_i_i_f32(float %a, float %b, float %c) #0 {
492 ; GCN-LABEL: v_test_known_not_snan_fmed3_input_fmed3_r_i_i_f32:
493 ; GCN: ; %bb.0:
494 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
495 ; GCN-NEXT: v_med3_f32 v0, v0, v1, v2
496 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
497 ; GCN-NEXT: s_setpc_b64 s[30:31]
498 %known.not.snan = call float @llvm.amdgcn.fmed3.f32(float %a, float %b, float %c)
499 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
500 %med = call float @llvm.minnum.f32(float %max, float 4.0)
501 ret float %med
502 }
503
504 define float @v_test_known_not_snan_fmin3_input_fmed3_r_i_i_f32(float %a, float %b, float %c) #0 {
505 ; GCN-LABEL: v_test_known_not_snan_fmin3_input_fmed3_r_i_i_f32:
506 ; GCN: ; %bb.0:
507 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
508 ; GCN-NEXT: v_min3_f32 v0, v0, v1, v2
509 ; GCN-NEXT: v_max_f32_e32 v0, 2.0, v0
510 ; GCN-NEXT: v_min_f32_e32 v0, 4.0, v0
511 ; GCN-NEXT: s_setpc_b64 s[30:31]
512 %min0 = call float @llvm.minnum.f32(float %a, float %b)
513 %known.not.snan = call float @llvm.minnum.f32(float %min0, float %c)
514 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
515 %med = call float @llvm.minnum.f32(float %max, float 4.0)
516 ret float %med
517 }
518
519 define float @v_test_known_not_snan_cvt_ubyte0_input_fmed3_r_i_i_f32(i8 %char) #0 {
520 ; GCN-LABEL: v_test_known_not_snan_cvt_ubyte0_input_fmed3_r_i_i_f32:
521 ; GCN: ; %bb.0:
522 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
523 ; GCN-NEXT: v_cvt_f32_ubyte0_e32 v0, v0
524 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
525 ; GCN-NEXT: s_setpc_b64 s[30:31]
526 %cvt = uitofp i8 %char to float
527 %max = call float @llvm.maxnum.f32(float %cvt, float 2.0)
528 %med = call float @llvm.minnum.f32(float %max, float 4.0)
529 ret float %med
530 }
531
532 define float @v_test_not_known_frexp_mant_input_fmed3_r_i_i_f32(float %arg) #0 {
533 ; GCN-LABEL: v_test_not_known_frexp_mant_input_fmed3_r_i_i_f32:
534 ; GCN: ; %bb.0:
535 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
536 ; GCN-NEXT: v_frexp_mant_f32_e32 v0, v0
537 ; GCN-NEXT: v_max_f32_e32 v0, 2.0, v0
538 ; GCN-NEXT: v_min_f32_e32 v0, 4.0, v0
539 ; GCN-NEXT: s_setpc_b64 s[30:31]
540 %known.not.snan = call float @llvm.amdgcn.frexp.mant.f32(float %arg)
541 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
542 %med = call float @llvm.minnum.f32(float %max, float 4.0)
543 ret float %med
544 }
545
546 define float @v_test_known_not_frexp_mant_input_fmed3_r_i_i_f32(float %arg) #0 {
547 ; GCN-LABEL: v_test_known_not_frexp_mant_input_fmed3_r_i_i_f32:
548 ; GCN: ; %bb.0:
549 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
550 ; GCN-NEXT: v_add_f32_e32 v0, 1.0, v0
551 ; GCN-NEXT: v_frexp_mant_f32_e32 v0, v0
552 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
553 ; GCN-NEXT: s_setpc_b64 s[30:31]
554 %add = fadd float %arg, 1.0
555 %known.not.snan = call float @llvm.amdgcn.frexp.mant.f32(float %add)
556 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
557 %med = call float @llvm.minnum.f32(float %max, float 4.0)
558 ret float %med
559 }
560
561 define float @v_test_known_not_snan_cubeid_input_fmed3_r_i_i_f32(float %a, float %b, float %c) #0 {
562 ; GCN-LABEL: v_test_known_not_snan_cubeid_input_fmed3_r_i_i_f32:
563 ; GCN: ; %bb.0:
564 ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
565 ; GCN-NEXT: v_cubeid_f32 v0, v0, v1, v2
566 ; GCN-NEXT: v_med3_f32 v0, v0, 2.0, 4.0
567 ; GCN-NEXT: s_setpc_b64 s[30:31]
568 %known.not.snan = call float @llvm.amdgcn.cubeid(float %a, float %b, float %c)
569 %max = call float @llvm.maxnum.f32(float %known.not.snan, float 2.0)
570 %med = call float @llvm.minnum.f32(float %max, float 4.0)
571 ret float %med
572 }
573
574 declare float @llvm.fabs.f32(float) #1
575 declare float @llvm.sin.f32(float) #1
576 declare float @llvm.cos.f32(float) #1
577 declare float @llvm.exp2.f32(float) #1
578 declare float @llvm.trunc.f32(float) #1
579 declare float @llvm.floor.f32(float) #1
580 declare float @llvm.ceil.f32(float) #1
581 declare float @llvm.round.f32(float) #1
582 declare float @llvm.rint.f32(float) #1
583 declare float @llvm.nearbyint.f32(float) #1
584 declare float @llvm.canonicalize.f32(float) #1
585 declare float @llvm.minnum.f32(float, float) #1
586 declare float @llvm.maxnum.f32(float, float) #1
587 declare float @llvm.copysign.f32(float, float) #1
588 declare float @llvm.fma.f32(float, float, float) #1
589 declare float @llvm.fmuladd.f32(float, float, float) #1
590 declare float @llvm.amdgcn.ldexp.f32(float, i32) #1
591 declare float @llvm.amdgcn.fmul.legacy(float, float) #1
592 declare float @llvm.amdgcn.fmed3.f32(float, float, float) #1
593 declare float @llvm.amdgcn.frexp.mant.f32(float) #1
594 declare float @llvm.amdgcn.cubeid(float, float, float) #0
595
596 attributes #0 = { nounwind }
597 attributes #1 = { nounwind readnone speculatable }