https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82666
Jeffrey A. Law <law at redhat dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |law at redhat dot com See Also| |https://gcc.gnu.org/bugzill | |a/show_bug.cgi?id=80520 --- Comment #2 from Jeffrey A. Law <law at redhat dot com> --- This is another case where PRE does the right thing on a local basis, but the result isn't well handled later in the pipeline. Prior to PRE the key blocks look like: <bb3> [ ... ] if (_4 > 127) goto <bb 4>; [50.00%] else goto <bb 5>; [50.00%] <bb 4> [local count: 531502203]: <bb 5> [local count: 1063004407]: # _17 = PHI <_4(4), 0(3)> iftmp.0_8 = (long long int) _17; sum_13 = iftmp.0_8 + sum_19; Not surprisingly PRE realizes it can reduce the total expressions evaluated on the path 3->5 by moving the arithmetic into bb4: <bb 3> [ ... ] if (_4 > 127) goto <bb 4>; [50.00%] else goto <bb 5>; [50.00%] <bb 4> [local count: 531502203]: _22 = (long long int) _4; _24 = sum_19 + _22; <bb 5> [local count: 1063004407]: # _17 = PHI <_4(4), 0(3)> # prephitmp_25 = PHI <_24(4), sum_19(3)> We keep that form through the rest of the gimple optimizers and into RTL where it turns into the problematic cmov during the first if-conversion pass. Compiling with -fno-tree-pre gives code that I believe is equivalent to gcc-6.x.