The following patch fixes address difference folding to consider when one operand doesn't need a conversion.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard. 2018-07-13 Richard Biener <rguent...@suse.de> PR middle-end/85974 * match.pd (addr1 - addr2): Allow either of the operand to have a conversion. * gcc.c-torture/compile/930326-1.c: Adjust to cover widening. Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 262624) +++ gcc/match.pd (working copy) @@ -1673,14 +1673,14 @@ (define_operator_list COND_TERNARY (if (ptr_difference_const (@0, @1, &diff)) { build_int_cst_type (type, diff); })))) (simplify - (pointer_diff (convert?@2 ADDR_EXPR@0) (convert?@3 @1)) + (pointer_diff (convert?@2 ADDR_EXPR@0) (convert1?@3 @1)) (if (tree_nop_conversion_p (TREE_TYPE(@2), TREE_TYPE (@0)) && tree_nop_conversion_p (TREE_TYPE(@3), TREE_TYPE (@1))) (with { poly_int64 diff; } (if (ptr_difference_const (@0, @1, &diff)) { build_int_cst_type (type, diff); })))) (simplify - (pointer_diff (convert?@2 @0) (convert?@3 ADDR_EXPR@1)) + (pointer_diff (convert?@2 @0) (convert1?@3 ADDR_EXPR@1)) (if (tree_nop_conversion_p (TREE_TYPE(@2), TREE_TYPE (@0)) && tree_nop_conversion_p (TREE_TYPE(@3), TREE_TYPE (@1))) (with { poly_int64 diff; } Index: gcc/testsuite/gcc.c-torture/compile/930326-1.c =================================================================== --- gcc/testsuite/gcc.c-torture/compile/930326-1.c (revision 262624) +++ gcc/testsuite/gcc.c-torture/compile/930326-1.c (working copy) @@ -4,3 +4,4 @@ struct } s; long i = s.f-&s.b; +long long j = s.f-&s.b;