You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Thanks for the test case. I can confirm that the bug is in gvn-hoist. It is unable to determine the availability on all paths because of an infinite loop (because of no path to the end of the function). I'm working on the fix.
Extended Description
Consider the following test case:
% cat bug.cc
class base
{
public:
base() {}
virtual ~base() {}
virtual void destroy() = 0;
virtual void destroy_deallocate() = 0;
};
class bar
{
public:
bar() : _f(0) {}
~bar()
{
if ((void *)_f == &_buf)
_f->destroy();
else if (_f)
_f->destroy_deallocate();
}
void* _buf;
base* _f;
};
extern "C" {
unsigned sleep (unsigned int __seconds);
}
extern void foo(bar x);
void baz()
{
bar x;
foo(x);
while (1) sleep(10);
}
% clang --target=x86_64-unknown-unknown -S -o - bug.cc -O2 -fno-exceptions -fno-rtti -mllvm -enable-gvn-hoist=false
.text
.file "bug.cc"
.globl _Z3bazv
.p2align 4, 0x90
.type _Z3bazv,@function
_Z3bazv: # @_Z3bazv
.cfi_startproc
BB#0: # %entry
.Lcfi0:
.cfi_def_cfa_offset 16
.Lcfi1:
.cfi_offset %rbp, -16
movq %rsp, %rbp
.Lcfi2:
.cfi_def_cfa_register %rbp
pushq %rbx
subq $24, %rsp
.Lcfi3:
.cfi_offset %rbx, -24
movq $0, -16(%rbp)
leaq -24(%rbp), %rbx
movq %rbx, %rdi
callq _Z3foo3bar
movq -16(%rbp), %rdi
cmpq %rbx, %rdi
je .LBB0_1
BB#2: # %if.else.i
BB#3: # %if.then4.i
.LBB0_1: # %if.then.i
movq (%rdi), %rax
callq *16(%rax)
.p2align 4, 0x90
.LBB0_4: # %while.cond
# =>This Inner Loop Header: Depth=1
movl $10, %edi
callq sleep
jmp .LBB0_4
.Lfunc_end0:
.size _Z3bazv, .Lfunc_end0-_Z3bazv
.cfi_endproc
versus:
% clang --target=x86_64-unknown-unknown -S -o - bug.cc -O2 -fno-exceptions -fno-rtti -mllvm -enable-gvn-hoist=true
.text
.file "bug.cc"
.globl _Z3bazv
.p2align 4, 0x90
.type _Z3bazv,@function
_Z3bazv: # @_Z3bazv
.cfi_startproc
BB#0: # %entry
.Lcfi0:
.cfi_def_cfa_offset 16
.Lcfi1:
.cfi_offset %rbp, -16
movq %rsp, %rbp
.Lcfi2:
.cfi_def_cfa_register %rbp
pushq %rbx
subq $24, %rsp
.Lcfi3:
.cfi_offset %rbx, -24
movq $0, -16(%rbp)
leaq -24(%rbp), %rbx
movq %rbx, %rdi
callq _Z3foo3bar
movq -16(%rbp), %rdi
cmpq %rbx, %rdi
movq (%rdi), %rax # CRASH
je .LBB0_1
BB#2: # %if.else.i
BB#3: # %if.then4.i
.LBB0_1: # %if.then.i
callq *16(%rax)
.p2align 4, 0x90
.LBB0_4: # %while.cond
# =>This Inner Loop Header: Depth=1
movl $10, %edi
callq sleep
jmp .LBB0_4
.Lfunc_end0:
.size _Z3bazv, .Lfunc_end0-_Z3bazv
.cfi_endproc
See the lines marked "NULL TEST", "LOAD", and "CRASH". GVN Hoist is lifting the load through %rdi in this example across the null test.
You can also see this in the IR, nothing x86 specific here.
The text was updated successfully, but these errors were encountered: