This addresses some code quality regressions with some work scheduled for gcc-9. However, if anyone is aware of BZs that could be helped with this patch, don't hesitate to pass them along. Depending on their severity we could always re-evaluate the plan for this patch. The patch optimizes sequences like this: # iftmp.4_16 = PHI <0(7), 1(8), 0(9)> _30 = (unsigned char) iftmp.4_16; ie, we have a PHI where all its arguments are known (differing) constants. The PHI feeds an operation which can be compile-time evaluated for all the PHI's arguments. This arises most often where the result of the PHI is type converted via NOP_EXPR. But it also happens for a boolean comparisons, arithmetic and logicals and other type conversions. We can optimize away the statement by creating a new PHI node holding the result of the statement applied to each of the original PHI's constant operands. So for the fragment above we'd generate: # iftmp.4_16 = PHI <0(7), 1(8), 0(9)> # _30 = PHI <0(7), 1(8), 0(9)> These kind of backward propagations can cascade. Here's an example I saw during analysis of test results: # m_5 = PHI <10(5), 12(6), 14(7)> : _2 = (long unsigned int) m_5; _3 = _2 * 32; goto ; [100.00%] After this patch the two statements have been eliminated in favor of generating PHIs with constant arguments: And after PHI propagation we have: # m_5 = PHI <10(5), 12(6), 14(7)> # _2 = PHI <10(5), 12(6), 14(7)> # _3 = PHI <320(5), 384(6), 448(7)> : goto ; [100.00%] DCE will come along and wipe out m_5 and _2 if they are unused. I initially covered just NOP_EXPR in the proof of concept. But it's trivial to extend to cover other unaries, and binary/comparisons where one operand was already a constant, so I did that. This applies surprisingly often during a bootstrap. An earlier version (which didn't handle multiple uses of the result of the PHI) triggered over 6000 times during a bootstrap: NOP_EXPR 5161 LT_EXPR 658 GE_EXPR 504 NE_EXPR 310 BIT_NOT_EXPR 295 BIT_AND_EXPR 94 PLUS_EXPR 77 NEGATE_EXPR 48 LSHIFT_EXPR 40 EQ_EXPR 34 GT_EXPR 16 BIT_IOR_EXPR 10 MINUS_EXPR 8 There's actually other cases we could handle were x = PHI (a, 0); y = a & x; Turns into x = PHI (a, 0); y = PHI (a, 0); I'm not sure how often these non-constant cases happen -- I haven't tried to support this or gain any data on how often this kidn of case might happen. FWIW, there are cases were the PHI arguments are constant, but we still can't simplify. For example: x = PHI (0, 1, 2) y = 1234 / x; When we process this we'll try to simplify 1234 / 0 to a constant which fails. We have to gracefully remove the partially initialized PHI node in that case. This is tested by existing tests in the suite. You'll also see that certain tests in the suite such as pr61839_3, ssa-pre-4.c are twiddled. I've suppressed phi backwards propagation in the original test so that it's not compromised. THere's also a variant of each test which verifies that the transformation is handled by phi back propagation. Bootstrapped and regression tested on x86, both in isolation and in a larger patch series. Will ping when gcc-9 opens for development. Jeff