Skip to content

Commit 019d769

Browse files
authored
[MIPS]Fix QNaNs in the MIPS legacy NaN encodings (#139829)
The MSB of the mantissa should be zero for QNaNs in the MIPS legacy NaN encodings, and one for sNaNs. Fix #100495
1 parent 8f91b10 commit 019d769

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed

llvm/lib/Target/Mips/MipsISelLowering.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,9 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
520520

521521
setOperationAction(ISD::TRAP, MVT::Other, Legal);
522522

523+
setOperationAction(ISD::ConstantFP, MVT::f32, Custom);
524+
setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
525+
523526
setTargetDAGCombine({ISD::SDIVREM, ISD::UDIVREM, ISD::SELECT, ISD::AND,
524527
ISD::OR, ISD::ADD, ISD::SUB, ISD::AssertZext, ISD::SHL,
525528
ISD::SIGN_EXTEND});
@@ -1355,6 +1358,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const
13551358
case ISD::FP_TO_SINT: return lowerFP_TO_SINT(Op, DAG);
13561359
case ISD::READCYCLECOUNTER:
13571360
return lowerREADCYCLECOUNTER(Op, DAG);
1361+
case ISD::ConstantFP:
1362+
return lowerConstantFP(Op, DAG);
13581363
}
13591364
return SDValue();
13601365
}
@@ -3015,6 +3020,30 @@ SDValue MipsTargetLowering::lowerFP_TO_SINT(SDValue Op,
30153020
return DAG.getNode(ISD::BITCAST, SDLoc(Op), Op.getValueType(), Trunc);
30163021
}
30173022

3023+
SDValue MipsTargetLowering::lowerConstantFP(SDValue Op,
3024+
SelectionDAG &DAG) const {
3025+
SDLoc DL(Op);
3026+
EVT VT = Op.getSimpleValueType();
3027+
SDNode *N = Op.getNode();
3028+
ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(N);
3029+
3030+
if (!CFP->isNaN() || Subtarget.isNaN2008()) {
3031+
return SDValue();
3032+
}
3033+
3034+
APFloat NaNValue = CFP->getValueAPF();
3035+
auto &Sem = NaNValue.getSemantics();
3036+
3037+
// The MSB of the mantissa should be zero for QNaNs in the MIPS legacy NaN
3038+
// encodings, and one for sNaNs. Check every NaN constants and make sure
3039+
// they are correctly encoded for legacy encodings.
3040+
if (!NaNValue.isSignaling()) {
3041+
APFloat RealQNaN = NaNValue.getSNaN(Sem);
3042+
return DAG.getConstantFP(RealQNaN, DL, VT);
3043+
}
3044+
return SDValue();
3045+
}
3046+
30183047
//===----------------------------------------------------------------------===//
30193048
// Calling Convention Implementation
30203049
//===----------------------------------------------------------------------===//

llvm/lib/Target/Mips/MipsISelLowering.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,7 @@ class TargetRegisterClass;
592592
SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const;
593593
SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const;
594594
SDValue lowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const;
595+
SDValue lowerConstantFP(SDValue Op, SelectionDAG &DAG) const;
595596

596597
/// isEligibleForTailCallOptimization - Check whether the call is eligible
597598
/// for tail call optimization.

llvm/test/CodeGen/Mips/qnan.ll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
; RUN: llc -O3 -mcpu=mips32r2 -mtriple=mips-linux-gnu < %s -o - | FileCheck %s -check-prefixes=MIPS_Legacy
2+
; RUN: llc -O3 -mcpu=mips32r2 -mtriple=mips-linux-gnu -mattr=+nan2008 < %s -o - | FileCheck %s -check-prefixes=MIPS_NaN2008
3+
4+
define dso_local float @nan(float noundef %a, float noundef %b) local_unnamed_addr #0 {
5+
; MIPS_Legacy: $CPI0_0:
6+
; MIPS_Legacy-NEXT: .4byte 0x7fa00000 # float NaN
7+
8+
; MIPS_NaN2008: $CPI0_0:
9+
; MIPS_NaN2008-NEXT: .4byte 0x7fc00000 # float NaN
10+
11+
entry:
12+
%0 = tail call float @llvm.minimum.f32(float %a, float %b)
13+
ret float %0
14+
}

0 commit comments

Comments
 (0)