1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt -S < %s -p loop-vectorize -enable-early-exit-vectorization | FileCheck %s 3 4declare void @init_mem(ptr, i64); 5 6define i64 @one_uncountable_two_countable_same_exit_phi_of_consts() { 7; CHECK-LABEL: define i64 @one_uncountable_two_countable_same_exit_phi_of_consts() { 8; CHECK-NEXT: entry: 9; CHECK-NEXT: [[P1:%.*]] = alloca [1024 x i8], align 1 10; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1 11; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) 12; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) 13; CHECK-NEXT: br label [[LOOP:%.*]] 14; CHECK: loop: 15; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] 16; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i64 [[INDEX]], 64 17; CHECK-NEXT: br i1 [[CMP1]], label [[SEARCH:%.*]], label [[LOOP_END:%.*]] 18; CHECK: search: 19; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] 20; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 21; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] 22; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 23; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] 24; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_END]], label [[LOOP_INC]] 25; CHECK: loop.inc: 26; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 27; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 128 28; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] 29; CHECK: loop.end: 30; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ 0, [[LOOP]] ], [ 1, [[SEARCH]] ], [ 0, [[LOOP_INC]] ] 31; CHECK-NEXT: ret i64 [[RETVAL]] 32; 33entry: 34 %p1 = alloca [1024 x i8] 35 %p2 = alloca [1024 x i8] 36 call void @init_mem(ptr %p1, i64 1024) 37 call void @init_mem(ptr %p2, i64 1024) 38 br label %loop 39 40loop: 41 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ] 42 %cmp1 = icmp ne i64 %index, 64 43 br i1 %cmp1, label %search, label %loop.end 44 45search: 46 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index 47 %ld1 = load i8, ptr %arrayidx, align 1 48 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index 49 %ld2 = load i8, ptr %arrayidx1, align 1 50 %cmp3 = icmp eq i8 %ld1, %ld2 51 br i1 %cmp3, label %loop.end, label %loop.inc 52 53loop.inc: 54 %index.next = add i64 %index, 1 55 %exitcond = icmp ne i64 %index.next, 128 56 br i1 %exitcond, label %loop, label %loop.end 57 58loop.end: 59 %retval = phi i64 [ 0, %loop ], [ 1, %search ], [ 0, %loop.inc ] 60 ret i64 %retval 61} 62 63 64define i64 @one_uncountable_two_countable_diff_exit_no_phis() { 65; CHECK-LABEL: define i64 @one_uncountable_two_countable_diff_exit_no_phis() { 66; CHECK-NEXT: entry: 67; CHECK-NEXT: [[P1:%.*]] = alloca [1024 x i8], align 1 68; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1 69; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024) 70; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024) 71; CHECK-NEXT: br label [[LOOP:%.*]] 72; CHECK: loop: 73; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ] 74; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i64 [[INDEX]], 64 75; CHECK-NEXT: br i1 [[CMP1]], label [[SEARCH:%.*]], label [[LOOP_END:%.*]] 76; CHECK: search: 77; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]] 78; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 79; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]] 80; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1 81; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]] 82; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_END_EARLY:%.*]], label [[LOOP_INC]] 83; CHECK: loop.inc: 84; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1 85; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 128 86; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]] 87; CHECK: loop.end.early: 88; CHECK-NEXT: ret i64 1 89; CHECK: loop.end: 90; CHECK-NEXT: ret i64 0 91; 92entry: 93 %p1 = alloca [1024 x i8] 94 %p2 = alloca [1024 x i8] 95 call void @init_mem(ptr %p1, i64 1024) 96 call void @init_mem(ptr %p2, i64 1024) 97 br label %loop 98 99loop: 100 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ] 101 %cmp1 = icmp ne i64 %index, 64 102 br i1 %cmp1, label %search, label %loop.end 103 104search: 105 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index 106 %ld1 = load i8, ptr %arrayidx, align 1 107 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index 108 %ld2 = load i8, ptr %arrayidx1, align 1 109 %cmp3 = icmp eq i8 %ld1, %ld2 110 br i1 %cmp3, label %loop.end.early, label %loop.inc 111 112loop.inc: 113 %index.next = add i64 %index, 1 114 %exitcond = icmp ne i64 %index.next, 128 115 br i1 %exitcond, label %loop, label %loop.end 116 117loop.end.early: 118 ret i64 1 119 120loop.end: 121 ret i64 0 122} 123