Search in sources :

Example 1 with FloatStamp

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;
}
Also used : FloatDivNode(org.graalvm.compiler.nodes.calc.FloatDivNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) MulNode(org.graalvm.compiler.nodes.calc.MulNode) FloatStamp(org.graalvm.compiler.core.common.type.FloatStamp) NodeView(org.graalvm.compiler.nodes.NodeView)

Example 2 with FloatStamp

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);
}
Also used : FloatStamp(org.graalvm.compiler.core.common.type.FloatStamp)

Example 3 with FloatStamp

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;
}
Also used : FloatStamp(org.graalvm.compiler.core.common.type.FloatStamp)

Example 4 with FloatStamp

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));
}
Also used : FloatStamp(org.graalvm.compiler.core.common.type.FloatStamp)

Example 5 with FloatStamp

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);
    }
}
Also used : IntegerStamp(org.graalvm.compiler.core.common.type.IntegerStamp) FloatStamp(org.graalvm.compiler.core.common.type.FloatStamp)

Aggregations

FloatStamp (org.graalvm.compiler.core.common.type.FloatStamp)14 ValueNode (org.graalvm.compiler.nodes.ValueNode)5 IntegerStamp (org.graalvm.compiler.core.common.type.IntegerStamp)4 Stamp (org.graalvm.compiler.core.common.type.Stamp)3 ArrayList (java.util.ArrayList)2 Constant (jdk.vm.ci.meta.Constant)2 JavaConstant (jdk.vm.ci.meta.JavaConstant)2 PrimitiveStamp (org.graalvm.compiler.core.common.type.PrimitiveStamp)2 ParameterNode (org.graalvm.compiler.nodes.ParameterNode)2 Test (org.junit.Test)2 Parameters (org.junit.runners.Parameterized.Parameters)2 PrimitiveConstant (jdk.vm.ci.meta.PrimitiveConstant)1 AbstractObjectStamp (org.graalvm.compiler.core.common.type.AbstractObjectStamp)1 ArithmeticOpTable (org.graalvm.compiler.core.common.type.ArithmeticOpTable)1 Neg (org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp.Neg)1 LogicNode (org.graalvm.compiler.nodes.LogicNode)1 NodeView (org.graalvm.compiler.nodes.NodeView)1 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)1 ConditionalNode (org.graalvm.compiler.nodes.calc.ConditionalNode)1 FloatDivNode (org.graalvm.compiler.nodes.calc.FloatDivNode)1