1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: -p 2; RUN: opt < %s -passes=indvars -S | FileCheck %s 3target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 4 5declare i1 @foo(ptr, ptr) 6declare i1 @bar() 7declare i1 @baz() 8 9define i1 @kill_backedge_and_phis(ptr align 1 %lhs, ptr align 1 %rhs, i32 %len) { 10; CHECK-LABEL: @kill_backedge_and_phis( 11; CHECK-NEXT: entry: 12; CHECK-NEXT: %length_not_zero = icmp ne i32 %len, 0 13; CHECK-NEXT: br i1 %length_not_zero, label %loop_preheader, label %exit 14; CHECK: loop_preheader: 15; CHECK-NEXT: br label %loop 16; CHECK: loop: 17; CHECK-NEXT: %result = call i1 @foo(ptr %lhs, ptr %rhs) 18; CHECK-NEXT: br i1 %result, label %exiting_1, label %exit.loopexit 19; CHECK: exiting_1: 20; CHECK-NEXT: br i1 false, label %exiting_2, label %exit.loopexit 21; CHECK: exiting_2: 22; CHECK-NEXT: %bar_ret = call i1 @bar() 23; CHECK-NEXT: br i1 %bar_ret, label %exit.loopexit, label %exiting_3 24; CHECK: exiting_3: 25; CHECK-NEXT: %baz_ret = call i1 @baz() 26; CHECK-NEXT: %or.cond = select i1 %baz_ret, i1 true, i1 false 27; CHECK-NEXT: br i1 %or.cond, label %loop, label %exit.loopexit 28; CHECK: exit.loopexit: 29; CHECK-NEXT: %val.ph = phi i1 [ %baz_ret, %exiting_3 ], [ %bar_ret, %exiting_2 ], [ false, %exiting_1 ], [ %result, %loop ] 30; CHECK-NEXT: br label %exit 31; CHECK: exit: 32; CHECK-NEXT: %val = phi i1 [ false, %entry ], [ %val.ph, %exit.loopexit ] 33; CHECK-NEXT: ret i1 %val 34; 35entry: 36 %length_not_zero = icmp ne i32 %len, 0 37 br i1 %length_not_zero, label %loop_preheader, label %exit 38 39loop_preheader: 40 br label %loop 41 42loop: 43 %iv = phi i32 [ 0, %loop_preheader ], [ %iv.next, %latch ] 44 %iv.wide = phi i64 [ 0, %loop_preheader ], [ %iv.wide.next, %latch ] 45 %iv.next = add i32 %iv, 1 46 %iv.wide.next = add i64 %iv.wide, 1 47 %left_ptr = getelementptr inbounds i8, ptr %lhs, i32 %iv 48 %right_ptr = getelementptr inbounds i8, ptr %rhs, i32 %iv 49 %result = call i1 @foo(ptr %left_ptr, ptr %right_ptr) 50 br i1 %result, label %exiting_1, label %exit 51 52exiting_1: 53 %iv.wide.is_not_zero = icmp ne i64 %iv.wide, 0 54 br i1 %iv.wide.is_not_zero, label %exiting_2, label %exit 55 56exiting_2: 57 %bar_ret = call i1 @bar() 58 br i1 %bar_ret, label %exit, label %exiting_3 59 60exiting_3: 61 %baz_ret = call i1 @baz() 62 br i1 %baz_ret, label %latch, label %exit 63 64latch: 65 %continue = icmp ne i32 %iv.next, %len 66 br i1 %continue, label %loop, label %exit 67 68exit: 69 %val = phi i1 [ %result, %loop ], [ %iv.wide.is_not_zero, %exiting_1 ], 70 [ %bar_ret, %exiting_2 ], [ %baz_ret, %exiting_3 ], 71 [ %baz_ret, %latch ], [ 0, %entry ] 72 ret i1 %val 73} 74 75define i1 @siblings(ptr align 1 %lhs, ptr align 1 %rhs, i32 %len) { 76; CHECK-LABEL: @siblings( 77; CHECK-NEXT: entry: 78; CHECK-NEXT: %length_not_zero = icmp ne i32 %len, 0 79; CHECK-NEXT: br i1 %length_not_zero, label %weird_loop.preheader, label %exit 80; CHECK: weird_loop.preheader: 81; CHECK-NEXT: br label %weird_loop 82; CHECK: weird_loop: 83; CHECK-NEXT: %weird.iv = phi i32 [ %weird.iv.next, %weird_loop ], [ 0, %weird_loop.preheader ] 84; CHECK-NEXT: %weird.iv.next = add i32 %weird.iv, 1 85; CHECK-NEXT: %weird.cond = call i1 @bar() 86; CHECK-NEXT: br i1 %weird.cond, label %weird_loop, label %loop.preheader 87; CHECK: loop.preheader: 88; CHECK-NEXT: %weird.iv.lcssa = phi i32 [ %weird.iv, %weird_loop ] 89; CHECK-NEXT: br label %loop 90; CHECK: loop: 91; CHECK-NEXT: %left_ptr = getelementptr inbounds i8, ptr %lhs, i32 %weird.iv.lcssa 92; CHECK-NEXT: %right_ptr = getelementptr inbounds i8, ptr %rhs, i32 %weird.iv.lcssa 93; CHECK-NEXT: %result = call i1 @foo(ptr %left_ptr, ptr %right_ptr) 94; CHECK-NEXT: br i1 %result, label %exiting_1, label %exit.loopexit 95; CHECK: exiting_1: 96; CHECK-NEXT: br i1 false, label %exiting_2, label %exit.loopexit 97; CHECK: exiting_2: 98; CHECK-NEXT: %bar_ret = call i1 @bar() 99; CHECK-NEXT: br i1 %bar_ret, label %exit.loopexit, label %exiting_3 100; CHECK: exiting_3: 101; CHECK-NEXT: %baz_ret = call i1 @baz() 102; CHECK-NEXT: %or.cond = select i1 %baz_ret, i1 true, i1 false 103; CHECK-NEXT: br i1 %or.cond, label %loop, label %exit.loopexit 104; CHECK: exit.loopexit: 105; CHECK-NEXT: %val.ph = phi i1 [ %baz_ret, %exiting_3 ], [ %bar_ret, %exiting_2 ], [ false, %exiting_1 ], [ %result, %loop ] 106; CHECK-NEXT: br label %exit 107; CHECK: exit: 108; CHECK-NEXT: %val = phi i1 [ false, %entry ], [ %val.ph, %exit.loopexit ] 109; CHECK-NEXT: ret i1 %val 110; 111entry: 112 %length_not_zero = icmp ne i32 %len, 0 113 br i1 %length_not_zero, label %weird_loop, label %exit 114 115weird_loop: 116 %weird.iv = phi i32 [ 0, %entry ], [ %weird.iv.next, %weird_loop ] 117 %weird.iv.next = add i32 %weird.iv, 1 118 %weird.iv.wide = zext i32 %weird.iv to i64 119 %weird.cond = call i1 @bar() 120 br i1 %weird.cond, label %weird_loop, label %loop 121 122loop: 123 %iv = phi i32 [ %weird.iv, %weird_loop ], [ %iv.next, %latch ] 124 %iv.wide = phi i64 [ %weird.iv.wide, %weird_loop ], [ %iv.wide.next, %latch ] 125 %iv.next = add i32 %iv, 1 126 %iv.wide.next = add i64 %iv.wide, 1 127 %left_ptr = getelementptr inbounds i8, ptr %lhs, i32 %iv 128 %right_ptr = getelementptr inbounds i8, ptr %rhs, i32 %iv 129 %result = call i1 @foo(ptr %left_ptr, ptr %right_ptr) 130 br i1 %result, label %exiting_1, label %exit 131 132exiting_1: 133 %iv.wide.is_not_zero = icmp ne i64 %iv.wide, %weird.iv.wide 134 br i1 %iv.wide.is_not_zero, label %exiting_2, label %exit 135 136exiting_2: 137 %bar_ret = call i1 @bar() 138 br i1 %bar_ret, label %exit, label %exiting_3 139 140exiting_3: 141 %baz_ret = call i1 @baz() 142 br i1 %baz_ret, label %latch, label %exit 143 144latch: 145 %continue = icmp ne i32 %iv.next, %len 146 br i1 %continue, label %loop, label %exit 147 148exit: 149 %val = phi i1 [ %result, %loop ], [ %iv.wide.is_not_zero, %exiting_1 ], 150 [ %bar_ret, %exiting_2 ], [ %baz_ret, %exiting_3 ], 151 [ %baz_ret, %latch ], [ 0, %entry ] 152 ret i1 %val 153} 154