{"record":{"id":"b1e8b47caaf7b464","repo":"oracle/graal","slug":"a-probability-of-more-than-1-0-is-not-allowed","errorCode":null,"errorMessage":"A probability of more than 1.0 ({}) is not allowed!","messagePattern":"A probability of more than 1\\.0 \\((.+?)\\) is not allowed!","errorType":"exception","errorClass":"GraalError","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/extended/SwitchNode.java","lineNumber":343,"sourceCode":"            assertTrue(succ.next() instanceof SwitchCaseProbabilityNode,\n                            \"Cannot inject switch probability, since key successor %s is not a SwitchCaseProbabilityNode\",\n                            succ.next());\n            SwitchCaseProbabilityNode caseProbabilityNode = (SwitchCaseProbabilityNode) succ.next();\n\n            ValueNode probabilityNode = caseProbabilityNode.getProbability();\n            if (!probabilityNode.isConstant()) {\n                /*\n                 * If any of the probabilities are not constant we bail out of simplification, which\n                 * will cause compilation to fail later during lowering since the node will be left\n                 * behind\n                 */\n                return;\n            }\n            double probabilityValue = probabilityNode.asJavaConstant().asDouble();\n            if (probabilityValue < 0.0) {\n                throw new GraalError(\"A negative probability of \" + probabilityValue + \" is not allowed!\");\n            } else if (probabilityValue > 1.0) {\n                throw new GraalError(\"A probability of more than 1.0 (\" + probabilityValue + \") is not allowed!\");\n            } else if (Double.isNaN(probabilityValue)) {\n                /*\n                 * We allow NaN if the node is in unreachable code that will eventually fall away,\n                 * or else an error will be thrown during lowering since we keep the node around.\n                 * See analogous case in BranchProbabilityNode.\n                 */\n                return;\n            }\n            nodeProbabilities[i] = probabilityValue / numKeysPerBlock[keySuccessorIndex(i)];\n        }\n\n        for (AbstractBeginNode blockSuccessor : successors) {\n            AbstractBeginNode succ = blockSuccessor;\n            while (succ.next() instanceof AbstractBeginNode next) {\n                succ = next;\n            }\n            SwitchCaseProbabilityNode caseProbabilityNode = (SwitchCaseProbabilityNode) succ.next();\n            caseProbabilityNode.replaceAtUsages(null);","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/extended/SwitchNode.java#L325-L361","documentation":"SwitchNode's simplification (SwitchNode.java:343) validates that every constant case probability is in [0.0, 1.0]. This variant fires when a probability constant exceeds 1.0 (100%), which is invalid because probabilities are ratios. It usually indicates unnormalized counts were passed where ratios were expected.","triggerScenarios":"Calling SwitchNode.create(...) / IntegerSwitchNode with a constant probabilities array entry > 1.0; most often raw execution counts from profiling instead of ratios.","commonSituations":"Passing profile hit counts (e.g., {120, 30, 900}) directly as probabilities; computing a ratio with the wrong denominator (dividing by the max instead of the total).","solutions":["Normalize the values: divide each entry by the sum of all entries so they sum to <= 1.0","Check the denominator used to compute each probability (should be total key count or total weight, not the maximum)","Guard the array with an assert/validation loop before constructing the switch"],"exampleFix":"// before\ndouble[] probs = {120, 30, 900}; // raw counts, >1.0\nSwitchNode.create(..., probs, ...);\n\n// after\ndouble total = 1050;\ndouble[] probs = {120 / total, 30 / total, 900 / total};\nSwitchNode.create(..., probs, ...);","handlingStrategy":"validation","validationCode":"static double[] normalize(double[] weights) {\n    double total = Arrays.stream(weights).sum();\n    double[] out = new double[weights.length];\n    for (int i = 0; i < weights.length; i++) out[i] = weights[i] / total;\n    return out; // every entry now <= 1.0\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Divide each weight by the TOTAL, not by the maximum","Unit-test probability-producing code with the assert-enabled compiler so range violations fail early"],"tags":["graal","compiler","switch","branch-probability","normalization"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}