On Thu, 9 Feb 2017, Richard Biener wrote: > > The following patch fixes a missed optimization caused by niter analysis > returning a complex pointer subtraction expression instead of a constant > for a loop with a pointer IV (it looks like pointer IVs are quite common > in libstdc++). > > Bootstrapped and tested on x86_64-unknown-linux-gnu. > > Not a regression (well, didn't try to find a release where we optimized > the testcase, but it needs c++14 library support anyway). I'm also > not quite sure associate_trees handles pointer types correctly > (there is some pointer type handling in the associate case but > POINTER_PLUS_EXPR folding for example does not dispatch to associate). > > I guess trying to add some more exhaustive testcases for GENERIC input > is required.
I've generalized a bit and convinced myself it is safe. Bootstrapped and tested on x86_64-unknow-linux-gnu, applied to trunk. Richard. 2017-04-21 Richard Biener <rguent...@suse.de> PR tree-optimization/78847 * fold-const.c (split_tree): Handle POINTER_PLUS_EXPR. * g++.dg/tree-ssa/pr78847.C: New testcase. Index: gcc/testsuite/g++.dg/tree-ssa/pr78847.C =================================================================== *** gcc/testsuite/g++.dg/tree-ssa/pr78847.C (nonexistent) --- gcc/testsuite/g++.dg/tree-ssa/pr78847.C (working copy) *************** *** 0 **** --- 1,26 ---- + /* { dg-do compile } */ + /* { dg-require-effective-target c++14 } */ + /* { dg-options "-O3 -fdump-tree-ldist" } */ + + #include <stddef.h> + #include <cstring> + #include <experimental/string_view> + + using string_view = std::experimental::string_view; + + class Foo { + constexpr static size_t Length = 9; + char ascii_[Length]; + public: + Foo(); + string_view view() const { + return string_view(ascii_, Length); + } + }; + + void testWithLoopValue(const Foo foo, size_t ptr, char *buf_) { + for (auto c : foo.view()) + buf_[ptr++] = c; + } + + /* { dg-final { scan-tree-dump "memcpy\[^\n\r\]*, 9\\);" "ldist" } } */ Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 247049) +++ gcc/fold-const.c (working copy) @@ -798,8 +798,11 @@ split_tree (location_t loc, tree in, tre though the C standard doesn't say so) for integers because the value is not affected. For reals, the value might be affected, so we can't. */ - && ((code == PLUS_EXPR && TREE_CODE (in) == MINUS_EXPR) - || (code == MINUS_EXPR && TREE_CODE (in) == PLUS_EXPR)))) + && ((code == PLUS_EXPR && TREE_CODE (in) == POINTER_PLUS_EXPR) + || (code == PLUS_EXPR && TREE_CODE (in) == MINUS_EXPR) + || (code == MINUS_EXPR + && (TREE_CODE (in) == PLUS_EXPR + || TREE_CODE (in) == POINTER_PLUS_EXPR))))) { tree op0 = TREE_OPERAND (in, 0); tree op1 = TREE_OPERAND (in, 1);