https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69606
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- So before VRP2 we have <bb 2>: load_dst_16 = b; # RANGE [2, 65535] NONZERO 65535 _12 = (int) load_dst_16; # RANGE [0, 255] _9 = (unsigned char) load_dst_16; e = _9; # RANGE [0, 255] NONZERO 255 _11 = (int) _9; d = _12; # RANGE [0, 1] NONZERO 1 _14 = 1 % 0; c = _14; return 0; the range on _12 is bogus, it was once conditional: <bb 2>: a.0_4 = a; # RANGE [-128, 127] _5 = (int) a.0_4; # RANGE [-128, 127] g_6 = ~_5; b.1_7 = b; # RANGE [0, 65535] NONZERO 65535 _8 = (int) b.1_7; if (_8 > 1) goto <bb 3>; else goto <bb 4>; <bb 3>: # RANGE [0, 255] _9 = (unsigned char) b.1_7; e = _9; # RANGE [0, 255] NONZERO 255 _11 = (int) _9; # RANGE [2, 65535] NONZERO 65535 _12 = _8 | _11; d = _12; <bb 4>: # RANGE [-128, 127] # g_1 = PHI <g_6(2), 0(3)> # RANGE [0, 1] NONZERO 1 _14 = 1 % g_1; c = _14; return 0; And it's the bswap pass breaking it: 16 bit load in target endianness found at: _12 = (int) load_dst_16; ... <bb 2>: a.0_4 = a; # RANGE [-128, 127] _5 = (int) a.0_4; # RANGE [-128, 127] g_6 = ~_5; load_dst_16 = b; # RANGE [2, 65535] NONZERO 65535 _12 = (int) load_dst_16; because it does if (!useless_type_conversion_p (TREE_TYPE (tgt), load_type)) { val_tmp = make_temp_ssa_name (aligned_load_type, NULL, "load_dst"); load_stmt = gimple_build_assign (val_tmp, val_expr); gimple_set_vuse (load_stmt, n->vuse); gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT); gimple_assign_set_rhs_with_ops (&gsi, NOP_EXPR, val_tmp); } else { gimple_assign_set_rhs_with_ops (&gsi, MEM_REF, val_expr); gimple_set_vuse (cur_stmt, n->vuse); } thus simply replaces the RHS and before: /* Move cur_stmt just before one of the load of the original to ensure it has the same VUSE. See PR61517 for what could go wrong. */ gsi_move_before (&gsi, &gsi_ins); gsi = gsi_for_stmt (cur_stmt); which in this case moves the computation to a different BB.