blob: 2338e5bfe33108ff2e07b6b4ac192084ee4994de [file] [edit]
; RUN: opt %s -pnacl-sjlj-eh -O2 -S | FileCheck %s
; datalayout must be specified for GVN to work.
target datalayout = "p:32:32:32"
; This must be declared for expanding "invoke" and "landingpad" instructions.
@__pnacl_eh_stack = external thread_local global i8*
declare i1 @might_be_setjmp()
declare void @external_func(i32* %ptr)
declare void @var_is_nonzero()
; Test for a bug in which PNaClSjLjEH would transform
; @invoke_optimize_test() such that the call to @var_is_nonzero()
; could get optimized away by a later optimization pass. This
; happened because PNaClSjLjEH generated code similar to
; @branch_optimize_test() below.
define void @invoke_optimize_test() {
%var = alloca i32
store i32 0, i32* %var
invoke void @external_func(i32* %var)
to label %exit unwind label %lpad
lpad:
landingpad i32 personality i8* null
catch i8* null
%value = load i32, i32* %var
%is_zero = icmp eq i32 %value, 0
br i1 %is_zero, label %exit, label %do_call
do_call:
call void @var_is_nonzero()
ret void
exit:
ret void
}
; CHECK: define void @invoke_optimize_test()
; CHECK: @var_is_nonzero()
; In @branch_optimize_test(), the optimizer can optimize away the call
; to @var_is_nonzero(), because it can assume that %var always
; contains 0 on the "iffalse" branch.
;
; The passes "-gvn -instcombine" are enough to do this.
;
; The optimizer can do this regardless of whether @might_be_setjmp()
; is setjmp() or a normal function. It doesn't need to know that
; @might_be_setjmp() might return twice, because storing to %var
; between setjmp() and longjmp() leaves %var pointing to an undefined
; value.
define void @branch_optimize_test() {
%var = alloca i32
store i32 0, i32* %var
%cond = call i1 @might_be_setjmp() returns_twice
br i1 %cond, label %iftrue, label %iffalse
iftrue:
call void @external_func(i32* %var)
ret void
iffalse:
%value = load i32, i32* %var
%is_zero = icmp eq i32 %value, 0
br i1 %is_zero, label %exit, label %do_call
do_call:
call void @var_is_nonzero()
ret void
exit:
ret void
}
; CHECK: define void @branch_optimize_test()
; CHECK-NOT: @var_is_nonzero