Add support for generating MIPS legacy NaN

Currently, the NaN values emitted for MIPS architectures do not cover
non-IEEE754-2008 compliant case. This change fixes the issue.

Patch by Vladimir Radosavljevic.

Differential Revision: http://reviews.llvm.org/D7882

llvm-svn: 230653
This commit is contained in:
Petar Jovanovic 2015-02-26 18:19:22 +00:00
parent da86749a92
commit d55ae6ba37
4 changed files with 40 additions and 4 deletions

View File

@ -638,6 +638,12 @@ public:
return std::string(1, *Constraint);
}
/// \brief Returns true if NaN encoding is IEEE 754-2008.
/// Only MIPS allows a different encoding.
virtual bool isNan2008() const {
return true;
}
/// \brief Returns a string of target-specific clobbers, in LLVM format.
virtual const char *getClobbers() const = 0;

View File

@ -7590,10 +7590,23 @@ static bool TryEvaluateBuiltinNaN(const ASTContext &Context,
else if (S->getString().getAsInteger(0, fill))
return false;
if (SNaN)
Result = llvm::APFloat::getSNaN(Sem, false, &fill);
else
Result = llvm::APFloat::getQNaN(Sem, false, &fill);
if (Context.getTargetInfo().isNan2008()) {
if (SNaN)
Result = llvm::APFloat::getSNaN(Sem, false, &fill);
else
Result = llvm::APFloat::getQNaN(Sem, false, &fill);
} else {
// Prior to IEEE 754-2008, architectures were allowed to choose whether
// the first bit of their significand was set for qNaN or sNaN. MIPS chose
// a different encoding to what became a standard in 2008, and for pre-
// 2008 revisions, MIPS interpreted sNaN-2008 as qNan and qNaN-2008 as
// sNaN. This is now known as "legacy NaN" encoding.
if (SNaN)
Result = llvm::APFloat::getQNaN(Sem, false, &fill);
else
Result = llvm::APFloat::getSNaN(Sem, false, &fill);
}
return true;
}

View File

@ -5674,6 +5674,10 @@ public:
return CPU == "mips32r6" || ABI == "n32" || ABI == "n64" || ABI == "64";
}
bool isNan2008() const override {
return IsNan2008;
}
StringRef getABI() const override { return ABI; }
bool setCPU(const std::string &Name) override {
bool IsMips32 = getTriple().getArch() == llvm::Triple::mips ||

View File

@ -0,0 +1,13 @@
// RUN: %clang -target mipsel-unknown-linux -mnan=legacy -emit-llvm -S %s -o - | FileCheck %s
// CHECK: float 0x7FF4000000000000, float 0x7FF8000000000000
// CHECK: double 0x7FF4000000000000, double 0x7FF8000000000000
float f[] = {
__builtin_nan(""),
__builtin_nans(""),
};
double d[] = {
__builtin_nan(""),
__builtin_nans(""),
};