LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 28880 - GVNHoist leads to miscompile of llvm test-suite SingleSource/Benchmarks/Misc/fbench.c
Summary: GVNHoist leads to miscompile of llvm test-suite SingleSource/Benchmarks/Misc/...
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: Scalar Optimizations (show other bugs)
Version: trunk
Hardware: PC All
: P normal
Assignee: Unassigned LLVM Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-08-05 21:21 PDT by Matthias Braun
Modified: 2016-08-08 09:50 PDT (History)
6 users (show)

See Also:
Fixed By Commit(s):


Attachments
Preprocessed testcase (95.87 KB, application/octet-stream)
2016-08-05 21:29 PDT, Sebastian Pop
Details
MSSA with -gvn-max-hoisted=62 (7.34 KB, application/octet-stream)
2016-08-05 21:35 PDT, Sebastian Pop
Details
MSSA with -gvn-max-hoisted=63 (7.25 KB, application/octet-stream)
2016-08-05 21:35 PDT, Sebastian Pop
Details
Complete dump you can use to see incorrect version (9.39 KB, application/octet-stream)
2016-08-06 10:22 PDT, Daniel Berlin
Details
Reduced version of testcase (1.66 KB, application/octet-stream)
2016-08-06 10:43 PDT, Daniel Berlin
Details
Patch that should fix it (1.05 KB, patch)
2016-08-06 10:53 PDT, Daniel Berlin
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Matthias Braun 2016-08-05 21:21:06 PDT
GVN-hoist appears to miscompile SingleSource/Benchmarks/Misc/fbench.c as this builder:

http://lab.llvm.org:8080/green/job/Performance_O3flto/

is broken after r277786 "GVN-hoist: enable by default".

Citing Sebastians analysis: "

 think there is a problem with the MemorySSA when compiling fbench with -Ofast
The problem appears with -mllvm -gvn-max-hoisted=63, (at 62 the
program is not miscompiled.)
before.ll is the MSSA dump at 62 and after.ll is the MSSA for 63.

We end up hoisting two loads past a store, and the loads do not link
to the store: they are both liveOnEntry:

; MemoryUse(liveOnEntry)
 %19 = load double, double* @axis_slope_angle, align 8, !tbaa !5

and

; MemoryUse(liveOnEntry)
 %22 = load double, double* @axis_slope_angle, align 8, !tbaa !5

past a store to the global variable:

; 7 = MemoryDef(liveOnEntry)
 store double 0.000000e+00, double* @axis_slope_angle, align 8, !tbaa !5
"
Comment 1 Matthias Braun 2016-08-05 21:24:08 PDT
I reverted r277786 in the meantime (in r277909)
Comment 2 Sebastian Pop 2016-08-05 21:29:24 PDT
Created attachment 16895 [details]
Preprocessed testcase

Compile the attached file with:

$ clang -Ofast fbench.i -fblocks -o a.out -lm -mllvm -gvn-max-hoisted=63
$ ./a.out
[...]
93 errors in results.  This is VERY SERIOUS.

$ clang -Ofast fbench.i -fblocks -o a.out -lm -mllvm -gvn-max-hoisted=62
$ ./a.out
[...]
No errors in results.
Comment 3 Sebastian Pop 2016-08-05 21:35:25 PDT
Created attachment 16896 [details]
MSSA with -gvn-max-hoisted=62
Comment 4 Sebastian Pop 2016-08-05 21:35:55 PDT
Created attachment 16897 [details]
MSSA with -gvn-max-hoisted=63
Comment 5 Daniel Berlin 2016-08-06 10:22:28 PDT
Created attachment 16898 [details]
Complete dump you can use to see incorrect version

use opt -tbaa -print-memoryssa to see:

if.then22:                                        ; preds = %if.then20
; 7 = MemoryDef(liveOnEntry)
  store double 0.000000e+00, double* @axis_slope_angle, align 8, !tbaa !3
...

; 13 = MemoryPhi({if.then22,7},{if.else24,liveOnEntry})
...

; MemoryUse(liveOnEntry)
  %22 = load double, double* @axis_slope_angle, align 8, !tbaa !3
Comment 6 Daniel Berlin 2016-08-06 10:43:54 PDT
Created attachment 16899 [details]
Reduced version of testcase
Comment 7 Daniel Berlin 2016-08-06 10:52:23 PDT
This is a silly bug: We are trying to figure out whether the size of the  stack has changed due to popping off non-dominating accesses,and we are not doing it right:

We were doing:
      if (LocInfo.LowerBound >= VersionStack.size() - 1) {


To see if the lower bound needed to be reset after popping the stack.
The problem with this is that if you have any pushes, it may be that the lower bound is still wrong, the size will still now be "right".

The correct fix is to store the size of the stack after we are done popping, and use it in the comparison above.

Ironically, I had thought about this, and in the first versions of the use optimizer i sent george, we were storing the stack size, but i couldn't remember why we needed to do that so i removed it :)

I'll fix this and add a testcase.
Comment 8 Daniel Berlin 2016-08-06 10:53:53 PDT
Created attachment 16900 [details]
Patch that should fix it
Comment 9 Sebastian Pop 2016-08-08 09:50:35 PDT
Fixed in https://reviews.llvm.org/rL277978
and enabled gvn-hoist by default in https://reviews.llvm.org/rL278010