143 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 52; RUN: opt -p loop-vectorize -force-vector-width=1 -force-vector-interleave=2 -S %s | FileCheck %s3 4 5; FIXME: currently the live-outs are not handled correctly.6; Test for https://github.com/llvm/llvm-project/issues/154967.7define i8 @iv_used_in_exit_with_math(i8 noundef %g) {8; CHECK-LABEL: define i8 @iv_used_in_exit_with_math(9; CHECK-SAME: i8 noundef [[G:%.*]]) {10; CHECK-NEXT: [[ENTRY:.*:]]11; CHECK-NEXT: br label %[[VECTOR_PH:.*]]12; CHECK: [[VECTOR_PH]]:13; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]14; CHECK: [[VECTOR_BODY]]:15; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]16; CHECK-NEXT: [[OFFSET_IDX:%.*]] = trunc i32 [[INDEX]] to i817; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[OFFSET_IDX]], 118; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i8 1, [[OFFSET_IDX]]19; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i8 1, [[TMP0]]20; CHECK-NEXT: [[TMP3:%.*]] = and i8 [[TMP1]], [[G]]21; CHECK-NEXT: [[TMP4:%.*]] = and i8 [[TMP2]], [[G]]22; CHECK-NEXT: [[TMP7:%.*]] = icmp ne i8 [[TMP3]], 023; CHECK-NEXT: [[TMP8:%.*]] = icmp ne i8 [[TMP4]], 024; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 225; CHECK-NEXT: [[TMP12:%.*]] = freeze i1 [[TMP7]]26; CHECK-NEXT: [[TMP13:%.*]] = freeze i1 [[TMP8]]27; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP12]], [[TMP13]]28; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i32 [[INDEX_NEXT]], 429; CHECK-NEXT: [[TMP11:%.*]] = or i1 [[TMP9]], [[TMP10]]30; CHECK-NEXT: br i1 [[TMP11]], label %[[MIDDLE_SPLIT:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]31; CHECK: [[MIDDLE_SPLIT]]:32; CHECK-NEXT: br i1 [[TMP9]], label %[[VECTOR_EARLY_EXIT:.*]], label %[[MIDDLE_BLOCK:.*]]33; CHECK: [[MIDDLE_BLOCK]]:34; CHECK-NEXT: br label %[[RETURN:.*]]35; CHECK: [[VECTOR_EARLY_EXIT]]:36; CHECK-NEXT: [[TMP32:%.*]] = icmp eq i1 [[TMP8]], false37; CHECK-NEXT: [[TMP33:%.*]] = zext i1 [[TMP32]] to i6438; CHECK-NEXT: [[TMP34:%.*]] = add i64 1, [[TMP33]]39; CHECK-NEXT: [[TMP35:%.*]] = icmp eq i1 [[TMP7]], false40; CHECK-NEXT: [[TMP14:%.*]] = zext i1 [[TMP35]] to i6441; CHECK-NEXT: [[TMP15:%.*]] = add i64 0, [[TMP14]]42; CHECK-NEXT: [[TMP16:%.*]] = icmp ne i64 [[TMP14]], 143; CHECK-NEXT: [[TMP17:%.*]] = select i1 [[TMP16]], i64 [[TMP15]], i64 [[TMP34]]44; CHECK-NEXT: [[TMP18:%.*]] = trunc i64 [[TMP17]] to i3245; CHECK-NEXT: [[TMP19:%.*]] = add i32 [[INDEX]], [[TMP18]]46; CHECK-NEXT: [[TMP20:%.*]] = trunc i32 [[TMP19]] to i847; CHECK-NEXT: [[TMP23:%.*]] = trunc i32 [[TMP19]] to i848; CHECK-NEXT: br label %[[RETURN]]49; CHECK: [[RETURN]]:50; CHECK-NEXT: [[RES_IV1:%.*]] = phi i8 [ 32, %[[MIDDLE_BLOCK]] ], [ [[TMP20]], %[[VECTOR_EARLY_EXIT]] ]51; CHECK-NEXT: [[RES_IV2:%.*]] = phi i8 [ 0, %[[MIDDLE_BLOCK]] ], [ [[TMP23]], %[[VECTOR_EARLY_EXIT]] ]52; CHECK-NEXT: [[RES:%.*]] = add i8 [[RES_IV1]], [[RES_IV2]]53; CHECK-NEXT: ret i8 [[RES]]54;55entry:56 br label %loop.header57 58loop.header:59 %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop.latch ]60 %s = shl nuw i8 1, %iv61 %a = and i8 %s, %g62 %c = icmp eq i8 %a, 063 br i1 %c, label %loop.latch, label %return64 65loop.latch:66 %iv.next = add nuw nsw i8 %iv, 167 %ec = icmp eq i8 %iv.next, 468 br i1 %ec, label %return, label %loop.header69 70return:71 %res.iv1 = phi i8 [ 32, %loop.latch ], [ %iv, %loop.header ]72 %res.iv2 = phi i8 [ 0, %loop.latch ], [ %iv, %loop.header ]73 %res = add i8 %res.iv1, %res.iv274 ret i8 %res75}76 77define i32 @iv_used_in_exit_with_loads(ptr align 4 dereferenceable(128) %src) {78; CHECK-LABEL: define i32 @iv_used_in_exit_with_loads(79; CHECK-SAME: ptr align 4 dereferenceable(128) [[SRC:%.*]]) {80; CHECK-NEXT: [[ENTRY:.*:]]81; CHECK-NEXT: br label %[[VECTOR_PH:.*]]82; CHECK: [[VECTOR_PH]]:83; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]84; CHECK: [[VECTOR_BODY]]:85; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]86; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[INDEX]], 187; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i32 [[INDEX]]88; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i32 [[TMP0]]89; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP1]], align 490; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP2]], align 491; CHECK-NEXT: [[TMP7:%.*]] = icmp ne i32 [[TMP3]], 092; CHECK-NEXT: [[TMP8:%.*]] = icmp ne i32 [[TMP4]], 093; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 294; CHECK-NEXT: [[TMP12:%.*]] = freeze i1 [[TMP7]]95; CHECK-NEXT: [[TMP13:%.*]] = freeze i1 [[TMP8]]96; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP12]], [[TMP13]]97; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i32 [[INDEX_NEXT]], 3298; CHECK-NEXT: [[TMP11:%.*]] = or i1 [[TMP9]], [[TMP10]]99; CHECK-NEXT: br i1 [[TMP11]], label %[[MIDDLE_SPLIT:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]100; CHECK: [[MIDDLE_SPLIT]]:101; CHECK-NEXT: br i1 [[TMP9]], label %[[VECTOR_EARLY_EXIT:.*]], label %[[MIDDLE_BLOCK:.*]]102; CHECK: [[MIDDLE_BLOCK]]:103; CHECK-NEXT: br label %[[RETURN:.*]]104; CHECK: [[VECTOR_EARLY_EXIT]]:105; CHECK-NEXT: [[TMP20:%.*]] = icmp eq i1 [[TMP8]], false106; CHECK-NEXT: [[TMP21:%.*]] = zext i1 [[TMP20]] to i64107; CHECK-NEXT: [[TMP22:%.*]] = add i64 1, [[TMP21]]108; CHECK-NEXT: [[TMP23:%.*]] = icmp eq i1 [[TMP7]], false109; CHECK-NEXT: [[TMP24:%.*]] = zext i1 [[TMP23]] to i64110; CHECK-NEXT: [[TMP25:%.*]] = add i64 0, [[TMP24]]111; CHECK-NEXT: [[TMP26:%.*]] = icmp ne i64 [[TMP24]], 1112; CHECK-NEXT: [[TMP27:%.*]] = select i1 [[TMP26]], i64 [[TMP25]], i64 [[TMP22]]113; CHECK-NEXT: [[TMP28:%.*]] = trunc i64 [[TMP27]] to i32114; CHECK-NEXT: [[TMP29:%.*]] = add i32 [[INDEX]], [[TMP28]]115; CHECK-NEXT: br label %[[RETURN]]116; CHECK: [[RETURN]]:117; CHECK-NEXT: [[RES_IV1:%.*]] = phi i32 [ 32, %[[MIDDLE_BLOCK]] ], [ [[TMP29]], %[[VECTOR_EARLY_EXIT]] ]118; CHECK-NEXT: [[RES_IV2:%.*]] = phi i32 [ 0, %[[MIDDLE_BLOCK]] ], [ [[TMP29]], %[[VECTOR_EARLY_EXIT]] ]119; CHECK-NEXT: [[RES:%.*]] = add i32 [[RES_IV1]], [[RES_IV2]]120; CHECK-NEXT: ret i32 [[RES]]121;122entry:123 br label %loop.header124 125loop.header:126 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]127 %gep = getelementptr inbounds i32, ptr %src, i32 %iv128 %l = load i32, ptr %gep129 %c = icmp eq i32 %l, 0130 br i1 %c, label %loop.latch, label %return131 132loop.latch:133 %iv.next = add nuw nsw i32 %iv, 1134 %ec = icmp eq i32 %iv.next, 32135 br i1 %ec, label %return, label %loop.header136 137return:138 %res.iv1 = phi i32 [ 32, %loop.latch ], [ %iv, %loop.header ]139 %res.iv2 = phi i32 [ 0, %loop.latch ], [ %iv, %loop.header ]140 %res = add i32 %res.iv1, %res.iv2141 ret i32 %res142}143