The following fixes PR86945, single-case switch conversion to range check using signed arithmetic that can overflow.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2018-08-22 Richard Biener <rguent...@suse.de> PR tree-optimization/86945 * tree-cfg.c (generate_range_test): Use unsigned arithmetic. * gcc.dg/torture/pr86945.c: New testcase. Index: gcc/tree-cfg.c =================================================================== --- gcc/tree-cfg.c (revision 263705) +++ gcc/tree-cfg.c (working copy) @@ -9131,20 +9131,16 @@ generate_range_test (basic_block bb, tre tree type = TREE_TYPE (index); tree utype = unsigned_type_for (type); - low = fold_convert (type, low); - high = fold_convert (type, high); + low = fold_convert (utype, low); + high = fold_convert (utype, high); - tree tmp = make_ssa_name (type); - gassign *sub1 - = gimple_build_assign (tmp, MINUS_EXPR, index, low); + gimple_seq seq = NULL; + index = gimple_convert (&seq, utype, index); + *lhs = gimple_build (&seq, MINUS_EXPR, utype, index, low); + *rhs = const_binop (MINUS_EXPR, utype, high, low); - *lhs = make_ssa_name (utype); - gassign *a = gimple_build_assign (*lhs, NOP_EXPR, tmp); - - *rhs = fold_build2 (MINUS_EXPR, utype, high, low); gimple_stmt_iterator gsi = gsi_last_bb (bb); - gsi_insert_before (&gsi, sub1, GSI_SAME_STMT); - gsi_insert_before (&gsi, a, GSI_SAME_STMT); + gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT); } /* Emit return warnings. */ Index: gcc/testsuite/gcc.dg/torture/pr86945.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr86945.c (nonexistent) +++ gcc/testsuite/gcc.dg/torture/pr86945.c (working copy) @@ -0,0 +1,18 @@ +/* { dg-do run } */ + +void __attribute__((noinline,noipa)) +foo(int id) +{ + switch (id) + { + case (-__INT_MAX__ - 1)...-1: + __builtin_abort (); + default:; + } +} + +int main() +{ + foo(1); + return 0; +}