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 4define 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, align 4 ; (mustexec in: loop) 9; CHECK: call void @maythrow_and_use(i32 %v) ; (mustexec in: loop) 10; CHECK-NOT: mustexec 11 12entry: 13 br label %loop 14 15loop: 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 23exit: 24 ret i1 false 25} 26 27define 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, align 4 ; (mustexec in: loop) 32; CHECK: br label %next ; (mustexec in: loop) 33; CHECK-NOT: mustexec 34entry: 35 br label %loop 36 37loop: 38 %iv = phi i32 [0, %entry], [%iv.next, %next] 39 %v = load i32, i32* %p 40 br label %next 41next: 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 47exit: 48 ret i1 false 49} 50 51; FIXME: everything in inner loop header should be must execute 52; for outer as well 53define 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, align 4 ; (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 64entry: 65 br label %loop 66 67loop: 68 %iv = phi i32 [0, %entry], [%iv.next, %next] 69 br label %inner_loop 70 71inner_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 76next: 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 82exit: 83 ret i1 false 84} 85 86define i1 @nested_no_throw(i32* noalias %p, i32 %high) { 87; CHECK-LABEL: @nested_no_throw 88; CHECK-LABEL: loop: ; preds = %next 89; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.next, %next ] ; (mustexec in: loop) 90; CHECK: br label %inner_loop ; (mustexec in: loop) 91; CHECK-LABEL: inner_loop: 92; CHECK: %v = load i32, i32* %p, align 4 ; (mustexec in 2 loops: inner_loop, loop) 93; CHECK: %inner.test = icmp eq i32 %v, 0 ; (mustexec in 2 loops: inner_loop, loop) 94; CHECK: br i1 %inner.test, label %inner_loop, label %next ; (mustexec in 2 loops: inner_loop, loop) 95; CHECK-LABEL: next: 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 100entry: 101 br label %loop 102 103loop: 104 %iv = phi i32 [0, %entry], [%iv.next, %next] 105 br label %inner_loop 106 107inner_loop: 108 %v = load i32, i32* %p 109 %inner.test = icmp eq i32 %v, 0 110 br i1 %inner.test, label %inner_loop, label %next 111 112next: 113 %iv.next = add nsw nuw i32 %iv, 1 114 %exit.test = icmp slt i32 %iv, %high 115 br i1 %exit.test, label %exit, label %loop 116 117exit: 118 ret i1 false 119} 120 121; Since all the instructions in the loop dominate the only exit 122; and there's no implicit control flow in the loop, all must execute 123; FIXME: handled by loop safety info, test it 124define i1 @nothrow_loop(i32* noalias %p, i32 %high) { 125; CHECK-LABEL: @nothrow_loop( 126; CHECK-LABEL: loop: 127; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.next, %next ] ; (mustexec in: loop) 128; CHECK: br label %next ; (mustexec in: loop) 129; CHECK-LABEL: next: 130; CHECK: %v = load i32, i32* %p, align 4 ; (mustexec in: loop) 131; CHECK: %iv.next = add nuw nsw i32 %iv, 1 ; (mustexec in: loop) 132; CHECK: %exit.test = icmp slt i32 %iv, %high ; (mustexec in: loop) 133; CHECK: br i1 %exit.test, label %exit, label %loop ; (mustexec in: loop) 134; CHECK-NOT: mustexec 135 136entry: 137 br label %loop 138 139loop: 140 %iv = phi i32 [0, %entry], [%iv.next, %next] 141 br label %next 142next: 143 %v = load i32, i32* %p 144 %iv.next = add nsw nuw i32 %iv, 1 145 %exit.test = icmp slt i32 %iv, %high 146 br i1 %exit.test, label %exit, label %loop 147 148exit: 149 ret i1 false 150} 151 152 153declare void @maythrow_and_use(i32) 154