@@ -5599,7 +5599,22 @@ bool SelectionDAG::isBaseWithConstantOffset(SDValue Op) const {
5599
5599
(Op.getOpcode() == ISD::ADD || isADDLike(Op));
5600
5600
}
5601
5601
5602
- bool SelectionDAG::isKnownNeverNaN(SDValue Op, bool SNaN, unsigned Depth) const {
5602
+ bool SelectionDAG::isKnownNeverNaN(SDValue Op, bool SNaN,
5603
+ unsigned Depth) const {
5604
+ EVT VT = Op.getValueType();
5605
+
5606
+ // Since the number of lanes in a scalable vector is unknown at compile time,
5607
+ // we track one bit which is implicitly broadcast to all lanes. This means
5608
+ // that all lanes in a scalable vector are considered demanded.
5609
+ APInt DemandedElts = VT.isFixedLengthVector()
5610
+ ? APInt::getAllOnes(VT.getVectorNumElements())
5611
+ : APInt(1, 1);
5612
+
5613
+ return isKnownNeverNaN(Op, DemandedElts, SNaN, Depth);
5614
+ }
5615
+
5616
+ bool SelectionDAG::isKnownNeverNaN(SDValue Op, const APInt &DemandedElts,
5617
+ bool SNaN, unsigned Depth) const {
5603
5618
// If we're told that NaNs won't happen, assume they won't.
5604
5619
if (getTarget().Options.NoNaNsFPMath || Op->getFlags().hasNoNaNs())
5605
5620
return true;
@@ -5613,6 +5628,9 @@ bool SelectionDAG::isKnownNeverNaN(SDValue Op, bool SNaN, unsigned Depth) const
5613
5628
(SNaN && !C->getValueAPF().isSignaling());
5614
5629
}
5615
5630
5631
+ if (!DemandedElts)
5632
+ return false; // No demanded elts, better to assume we don't know anything.
5633
+
5616
5634
unsigned Opcode = Op.getOpcode();
5617
5635
switch (Opcode) {
5618
5636
case ISD::FADD:
@@ -5655,21 +5673,21 @@ bool SelectionDAG::isKnownNeverNaN(SDValue Op, bool SNaN, unsigned Depth) const
5655
5673
case ISD::FLDEXP: {
5656
5674
if (SNaN)
5657
5675
return true;
5658
- return isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1);
5676
+ return isKnownNeverNaN(Op.getOperand(0), DemandedElts, SNaN, Depth + 1);
5659
5677
}
5660
5678
case ISD::FABS:
5661
5679
case ISD::FNEG:
5662
5680
case ISD::FCOPYSIGN: {
5663
- return isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1);
5681
+ return isKnownNeverNaN(Op.getOperand(0), DemandedElts, SNaN, Depth + 1);
5664
5682
}
5665
5683
case ISD::SELECT:
5666
- return isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1) &&
5667
- isKnownNeverNaN(Op.getOperand(2), SNaN, Depth + 1);
5684
+ return isKnownNeverNaN(Op.getOperand(1), DemandedElts, SNaN, Depth + 1) &&
5685
+ isKnownNeverNaN(Op.getOperand(2), DemandedElts, SNaN, Depth + 1);
5668
5686
case ISD::FP_EXTEND:
5669
5687
case ISD::FP_ROUND: {
5670
5688
if (SNaN)
5671
5689
return true;
5672
- return isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1);
5690
+ return isKnownNeverNaN(Op.getOperand(0), DemandedElts, SNaN, Depth + 1);
5673
5691
}
5674
5692
case ISD::SINT_TO_FP:
5675
5693
case ISD::UINT_TO_FP:
@@ -5691,42 +5709,50 @@ bool SelectionDAG::isKnownNeverNaN(SDValue Op, bool SNaN, unsigned Depth) const
5691
5709
case ISD::FMAXIMUMNUM: {
5692
5710
// Only one needs to be known not-nan, since it will be returned if the
5693
5711
// other ends up being one.
5694
- return isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1) ||
5695
- isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1);
5712
+ return isKnownNeverNaN(Op.getOperand(0), DemandedElts, SNaN, Depth + 1) ||
5713
+ isKnownNeverNaN(Op.getOperand(1), DemandedElts, SNaN, Depth + 1);
5696
5714
}
5697
5715
case ISD::FMINNUM_IEEE:
5698
5716
case ISD::FMAXNUM_IEEE: {
5699
5717
if (SNaN)
5700
5718
return true;
5701
5719
// This can return a NaN if either operand is an sNaN, or if both operands
5702
5720
// are NaN.
5703
- return (isKnownNeverNaN(Op.getOperand(0), false, Depth + 1) &&
5704
- isKnownNeverSNaN(Op.getOperand(1), Depth + 1)) ||
5705
- (isKnownNeverNaN(Op.getOperand(1), false, Depth + 1) &&
5706
- isKnownNeverSNaN(Op.getOperand(0), Depth + 1));
5721
+ return (isKnownNeverNaN(Op.getOperand(0), DemandedElts, false, Depth + 1) &&
5722
+ isKnownNeverSNaN(Op.getOperand(1), DemandedElts, Depth + 1)) ||
5723
+ (isKnownNeverNaN(Op.getOperand(1), DemandedElts, false, Depth + 1) &&
5724
+ isKnownNeverSNaN(Op.getOperand(0), DemandedElts, Depth + 1));
5707
5725
}
5708
5726
case ISD::FMINIMUM:
5709
5727
case ISD::FMAXIMUM: {
5710
5728
// TODO: Does this quiet or return the origina NaN as-is?
5711
- return isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1) &&
5712
- isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1);
5729
+ return isKnownNeverNaN(Op.getOperand(0), DemandedElts, SNaN, Depth + 1) &&
5730
+ isKnownNeverNaN(Op.getOperand(1), DemandedElts, SNaN, Depth + 1);
5713
5731
}
5714
- case ISD::EXTRACT_VECTOR_ELT:
5715
- case ISD::EXTRACT_SUBVECTOR: {
5732
+ case ISD::EXTRACT_VECTOR_ELT: {
5733
+ // TODO: Set DemandedSrcElts for constant index.
5716
5734
return isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1);
5717
5735
}
5736
+ case ISD::EXTRACT_SUBVECTOR: {
5737
+ SDValue Src = Op.getOperand(0);
5738
+ unsigned Idx = Op.getConstantOperandVal(1);
5739
+ unsigned NumSrcElts = Src.getValueType().getVectorNumElements();
5740
+ APInt DemandedSrcElts = DemandedElts.zext(NumSrcElts).shl(Idx);
5741
+ return isKnownNeverNaN(Src, DemandedSrcElts, SNaN, Depth + 1);
5742
+ }
5718
5743
case ISD::BUILD_VECTOR: {
5719
- for (const SDValue &Opnd : Op->ops())
5720
- if (!isKnownNeverNaN(Opnd, SNaN, Depth + 1))
5744
+ unsigned NumElts = Op.getNumOperands();
5745
+ for (unsigned I = 0; I != NumElts; ++I)
5746
+ if (DemandedElts[I] &&
5747
+ !isKnownNeverNaN(Op.getOperand(I), SNaN, Depth + 1))
5721
5748
return false;
5722
5749
return true;
5723
5750
}
5724
5751
default:
5725
- if (Opcode >= ISD::BUILTIN_OP_END ||
5726
- Opcode == ISD::INTRINSIC_WO_CHAIN ||
5727
- Opcode == ISD::INTRINSIC_W_CHAIN ||
5728
- Opcode == ISD::INTRINSIC_VOID) {
5729
- return TLI->isKnownNeverNaNForTargetNode(Op, *this, SNaN, Depth);
5752
+ if (Opcode >= ISD::BUILTIN_OP_END || Opcode == ISD::INTRINSIC_WO_CHAIN ||
5753
+ Opcode == ISD::INTRINSIC_W_CHAIN || Opcode == ISD::INTRINSIC_VOID) {
5754
+ return TLI->isKnownNeverNaNForTargetNode(Op, DemandedElts, *this, SNaN,
5755
+ Depth);
5730
5756
}
5731
5757
5732
5758
return false;
0 commit comments