<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - [GVN] Miscompile: incorrect replacement of redundant load with PHIs"
href="https://bugs.llvm.org/show_bug.cgi?id=42733">42733</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>[GVN] Miscompile: incorrect replacement of redundant load with PHIs
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Scalar Optimizations
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>suc-daniil@yandex.ru
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>In this case GVN eliminates following load:
%tmp25 = load atomic i64, i64 addrspace(1)* %tmp24 unordered, align 8
by replacing it with a sequence of PHIs and the problem is that the first phi
in this sequence contains undef:
bb6: ; preds = %bb19, %bb
%tmp251 = phi i64 [ undef, %bb ], [ %tmp252, %bb19 ]
This bug is not reproducible without !tbaa metadata on this load:
%tmp22 = load atomic i64, i64 addrspace(1)* %tmp21 unordered, align 8, !tbaa
!0
even though only BasicAA is used.
>From what I was able to find, it looks like this PHI contains undef because for
some reason MemoryDependenceAnalysis reports incomplete list of dependencies
for that load.
The reproducer:
========================================================
define i64 @foo(i64 addrspace(1)** %arg, i1 %arg1, i1 %arg2, i1 %arg3, i32
%arg4) {
bb:
%tmp = load atomic i64 addrspace(1)*, i64 addrspace(1)** %arg unordered,
align 8
%tmp5 = getelementptr inbounds i64, i64 addrspace(1)* %tmp, i64 8
store atomic i64 0, i64 addrspace(1)* %tmp5 unordered, align 8
br label %bb6
bb6: ; preds = %bb19, %bb
%tmp7 = phi i64 [ 0, %bb ], [ %tmp22, %bb19 ]
br i1 %arg1, label %bb19, label %bb8
bb8: ; preds = %bb6
%tmp9 = load atomic i64 addrspace(1)*, i64 addrspace(1)** %arg unordered,
align 8
br i1 %arg2, label %bb11, label %bb10
bb10: ; preds = %bb8
br label %bb15
bb11: ; preds = %bb8
br i1 %arg3, label %bb12, label %bb18
bb12: ; preds = %bb11
%tmp13 = phi i64 addrspace(1)* [ %tmp9, %bb11 ]
%tmp14 = getelementptr inbounds i64, i64 addrspace(1)* %tmp13, i64 8
store atomic i64 1, i64 addrspace(1)* %tmp14 unordered, align 8
ret i64 0
bb15: ; preds = %bb26, %bb10
%tmp16 = phi i64 addrspace(1)* [ %tmp9, %bb10 ], [ %tmp27, %bb26 ]
%tmp17 = phi i64 [ %tmp7, %bb10 ], [ 0, %bb26 ]
switch i32 %arg4, label %bb19 [
i32 0, label %bb26
i32 1, label %bb23
]
bb18: ; preds = %bb11
br label %bb19
bb19: ; preds = %bb18, %bb15, %bb6
%tmp20 = phi i64 addrspace(1)* [ %tmp16, %bb15 ], [ null, %bb6 ], [ %tmp9,
%bb18 ]
%tmp21 = getelementptr inbounds i64, i64 addrspace(1)* %tmp20, i64 8
%tmp22 = load atomic i64, i64 addrspace(1)* %tmp21 unordered, align 8, !tbaa
!0
br label %bb6
bb23: ; preds = %bb15
%tmp24 = getelementptr inbounds i64, i64 addrspace(1)* %tmp16, i64 8
%tmp25 = load atomic i64, i64 addrspace(1)* %tmp24 unordered, align 8
call void @baz(i64 %tmp25) #0
ret i64 0
bb26: ; preds = %bb15
call void @bar()
%tmp27 = load atomic i64 addrspace(1)*, i64 addrspace(1)** %arg unordered,
align 8
%tmp28 = getelementptr inbounds i64, i64 addrspace(1)* %tmp27, i64 8
%tmp29 = load atomic i64, i64 addrspace(1)* %tmp28 unordered, align 8
%tmp30 = getelementptr inbounds i64, i64 addrspace(1)* %tmp27, i64 40
store atomic i64 %tmp29, i64 addrspace(1)* %tmp30 unordered, align 4
br label %bb15
}
declare void @bar()
; Function Attrs: inaccessiblememonly readonly
declare void @baz(i64) #0
attributes #0 = { inaccessiblememonly readonly }
!0 = !{!1, !2, i64 8}
!1 = !{!"Name", !2, i64 8}
!2 = !{!"tbaa_local_fields", !3, i64 0}
!3 = !{!"tbaa-access-type"}
========================================================
$ opt -aa-pipeline=basic-aa -passes=gvn -S repro.ll -debug-only=gvn
GVN iteration: 0
GVN: load i64 addrspace(1)* %tmp has unknown dependence
GVN: load i64 addrspace(1)* %tmp9 is clobbered by store atomic i64 0, i64
addrspace(1)* %tmp5 unordered, align 8
GVN: load i64 addrspace(1)* %tmp9 is clobbered by store atomic i64 %tmp29,
i64 addrspace(1)* %tmp30 unordered, align 4
GVN: load i64 addrspace(1)* %tmp27 is clobbered by call void @bar()
GVN: load i64 %tmp29 is clobbered by call void @bar()
GVN removed: %tmp13 = phi i64 addrspace(1)* [ %tmp9, %bb11 ]
GVN: load i64 %tmp22 is clobbered by store atomic i64 0, i64 addrspace(1)*
%tmp5 unordered, align 8
GVN iteration: 1
GVN: load i64 addrspace(1)* %tmp has unknown dependence
GVN: load i64 addrspace(1)* %tmp9 is clobbered by store atomic i64 0, i64
addrspace(1)* %tmp5 unordered, align 8
GVN: load i64 addrspace(1)* %tmp9 is clobbered by store atomic i64 %tmp29,
i64 addrspace(1)* %tmp30 unordered, align 4
GVN REMOVING NONLOCAL LOAD: %tmp25 = load atomic i64, i64 addrspace(1)*
%tmp24 unordered, align 8
GVN removed: %0 = load atomic i64, i64 addrspace(1)* %tmp24 unordered, align
8
GVN: load i64 addrspace(1)* %tmp27 is clobbered by call void @bar()
GVN: load i64 %tmp29 is clobbered by call void @bar()
GVN: load i64 %tmp22 is clobbered by store atomic i64 0, i64 addrspace(1)*
%tmp5 unordered, align 8
GVN iteration: 2
GVN: load i64 addrspace(1)* %tmp has unknown dependence
GVN: load i64 addrspace(1)* %tmp9 is clobbered by store atomic i64 0, i64
addrspace(1)* %tmp5 unordered, align 8
GVN: load i64 addrspace(1)* %tmp9 is clobbered by store atomic i64 %tmp29,
i64 addrspace(1)* %tmp30 unordered, align 4
GVN: load i64 addrspace(1)* %tmp27 is clobbered by call void @bar()
GVN: load i64 %tmp29 is clobbered by call void @bar()
GVN: load i64 %tmp22 is clobbered by store atomic i64 0, i64 addrspace(1)*
%tmp5 unordered, align 8
; ModuleID = 'repro.ll'
source_filename = "repro.ll"
define i64 @foo(i64 addrspace(1)** %arg, i1 %arg1, i1 %arg2, i1 %arg3, i32
%arg4) {
bb:
%tmp = load atomic i64 addrspace(1)*, i64 addrspace(1)** %arg unordered,
align 8
%tmp5 = getelementptr inbounds i64, i64 addrspace(1)* %tmp, i64 8
store atomic i64 0, i64 addrspace(1)* %tmp5 unordered, align 8
br label %bb6
bb6: ; preds = %bb19, %bb
%tmp251 = phi i64 [ undef, %bb ], [ %tmp252, %bb19 ]
%tmp7 = phi i64 [ 0, %bb ], [ %tmp22, %bb19 ]
br i1 %arg1, label %bb19, label %bb8
bb8: ; preds = %bb6
%tmp9 = load atomic i64 addrspace(1)*, i64 addrspace(1)** %arg unordered,
align 8
br i1 %arg2, label %bb11, label %bb10
bb10: ; preds = %bb8
br label %bb15
bb11: ; preds = %bb8
br i1 %arg3, label %bb12, label %bb18
bb12: ; preds = %bb11
%tmp14 = getelementptr inbounds i64, i64 addrspace(1)* %tmp9, i64 8
store atomic i64 1, i64 addrspace(1)* %tmp14 unordered, align 8
ret i64 0
bb15: ; preds = %bb26, %bb10
%tmp25 = phi i64 [ %tmp251, %bb10 ], [ %tmp29, %bb26 ]
%tmp16 = phi i64 addrspace(1)* [ %tmp9, %bb10 ], [ %tmp27, %bb26 ]
%tmp17 = phi i64 [ %tmp7, %bb10 ], [ 0, %bb26 ]
switch i32 %arg4, label %bb19 [
i32 0, label %bb26
i32 1, label %bb23
]
bb18: ; preds = %bb11
br label %bb19
bb19: ; preds = %bb18, %bb15, %bb6
%tmp252 = phi i64 [ %tmp25, %bb15 ], [ %tmp251, %bb6 ], [ %tmp251, %bb18 ]
%tmp20 = phi i64 addrspace(1)* [ %tmp16, %bb15 ], [ null, %bb6 ], [ %tmp9,
%bb18 ]
%tmp21 = getelementptr inbounds i64, i64 addrspace(1)* %tmp20, i64 8
%tmp22 = load atomic i64, i64 addrspace(1)* %tmp21 unordered, align 8, !tbaa
!0
br label %bb6
bb23: ; preds = %bb15
%tmp24 = getelementptr inbounds i64, i64 addrspace(1)* %tmp16, i64 8
call void @baz(i64 %tmp25) #0
ret i64 0
bb26: ; preds = %bb15
call void @bar()
%tmp27 = load atomic i64 addrspace(1)*, i64 addrspace(1)** %arg unordered,
align 8
%tmp28 = getelementptr inbounds i64, i64 addrspace(1)* %tmp27, i64 8
%tmp29 = load atomic i64, i64 addrspace(1)* %tmp28 unordered, align 8
%tmp30 = getelementptr inbounds i64, i64 addrspace(1)* %tmp27, i64 40
store atomic i64 %tmp29, i64 addrspace(1)* %tmp30 unordered, align 4
br label %bb15
}
declare void @bar()
; Function Attrs: inaccessiblememonly readonly
declare void @baz(i64) #0
attributes #0 = { inaccessiblememonly readonly }
!0 = !{!1, !2, i64 8}
!1 = !{!"Name", !2, i64 8}
!2 = !{!"tbaa_local_fields", !3, i64 0}
!3 = !{!"tbaa-access-type"}
========================================================
Any further simplification of the reproducer breaks it.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>