The following extends split_address_to_core_and_offset to handle POINTER_PLUS_EXPR to be able to simplify (unsigned long) &MEM[(void *)&D.15512 + 12B] - (unsigned long) ((const int *) &D.15512 + 4) which appears during niter analysis.
We seem to have various copies of similar code but refactoring didn't seem appropriate at this stage so I went for the minimal fix. Bootstrap and regtest running on x86_64-unknown-linux-gnu. Richard. 2017-04-03 Richard Biener <rguent...@suse.de> PR tree-optimization/80275 * fold-const.c (split_address_to_core_and_offset): Handle POINTER_PLUS_EXPR. * g++.dg/opt/pr80275.C: New testcase. Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 246642) +++ gcc/fold-const.c (working copy) @@ -14341,6 +14341,24 @@ split_address_to_core_and_offset (tree e &volatilep); core = build_fold_addr_expr_loc (loc, core); } + else if (TREE_CODE (exp) == POINTER_PLUS_EXPR) + { + core = TREE_OPERAND (exp, 0); + STRIP_NOPS (core); + *pbitpos = 0; + *poffset = TREE_OPERAND (exp, 1); + if (TREE_CODE (*poffset) == INTEGER_CST) + { + offset_int tem = wi::sext (wi::to_offset (*poffset), + TYPE_PRECISION (TREE_TYPE (*poffset))); + tem <<= LOG2_BITS_PER_UNIT; + if (wi::fits_shwi_p (tem)) + { + *pbitpos = tem.to_shwi (); + *poffset = NULL_TREE; + } + } + } else { core = exp; Index: gcc/testsuite/g++.dg/opt/pr80275.C =================================================================== --- gcc/testsuite/g++.dg/opt/pr80275.C (nonexistent) +++ gcc/testsuite/g++.dg/opt/pr80275.C (working copy) @@ -0,0 +1,16 @@ +// { dg-do compile { target c++14 } } +// { dg-options "-O2 -fdump-tree-optimized" } + +#include <algorithm> + +int g() +{ + return 1234; +} + +int f2() +{ + return std::min({1, g(), 4}); +} + +// { dg-final { scan-tree-dump "return 1;" "optimized" } }