[llvm-bugs] [Bug 41998] New: After r345814, IndVars regression causing infinite loop
via llvm-bugs
llvm-bugs at lists.llvm.org
Thu May 23 12:54:03 PDT 2019
https://bugs.llvm.org/show_bug.cgi?id=41998
Bug ID: 41998
Summary: After r345814, IndVars regression causing infinite
loop
Product: new-bugs
Version: 8.0
Hardware: PC
OS: All
Status: NEW
Severity: normal
Priority: P
Component: new bugs
Assignee: unassignedbugs at nondot.org
Reporter: dimitry at andric.com
CC: htmldeveloper at gmail.com, llvm-bugs at lists.llvm.org
As reported in https://bugs.freebsd.org/237515 and
https://github.com/michaelrsweet/htmldoc/issues/349, the HTMLDOC program
compiled with clang 8.0 hangs (and eventually causes a stack overflow)
when processing a PDF.
Bisection shows this is a regression caused by
https://reviews.llvm.org/rL345814 ("[IndVars] Smart hard uses
detection").
I attempted to minimize the test case as much as possible; the following
is a small self-contained program showing the issue:
========================================================================
#include <stdio.h>
__attribute__((__noinline__)) void parse_pre(const char *dataptr) {
int col;
char line[1024];
char *lineptr;
for (col = 0, lineptr = line; *dataptr != '\0'; dataptr++) {
printf("before inner loop: col=%d, diff=%td\n", col, lineptr - line);
do {
printf("inside inner loop: col=%d, diff=%td\n", col, lineptr - line);
*lineptr++ = ' ';
col++;
} while (col & 7);
}
}
int main(void) {
parse_pre("a");
return 0;
}
========================================================================
What appears to happen is that IndVars pulls the (col & 7) test out of
the inner loop, but it precalculates the iteration count incorrectly,
causing that inner loop to never exit. It will keep on overwriting the
line[] buffer until it crashes.
With clang trunk r345813, the inner loop looks like:
.LBB0_3: # %do.body
# Parent Loop BB0_2 Depth=1
# => This Inner Loop Header: Depth=2
#DEBUG_VALUE: parse_pre:lineptr <- [DW_OP_constu 48, DW_OP_minus]
[$rbp+0]
#DEBUG_VALUE: parse_pre:dataptr <- [DW_OP_constu 56, DW_OP_minus]
[$rbp+0]
#DEBUG_VALUE: parse_pre:col <- $r15d
#DEBUG_VALUE: parse_pre:col <- $ebx
#DEBUG_VALUE: parse_pre:lineptr <- $r13
.loc 1 11 68 is_stmt 1 # ps-pdf-min.c:11:68
movq %r13, %rdx
subq %r12, %rdx
.loc 1 11 7 is_stmt 0 # ps-pdf-min.c:11:7
movl $.L.str.1, %edi
xorl %eax, %eax
movl %ebx, %esi
callq printf
.loc 1 12 18 is_stmt 1 # ps-pdf-min.c:12:18
movb $32, (%r13)
.loc 1 12 15 is_stmt 0 # ps-pdf-min.c:12:15
addq $1, %r13
.Ltmp9:
.loc 1 13 10 is_stmt 1 # ps-pdf-min.c:13:10
addl $1, %ebx
.Ltmp10:
#DEBUG_VALUE: parse_pre:col <- $ebx
.loc 1 14 5 # ps-pdf-min.c:14:5
testb $7, %bl
jne .LBB0_3
E.g., %ebx contains 'col', is increased by 'addl $1, %ebx', and is then
tested with 'testb $7, %bl'. This works correctly.
With clang trunk r345814, the inner loop becomes:
.loc 1 10 5 is_stmt 1 # ps-pdf-min.c:10:5
movl %r12d, %r13d
negl %r13d
andl $7, %r13d
leaq (%rbx,%r13), %rax
.Ltmp6:
#DEBUG_VALUE: parse_pre:lineptr <- [DW_OP_constu 48, DW_OP_minus]
[$rbp+0]
.loc 1 0 5 is_stmt 0 # ps-pdf-min.c:0:5
movq %rax, -48(%rbp) # 8-byte Spill
.Ltmp7:
.p2align 4, 0x90
.LBB0_3: # %do.body
# Parent Loop BB0_2 Depth=1
# => This Inner Loop Header: Depth=2
#DEBUG_VALUE: parse_pre:lineptr <- [DW_OP_constu 48, DW_OP_minus]
[$rbp+0]
#DEBUG_VALUE: parse_pre:col <- $r12d
#DEBUG_VALUE: parse_pre:dataptr <- $r14
#DEBUG_VALUE: parse_pre:col <- $r12d
#DEBUG_VALUE: parse_pre:lineptr <- $rbx
.loc 1 11 68 is_stmt 1 # ps-pdf-min.c:11:68
movq %rbx, %rdx
subq %r15, %rdx
.loc 1 11 7 is_stmt 0 # ps-pdf-min.c:11:7
movl $.L.str.1, %edi
xorl %eax, %eax
movl %r12d, %esi
callq printf
.loc 1 12 18 is_stmt 1 # ps-pdf-min.c:12:18
movb $32, (%rbx)
.loc 1 12 15 is_stmt 0 # ps-pdf-min.c:12:15
addq $1, %rbx
.Ltmp8:
.loc 1 13 10 is_stmt 1 # ps-pdf-min.c:13:10
addl $1, %r12d
.Ltmp9:
#DEBUG_VALUE: parse_pre:col <- $r12d
.loc 1 14 5 # ps-pdf-min.c:14:5
addq $-1, %r13
jne .LBB0_3
Here, %r12d contains 'col', which is first stored in %r13d, negated,
then anded with $7. Unfortunately, on the first loop, 'col' is zero, so
negation doesn't do anything, and neither does 'andl $7'. So at the end
of the loop, %r13 is decremented to -1, and the loop effectively
executes 2^64 times... :-/
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190523/27f0d04d/attachment.html>
More information about the llvm-bugs
mailing list