1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2 ; RUN: opt -disable-output -print-mustexecute %s 2>&1 | FileCheck %s 3 4 define i1 @header_with_icf(i32* noalias %p, i32 %high) { 5 ; CHECK-LABEL: @header_with_icf( 6 ; CHECK-LABEL: loop: 7 ; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] ; (mustexec in: loop) 8 ; CHECK: %v = load i32, i32* %p ; (mustexec in: loop) 9 ; CHECK: call void @maythrow_and_use(i32 %v) ; (mustexec in: loop) 10 ; CHECK-NOT: mustexec 11 12 entry: 13 br label %loop 14 15 loop: 16 %iv = phi i32 [0, %entry], [%iv.next, %loop] 17 %v = load i32, i32* %p 18 call void @maythrow_and_use(i32 %v) 19 %iv.next = add nsw nuw i32 %iv, 1 20 %exit.test = icmp slt i32 %iv, %high 21 br i1 %exit.test, label %exit, label %loop 22 23 exit: 24 ret i1 false 25 } 26 27 define i1 @split_header(i32* noalias %p, i32 %high) { 28 ; CHECK-LABEL: @split_header( 29 ; CHECK-LABEL: loop: 30 ; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.next, %next ] ; (mustexec in: loop) 31 ; CHECK: %v = load i32, i32* %p ; (mustexec in: loop) 32 ; CHECK: br label %next ; (mustexec in: loop) 33 ; CHECK-NOT: mustexec 34 entry: 35 br label %loop 36 37 loop: 38 %iv = phi i32 [0, %entry], [%iv.next, %next] 39 %v = load i32, i32* %p 40 br label %next 41 next: 42 call void @maythrow_and_use(i32 %v) 43 %iv.next = add nsw nuw i32 %iv, 1 44 %exit.test = icmp slt i32 %iv, %high 45 br i1 %exit.test, label %exit, label %loop 46 47 exit: 48 ret i1 false 49 } 50 51 ; FIXME: everything in inner loop header should be must execute 52 ; for outer as well 53 define i1 @nested(i32* noalias %p, i32 %high) { 54 ; CHECK-LABEL: @nested 55 ; CHECK-LABEL: loop: ; preds = %next 56 ; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.next, %next ] ; (mustexec in: loop) 57 ; CHECK: br label %inner_loop ; (mustexec in: loop) 58 ; CHECK-LABEL: inner_loop: 59 ; CHECK: %v = load i32, i32* %p ; (mustexec in: inner_loop) 60 ; CHECK: %inner.test = icmp eq i32 %v, 0 ; (mustexec in: inner_loop) 61 ; CHECK: br i1 %inner.test, label %inner_loop, label %next ; (mustexec in: inner_loop) 62 ; CHECK-NOT: mustexec 63 64 entry: 65 br label %loop 66 67 loop: 68 %iv = phi i32 [0, %entry], [%iv.next, %next] 69 br label %inner_loop 70 71 inner_loop: 72 %v = load i32, i32* %p 73 %inner.test = icmp eq i32 %v, 0 74 br i1 %inner.test, label %inner_loop, label %next 75 76 next: 77 call void @maythrow_and_use(i32 %v) 78 %iv.next = add nsw nuw i32 %iv, 1 79 %exit.test = icmp slt i32 %iv, %high 80 br i1 %exit.test, label %exit, label %loop 81 82 exit: 83 ret i1 false 84 } 85 86 ; Since all the instructions in the loop dominate the only exit 87 ; and there's no implicit control flow in the loop, all must execute 88 ; FIXME: handled by loop safety info, test it 89 define i1 @nothrow_loop(i32* noalias %p, i32 %high) { 90 ; CHECK-LABEL: @nothrow_loop( 91 ; CHECK-LABEL: loop: 92 ; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.next, %next ] ; (mustexec in: loop) 93 ; CHECK: br label %next ; (mustexec in: loop) 94 ; CHECK-LABEL: next: 95 ; CHECK: %v = load i32, i32* %p ; (mustexec in: loop) 96 ; CHECK: %iv.next = add nuw nsw i32 %iv, 1 ; (mustexec in: loop) 97 ; CHECK: %exit.test = icmp slt i32 %iv, %high ; (mustexec in: loop) 98 ; CHECK: br i1 %exit.test, label %exit, label %loop ; (mustexec in: loop) 99 ; CHECK-NOT: mustexec 100 101 entry: 102 br label %loop 103 104 loop: 105 %iv = phi i32 [0, %entry], [%iv.next, %next] 106 br label %next 107 next: 108 %v = load i32, i32* %p 109 %iv.next = add nsw nuw i32 %iv, 1 110 %exit.test = icmp slt i32 %iv, %high 111 br i1 %exit.test, label %exit, label %loop 112 113 exit: 114 ret i1 false 115 } 116 117 118 declare void @maythrow_and_use(i32) 119