Skip to content

Commit 52b1d4e

Browse files
committed
[MIPS]Fix QNaNs in the MIPS legacy NaN encodings
The MSB of the mantissa should be zero for QNaNs in the MIPS legacy NaN encodings, and one for sNaNs. Fix #100495
1 parent c533127 commit 52b1d4e

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

llvm/lib/Target/Mips/MipsISelLowering.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,8 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
467467
setOperationAction(ISD::FMA, MVT::f64, Expand);
468468
setOperationAction(ISD::FREM, MVT::f32, Expand);
469469
setOperationAction(ISD::FREM, MVT::f64, Expand);
470+
setOperationAction(ISD::ConstantFP, MVT::f32, Custom);
471+
setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
470472

471473
// Lower f16 conversion operations into library calls
472474
setOperationAction(ISD::FP16_TO_FP, MVT::f32, Expand);
@@ -1355,6 +1357,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const
13551357
case ISD::FP_TO_SINT: return lowerFP_TO_SINT(Op, DAG);
13561358
case ISD::READCYCLECOUNTER:
13571359
return lowerREADCYCLECOUNTER(Op, DAG);
1360+
case ISD::ConstantFP: return lowerConstantFP(Op, DAG);
13581361
}
13591362
return SDValue();
13601363
}
@@ -3015,6 +3018,30 @@ SDValue MipsTargetLowering::lowerFP_TO_SINT(SDValue Op,
30153018
return DAG.getNode(ISD::BITCAST, SDLoc(Op), Op.getValueType(), Trunc);
30163019
}
30173020

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

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)