https://gcc.gnu.org/g:af401d2507d2c50fa551291490a1482660c4d417
commit r17-4984-gaf401d2507d2c50fa551291490a1482660c4d417 Author: Richard Biener <[email protected]> Date: Thu Oct 8 11:26:09 2026 +0200 tree-optimization/127764 - bogus switch stmt IPA predicates set_switch_stmt_execution_predicate does wide_int_to_tree (type, wi::to_wide (min)) to extend min, but that fails to preserve the sign and in general is a bad idiom when the precision between min an type differs. Using ::to_widest is the appropriate thing to do. PR tree-optimization/127764 * ipa-fnsummary.cc (set_switch_stmt_execution_predicate): Use wi::to_widest to preserve sign when extending min to type. * gcc.dg/torture/pr127764.c: New testcase. Diff: --- gcc/ipa-fnsummary.cc | 4 ++-- gcc/testsuite/gcc.dg/torture/pr127764.c | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc index b8571c5b718f..09f508469038 100644 --- a/gcc/ipa-fnsummary.cc +++ b/gcc/ipa-fnsummary.cc @@ -1816,12 +1816,12 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi, /* The case value might not have same type as switch expression, extend the value based on the expression type. */ if (TREE_TYPE (min) != type) - min = wide_int_to_tree (type, wi::to_wide (min)); + min = wide_int_to_tree (type, wi::to_widest (min)); if (!max) max = min; else if (TREE_TYPE (max) != type) - max = wide_int_to_tree (type, wi::to_wide (max)); + max = wide_int_to_tree (type, wi::to_widest (max)); /* The case's target basic block is in convergence point of all switch cases, its predicate should be at least as that of the switch diff --git a/gcc/testsuite/gcc.dg/torture/pr127764.c b/gcc/testsuite/gcc.dg/torture/pr127764.c new file mode 100644 index 000000000000..4e2787f608b7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr127764.c @@ -0,0 +1,20 @@ +/* { dg-do run } */ + +int b, c; +int d (int *p1) +{ + switch ((unsigned char)*p1) + case 1: + case 3: + case 255: + return 1 + b % 60; + return 0; +} +int main () +{ + int e[] = {255}; + c = d(e); + if (c != 1) + __builtin_abort (); + return 0; +}
