// is a common case, and can save some work, check it now.
if (Inst.getParent() == CurLoop->getHeader())
// If there's a throw in the header block, we can't guarantee we'll reach
- // Inst.
- return !SafetyInfo->HeaderMayThrow;
+ // Inst unless we can prove that Inst comes before the potential implicit
+ // exit. At the moment, we use a (cheap) hack for the common case where
+ // the instruction of interest is the first one in the block.
+ return !SafetyInfo->HeaderMayThrow ||
+ Inst.getParent()->getFirstNonPHI() == &Inst;
// Somewhere in this loop there is an instruction which may throw and make us
// exit the loop.
declare void @use_nothrow(i64 %a) nounwind
declare void @use(i64 %a)
+declare void @maythrow()
define void @nothrow(i64 %x, i64 %y, i1* %cond) {
; CHECK-LABEL: nothrow
call void @use_nothrow(i64 %div)
br label %loop
}
+
+; The udiv is guarantee to execute if the loop is
+define void @throw_header_after(i64 %x, i64 %y, i1* %cond) {
+; CHECK-LABEL: throw_header_after
+; CHECK: %div = udiv i64 %x, %y
+; CHECK-LABEL: loop
+; CHECK: call void @use(i64 %div)
+entry:
+ br label %loop
+
+loop: ; preds = %entry, %for.inc
+ %div = udiv i64 %x, %y
+ call void @use(i64 %div)
+ br label %loop
+}
+define void @throw_header_after_rec(i64* %xp, i64* %yp, i1* %cond) {
+; CHECK-LABEL: throw_header_after_rec
+; CHECK: %x = load i64, i64* %xp
+; CHECK: %y = load i64, i64* %yp
+; CHECK: %div = udiv i64 %x, %y
+; CHECK-LABEL: loop
+; CHECK: call void @use(i64 %div)
+entry:
+ br label %loop
+
+loop: ; preds = %entry, %for.inc
+ %x = load i64, i64* %xp
+ %y = load i64, i64* %yp
+ %div = udiv i64 %x, %y
+ call void @use(i64 %div) readonly
+ br label %loop
+}
+
+
+
; Negative test
-define void @throw_header(i64 %x, i64 %y, i1* %cond) {
-; CHECK-LABEL: throw_header
+define void @throw_header_before(i64 %x, i64 %y, i1* %cond) {
+; CHECK-LABEL: throw_header_before
; CHECK-LABEL: loop
; CHECK: %div = udiv i64 %x, %y
; CHECK: call void @use(i64 %div)
br label %loop
loop: ; preds = %entry, %for.inc
+ call void @maythrow()
%div = udiv i64 %x, %y
call void @use(i64 %div)
br label %loop
; CHECK-LABEL: entry
; CHECK: %div = udiv i64 %x, %y
; CHECK-LABEL: loop
-; CHECK: call void @use(i64 %div)
+ ; CHECK: call void @use(i64 %div)
entry:
br label %loop
loop: ; preds = %entry, %for.inc