Hi! unsigned_type_for doesn't handle complex types, so will return NULL for them, which this optimization wasn't prepared to handle.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, pre-approved in the PR by Richard, committed to trunk and will commit to 8.2. This doesn't mean we can't change on the trunk {,un}signed_type_for to handle complex types, I just don't have cycles to handle it now. 2018-06-14 Jakub Jelinek <ja...@redhat.com> PR middle-end/86122 * match.pd ((A +- CST1) +- CST2): Punt if last resort unsigned_type_for returns NULL. * gcc.c-torture/compile/pr86122.c: New test. --- gcc/match.pd.jj 2018-05-25 14:34:42.268381974 +0200 +++ gcc/match.pd 2018-06-14 15:53:20.538712014 +0200 @@ -1771,10 +1771,11 @@ (define_operator_list COND_BINARY (neg_inner_op @0 { wide_int_to_tree (type, wi::to_wide (cst)); }) /* Last resort, use some unsigned type. */ (with { tree utype = unsigned_type_for (type); } - (view_convert (inner_op - (view_convert:utype @0) - (view_convert:utype - { drop_tree_overflow (cst); }))))))))))))) + (if (utype) + (view_convert (inner_op + (view_convert:utype @0) + (view_convert:utype + { drop_tree_overflow (cst); })))))))))))))) /* (CST1 - A) +- CST2 -> CST3 - A */ (for outer_op (plus minus) --- gcc/testsuite/gcc.c-torture/compile/pr86122.c.jj 2018-06-14 15:58:14.676891695 +0200 +++ gcc/testsuite/gcc.c-torture/compile/pr86122.c 2018-06-14 15:58:27.557899555 +0200 @@ -0,0 +1,17 @@ +/* PR middle-end/86122 */ + +_Complex int +foo (_Complex int x) +{ + x += __INT_MAX__; + x += 1; + return x; +} + +_Complex int +bar (_Complex int x) +{ + x += 1; + x += __INT_MAX__; + return x; +} Jakub