use of org.graalvm.compiler.core.common.type.FloatStamp in project graal by oracle.
the class BinaryMathIntrinsicNode method canonical.
@Override
public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
NodeView view = NodeView.from(tool);
ValueNode c = tryConstantFold(forX, forY, getOperation());
if (c != null) {
return c;
}
if (forY.isConstant()) {
double yValue = forY.asJavaConstant().asDouble();
// If the second argument is positive or negative zero, then the result is 1.0.
if (yValue == 0.0D) {
return ConstantNode.forDouble(1);
}
// If the second argument is 1.0, then the result is the same as the first argument.
if (yValue == 1.0D) {
return x;
}
// If the second argument is NaN, then the result is NaN.
if (Double.isNaN(yValue)) {
return ConstantNode.forDouble(Double.NaN);
}
// x**-1 = 1/x
if (yValue == -1.0D) {
return new FloatDivNode(ConstantNode.forDouble(1), x);
}
// x**2 = x*x
if (yValue == 2.0D) {
return new MulNode(x, x);
}
// x**0.5 = sqrt(x)
if (yValue == 0.5D && x.stamp(view) instanceof FloatStamp && ((FloatStamp) x.stamp(view)).lowerBound() >= 0.0D) {
return SqrtNode.create(x, view);
}
}
return this;
}
use of org.graalvm.compiler.core.common.type.FloatStamp in project graal by oracle.
the class ReinterpretNode method intToFloat.
/**
* Compute the {@link IntegerStamp} from a {@link FloatStamp}, losing as little information as
* possible.
*
* Sorting by their bit pattern reinterpreted as signed integers gives the following order of
* floating point numbers:
*
* -0 | negative numbers | -Inf | NaNs | 0 | positive numbers | +Inf | NaNs
*
* So from certain integer ranges we may be able to infer something about the sign, finiteness
* or NaN-ness of the result.
*/
private static FloatStamp intToFloat(IntegerStamp stamp) {
int bits = stamp.getBits();
double minPositive;
double maxPositive;
long signBit = 1L << (bits - 1);
long exponentMask;
if (bits == 64) {
exponentMask = Double.doubleToRawLongBits(Double.POSITIVE_INFINITY);
minPositive = Double.MIN_VALUE;
maxPositive = Double.MAX_VALUE;
} else {
assert bits == 32;
exponentMask = Float.floatToRawIntBits(Float.POSITIVE_INFINITY);
minPositive = Float.MIN_VALUE;
maxPositive = Float.MAX_VALUE;
}
long significandMask = CodeUtil.mask(bits) & ~(signBit | exponentMask);
long positiveInfinity = exponentMask;
long negativeInfinity = CodeUtil.signExtend(signBit | positiveInfinity, bits);
long negativeZero = CodeUtil.signExtend(signBit | 0, bits);
if ((stamp.downMask() & exponentMask) == exponentMask && (stamp.downMask() & significandMask) != 0) {
// if all exponent bits and at least one significand bit are set, the result is NaN
return new FloatStamp(bits, Double.NaN, Double.NaN, false);
}
double upperBound;
if (stamp.upperBound() < negativeInfinity) {
if (stamp.lowerBound() > negativeZero) {
upperBound = -minPositive;
} else {
upperBound = -0.0;
}
} else if (stamp.upperBound() < 0) {
if (stamp.lowerBound() > negativeInfinity) {
return new FloatStamp(bits, Double.NaN, Double.NaN, false);
} else if (stamp.lowerBound() == negativeInfinity) {
upperBound = Double.NEGATIVE_INFINITY;
} else if (stamp.lowerBound() > negativeZero) {
upperBound = -minPositive;
} else {
upperBound = -0.0;
}
} else if (stamp.upperBound() == 0) {
upperBound = 0.0;
} else if (stamp.upperBound() < positiveInfinity) {
upperBound = maxPositive;
} else {
upperBound = Double.POSITIVE_INFINITY;
}
double lowerBound;
if (stamp.lowerBound() > positiveInfinity) {
return new FloatStamp(bits, Double.NaN, Double.NaN, false);
} else if (stamp.lowerBound() == positiveInfinity) {
lowerBound = Double.POSITIVE_INFINITY;
} else if (stamp.lowerBound() > 0) {
lowerBound = minPositive;
} else if (stamp.lowerBound() > negativeInfinity) {
lowerBound = 0.0;
} else {
lowerBound = Double.NEGATIVE_INFINITY;
}
boolean nonNaN;
if ((stamp.upMask() & exponentMask) != exponentMask) {
// NaN has all exponent bits set
nonNaN = true;
} else {
boolean negativeNaNBlock = stamp.lowerBound() < 0 && stamp.upperBound() > negativeInfinity;
boolean positiveNaNBlock = stamp.upperBound() > positiveInfinity;
nonNaN = !negativeNaNBlock && !positiveNaNBlock;
}
return new FloatStamp(bits, lowerBound, upperBound, nonNaN);
}
use of org.graalvm.compiler.core.common.type.FloatStamp in project graal by oracle.
the class FloatEqualsNode method tryFold.
@Override
public TriState tryFold(Stamp xStampGeneric, Stamp yStampGeneric) {
if (xStampGeneric instanceof FloatStamp && yStampGeneric instanceof FloatStamp) {
FloatStamp xStamp = (FloatStamp) xStampGeneric;
FloatStamp yStamp = (FloatStamp) yStampGeneric;
if (xStamp.alwaysDistinct(yStamp)) {
return TriState.FALSE;
} else if (xStamp.neverDistinct(yStamp)) {
return TriState.TRUE;
}
}
return TriState.UNKNOWN;
}
use of org.graalvm.compiler.core.common.type.FloatStamp in project graal by oracle.
the class FloatEqualsNode method isIdentityComparison.
@Override
public boolean isIdentityComparison() {
FloatStamp xStamp = (FloatStamp) x.stamp(NodeView.DEFAULT);
FloatStamp yStamp = (FloatStamp) y.stamp(NodeView.DEFAULT);
/*
* If both stamps have at most one 0.0 and it's the same 0.0 then this is an identity
* comparison. FloatStamp isn't careful about tracking the presence of -0.0 so assume that
* anything that includes 0.0 might include -0.0. So if either one is non-zero then it's an
* identity comparison.
*/
return (!xStamp.contains(0.0) || !yStamp.contains(0.0));
}
use of org.graalvm.compiler.core.common.type.FloatStamp in project graal by oracle.
the class PrimitiveStampBoundaryTest method boundaryStamp.
private static Stamp boundaryStamp(Stamp v1, boolean upper) {
if (v1.isEmpty()) {
return v1;
}
if (v1 instanceof IntegerStamp) {
IntegerStamp istamp = (IntegerStamp) v1;
long bound = upper ? istamp.upperBound() : istamp.lowerBound();
return IntegerStamp.create(istamp.getBits(), bound, bound);
} else if (v1 instanceof FloatStamp) {
FloatStamp floatStamp = (FloatStamp) v1;
double bound = upper ? floatStamp.upperBound() : floatStamp.lowerBound();
int bits = floatStamp.getBits();
return floatStampForConstant(bound, bits);
} else {
throw new InternalError("unexpected stamp type " + v1);
}
}
Aggregations