Hi! We don't support BIT_{AND,IOR,XOR,NOT}_EXPR on complex types, &/|/^ are just rejected for them, and ~ is parsed as CONJ_EXPR. So, we should avoid simplifications which turn valid complex type expressions into something that will ICE during expansion.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2022-02-24 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/104675 * match.pd (-A - 1 -> ~A, -1 - A -> ~A): Don't simplify for COMPLEX_TYPE. * gcc.dg/pr104675-1.c: New test. * gcc.dg/pr104675-2.c: New test. --- gcc/match.pd.jj 2022-02-23 12:03:20.552435367 +0100 +++ gcc/match.pd 2022-02-24 11:55:20.205673823 +0100 @@ -2776,13 +2776,15 @@ (define_operator_list SYNC_FETCH_AND_AND (simplify (minus (convert? (negate @0)) integer_each_onep) (if (!TYPE_OVERFLOW_TRAPS (type) + && TREE_CODE (type) != COMPLEX_TYPE && tree_nop_conversion_p (type, TREE_TYPE (@0))) (bit_not (convert @0)))) /* -1 - A -> ~A */ (simplify (minus integer_all_onesp @0) - (bit_not @0)) + (if (TREE_CODE (type) != COMPLEX_TYPE) + (bit_not @0))) /* (T)(P + A) - (T)P -> (T) A */ (simplify --- gcc/testsuite/gcc.dg/pr104675-1.c.jj 2022-02-24 11:56:33.253653436 +0100 +++ gcc/testsuite/gcc.dg/pr104675-1.c 2022-02-24 11:56:14.450916087 +0100 @@ -0,0 +1,29 @@ +/* PR tree-optimization/104675 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +_Complex int +foo (_Complex int a) +{ + return (-1 + -1i) - a; +} + +_Complex int +bar (_Complex int a) +{ + return -a - (1 + 1i); +} + +_Complex int +baz (_Complex int a) +{ + _Complex int b = -1 + -1i; + return b - a; +} + +_Complex int +qux (_Complex int a) +{ + _Complex int b = 1 + 1i; + return -a - b; +} --- gcc/testsuite/gcc.dg/pr104675-2.c.jj 2022-02-24 11:57:09.200151312 +0100 +++ gcc/testsuite/gcc.dg/pr104675-2.c 2022-02-24 11:57:04.646214924 +0100 @@ -0,0 +1,18 @@ +/* PR tree-optimization/104675 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +void baz (int i); + +void +bar (_Complex int c, short s) +{ + c -= s; + baz (__real__ c + __imag__ c); +} + +void +foo (void) +{ + bar (-1 - 1i, 0); +} Jakub