; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -disable-output -print-mustexecute %s 2>&1 | FileCheck %s define i1 @header_with_icf(i32* noalias %p, i32 %high) { ; CHECK-LABEL: @header_with_icf( ; CHECK-LABEL: loop: ; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] ; (mustexec in: loop) ; CHECK: %v = load i32, i32* %p ; (mustexec in: loop) ; CHECK: call void @maythrow_and_use(i32 %v) ; (mustexec in: loop) ; CHECK-NOT: mustexec entry: br label %loop loop: %iv = phi i32 [0, %entry], [%iv.next, %loop] %v = load i32, i32* %p call void @maythrow_and_use(i32 %v) %iv.next = add nsw nuw i32 %iv, 1 %exit.test = icmp slt i32 %iv, %high br i1 %exit.test, label %exit, label %loop exit: ret i1 false } define i1 @split_header(i32* noalias %p, i32 %high) { ; CHECK-LABEL: @split_header( ; CHECK-LABEL: loop: ; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.next, %next ] ; (mustexec in: loop) ; CHECK: %v = load i32, i32* %p ; (mustexec in: loop) ; CHECK: br label %next ; (mustexec in: loop) ; CHECK-NOT: mustexec entry: br label %loop loop: %iv = phi i32 [0, %entry], [%iv.next, %next] %v = load i32, i32* %p br label %next next: call void @maythrow_and_use(i32 %v) %iv.next = add nsw nuw i32 %iv, 1 %exit.test = icmp slt i32 %iv, %high br i1 %exit.test, label %exit, label %loop exit: ret i1 false } ; FIXME: everything in inner loop header should be must execute ; for outer as well define i1 @nested(i32* noalias %p, i32 %high) { ; CHECK-LABEL: @nested ; CHECK-LABEL: loop: ; preds = %next ; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.next, %next ] ; (mustexec in: loop) ; CHECK: br label %inner_loop ; (mustexec in: loop) ; CHECK-LABEL: inner_loop: ; CHECK: %v = load i32, i32* %p ; (mustexec in: inner_loop) ; CHECK: %inner.test = icmp eq i32 %v, 0 ; (mustexec in: inner_loop) ; CHECK: br i1 %inner.test, label %inner_loop, label %next ; (mustexec in: inner_loop) ; CHECK-NOT: mustexec entry: br label %loop loop: %iv = phi i32 [0, %entry], [%iv.next, %next] br label %inner_loop inner_loop: %v = load i32, i32* %p %inner.test = icmp eq i32 %v, 0 br i1 %inner.test, label %inner_loop, label %next next: call void @maythrow_and_use(i32 %v) %iv.next = add nsw nuw i32 %iv, 1 %exit.test = icmp slt i32 %iv, %high br i1 %exit.test, label %exit, label %loop exit: ret i1 false } ; FIXME: everything in inner loop header should be must execute ; for outer as well define i1 @nested_no_throw(i32* noalias %p, i32 %high) { ; CHECK-LABEL: @nested_no_throw ; CHECK-LABEL: loop: ; preds = %next ; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.next, %next ] ; (mustexec in: loop) ; CHECK: br label %inner_loop ; (mustexec in: loop) ; CHECK-LABEL: inner_loop: ; CHECK: %v = load i32, i32* %p ; (mustexec in: inner_loop) ; CHECK: %inner.test = icmp eq i32 %v, 0 ; (mustexec in: inner_loop) ; CHECK: br i1 %inner.test, label %inner_loop, label %next ; (mustexec in: inner_loop) ; CHECK-LABEL: next: ; CHECK: %iv.next = add nuw nsw i32 %iv, 1 ; (mustexec in: loop) ; CHECK: %exit.test = icmp slt i32 %iv, %high ; (mustexec in: loop) ; CHECK: br i1 %exit.test, label %exit, label %loop ; (mustexec in: loop) entry: br label %loop loop: %iv = phi i32 [0, %entry], [%iv.next, %next] br label %inner_loop inner_loop: %v = load i32, i32* %p %inner.test = icmp eq i32 %v, 0 br i1 %inner.test, label %inner_loop, label %next next: %iv.next = add nsw nuw i32 %iv, 1 %exit.test = icmp slt i32 %iv, %high br i1 %exit.test, label %exit, label %loop exit: ret i1 false } ; Since all the instructions in the loop dominate the only exit ; and there's no implicit control flow in the loop, all must execute ; FIXME: handled by loop safety info, test it define i1 @nothrow_loop(i32* noalias %p, i32 %high) { ; CHECK-LABEL: @nothrow_loop( ; CHECK-LABEL: loop: ; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.next, %next ] ; (mustexec in: loop) ; CHECK: br label %next ; (mustexec in: loop) ; CHECK-LABEL: next: ; CHECK: %v = load i32, i32* %p ; (mustexec in: loop) ; CHECK: %iv.next = add nuw nsw i32 %iv, 1 ; (mustexec in: loop) ; CHECK: %exit.test = icmp slt i32 %iv, %high ; (mustexec in: loop) ; CHECK: br i1 %exit.test, label %exit, label %loop ; (mustexec in: loop) ; CHECK-NOT: mustexec entry: br label %loop loop: %iv = phi i32 [0, %entry], [%iv.next, %next] br label %next next: %v = load i32, i32* %p %iv.next = add nsw nuw i32 %iv, 1 %exit.test = icmp slt i32 %iv, %high br i1 %exit.test, label %exit, label %loop exit: ret i1 false } declare void @maythrow_and_use(i32)