On PTO until Monday but thinking out loud here.... Shouldn't we put this code in set_nonzero_bits instead, and leave maybe* alone? That way any possible setters may benefit from your change? Also, havent looked (AFK) but does this change work with the global range getter (get_global_range_query...)? Thoughts? Aldy On Wed, Jan 4, 2023, 10:13 Jakub Jelinek wrote: > Hi! > > maybe_set_nonzero_bits calls set_nonzero_bits which asserts that > var doesn't have pointer type. While we could punt for those > cases, I think we can handle at least some easy cases. > Earlier in maybe_set_nonzero_bits we've checked this is on > (var & cst) == 0 > edge and the other edge is __builtin_unreachable, so if cst > is say 3 as in the testcase, we want to turn it into 4 byte alignment > of the pointer. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2023-01-04 Jakub Jelinek > > PR tree-optimization/108253 > * tree-vrp.cc (maybe_set_nonzero_bits): Handle var with pointer > types. > > * g++.dg/opt/pr108253.C: New test. > > --- gcc/tree-vrp.cc.jj 2023-01-02 09:32:53.634833769 +0100 > +++ gcc/tree-vrp.cc 2023-01-03 15:57:51.613239761 +0100 > @@ -789,8 +789,22 @@ maybe_set_nonzero_bits (edge e, tree var > return; > } > cst = gimple_assign_rhs2 (stmt); > - set_nonzero_bits (var, wi::bit_and_not (get_nonzero_bits (var), > - wi::to_wide (cst))); > + if (POINTER_TYPE_P (TREE_TYPE (var))) > + { > + struct ptr_info_def *pi = SSA_NAME_PTR_INFO (var); > + if (pi && pi->misalign) > + return; > + wide_int w = wi::bit_not (wi::to_wide (cst)); > + unsigned int bits = wi::ctz (w); > + if (bits == 0 || bits >= HOST_BITS_PER_INT) > + return; > + unsigned int align = 1U << bits; > + if (pi == NULL || pi->align < align) > + set_ptr_info_alignment (get_ptr_info (var), align, 0); > + } > + else > + set_nonzero_bits (var, wi::bit_and_not (get_nonzero_bits (var), > + wi::to_wide (cst))); > } > > /* Searches the case label vector VEC for the index *IDX of the CASE_LABEL > --- gcc/testsuite/g++.dg/opt/pr108253.C.jj 2023-01-03 > 16:02:16.366438488 +0100 > +++ gcc/testsuite/g++.dg/opt/pr108253.C 2023-01-03 16:02:33.549191780 +0100 > @@ -0,0 +1,48 @@ > +// PR tree-optimization/108253 > +// { dg-do compile { target c++11 } } > +// { dg-options "-O2" } > + > +struct S > +{ > + int *s; > + S () : s (new int) {} > + S (const S &r) noexcept : s (r.s) { __atomic_fetch_add (r.s, 1, 4); } > +}; > +struct T > +{ > + explicit T (const S &x) : t (x) {} > + const S t; > +}; > +struct U > +{ > + operator int () const { new T (u); return 0; } > + S u; > +}; > +bool foo (int matcher); > +unsigned long bar (unsigned long pos, unsigned long end_pos); > +struct V > +{ > + alignas (4) char v[4]; > +}; > +struct W > +{ > + void baz () > + { > + if (!w) __builtin_abort (); > + if (reinterpret_cast <__UINTPTR_TYPE__> (w->v) % 4 != 0) > __builtin_abort (); > + __builtin_unreachable (); > + } > + [[gnu::noinline]] void qux (unsigned long) { if (!w) bar (0, x); } > + V *w = nullptr; > + unsigned x = 0; > +}; > + > +void > +test () > +{ > + W w; > + U t; > + if (!foo (t)) > + w.baz (); > + w.qux (0); > +} > > Jakub > >