oracle/graal · error · GraalError

A negative probability of + probabilityValue + is not allo

Error message

A negative probability of  + probabilityValue +  is not allowed!

What it means

BranchProbabilityNode.simplify validates the injected probability constant: values must be within [0.0, 1.0]. A negative constant throws GraalError with the offending value inline. The node comes from the branch probability intrinsic (com.oracle.graal.nodes.extended.BranchProbabilityNode.probability(double, boolean) / ProbabilityNode style intrinsics), so the error pinpoints an invalid literal in source or snippet code.

Source

Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/extended/BranchProbabilityNode.java:154

    @Override
    public Node canonical(CanonicalizerTool tool) {
        if (condition.isConstant()) {
            // fold constant conditions early during PE
            return condition;
        }
        return this;
    }

    @Override
    public void simplify(SimplifierTool tool) {
        if (!hasUsages()) {
            return;
        }
        if (probability.isConstant()) {
            double probabilityValue = probability.asJavaConstant().asDouble();
            if (probabilityValue < 0.0) {
                throw new GraalError("A negative probability of " + probabilityValue + " is not allowed!");
            } else if (probabilityValue > 1.0) {
                throw new GraalError("A probability of more than 1.0 (" + probabilityValue + ") is not allowed!");
            } else if (Double.isNaN(probabilityValue)) {
                /*
                 * We allow NaN if the node is in unreachable code that will eventually fall away,
                 * or else an error will be thrown during lowering since we keep the node around.
                 */
                return;
            }
            boolean usageFound = false;
            for (IntegerEqualsNode node : this.usages().filter(IntegerEqualsNode.class)) {
                assert node.condition() == CanonicalCondition.EQ : Assertions.errorMessage(node, node.condition());
                ValueNode other = node.getX();
                if (node.getX() == this) {
                    other = node.getY();
                }
                if (other.isConstant()) {
                    double probabilityToSet = probabilityValue;

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Fix the probability value to be within [0.0, 1.0]
  2. Use the provided constants (BranchProbabilityNode.DELTA_ON_TAKEN / LIKELY_PROBABILITY / NOT_FREQUENT_PROBABILITY, etc.) instead of hand-written numbers
  3. If the value flows from configuration, validate/clamp it before it reaches the intrinsic

Example fix

// before
BranchProbabilityNode.probability(-0.1, cond)

// after
BranchProbabilityNode.probability(BranchProbabilityNode.NOT_FREQUENT_PROBABILITY, cond)
Defensive patterns

Strategy: validation

Validate before calling

static double checkProbability(double p) {
    if (p < 0.0 || p > 1.0 || Double.isNaN(p)) throw new IllegalArgumentException("probability out of range: " + p);
    return p;
}

Prevention

When it happens

Trigger: Calling the branch-probability intrinsic with a negative constant that survives to a constant node: probability(-0.1, cond), or a snippet/substitution parameter constant-folding to a negative value.

Common situations: Copy-pasted probability values; passing NOT_FREQUENT_PROBABILITY-style constants through arithmetic that can go negative; refactoring prob constants into computations with a sign bug.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/d506e5334e4b6a09. Report an issue: GitHub.