#include "llvm/ADT/APInt.h"
using namespace llvm;
// example compilation command:
// clang++ -std=c++11 floattest.cpp -Illvmbuild/include -Illvm/include \
-lcurses -dynamiclib llvmbuild/lib/libLLVMCore.a \
llvmbuild/lib/libLLVMSupport.a -o floattest.dylib
extern "C" bool wouldFold(uint32_t BitWidth, int knownZero, int knownOne, bool IsInputSigned, int SignificandWidth) {
APInt KnownZero(BitWidth, knownZero), KnownOne(BitWidth, knownOne);
// MostSignificantPossiblySetBit and LeastSignificantPossiblySetBit
// refer to the most and least significant possibly set (not known zero)
// bits of the absolute value of the integer.
int LeastSignificantPossiblySetBit;
int MostSignificantPossiblySetBit;
bool PossiblyNegative = IsInputSigned && !KnownZero[BitWidth - 1];
bool KnownNegative = PossiblyNegative && KnownOne[BitWidth - 1];
// The lowest possibly set bit is always the lowest bit not known to be
// zero.
LeastSignificantPossiblySetBit = int(KnownZero.countTrailingOnes());
// If the number is known to be negative, the highest possibly set bit is
// the highest bit not known to be one.
// If the number is known to be positive, the highest possibly set bit is
// the highest bit not known to be zero.
// If the number is of unknown sign, the highest possibly set bit is the
// bit to the right of the sign bit. This causes an interesting behavior
// if the sign bit is unknown and every other bit is known zero: the value
// we set for lowest possibly set bit will be 1 higher than that for highest
// possibly set bit, leading to a BitRange of 0. The real BitRange would be
// 1, which will fit into any significand, so this doesn't cause any
// incorrect behavior.
if (KnownNegative)
MostSignificantPossiblySetBit = int(BitWidth -
KnownOne.countLeadingOnes()) - 1;
else if (!PossiblyNegative)
MostSignificantPossiblySetBit = int(BitWidth -
KnownZero.countLeadingOnes()) - 1;
else
MostSignificantPossiblySetBit = int(BitWidth) - 2;
int BitRange = MostSignificantPossiblySetBit -
LeastSignificantPossiblySetBit + 1;
// To be safe, the width between the most and least significant possibly
// set bits must fit within the width of the significand. We don't have to
// worry about the exponent; if the number doesn't fit into the exponent,
// then the conversion is undefined behavior.
return BitRange <= SignificandWidth;
}