Skip to content

Commit f54fa77

Browse files
Gary Liujrose-apple
authored andcommitted
[SystemZ] Disable shrinking of SNaN constants (apple#20)
When expanding FP constants, we attempt to shrink doubles to floats and perform an extending load. However, on SystemZ, and possibly on other targets (I've only confirmed the problem on SystemZ), the FP extending load instruction may convert SNaN into QNaN, or may cause an exception. So in the general case, we would still like to shrink FP constants, but SNaNs should be left as doubles. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277602 91177308-0d34-0410-b5e6-96231b3b80d8 LLLexer.cpp: Avoid using BitsToDouble() to preserve SNaN like "double 0x7FF4000000000000". We should not use double (or float) in the LLVM, unless it is really needed. x87 FP register doesn't preserve SNaN to move the value. FIXME: APFloat() may have the constructor by raw bit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277813 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 17c4c6c commit f54fa77

File tree

2 files changed

+18
-12
lines changed

2 files changed

+18
-12
lines changed

lib/AsmParser/LLLexer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,8 @@ lltok::Kind LLLexer::Lex0x() {
859859
// HexFPConstant - Floating point constant represented in IEEE format as a
860860
// hexadecimal number for when exponential notation is not precise enough.
861861
// Half, Float, and double only.
862-
APFloatVal = APFloat(BitsToDouble(HexIntToVal(TokStart+2, CurPtr)));
862+
APFloatVal = APFloat(APFloat::IEEEdouble,
863+
APInt(64, HexIntToVal(TokStart + 2, CurPtr)));
863864
return lltok::APFloat;
864865
}
865866

lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -263,19 +263,24 @@ SelectionDAGLegalize::ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP) {
263263
(VT == MVT::f64) ? MVT::i64 : MVT::i32);
264264
}
265265

266+
APFloat APF = CFP->getValueAPF();
266267
EVT OrigVT = VT;
267268
EVT SVT = VT;
268-
while (SVT != MVT::f32 && SVT != MVT::f16) {
269-
SVT = (MVT::SimpleValueType)(SVT.getSimpleVT().SimpleTy - 1);
270-
if (ConstantFPSDNode::isValueValidForType(SVT, CFP->getValueAPF()) &&
271-
// Only do this if the target has a native EXTLOAD instruction from
272-
// smaller type.
273-
TLI.isLoadExtLegal(ISD::EXTLOAD, OrigVT, SVT) &&
274-
TLI.ShouldShrinkFPConstant(OrigVT)) {
275-
Type *SType = SVT.getTypeForEVT(*DAG.getContext());
276-
LLVMC = cast<ConstantFP>(ConstantExpr::getFPTrunc(LLVMC, SType));
277-
VT = SVT;
278-
Extend = true;
269+
// We don't want to shrink SNaNs. Converting the SNaN back to its real type
270+
// can cause it to be changed into a QNaN on some platforms (e.g. on SystemZ).
271+
if (!APF.isSignaling()) {
272+
while (SVT != MVT::f32 && SVT != MVT::f16) {
273+
SVT = (MVT::SimpleValueType)(SVT.getSimpleVT().SimpleTy - 1);
274+
if (ConstantFPSDNode::isValueValidForType(SVT, APF) &&
275+
// Only do this if the target has a native EXTLOAD instruction from
276+
// smaller type.
277+
TLI.isLoadExtLegal(ISD::EXTLOAD, OrigVT, SVT) &&
278+
TLI.ShouldShrinkFPConstant(OrigVT)) {
279+
Type *SType = SVT.getTypeForEVT(*DAG.getContext());
280+
LLVMC = cast<ConstantFP>(ConstantExpr::getFPTrunc(LLVMC, SType));
281+
VT = SVT;
282+
Extend = true;
283+
}
279284
}
280285
}
281286

0 commit comments

Comments
 (0)