Fold does not fold two comparisons in a row if the intermediate type differs in being a pointer vs. an integer variable. This also is the reason for not folding (Foo *)(char *)foo with foo being of Foo& type (we can fold that to (Foo *)foo).
There's code to do that I think, but it's just missing adjustment for pointers: /* In addition to the cases of two conversions in a row handled below, if we are converting something to its own type via an object of identical or wider precision, neither conversion is needed. */ if (TYPE_MAIN_VARIANT (inside_type) == TYPE_MAIN_VARIANT (type) && ((inter_int && final_int) || (inter_float && final_float)) && inter_prec >= final_prec) return fold_build1 (code, type, TREE_OPERAND (op0, 0)); I have a patch. Of course RTL doesn't care. -- Summary: Does not fold (char *)(size_t)char_ptr or (size_t)(char *)size_t_var Product: gcc Version: 4.2.0 Status: UNCONFIRMED Keywords: missed-optimization, TREE Severity: enhancement Priority: P3 Component: middle-end AssignedTo: rguenth at gcc dot gnu dot org ReportedBy: rguenth at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27529