[llvm-bugs] [Bug 31928] New: After r280351: if/else blocks incorrectly optimized away?
via llvm-bugs
llvm-bugs at lists.llvm.org
Fri Feb 10 06:22:41 PST 2017
https://llvm.org/bugs/show_bug.cgi?id=31928
Bug ID: 31928
Summary: After r280351: if/else blocks incorrectly optimized
away?
Product: new-bugs
Version: 4.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: llvm-bugs at lists.llvm.org
Classification: Unclassified
Created attachment 17965
--> https://llvm.org/bugs/attachment.cgi?id=17965&action=edit
Test case reduces from gdtoa's ratio() function
>From https://bugs.freebsd.org/216770, where we had some trouble building the
Julia port, we found out that clang 4.0.0 seems to miscompile gdtoa's [1]
ratio() function in smisc.c [2], leading to incorrect strtrod(3) output.
What seems to be happening is that after r280351 ("[SimplifyCFG] Change the
algorithm in SinkThenElseCodeToEnd"), the if/else block is either entirely
optimized away, or only the else block is.
The function itself takes unions of doubles and unsigned, and a parameter 'k'
which determines the fork to take in the if/else statement. Simplified:
typedef union {
double d;
unsigned L[2];
} U;
double ratio(U da, U db, int k)
{
if (k > 0) {
da.L[1] += k * 0x100000;
} else {
k = -k;
db.L[1] += k * 0x100000;
}
return da.d / db.d;
}
Trunk r280350 with -O2, targeting x86_64, compiles this to:
ratio: # @ratio
.cfi_startproc
# BB#0: # %entry
testl %edx, %edx
jle .LBB0_2
# BB#1: # %if.then
shll $20, %edx
movq %rdi, %rax
shrq $32, %rax
addl %edx, %eax
shlq $32, %rax
movl %edi, %edi
orq %rax, %rdi
jmp .LBB0_3
.LBB0_2: # %if.else
shll $20, %edx
movq %rsi, %rax
shrq $32, %rax
subl %edx, %eax
shlq $32, %rax
movl %esi, %esi
orq %rax, %rsi
.LBB0_3: # %if.end
movd %rdi, %xmm0
movd %rsi, %xmm1
divsd %xmm1, %xmm0
retq
while r280351 and later compile this to just:
ratio: # @ratio
.cfi_startproc
# BB#0: # %entry
movd %rdi, %xmm0
movd %rsi, %xmm1
divsd %xmm1, %xmm0
retq
E.g., the whole if/else block is now gone. I do not think the C code exhibits
undefined behavior, so getting rid of the if/else block is incorrect.
When targeting 32-bit x86, the results are slightly different, because adding a
printf of either the da or db parameter's d member changes the result. Without
the printf, the end result is correct, with the printf, the result is
incorrect. Also, printing the unsigned member of the union makes the result
correct again. Test case:
#include <stdio.h>
typedef union {
double d;
unsigned L[2];
} U;
double ratio(U da, U db, int k)
{
printf("%f\n", da.d);
if (k > 0) {
da.L[1] += k * 0x100000;
} else {
k = -k;
db.L[1] += k * 0x100000;
}
return da.d / db.d;
}
Trunk r280350 using -m32 -O2 gives:
ratio: # @ratio
# BB#0: # %entry
pushl %edi
pushl %esi
subl $36, %esp
movsd 48(%esp), %xmm0 # xmm0 = mem[0],zero
movl 64(%esp), %edi
leal 56(%esp), %esi
movsd %xmm0, 4(%esp)
movsd %xmm0, 16(%esp) # 8-byte Spill
movl $.L.str, (%esp)
calll printf
testl %edi, %edi
jle .LBB0_2
# BB#1: # %if.then
leal 48(%esp), %eax
shll $20, %edi
addl %edi, 4(%eax)
movsd (%eax), %xmm0 # xmm0 = mem[0],zero
jmp .LBB0_3
.LBB0_2: # %if.else
shll $20, %edi
movsd 16(%esp), %xmm0 # 8-byte Reload
# xmm0 = mem[0],zero
subl %edi, 4(%esi)
.LBB0_3: # %if.end
divsd (%esi), %xmm0
movsd %xmm0, 24(%esp)
fldl 24(%esp)
addl $36, %esp
popl %esi
popl %edi
retl
Trunk r280351 using -m32 -O2 gives:
ratio: # @ratio
# BB#0: # %entry
pushl %edi
pushl %esi
subl $36, %esp
movl 64(%esp), %esi
movsd 48(%esp), %xmm0 # xmm0 = mem[0],zero
movl %esi, %edi
movsd %xmm0, 4(%esp)
movsd %xmm0, 16(%esp) # 8-byte Spill
movl $.L.str, (%esp)
negl %edi
cmovll %esi, %edi
calll printf
testl %esi, %esi
leal 48(%esp), %eax
leal 56(%esp), %ecx
movsd 16(%esp), %xmm0 # 8-byte Reload
# xmm0 = mem[0],zero
cmovgl %eax, %ecx
shll $20, %edi
orl $4, %ecx
addl %edi, (%ecx)
divsd 56(%esp), %xmm0
movsd %xmm0, 24(%esp)
fldl 24(%esp)
addl $36, %esp
popl %esi
popl %edi
retl
Again, the if/else block seems to have been optimized away.
[1] http://www.netlib.org/fp/
[2] https://github.com/jwiegley/gdtoa/blob/master/smisc.c#L72
--
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/20170210/c64bbcc9/attachment-0001.html>
More information about the llvm-bugs
mailing list