Bug 95638 - [10 Regression] Legit-looking code doesn't work with -O2
Summary: [10 Regression] Legit-looking code doesn't work with -O2
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 10.1.0
: P3 normal
Target Milestone: 10.3
Assignee: bin cheng
URL:
Keywords: wrong-code
Depends on: 95804
Blocks:
  Show dependency treegraph
 
Reported: 2020-06-11 11:45 UTC by Mykhailo Kremniov
Modified: 2021-03-27 02:44 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work: 10.2.0, 11.0, 9.3.0
Known to fail: 10.1.0
Last reconfirmed: 2020-07-09 00:00:00


Attachments
The failing code (889 bytes, text/x-csrc)
2020-06-11 11:45 UTC, Mykhailo Kremniov
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mykhailo Kremniov 2020-06-11 11:45:04 UTC
Created attachment 48718 [details]
The failing code

The attached code produces wrong result when build with -O2 and without -fno-strict-aliasing, but I don't believe it does anything illegal. The only fishy thing it does is creating a pointer to T before an object of that type is constructed at that location (in Storage::Storage and Storage::push_back), but the pointer is just passed to the placement new, which should be fine according to [basic.life] (because "...using the pointer as if the pointer were of type void*, is well-defined").

------------------------
$ g++-10.1.0 -v
Using built-in specs.
COLLECT_GCC=g++-10.1.0
COLLECT_LTO_WRAPPER=/home/brd/soft/gcc-10.1.0/libexec/gcc/x86_64-pc-linux-gnu/10.1.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ./configure --prefix=/home/brd/soft/gcc-10.1.0
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.1.0 (GCC) 

$ g++-10.1.0 -O2 gcc10_aliasing_issue.cpp -o test -std=c++14 && ./test
Null!!!

$ g++-10.1.0 -O2 -fno-strict-aliasing gcc10_aliasing_issue.cpp -o test -std=c++14 && ./test
OK
------------------------

P.S. The same code works fine with GCC 9 and earlier versions.
Comment 1 Jakub Jelinek 2020-06-11 12:08:10 UTC
All I can say is that bisection shows (at least when preprocessed with g++ 8.3.1 first) that this changed behavior in
r10-7184-ge4e9a59105a81cdd6c1328b0a5ed9fe4cc82840e
No time to analyze if it is a bug in the code or on the GCC side.
CCing patch author.
Comment 2 Martin Liška 2020-06-11 12:12:53 UTC
The code works with -flifetime-dse=1, so I bet there's some object that goes out of life:
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
https://gcc.gnu.org/gcc-6/porting_to.html#flifetime-dse
Comment 3 Jakub Jelinek 2020-06-11 12:23:05 UTC
(In reply to Martin Liška from comment #2)
> The code works with -flifetime-dse=1, so I bet there's some object that goes
> out of life:
> https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
> https://gcc.gnu.org/gcc-6/porting_to.html#flifetime-dse

The difference between -flifetime-dse=1 and the default is not in uses after end of scope, but in relying on content being defined across start of the constructor.
Comment 4 Jonathan Wakely 2020-06-11 15:40:36 UTC
I don't see anything obviously wrong with the code. Nothing seems to write to the storage before the constructor, let alone rely on those writes being preserved.
Comment 5 bin cheng 2020-06-12 01:17:40 UTC
(In reply to Jakub Jelinek from comment #1)
> All I can say is that bisection shows (at least when preprocessed with g++
> 8.3.1 first) that this changed behavior in
> r10-7184-ge4e9a59105a81cdd6c1328b0a5ed9fe4cc82840e
> No time to analyze if it is a bug in the code or on the GCC side.
> CCing patch author.

Thanks for ccing, I will look into it this WE.
Comment 6 bin cheng 2020-06-14 00:47:08 UTC
We call graphds_scc twice to break alias dependence, with alias dependence edges skipped in the second call.  The code (both before and after r10-7184-ge4e9a59105a81cdd6c1328b0a5ed9fe4cc82840e) tries to rectify post order information after the second call, however it never gets it right.  Actually I don't think it can be easily rectified (if possible).

Will test another patch which records/restores post order information for the second call.
Comment 7 GCC Commits 2020-06-20 07:56:18 UTC
The master branch has been updated by Bin Cheng <amker@gcc.gnu.org>:

https://gcc.gnu.org/g:2c0069fafb53ccb7a45a6815025dfcbd2882a36e

commit r11-1565-g2c0069fafb53ccb7a45a6815025dfcbd2882a36e
Author: Bin Cheng <bin.cheng@linux.alibaba.com>
Date:   Sat Jun 20 15:42:12 2020 +0800

    Record and restore postorder information in breaking alias sccs.
    
    gcc/
            PR tree-optimization/95638
            * tree-loop-distribution.c (pg_edge_callback_data): New field.
            (loop_distribution::break_alias_scc_partitions): Record and restore
            postorder information.  Fix memory leak.
    
    gcc/testsuite/
            PR tree-optimization/95638
            * g++.dg/tree-ssa/pr95638.C: New test.
Comment 8 Jakub Jelinek 2020-06-29 10:07:30 UTC
So fixed on the trunk, waiting for 10 backport?
Comment 9 bin cheng 2020-06-29 12:10:07 UTC
(In reply to Jakub Jelinek from comment #8)
> So fixed on the trunk, waiting for 10 backport?

Sorry, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95804 is also in this part which I believe is related to this fix.  Will backport the full patch after fixing 95804.

Thanks
Comment 10 Richard Biener 2020-07-09 11:48:18 UTC
Fixed on trunk sofar.
Comment 11 GCC Commits 2020-07-10 03:59:31 UTC
The releases/gcc-10 branch has been updated by Bin Cheng <amker@gcc.gnu.org>:

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

commit r10-8453-gf737ca45bee4ea61571393e04495955aeb7d67ab
Author: Bin Cheng <bin.cheng@linux.alibaba.com>
Date:   Sat Jun 20 15:42:12 2020 +0800

    Record and restore postorder information in breaking alias sccs.
    
    gcc/
            PR tree-optimization/95638
            * tree-loop-distribution.c (pg_edge_callback_data): New field.
            (loop_distribution::break_alias_scc_partitions): Record and restore
            postorder information.  Fix memory leak.
    
    gcc/testsuite/
            PR tree-optimization/95638
            * g++.dg/tree-ssa/pr95638.C: New test.
    
    (cherry picked from commit 2c0069fafb53ccb7a45a6815025dfcbd2882a36e)
Comment 12 GCC Commits 2020-07-10 04:12:53 UTC
The releases/gcc-9 branch has been updated by Bin Cheng <amker@gcc.gnu.org>:

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

commit r9-8730-gdc7a8afce35eb8948b481b5bcb8d26124a267f55
Author: Bin Cheng <bin.cheng@linux.alibaba.com>
Date:   Sat Jun 20 15:42:12 2020 +0800

    Record and restore postorder information in breaking alias sccs.
    
    gcc/
            PR tree-optimization/95638
            * tree-loop-distribution.c (pg_edge_callback_data): New field.
            (loop_distribution::break_alias_scc_partitions): Record and restore
            postorder information.  Fix memory leak.
    
    gcc/testsuite/
            PR tree-optimization/95638
            * g++.dg/tree-ssa/pr95638.C: New test.
    
    (cherry picked from commit 2c0069fafb53ccb7a45a6815025dfcbd2882a36e)
Comment 13 Richard Biener 2020-07-23 06:51:45 UTC
GCC 10.2 is released, adjusting target milestone.
Comment 14 bin cheng 2020-07-23 07:11:23 UTC
(In reply to Richard Biener from comment #13)
> GCC 10.2 is released, adjusting target milestone.

Hmm, this should be fixed on GCC10/GCC9.  I backported PR95638/PR95804 separately using cherry-pick, so the backport information for latter PR is not reflected here.
Comment 15 bin cheng 2021-03-27 02:44:35 UTC
Confirmed fixed for 10.2.0 also.  Closing.