<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 - loop-reroll rerolls loops with unrerollable instructions"
href="https://bugs.llvm.org/show_bug.cgi?id=47627">47627</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>loop-reroll rerolls loops with unrerollable instructions
</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>Loop Optimizer
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>t-kawashima@fujitsu.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Created <span class=""><a href="attachment.cgi?id=23995" name="attach_23995" title="unrerollable1.ll; IR with unrerollable instructions">attachment 23995</a> <a href="attachment.cgi?id=23995&action=edit" title="unrerollable1.ll; IR with unrerollable instructions">[details]</a></span>
unrerollable1.ll; IR with unrerollable instructions
Problem Description
===================
loop-reroll rerolls loops with unrerollable instructions.
See the following IR (same as the attached one).
--------------------------------
define dso_local void @foo([2 x i32]* nocapture %a) local_unnamed_addr {
entry:
br label %loop
loop:
; base instruction
%indvars = phi i64 [ 0, %entry ], [ %indvars.next, %loop ]
; unrerollable instructions
%stptrx = getelementptr inbounds [2 x i32], [2 x i32]* %a, i64 %indvars, i64
0
store i32 999, i32* %stptrx, align 4
; extra simple arithmetic operations
%plus20 = add nuw nsw i64 %indvars, 20
%plus10 = add nuw nsw i64 %indvars, 10
; root instruction 0
%ldptr0 = getelementptr inbounds [2 x i32], [2 x i32]* %a, i64 %plus20, i64 0
%value0 = load i32, i32* %ldptr0, align 4
%stptr0 = getelementptr inbounds [2 x i32], [2 x i32]* %a, i64 %plus10, i64 0
store i32 %value0, i32* %stptr0, align 4
; root instruction 1
%ldptr1 = getelementptr inbounds [2 x i32], [2 x i32]* %a, i64 %plus20, i64 1
%value1 = load i32, i32* %ldptr1, align 4
%stptr1 = getelementptr inbounds [2 x i32], [2 x i32]* %a, i64 %plus10, i64 1
store i32 %value1, i32* %stptr1, align 4
; latch
%indvars.next = add nuw nsw i64 %indvars, 1
%exitcond = icmp eq i64 %indvars.next, 5
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
--------------------------------
This IR is generated from the following C program.
--------------------------------
void foo(int a[][2]) {
for (int i = 0; i < 5; i++) {
a[i][0] = 999;
a[10+i][0] = a[20+i][0];
a[10+i][1] = a[20+i][1];
}
}
--------------------------------
This program is unrerollable because of the existence of
`a[i][0] = 999`. However, `opt -loop-reroll` rerolls this to
the following IR.
--------------------------------
define dso_local void @foo([2 x i32]* nocapture %a) local_unnamed_addr {
entry:
br label %loop
loop:
%indvars = phi i64 [ 0, %entry ], [ %indvars.next, %loop ]
%scevgep1 = getelementptr [2 x i32], [2 x i32]* %a, i64 20, i64 %indvars
%scevgep = getelementptr [2 x i32], [2 x i32]* %a, i64 10, i64 %indvars
%stptrx = getelementptr inbounds [2 x i32], [2 x i32]* %a, i64 %indvars, i64
0
store i32 999, i32* %stptrx, align 4
%value0 = load i32, i32* %scevgep1, align 4
store i32 %value0, i32* %scevgep, align 4
%indvars.next = add nuw nsw i64 %indvars, 1
%exitcond2 = icmp eq i64 %indvars, 9
br i1 %exitcond2, label %exit, label %loop
exit:
ret void
}
--------------------------------
This IR is equivalent to the following C program.
--------------------------------
void foo(int a[][2]) {
for (int i = 0; i < 10; i++) {
a[i][0] = 999;
a[10][i] = a[20][i];
}
}
--------------------------------
a[5][0], a[6][0], ..., a[9][0] should not be updated, but they
are updated. It's a bug.
I confirmed this problem with at least the latest master branch
(commit 10092291d7a) and LLVM 7.1.0.
This problem is not limited to two dimensional array. Also,
not limited to a store operation. Compiling the following C
programs with `clang -O1 -freroll-loops` also has the problem.
--------------------------------
void bar(int x);
void foo(int a[]) {
#pragma clang loop unroll(disable)
for (int i = 0; i < 5; i++) {
bar(a[i]);
a[20+2*i+0] = a[40+2*i+0];
a[20+2*i+1] = a[40+2*i+1];
}
}
--------------------------------
--------------------------------
struct x {
int m1;
int m2;
};
void foo(struct x *a) {
#pragma clang loop unroll(disable)
for (int i = 0; i < 5; i++) {
a[i].m1 = 999;
a[10+i].m1 = a[20+i].m1;
a[10+i].m2 = a[20+i].m2;
}
}
--------------------------------</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>