<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 - [LICM] LICM promotes real value to null in store instruction"
href="https://bugs.llvm.org/show_bug.cgi?id=36801">36801</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>[LICM] LICM promotes real value to null in store instruction
</td>
</tr>
<tr>
<th>Product</th>
<td>new-bugs
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>new bugs
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>ilia.taraban@intel.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>This test fails with wrong result after "Loop Invariant Code Motion":
================= nice.c ==============
unsigned int y = 0;
int main () {
unsigned int i = 0, j = 0, a = 0;
unsigned int gc[3] = {0};
unsigned int *p = &a;
scanf("");
for (i = 2; i < 4; ++i) {
gc[i - 1] += 1;
for (j = i; j < 1; ++j)
y = (*p);
p = &gc[i - 1];
gc[1]++;
}
*p = gc[0];
printf("res = %u\n", gc[1]);
return 0;
}
=======================================
<span class="quote">>>> clang -v</span >
clang version 7.0.0 (trunk 327823)
Target: x86_64-unknown-linux-gnu
Thread model: posix
...
<span class="quote">>>> clang -o nice.exe nice.c -O0
>>> nice.exe</span >
res = 3
<span class="quote">>>> clang -o nice.exe nice.c -O1
>>> nice.exe</span >
res = 2
BISECT:
<span class="quote">>>> clang -o nice.exe nice.c -mllvm -opt-bisect-limit=...</span >
...
BISECT: running pass (32) Unswitch loops on loop
BISECT: running pass (33) Rotate Loops on loop
res = 3
BISECT: running pass (34) Loop Invariant Code Motion on loop
res = 2
BISECT: NOT running pass (35) Unswitch loops on loop
...
Here is "small" reproducer:
================= fine.ll ==============
define dso_local i32 @main() local_unnamed_addr {
entry:
%gc = alloca [3 x i32], align 4
br label %for.cond
for.cond: ; preds = %for.end, %entry
%i.0 = phi i32 [ 2, %entry ], [ %inc10, %for.end ]
%p.0 = phi i32* [ null, %entry ], [ %arrayidx, %for.end ]
%cmp = icmp ult i32 %i.0, 4
br i1 %cmp, label %for.body, label %for.end11
for.body: ; preds = %for.cond
%arrayidx = getelementptr inbounds [3 x i32], [3 x i32]* %gc, i64 0, i64 0
store i32 0, i32* %arrayidx, align 4
br label %for.cond1
for.cond1: ; preds = %for.body3,
%for.body
%j.0 = phi i32 [ %i.0, %for.body ], [ 1, %for.body3 ]
br i1 false, label %for.body3, label %for.end
for.body3: ; preds = %for.cond1
%0 = load i32, i32* %p.0, align 4
br label %for.cond1
for.end: ; preds = %for.cond1
%arrayidx7 = getelementptr inbounds [3 x i32], [3 x i32]* %gc, i64 0, i64 1
%inc10 = add i32 %i.0, 1
br label %for.cond
for.end11: ; preds = %for.cond
%p.0.lcssa = phi i32* [ %p.0, %for.cond ]
ret i32 0
}
=======================================
Original test does nothing.
<span class="quote">>>> opt -S -o fine.post.rotate+licm.ll -loop-rotate -licm fine.ll
>>> clang fine.post.rotate+licm.ll && a.out</span >
Segmentation fault
After "Rotate Loops" and "Loop Invariant Code Motion", we receive "store into
null":
================= fine.post.rotate+licm.ll ==============
define dso_local i32 @main() local_unnamed_addr {
entry:
%gc = alloca [3 x i32], align 4
%arrayidx = getelementptr inbounds [3 x i32], [3 x i32]* %gc, i64 0, i64 0
br label %for.body
for.body: ; preds = %entry, %for.end
%i.01 = phi i32 [ 2, %entry ], [ %inc10, %for.end ]
br i1 false, label %for.body3.lr.ph, label %for.end
for.body3.lr.ph: ; preds = %for.body
br label %for.body3
for.body3: ; preds = %for.body3.lr.ph,
%for.body3
br i1 false, label %for.body3, label %for.cond1.for.end_crit_edge
for.cond1.for.end_crit_edge: ; preds = %for.body3
br label %for.end
for.end: ; preds =
%for.cond1.for.end_crit_edge, %for.body
%inc10 = add i32 %i.01, 1
%cmp = icmp ult i32 %inc10, 4
br i1 %cmp, label %for.body, label %for.end11
for.end11: ; preds = %for.end
store i32 0, i32* null, align 4
%arrayidx.le = getelementptr inbounds [3 x i32], [3 x i32]* %gc, i64 0, i64 0
ret i32 0
}
=======================================
Quick debug shows that %arrayidx aliases null. But in original code %arrayidx
always refers to array %gs.
<span class="quote">>>>CurAST of Loop:
>>>Alias Set Tracker: 1 alias sets for 2 pointer values.
>>> AliasSet[0x760ad30, 2] must alias, Mod/Ref Pointers: (i32* null, 4), (i32* %arrayidx, 4)</span >
So maybe problem is in Loop aliasing.</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>