Message ID | 20161205165448.GO3541@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
On 12/05/2016 09:54 AM, Jakub Jelinek wrote: > Hi! > > The recent changes to move strchr folding from builtins.c to gimple-fold.c > broke constexpr handling with __builtin_strchr etc. (which the libstdc++ > folks want to use). > > Fixed by handling it also in fold-const-call.c. Bootstrapped/regtested on > x86_64-linux and i686-linux, ok for trunk? > > 2016-12-05 Jakub Jelinek <jakub@redhat.com> > > PR c++/71537 > * fold-const-call.c (fold_const_call): Handle > CFN_BUILT_IN_{INDEX,STRCHR,RINDEX,STRRCHR}. > > * g++.dg/cpp0x/constexpr-strchr.C: New test. Thoughts on moving this into match.pd? I don't see any string builtins there, so perhaps leave it in fold-const-call for now, then move them as a group later? jeff
On Mon, Dec 05, 2016 at 10:55:05AM -0700, Jeff Law wrote: > On 12/05/2016 09:54 AM, Jakub Jelinek wrote: > >The recent changes to move strchr folding from builtins.c to gimple-fold.c > >broke constexpr handling with __builtin_strchr etc. (which the libstdc++ > >folks want to use). > > > >Fixed by handling it also in fold-const-call.c. Bootstrapped/regtested on > >x86_64-linux and i686-linux, ok for trunk? > > > >2016-12-05 Jakub Jelinek <jakub@redhat.com> > > > > PR c++/71537 > > * fold-const-call.c (fold_const_call): Handle > > CFN_BUILT_IN_{INDEX,STRCHR,RINDEX,STRRCHR}. > > > > * g++.dg/cpp0x/constexpr-strchr.C: New test. > Thoughts on moving this into match.pd? I don't see any string builtins > there, so perhaps leave it in fold-const-call for now, then move them as a > group later? At least my understanding has been that such stuff goes into fold-const-call.c in the new world. The GIMPLE optimizers for these functions have also been added to gimple-fold.c, not to match.pd. Jakub
On 12/05/2016 10:59 AM, Jakub Jelinek wrote: > On Mon, Dec 05, 2016 at 10:55:05AM -0700, Jeff Law wrote: >> On 12/05/2016 09:54 AM, Jakub Jelinek wrote: >>> The recent changes to move strchr folding from builtins.c to gimple-fold.c >>> broke constexpr handling with __builtin_strchr etc. (which the libstdc++ >>> folks want to use). >>> >>> Fixed by handling it also in fold-const-call.c. Bootstrapped/regtested on >>> x86_64-linux and i686-linux, ok for trunk? >>> >>> 2016-12-05 Jakub Jelinek <jakub@redhat.com> >>> >>> PR c++/71537 >>> * fold-const-call.c (fold_const_call): Handle >>> CFN_BUILT_IN_{INDEX,STRCHR,RINDEX,STRRCHR}. >>> >>> * g++.dg/cpp0x/constexpr-strchr.C: New test. >> Thoughts on moving this into match.pd? I don't see any string builtins >> there, so perhaps leave it in fold-const-call for now, then move them as a >> group later? > > At least my understanding has been that such stuff goes into > fold-const-call.c in the new world. The GIMPLE optimizers for these functions > have also been added to gimple-fold.c, not to match.pd. Good enough for me... OK for the trunk, if I wasn't clear about that.. jeff
On Mon, 5 Dec 2016, Jakub Jelinek wrote: > On Mon, Dec 05, 2016 at 10:55:05AM -0700, Jeff Law wrote: > > On 12/05/2016 09:54 AM, Jakub Jelinek wrote: > > >The recent changes to move strchr folding from builtins.c to gimple-fold.c > > >broke constexpr handling with __builtin_strchr etc. (which the libstdc++ > > >folks want to use). > > > > > >Fixed by handling it also in fold-const-call.c. Bootstrapped/regtested on > > >x86_64-linux and i686-linux, ok for trunk? > > > > > >2016-12-05 Jakub Jelinek <jakub@redhat.com> > > > > > > PR c++/71537 > > > * fold-const-call.c (fold_const_call): Handle > > > CFN_BUILT_IN_{INDEX,STRCHR,RINDEX,STRRCHR}. > > > > > > * g++.dg/cpp0x/constexpr-strchr.C: New test. > > Thoughts on moving this into match.pd? I don't see any string builtins > > there, so perhaps leave it in fold-const-call for now, then move them as a > > group later? > > At least my understanding has been that such stuff goes into > fold-const-call.c in the new world. The GIMPLE optimizers for these functions > have also been added to gimple-fold.c, not to match.pd. Yes, constant folding goes to fold-const-call.c and folding to gimple-fold.c. In theory match.pd would be an option but I need to sit down and invent a syntax for properly handling virtual operands (very few special cases would already work automagically but in general you need to be explicit). So for now, fold-const-call.c and gimple-fold.c. Richard.
--- gcc/fold-const-call.c.jj 2016-11-09 18:54:03.000000000 +0100 +++ gcc/fold-const-call.c 2016-12-05 12:53:38.597090946 +0100 @@ -1383,6 +1383,7 @@ tree fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1) { const char *p0, *p1; + char c; switch (fn) { case CFN_BUILT_IN_STRSPN: @@ -1409,6 +1410,30 @@ fold_const_call (combined_fn fn, tree ty } return NULL_TREE; + case CFN_BUILT_IN_INDEX: + case CFN_BUILT_IN_STRCHR: + if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c)) + { + const char *r = strchr (p0, c); + if (r == NULL) + return build_int_cst (type, 0); + return fold_convert (type, + fold_build_pointer_plus_hwi (arg0, r - p0)); + } + return NULL_TREE; + + case CFN_BUILT_IN_RINDEX: + case CFN_BUILT_IN_STRRCHR: + if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c)) + { + const char *r = strrchr (p0, c); + if (r == NULL) + return build_int_cst (type, 0); + return fold_convert (type, + fold_build_pointer_plus_hwi (arg0, r - p0)); + } + return NULL_TREE; + default: return fold_const_call_1 (fn, type, arg0, arg1); } --- gcc/testsuite/g++.dg/cpp0x/constexpr-strchr.C.jj 2016-12-05 13:00:19.448101292 +0100 +++ gcc/testsuite/g++.dg/cpp0x/constexpr-strchr.C 2016-12-05 13:00:36.270888812 +0100 @@ -0,0 +1,27 @@ +// { dg-do compile { target c++11 } } + +constexpr const char *f1 (const char *p, int q) { return __builtin_strchr (p, q); } +constexpr const char *f2 (const char *p, int q) { return __builtin_index (p, q); } +constexpr const char *f3 (const char *p, int q) { return __builtin_strrchr (p, q); } +constexpr const char *f4 (const char *p, int q) { return __builtin_rindex (p, q); } +constexpr const char a[] = "abcdefedcba"; +static_assert (f1 ("abcde", 'f') == nullptr, ""); +static_assert (f1 (a, 'g') == nullptr, ""); +static_assert (f1 (a, 'f') == a + 5, ""); +static_assert (f1 (a, 'c') == a + 2, ""); +static_assert (f1 (a, '\0') == a + 11, ""); +static_assert (f2 ("abcde", 'f') == nullptr, ""); +static_assert (f2 (a, 'g') == nullptr, ""); +static_assert (f2 (a, 'f') == a + 5, ""); +static_assert (f2 (a, 'c') == a + 2, ""); +static_assert (f2 (a, '\0') == a + 11, ""); +static_assert (f3 ("abcde", 'f') == nullptr, ""); +static_assert (f3 (a, 'g') == nullptr, ""); +static_assert (f3 (a, 'f') == a + 5, ""); +static_assert (f3 (a, 'c') == a + 8, ""); +static_assert (f3 (a, '\0') == a + 11, ""); +static_assert (f4 ("abcde", 'f') == nullptr, ""); +static_assert (f4 (a, 'g') == nullptr, ""); +static_assert (f4 (a, 'f') == a + 5, ""); +static_assert (f4 (a, 'c') == a + 8, ""); +static_assert (f4 (a, '\0') == a + 11, "");