https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110852
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> --- So, what about following patch (which also fixes the ICE, would of course need to add the testcase) and doesn't regress any predict-*.c tests)? --- gcc/predict.cc.jj 2024-01-03 11:51:32.000000000 +0100 +++ gcc/predict.cc 2024-01-04 16:28:55.041507010 +0100 @@ -2583,44 +2583,36 @@ expr_expected_value_1 (tree type, tree o if (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS) { tree res; - tree nop0 = op0; - tree nop1 = op1; - if (TREE_CODE (op0) != INTEGER_CST) - { - /* See if expected value of op0 is good enough to determine the result. */ - nop0 = expr_expected_value (op0, visited, predictor, probability); - if (nop0 - && (res = fold_build2 (code, type, nop0, op1)) != NULL - && TREE_CODE (res) == INTEGER_CST) - return res; - if (!nop0) - nop0 = op0; - } enum br_predictor predictor2; HOST_WIDE_INT probability2; - if (TREE_CODE (op1) != INTEGER_CST) + tree nop0 = expr_expected_value (op0, visited, predictor, probability); + if (!nop0) + { + nop0 = op0; + *predictor = PRED_UNCONDITIONAL; + *probability = -1; + } + tree nop1 = expr_expected_value (op1, visited, &predictor2, &probability2); + if (!nop1) + { + nop1 = op1; + predictor2 = PRED_UNCONDITIONAL; + probability2 = -1; + } + /* Finally see if we have two known values. */ + res = fold_build2 (code, type, nop0, nop1); + if (TREE_CODE (res) == INTEGER_CST) { - /* See if expected value of op1 is good enough to determine the result. */ - nop1 = expr_expected_value (op1, visited, &predictor2, &probability2); - if (nop1 - && (res = fold_build2 (code, type, op0, nop1)) != NULL - && TREE_CODE (res) == INTEGER_CST) + /* If one operand is PRED_UNCONDITIONAL, aka directly or indirectly + constant, prefer the other predictor. */ + if (predictor2 == PRED_UNCONDITIONAL) + return res; + if (*predictor == PRED_UNCONDITIONAL) { *predictor = predictor2; *probability = probability2; return res; } - if (!nop1) - nop1 = op1; - } - if (nop0 == op0 || nop1 == op1) - return NULL; - /* Finally see if we have two known values. */ - res = fold_build2 (code, type, nop0, nop1); - if (TREE_CODE (res) == INTEGER_CST - && TREE_CODE (nop0) == INTEGER_CST - && TREE_CODE (nop1) == INTEGER_CST) - { /* Combine binary predictions. */ if (*probability != -1 || probability2 != -1) { @@ -2631,6 +2623,9 @@ expr_expected_value_1 (tree type, tree o if (predictor2 < *predictor) *predictor = predictor2; + if (*predictor != PRED_BUILTIN_EXPECT + && *predictor != PRED_BUILTIN_EXPECT_WITH_PROBABILITY) + *probability = -1; return res; }