Skip to content
This repository was archived by the owner on Sep 2, 2018. It is now read-only.

Commit 364f2f3

Browse files
author
Charlie Turner
committed
Emit Tag_ABI_FP_denormal correctly in fast-math mode.
The default ARM floating-point mode does not support IEEE 754 mode exactly. Of relevance to this patch is that input denormals are flushed to zero. The way in which they're flushed to zero depends on the architecture, * For VFPv2, it is implementation defined as to whether the sign of zero is preserved. * For VFPv3 and above, the sign of zero is always preserved when a denormal is flushed to zero. When FP support has been disabled, the strategy taken by this patch is to assume the software support will mirror the behaviour of the hardware support for the target *if it existed*. That is, for architectures which can only have VFPv2, it is assumed the software will flush to positive zero. For later architectures it is assumed the software will flush to zero preserving sign. Change-Id: Icc5928633ba222a4ba3ca8c0df44a440445865fd git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223110 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 4b09648 commit 364f2f3

File tree

3 files changed

+255
-45
lines changed

3 files changed

+255
-45
lines changed

include/llvm/Support/ARMBuildAttributes.h

+2
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ enum {
171171
WCharWidth4Bytes = 4, // sizeof(wchar_t) == 4
172172

173173
// Tag_ABI_FP_denormal, (=20), uleb128
174+
PositiveZero = 0,
175+
IEEEDenormals = 1,
174176
PreserveFPSign = 2, // sign when flushed-to-zero is preserved
175177

176178
// Tag_ABI_FP_number_model, (=23), uleb128

lib/Target/ARM/ARMAsmPrinter.cpp

+26-1
Original file line numberDiff line numberDiff line change
@@ -694,9 +694,34 @@ void ARMAsmPrinter::emitAttributes() {
694694

695695
// Signal various FP modes.
696696
if (!TM.Options.UnsafeFPMath) {
697-
ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, ARMBuildAttrs::Allowed);
697+
ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
698+
ARMBuildAttrs::IEEEDenormals);
698699
ATS.emitAttribute(ARMBuildAttrs::ABI_FP_exceptions,
699700
ARMBuildAttrs::Allowed);
701+
} else {
702+
if (!Subtarget->hasVFP2()) {
703+
// When the target doesn't have an FPU (by design or
704+
// intention), the assumptions made on the software support
705+
// mirror that of the equivalent hardware support *if it
706+
// existed*. For v7 and better we indicate that denormals are
707+
// flushed preserving sign, and for V6 we indicate that
708+
// denormals are flushed to positive zero.
709+
if (Subtarget->hasV7Ops())
710+
ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
711+
ARMBuildAttrs::PreserveFPSign);
712+
} else if (Subtarget->hasVFP3()) {
713+
// In VFPv4, VFPv4U, VFPv3, or VFPv3U, it is preserved. That is,
714+
// the sign bit of the zero matches the sign bit of the input or
715+
// result that is being flushed to zero.
716+
ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
717+
ARMBuildAttrs::PreserveFPSign);
718+
}
719+
// For VFPv2 implementations it is implementation defined as
720+
// to whether denormals are flushed to positive zero or to
721+
// whatever the sign of zero is (ARM v7AR ARM 2.7.5). Historically
722+
// LLVM has chosen to flush this to positive zero (most likely for
723+
// GCC compatibility), so that's the chosen value here (the
724+
// absence of its emission implies zero).
700725
}
701726

702727
if (TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath)

0 commit comments

Comments
 (0)