[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-07-08 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #35 from GCC Commits  ---
The master branch has been updated by Richard Biener :

https://gcc.gnu.org/g:aa5ae523e84a97bf3a582ea0fa73d959afa9b9c7

commit r16-2085-gaa5ae523e84a97bf3a582ea0fa73d959afa9b9c7
Author: Richard Biener 
Date:   Mon Jul 7 15:13:38 2025 +0200

tree-optimization/120358 - bogus PTA with structure access

When we compute the constraint for something like
MEM[(const struct QStringView &)&tok2 + 32] we go and compute
what (const struct QStringView &)&tok2 + 32 points to and then
add subvariables to its dereference that possibly fall in the
range of the access according to the original refs size.  In
doing that we disregarded that the subvariable the starting
address points to might not be aligned to it and thus the
access might start at any point within that variable.  The following
conservatively adjusts the pruning of adjacent sub-variables to
honor this.

PR tree-optimization/120358
* tree-ssa-structalias.cc (get_constraint_for_1): Adjust
pruning of sub-variables according to the imprecise
known start offset.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-07-07 Thread sjames at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

Sam James  changed:

   What|Removed |Added

  Attachment #61749|0   |1
is obsolete||

--- Comment #34 from Sam James  ---
Created attachment 61813
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61813&action=edit
small.cxx

Still a bit big.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-07-07 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #33 from Richard Biener  ---
Something like the following might be a testcase, needs -fno-tree-sra
but it fails to demonstrate the particular sub-field layout for Y.

struct X { int *p; int *q; };
struct Y { struct X a; struct { unsigned pad : 1; struct X b; } b; };
static int i, j, k, l;
int foo (int c)
{
  struct Y y;
  y.b.b.p = &i;
  y.b.b.q = &j;
  char *p = (char *)&y;
  struct X z;
  z = *(struct X *)(p + sizeof (struct X) + sizeof (unsigned));
  return *z.q;
}

so no nice small testcase for now.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-07-07 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #32 from Richard Biener  ---
Hmm, or rather the logic is fine, there's simply no field at that offset in the
set of RHS constraints.  There's the missing field

$21 = {id = 30, is_artificial_var = 0, is_special_var = 0, 
  is_unknown_size_var = 0, is_full_var = 0, is_heap_var = 0, is_reg_var = 0, 
  may_have_pointers = 1, only_restrict_pointers = 0, is_restrict_var = 0, 
  is_global_var = 0, is_ipa_escape_point = 0, is_fn_info = 0, 
  address_taken = 0, ruid = 0, next = 31, head = 27, offset = 320, size = 64, 
  fullsize = 448, shadow_var_uid = 0, name = 0x7fffee90d3e0 "tok2.320+64", 
  decl = , solution = 0x586ee50, 
  oldsolution = 0x0}

and the issue is in get_constraint_for_1 which doesn't take into account
the case where the offset doesn't align with the first field that is
accessed.

diff --git a/gcc/tree-ssa-structalias.cc b/gcc/tree-ssa-structalias.cc
index deca44ae0bf..0215243d5be 100644
--- a/gcc/tree-ssa-structalias.cc
+++ b/gcc/tree-ssa-structalias.cc
@@ -3690,7 +3690,10 @@ get_constraint_for_1 (tree t, vec *results, bool
address_p,
size = -1;
  for (; curr; curr = vi_next (curr))
{
- if (curr->offset - vi->offset < size)
+ /* The start of the access might happen anywhere
+within vi, so conservatively assume it was
+at its end.  */
+ if (curr->offset - (vi->offset + vi->size - 1) < size)
{
  cs.var = curr->id;
  results->safe_push (cs);

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-07-07 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

Richard Biener  changed:

   What|Removed |Added

   Last reconfirmed|2025-05-19 00:00:00 |2025-07-07
 Ever confirmed|0   |1
 Status|UNCONFIRMED |ASSIGNED
   Assignee|unassigned at gcc dot gnu.org  |rguenth at gcc dot 
gnu.org

--- Comment #31 from Richard Biener  ---
(In reply to Alexander Monakov from comment #28)
> Created attachment 61811 [details]
> standalone testcase
> 
> A standalone variant of the comment #22 testcase, preprocessed and with
> enough noipa stubs added to avoid linking with QtBase.

Thanks, this produces with -O2 -std=gnu++20

> ./a.out 
test2: 1 2 3 

while -O3 -std=gnu++20

> ./a.out 
test2: 1 2 3 18446744073709551615 

it also reproduces with -O3 -fno-tree-vectorize, the main difference seems
to be IPA and inline differences.  -fno-tree-pta fixes it.

There are exactly two(!) comparisons eliminated with the added path, the
2nd triggers the issue in VRP1:

Folding statement: if (e_137 != n_142)
 Registering value_relation (e_137 != n_142) on (33->35)
 Registering value_relation (e_137 == n_142) on (33->34)

Visiting conditional with predicate: if (e_137 != n_142)

With known ranges
e_137: [prange] const char16_t * [1, +INF]  n_142: [prange] const
char16_t * VARYING

Predicate evaluates to: DON'T KNOW
***dbgcnt: lower limit 2 reached for prefetch.***
***dbgcnt: upper limit 2 reached for prefetch.***
gimple_simplified to if (1 != 0)
Folded into: if (1 != 0)


We have

  # PT = null
  e_137 = _130 + _136;
...
  # PT = nonlocal escaped null const-pool { D.189684 } (escaped)
  # USE = nonlocal escaped null const-pool { D.189684 } (escaped)
  n_142 = QtPrivate::qustrchr (D.206385, 46);
  D.206385 ={v} {CLOBBER(eos)};
  if (e_137 != n_142)

the interesting thing is that VRP computes

e_137  : [prange] const char16_t * [1, +INF]


VRP clears PT = null on the pointer and thus makes the compare compare
'nothing' with 'something'.  points-to computes

  # PT = null
  _130 = str.m_data;

the last initilizer is

   [local count: 1034442871]:
  _104 = state$start_100 + state$extra_101;
  MEM[(struct QChar *)&D.206374 clique 15 base 1] ={v} {CLOBBER(bob)};
  MEM[(struct QChar *)&D.206374 clique 15 base 1].ucs = 46;
  str = MEM[(const struct QStringView &)&tok2 + 32];

PTA has

tok2.128+192 = __old_val_8
tok2.128+192 = &NONLOCAL
tok2.128+192 = &NONLOCAL
tok2.128+192 = __old_val_8
str.0+64 = tok2.128+192
_130 = str.64+64

for some reason the

  str = MEM[(const struct QStringView &)&tok2 + 32];

assignment does not generate a

str.64+64 = tok2.192+64

constraint, that is, the source and dest varinfos do not seem to overlap.

We end up with

(gdb) p lhsc
$3 = {> = {m_vec = 0x5219080 = {{
type = SCALAR, var = 145, offset = 0}, {type = SCALAR, var = 146, 
offset = 0}}}, }
(gdb) p rhsc
$6 = {> = {m_vec = 0x5824f60 = {{
type = SCALAR, var = 29, offset = 0}}}, }

where for the RHS that's the third var from 'tok2'.  Having the copy
offset by 32 is a bit odd sice that puts us inside the third subobject
that we have not sub-setted.

In any case the issue seems to be that do_structure_copy applies
the offset "twice" here, it does

  if (!get_ref_base_and_extent_hwi (lhsop, &lhsoffset, &lhssize, &reverse)
  || !get_ref_base_and_extent_hwi (rhsop, &rhsoffset, &rhssize,
   &reverse))
{
  process_all_all_constraints (lhsc, rhsc);
  return;

computing 256 for rhsoffset (from the MEM_REF offset of 32 bytes) and
then checking overlap of two varinfos with

  || ranges_overlap_p (lhsv->offset + rhsoffset, lhsv->size,
   rhsv->offset + lhsoffset, rhsv->size)))

the 2nd var of the LHS does not satisfy overlap.

I think the logic might only work when the offset computed by
get_ref_base_and_extent_hwi aligns with any of the fields offsets.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-07-07 Thread amonakov at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #30 from Alexander Monakov  ---
Forgot to mention that the offending match.pd rule is

/* Simplify pointer equality compares using PTA.  */
(for neeq (ne eq)
 (simplify
  (neeq @0 @1)
  (if (POINTER_TYPE_P (TREE_TYPE (@0))
   && ptrs_compare_unequal (@0, @1))
   { constant_boolean_node (neeq != EQ_EXPR, type); })))

and ptrs_compare_unequal unexpectedly returns true (as already hinted in
comment #5)

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-07-07 Thread amonakov at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #29 from Alexander Monakov  ---
The above is bisectable on the 'match' dbgcnt, which ends on this transform in
vrp1:

Folding statement: if (e_137 != n_142)
 Registering value_relation (e_137 != n_142) on (33->35)
 Registering value_relation (e_137 == n_142) on (33->34)

Visiting conditional with predicate: if (e_137 != n_142)

With known ranges
e_137: [prange] const char16_t * [1, +INF]  n_142: [prange] const
char16_t * VARYING

Predicate evaluates to: DON'T KNOW
Matching expression match.pd:2934, gimple-match-8.cc:90
Matching expression match.pd:2938, gimple-match-4.cc:77
***dbgcnt: upper limit 22638 reached for match.***
Applying pattern match.pd:7956, gimple-match-9.cc:4682
gimple_simplified to if (1 != 0)
Folded into: if (1 != 0)

which looks highly suspicious as it eliminates this branch:

  # PT = nonlocal escaped null const-pool { D.189389 } (escaped)
  # USE = nonlocal escaped null const-pool { D.189389 } (escaped)
  n_142 = QtPrivate::qustrchr (D.204906, 46);
  D.204906 ={v} {CLOBBER(eos)};
  if (e_137 != n_142)
goto ; [98.33%]
  else
goto ; [1.67%]


above that, for e_137 we have

  # PT =
  e_137 = _130 + _136;

and for _130

  # PT = null
  _130 = str.m_data;

which is wrong?

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-07-07 Thread amonakov at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

Alexander Monakov  changed:

   What|Removed |Added

 CC||amonakov at gcc dot gnu.org

--- Comment #28 from Alexander Monakov  ---
Created attachment 61811
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61811&action=edit
standalone testcase

A standalone variant of the comment #22 testcase, preprocessed and with enough
noipa stubs added to avoid linking with QtBase.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-07-04 Thread holger--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #27 from Holger Hoffstätte  ---
If I add lifetime-extending printfs to QStringTokenizerBase::next() like this:

--- qstringtokenizer.h  2025-07-04 17:56:28.523676630 +0200
+++ qstringtokenizer-printf.h   2025-07-04 17:56:03.998840901 +0200
@@ -389,11 +389,14 @@ auto QStringTokenizerBase return final element:
 result = m_haystack.sliced(state.start);
+__builtin_printf("\nfinal: '%s'\n",
result.toString().toStdString().c_str());
 }
 if ((m_sb & Qt::SkipEmptyParts) && result.isEmpty()) {
+__builtin_printf("\nskipping empty result: '%s'\n",
result.toString().toStdString().c_str());
 continue;
 }
 return {result, true, state};

..it starts to work. Removing any one of these printfs breaks the lifetime of
the
intermediate "Haystack result" and leads to garbage when trying to find the
last element.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-07-04 Thread sjames at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #26 from Sam James  ---
I'm going to try clean it up with my poor C++, as I can't follow it at all
right now.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-07-04 Thread sjames at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #24 from Sam James  ---
(In reply to Sam James from comment #11)
> Created attachment 61749 [details]
> small.cxx

OK, on this, with a small adjustment to change the two ""s as args to char*
str1, str2:

--- a/small.cxx.057t.local-fnsummary2
+++ b/small.cxx.057t.local-fnsummary2
@@ -1795,7 +1795,6 @@ IPA function summary for ar::as ar::aw(ao) [with
aq = QStringView]/104 i
   calls:
 long long int QtPrivate::ck(QStringView, long long int)/27 function not
considered for inlining
   freq:0.41 loop depth: 0 size: 4 time: 13 callee size:12 stack: 0
predicate: (op1[offset: 32] >= 0)
-   op1 points to local or readonly memory

 struct as ar::aw (struct ar * const this, struct ao o)
 {
@@ -1882,7 +1881,6 @@ IPA function summary for void ar::bc::operator++()
[with aq = QStringView]/7
   calls:
 long long int QtPrivate::ck(QStringView, long long int)/27 function not
considered for inlining
   freq:0.41 loop depth: 0 size: 4 time: 13 callee size:12 stack: 0
predicate: (op0[ref offset: 256] >= 0)
-   op1 points to local or readonly memory

 void ar::bc::operator++ (struct bc * const this)
 {
diff --git a/small.cxx.088i.fnsummary b/small.cxx.088i.fnsummary
index 3b673e5..09d0885 100644
--- a/small.cxx.088i.fnsummary
+++ b/small.cxx.088i.fnsummary
@@ -233,7 +233,6 @@ IPA function summary for void ar::bc::operator++()
[with aq = QStringView]/7
   calls:
 long long int QtPrivate::ck(QStringView, long long int)/27 function not
considered for inlining
   freq:0.41 loop depth: 0 size: 4 time: 13 predicate: (op0[ref offset:
256] >= 0)
-   op1 points to local or readonly memory


 Analyzing function: decltype (QtPrivate::dc{0, l, df::t ...}) df(aq,
dd, de ...) [with aq = QString; dd = int; de = {am, }]/72

--- a/small.cxx.088i.fnsummary
+++ b/small.cxx.088i.fnsummary
@@ -233,7 +233,6 @@ IPA function summary for void ar::bc::operator++()
[with aq = QStringView]/7
   calls:
 long long int QtPrivate::ck(QStringView, long long int)/27 function not
considered for inlining
   freq:0.41 loop depth: 0 size: 4 time: 13 predicate: (op0[ref offset:
256] >= 0)
-   op1 points to local or readonly memory


 Analyzing function: decltype (QtPrivate::dc{0, l, df::t ...}) df(aq,
dd, de ...) [with aq = QString; dd = int; de = {am, }]/72

diff --git a/small.cxx.089i.inline b/small.cxx.089i.inline
index c31c4f8..abe0280 100644
--- a/small.cxx.089i.inline
+++ b/small.cxx.089i.inline
@@ -182,7 +182,6 @@ IPA function summary for void ar::bc::operator++()
[with aq = QStringView]/7
   calls:
 long long int QtPrivate::ck(QStringView, long long int)/27 function not
considered for inlining
   freq:0.41 loop depth: 0 size: 4 time: 13 callee size:12 stack: 0
predicate: (op0[ref offset: 256] >= 0)
-   op1 points to local or readonly memory

 IPA summary for bn<  >::~bn() [with ag = QString]/68
is missing.
 IPA function summary for bn<  >::~bn() [with ag =
QString]/67 inlinable
@@ -820,7 +819,7 @@ Updated mod-ref summary for int main()/52
 Considering long long int QtPrivate::ck(QStringView, long long int)/27 with 24
size
  to be inlined into void ar::bc::operator++() [with aq = QStringView]/79
in small.cxx:177
  Estimated badness is -0.15, frequency 3.36.
-  Parm map:  -1 -5
+  Parm map:  -1 -1
 Updated mod-ref summary for int main()/52
   loads:
   Base 0: alias set 8

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-07-04 Thread sjames at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #25 from Sam James  ---
(In reply to Sam James from comment #24)
> @@ -1882,7 +1881,6 @@ IPA function summary for void ar::bc::operator++()
> [with aq = QStringView]/7
>calls:

Adding __attribute__((noipa)) on that template works.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-29 Thread holger--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #23 from Holger Hoffstätte  ---
(In reply to Holger Hoffstätte from comment #22)
> Created attachment 61758 [details]
> Readable reproducer for debugging
> 
> Slightly more reduced, no need for the join business.

..and not for the factory function either.

I'm now sure that the added std::move is not accidental state reuse but
"simply" a matter of instantiating one template working for both cases instead
of two, where the second one goes off the rails. The executable differs in
size.
Why the second form (direct rvalue reference) makes a mess is unfortunately a
mystery.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-29 Thread holger--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

Holger Hoffstätte  changed:

   What|Removed |Added

  Attachment #61755|0   |1
is obsolete||

--- Comment #22 from Holger Hoffstätte  ---
Created attachment 61758
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61758&action=edit
Readable reproducer for debugging

Slightly more reduced, no need for the join business.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-29 Thread sjames at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #21 from Sam James  ---
(In reply to Holger Hoffstätte from comment #18)
> results in *both* tests using HaystackPinning and working as expected -
> though in the second case that might be accidental state reuse, which is
> also concerning:

-fstack-reuse=none doesn't help, but that doesn't prove much if it's a C++ FE
issue.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-29 Thread sjames at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #20 from Sam James  ---
(In reply to Holger Hoffstätte from comment #17)
>  I also get the impression that small.cxx now demonstrates a different 
> problem than before, but that might just be fallout from what I'm about to 
> show; this hole goes deeper.

I can always re-run it with some specific condition keeping the list
comparisons, but given it still kept the QList and dies w/o
-fno-tree-pta, I figured it was the same. But I'm happy to spend some CPU on it
if it provides some insight if people want ofc.

(I had the same thought and went back and forth on it.)

Next step if nobody has any insight yet is to do the debug counter I think and
also see if anything leaps out from dumps, now that the file is much smaller.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-29 Thread holger--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #19 from Holger Hoffstätte  ---
(In reply to Holger Hoffstätte from comment #18)
> Consequently the problematic second test (testNotOK) can be "fixed" by:
> 
>   auto tok = qTokenize(std::move(expected.join(u'.')), QLatin1Char('.'),
> Qt::CaseSensitive, Qt::SkipEmptyParts);

Sorry, no - this does *not* fix it. Sorry.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-29 Thread holger--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #18 from Holger Hoffstätte  ---
Furthermore, using an explicit std::move to the first test like this:

auto joined = expected.join(u'.');
auto tok = qTokenize(std::move(joined), QLatin1Char('.'),
Qt::CaseSensitive, Qt::SkipEmptyParts);

results in *both* tests using HaystackPinning and working as expected - though
in the second case that might be accidental state reuse, which is also
concerning:

Breakpoint 1, dump > (tok=...) at
/usr/include/qt6/QtCore/qstringtokenizer.h:377
377 auto QStringTokenizerBase::next(tokenizer_state
state) const noexcept -> next_result
(gdb) p tok
$6 = (QStringTokenizer &) @0x7fffde40:
{> =
{> = {m_string = {d = {
  d = 0x5556f640, ptr = 0x5556f650 u"a.ab.abc.abcd.abcde", 
  size = 19}}}, },
> = {> = {}, },
> = { = {
  m_sb = {> =
{> = {static IntegerSize = 4, 
i = 1}, }, }, m_cs =
Qt::CaseSensitive}, m_haystack = {m_size = 19, m_data = 0x5556f650
u"a.ab.abc.abcd.abcde"}, m_needle = {
  ucs = 46 u'.'}}, }
(gdb) c
Continuing.
1 2 3 4 5 

Breakpoint 1, dump > (tok=...) at
/usr/include/qt6/QtCore/qstringtokenizer.h:377
377 auto QStringTokenizerBase::next(tokenizer_state
state) const noexcept -> next_result
(gdb) p tok
$7 = (QStringTokenizer &) @0x7fffde40:
{> =
{> = {m_string = {d = {
  d = 0x5556f640, ptr = 0x5556f650 u"a.ab.abc.abcd.abcde", 
  size = 19}}}, },
> = {> = {}, },
> = { = {
  m_sb = {> =
{> = {static IntegerSize = 4, 
i = 1}, }, }, m_cs =
Qt::CaseSensitive}, m_haystack = {m_size = 19, m_data = 0x5556f650
u"a.ab.abc.abcd.abcde"}, m_needle = {
  ucs = 46 u'.'}}, }
(gdb) c
Continuing.
1 2 3 4 5 

Consequently the problematic second test (testNotOK) can be "fixed" by:

  auto tok = qTokenize(std::move(expected.join(u'.')), QLatin1Char('.'),
Qt::CaseSensitive, Qt::SkipEmptyParts);

Hope this helps.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-29 Thread holger--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #17 from Holger Hoffstätte  ---
Created attachment 61755
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61755&action=edit
Readable reproducer for debugging

(In reply to [email protected] from comment #16)
> Does -fno-lifetime-dse help?

It does not (in any example). I also get the impression that small.cxx now
demonstrates a different problem than before, but that might just be fallout
from what I'm about to show; this hole goes deeper.

With my "readable.cpp" attachment (still needs Qt):

holger>gdb a.out
(gdb) b dump
Breakpoint 1 at 0x148f: dump. (2 locations)
(gdb) r
Starting program: /mnt/tux/holger/Projects/qt6-gcc15/a.out 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Breakpoint 1.1, dump > (tok=...) at readable.cpp:8
8   for (auto &x : tok) {
(gdb) p tok.m_haystack 
$1 = {m_size = 19, m_data = 0x5556f650 u"a.ab.abc.abcd.abcde"}

--> looks fine

(gdb) c
Continuing.
1 2 3 4 5 

--> as expected

Breakpoint 1.2, dump > (tok=...) at
readable.cpp:8
8   for (auto &x : tok) {
(gdb) p tok.m_haystack 
$2 = {m_size = 93824992343616, m_data = 0x5556f650 u"a.ab.abc.abcd.abcde"}

--> m_size is obviously bogus

(gdb) c
Continuing.
1 2 3 4 5 18446744073709551615 

The interesting difference here is that the tokenizer "pins" moved-into
haystacks and that's when things go wrong.

Unpinned (good):

Breakpoint 1.1, dump > (tok=...) at readable.cpp:8
8   for (auto &x : tok) {
(gdb) p tok
$1 = (QStringTokenizer &) :
{> =
{> = {}, }, > =
{> = {}, }, > =
{ = {
  m_sb = {> =
{> = {static IntegerSize = 4, 
i = }, }, }, m_cs =
}, m_haystack = {m_size = 19, m_data = 0x5556f650
u"a.ab.abc.abcd.abcde"}, 
m_needle = {ucs = }}, }
(gdb) c
Continuing.
1 2 3 4 5 

Pinned (wrong):

Breakpoint 1.2, dump > (tok=...) at
readable.cpp:8
8   for (auto &x : tok) {
(gdb) p tok
$2 = (QStringTokenizer &) @0x7fffde20:
{> =
{> = {m_string = {d = {
  d = 0x002e, ptr = 0x5556f650 u"a.ab.abc.abcd.abcde", 
  size = 19}}}, },
> = {> = {}, },
> = { = {
  m_sb = {> =
{> = {static IntegerSize = 4, 
i = 1}, }, }, m_cs =
Qt::CaseSensitive}, m_haystack = {m_size = 93824992343616, m_data =
0x5556f650 u"a.ab.abc.abcd.abcde"}, 
m_needle = {ucs = 46 u'.'}}, }
(gdb) c
Continuing.
1 2 3 4 5 18446744073709551615 

We can see that Pinning has size=19 (correct), but m_haystack
has m_size = 93824992343616 (wrong).

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-29 Thread rguenther at suse dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #16 from rguenther at suse dot de  ---
> Am 29.06.2025 um 02:08 schrieb sjames at gcc dot gnu.org 
> :
> 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358
> 
> --- Comment #13 from Sam James  ---
> FWIW, it fails with -fno-strict-aliasing still (and the original).

Does -fno-lifetime-dse help?

> --
> You are receiving this mail because:
> You are on the CC list for the bug.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-28 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #15 from Andrew Pinski  ---
(In reply to Sam James from comment #13)
> FWIW, it fails with -fno-strict-aliasing still (and the original).

oh.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-28 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #14 from Andrew Pinski  ---
https://doc.qt.io/qt-6/qchar.html


yes what they mention is totally wrong.

I am 99% sure QT code is not alias friendly at all and needs to be fixed and it
looks hard to fix as they treat char16_t and QChar as compatible from an
aliasing point of view but that is never true in C++. Doing stores via QChar
and then loads via char16_t is fine but the opposite is undefined. And then in
this case doing comparisons of pointers will cause issues.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-28 Thread sjames at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #13 from Sam James  ---
FWIW, it fails with -fno-strict-aliasing still (and the original).

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-28 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #12 from Andrew Pinski  ---
(In reply to Sam James from comment #11)
> Created attachment 61749 [details]
> small.cxx

I think there might be some aliasing issue with char16_t and Qchar. 

```
  QChar *begin() const { return reinterpret_cast(d.bp()); }


  bn d;


bn::d :
  ag *bp() const { return bv; }
  ag *bv;



struct QChar {
  QChar(char16_t) {}
  char16_t bg;
};

```

I suspect this is true of the original code too.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-28 Thread sjames at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

Sam James  changed:

   What|Removed |Added

  Attachment #61748|0   |1
is obsolete||

--- Comment #11 from Sam James  ---
Created attachment 61749
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61749&action=edit
small.cxx

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-28 Thread sjames at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #10 from Sam James  ---
Created attachment 61748
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61748&action=edit
small.cxx

Not sure if this testcase is valid but it aborts with >=15 with -O3 and works
with -fno-tree-pta. It still needs to link against Qt though.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-27 Thread sjames at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #9 from Sam James  ---
Created attachment 61740
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61740&action=edit
foo.ii.xz

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-27 Thread sjames at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

Sam James  changed:

   What|Removed |Added

 CC||kacper.slominski72 at gmail 
dot co
   ||m

--- Comment #8 from Sam James  ---
Kacper Słomiński has got it down to:
```
#include 
#include 

int main() {
auto expected = QStringList{"a", "b", "c", "d", "e"};
auto tok = qTokenize(expected.join(u'x'), QLatin1Char('x'),
Qt::CaseSensitive, Qt::SkipEmptyParts);

QStringList r;
for (auto &&e : tok)
r.push_back(e.toString());

if (r.size() != expected.size()) abort();
}
```

which fails with:
```
$ g++ -DQT_NO_DEBUG $(pkg-config --libs --cflags Qt6Core) -std=gnu++17 foo.cxx
-o foo -O3 && ./foo
```

I'll attach preprocessed source for that but we're working on killing the Qt
dependency next.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-27 Thread holger--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #7 from Holger Hoffstätte  ---
Sorry if the following is unhelpful - I'm just an interested observer.

Since I could easily reproduce the problem I decided to poke at things
in gdb and got a bit annoyed at the bad test code style. So I un-inlined
the call to expected.join() into a local and .. all tests pass.
Yay?

--- a/tst_qstringtokenizer.cpp.ii
+++ b/tst_qstringtokenizer_hh.cpp.ii
@@ -257685,7 +257685,8 @@ void tst_QStringTokenizer::basics() const
 expected = skipped(expected);

 using namespace std::string_literals;
-auto tok = qTokenize(expected.join(u'x'), QLatin1Char('x'), cs, sb);
+auto joined = expected.join(u'x');
+auto tok = qTokenize(joined, QLatin1Char('x'), cs, sb);
 do { if (!QTest::qCompare(toQStringList(tok), expected,
"toQStringList(tok)", "expected",
"/home/sam/bugs/qt/qtbase-everywhere-src-6.9.0/tests/auto/corelib/text/qs>
 }

Is this maybe a temporary/lifetime thing going wrong?

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-27 Thread sjames at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #6 from Sam James  ---
(In reply to Richard Biener from comment #5)

I'll find some time to try make more progress. Will try adding a counter if I
cannot get further with reducing, but luckily, the C++ in the file isn't too
complex ;)

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-06-27 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #5 from Richard Biener  ---
(In reply to Sam James from comment #0)
> Looking at dumps between r15-579-ga9251ab3c91c8c and
> r15-580-gf3e5f4c58591f5, there's a lot of noise like:
> ```
> -  # PT = nonlocal escaped null { D.387695 D.418643 } (nonlocal, escaped)
> -  # USE = nonlocal escaped null { D.387695 D.418643 } (nonlocal, escaped)
> -  # CLB = nonlocal escaped null { D.387695 D.418643 } (nonlocal, escaped)
> +  # PT = nonlocal escaped null const-pool { D.387695 D.418643 } (nonlocal,
> escaped)
> +  # USE = nonlocal escaped null const-pool { D.387695 D.418643 } (nonlocal,
> escaped)
> +  # CLB = nonlocal escaped null const-pool { D.387695 D.418643 } (nonlocal,
> escaped)
> ```

without a testcase it's hard to see what goes wrong - the above is a
correctness fix, we get strictly larger points-to sets.  For ptr-ptr
compares we rely on those being conservative, so possibly we miss more.

I'll note the newer preprocessed source doesn't build around the offending rev
(the old does).

The first actual IL difference happens in VRP1.  Differences in wc -l for
all dump files (w/o details):

qt.ii.120t.threadfull1 0
qt.ii.121t.vrp1 20
qt.ii.122t.dse2 30
..
qt.ii.149t.walloca2 20
qt.ii.150t.pre 29
qt.ii.151t.sink1 53
qt.ii.155t.dse3 43
...
qt.ii.202t.thread2 7
qt.ii.203t.dom3 49
qt.ii.204t.strlen1 39
qt.ii.205t.threadfull2 180
qt.ii.206t.vrp2 106

it's not definite data since there's stuff that should be in -details
leaking into normal dumps.  It's quite difficult to isolate an
offending transform.  Possibly adding a dbgcnt to ptrs_compare_unequal
when it triggers the ptr-vs.-ptr case can track down the bogus offender...

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-05-19 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

Richard Biener  changed:

   What|Removed |Added

   Priority|P3  |P2
 CC||rguenth at gcc dot gnu.org

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-05-19 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #4 from Andrew Pinski  ---
(In reply to Sam James from comment #3)
> Created attachment 61474 [details]
> tst_qstringtokenizer.cpp.ii.xz

Just a quick note -march=znver2 is needed to compile this preprocessed source.
Even though -march=x86-64-v4 is mentioned in comment #0 :).

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-05-19 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

Andrew Pinski  changed:

   What|Removed |Added

 Ever confirmed|1   |0
 Status|WAITING |UNCONFIRMED

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-05-19 Thread sjames at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

Sam James  changed:

   What|Removed |Added

  Attachment #61472|0   |1
is obsolete||

--- Comment #3 from Sam James  ---
Created attachment 61474
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61474&action=edit
tst_qstringtokenizer.cpp.ii.xz

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-05-19 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

Andrew Pinski  changed:

   What|Removed |Added

 Ever confirmed|0   |1
   Last reconfirmed||2025-05-19
 Status|UNCONFIRMED |WAITING

--- Comment #2 from Andrew Pinski  ---
(In reply to Sam James from comment #0)
> Created attachment 61472 [details]
> tst_qstringtokenizer.cpp.ii.xz


Is there a way to regenerate this preprocessed source with a more recent GCC
15?
AVX512ER support has been removed so we get errors.

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-05-19 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

Andrew Pinski  changed:

   What|Removed |Added

   Target Milestone|--- |15.2
   Keywords||alias

[Bug tree-optimization/120358] [15/16 regression] qtbase-6.9.0 miscompiled since r15-580-gf3e5f4c58591f5

2025-05-19 Thread sjames at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120358

--- Comment #1 from Sam James  ---
Created attachment 61473
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61473&action=edit
build.sh