https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101179
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Blocks| |85316 --- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Jonathan Wakely from comment #1) > On IRC Richi said: "VRP has code to do that but maybe for some reason shifts > are not handled" Specifically simplify_using_ranges::simplify has /* Convert: LHS = CST BINOP VAR Where VAR is two-valued and LHS is used in GIMPLE_COND only To: LHS = VAR == VAL1 ? (CST BINOP VAL1) : (CST BINOP VAL2) Also handles: LHS = VAR BINOP CST Where VAR is two-valued and LHS is used in GIMPLE_COND only To: LHS = VAR == VAL1 ? (VAL1 BINOP CST) : (VAL2 BINOP CST) */ restrictions that stand in the way: if (TREE_CODE_CLASS (rhs_code) == tcc_binary ... && single_imm_use (lhs, &use_p, &use_stmt) && gimple_code (use_stmt) == GIMPLE_COND) VRP1 sees <bb 2> [local count: 1073741824]: _1 = y_7(D) % 100; x_8 = _1 == 0; _2 = (int) x_8; _3 = _2 * 2; _4 = 4 << _3; _5 = y_7(D) % _4; _6 = _5 == 0; _9 = (int) _6; return _9; so it would consider _2 * 2 but its single use is in a shift, the condition is after another op, the modulo, and there the condition is in an assignment, not in a GIMPLE_COND. Referenced Bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85316 [Bug 85316] [meta-bug] VRP range propagation missed cases