495 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 42; RUN: opt -S < %s -p loop-vectorize -force-vector-width=4 | FileCheck %s3 4declare void @init_mem(ptr, i64);5 6 7; The early exit (i.e. unknown exit-not-taken count) is the latch - we don't8; support this yet.9define i64 @early_exit_on_last_block() {10; CHECK-LABEL: define i64 @early_exit_on_last_block() {11; CHECK-NEXT: entry:12; CHECK-NEXT: [[P1:%.*]] = alloca [1024 x i8], align 113; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 114; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024)15; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024)16; CHECK-NEXT: br label [[LAND_RHS:%.*]]17; CHECK: loop:18; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[SEARCH:%.*]] ], [ 3, [[ENTRY:%.*]] ]19; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 120; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i64 [[INDEX_NEXT]], 6721; CHECK-NEXT: br i1 [[CMP1]], label [[SEARCH]], label [[FOR_END_LOOPEXIT:%.*]]22; CHECK: search:23; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]24; CHECK-NEXT: [[TMP41:%.*]] = load i8, ptr [[ARRAYIDX]], align 125; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]]26; CHECK-NEXT: [[TMP42:%.*]] = load i8, ptr [[ARRAYIDX1]], align 127; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[TMP41]], [[TMP42]]28; CHECK-NEXT: br i1 [[CMP3]], label [[FOR_END_LOOPEXIT]], label [[LAND_RHS]]29; CHECK: loop.end:30; CHECK-NEXT: [[START_0_LCSSA:%.*]] = phi i64 [ 64, [[LAND_RHS]] ], [ [[INDEX]], [[SEARCH]] ]31; CHECK-NEXT: ret i64 [[START_0_LCSSA]]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 %loop39 40loop:41 %index = phi i64 [ %index.next, %search ], [ 3, %entry ]42 %index.next = add i64 %index, 143 %exitcond = icmp ne i64 %index.next, 6744 br i1 %exitcond, label %search, label %loop.end45 46search:47 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index48 %ld1 = load i8, ptr %arrayidx, align 149 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index50 %ld2 = load i8, ptr %arrayidx1, align 151 %cmp3 = icmp eq i8 %ld1, %ld252 br i1 %cmp3, label %loop.end, label %loop53 54loop.end:55 %retval = phi i64 [ 64, %loop ], [ %index, %search ]56 ret i64 %retval57}58 59 60; We don't currently support multiple early exits.61define i64 @multiple_uncountable_exits() {62; CHECK-LABEL: define i64 @multiple_uncountable_exits() {63; CHECK-NEXT: entry:64; CHECK-NEXT: [[P1:%.*]] = alloca [1024 x i8], align 165; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 166; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024)67; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024)68; CHECK-NEXT: br label [[SEARCH1:%.*]]69; CHECK: search1:70; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]71; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]72; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 173; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]]74; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 175; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[LD1]], [[LD2]]76; CHECK-NEXT: br i1 [[CMP1]], label [[LOOP_END:%.*]], label [[SEARCH2:%.*]]77; CHECK: search2:78; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i8 [[LD1]], 3479; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP_END]], label [[LOOP_INC]]80; CHECK: loop.inc:81; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 182; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 6783; CHECK-NEXT: br i1 [[EXITCOND]], label [[SEARCH1]], label [[LOOP_END]]84; CHECK: loop.end:85; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[SEARCH1]] ], [ 100, [[SEARCH2]] ], [ 43, [[LOOP_INC]] ]86; CHECK-NEXT: ret i64 [[RETVAL]]87;88entry:89 %p1 = alloca [1024 x i8]90 %p2 = alloca [1024 x i8]91 call void @init_mem(ptr %p1, i64 1024)92 call void @init_mem(ptr %p2, i64 1024)93 br label %search194 95search1:96 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]97 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index98 %ld1 = load i8, ptr %arrayidx, align 199 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index100 %ld2 = load i8, ptr %arrayidx1, align 1101 %cmp1 = icmp eq i8 %ld1, %ld2102 br i1 %cmp1, label %loop.end, label %search2103 104search2:105 %cmp2 = icmp ult i8 %ld1, 34106 br i1 %cmp2, label %loop.end, label %loop.inc107 108loop.inc:109 %index.next = add i64 %index, 1110 %exitcond = icmp ne i64 %index.next, 67111 br i1 %exitcond, label %search1, label %loop.end112 113loop.end:114 %retval = phi i64 [ %index, %search1 ], [ 100, %search2 ], [ 43, %loop.inc ]115 ret i64 %retval116}117 118 119define i64 @uncountable_exit_infinite_loop() {120; CHECK-LABEL: define i64 @uncountable_exit_infinite_loop() {121; CHECK-NEXT: entry:122; CHECK-NEXT: [[P1:%.*]] = alloca [1024 x i8], align 1123; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1124; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024)125; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024)126; CHECK-NEXT: br label [[LOOP:%.*]]127; CHECK: loop:128; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]129; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]130; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1131; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]]132; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1133; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]]134; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END:%.*]]135; CHECK: loop.inc:136; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1137; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67138; CHECK-NEXT: br label [[LOOP]]139; CHECK: loop.end:140; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ]141; CHECK-NEXT: ret i64 [[RETVAL]]142;143entry:144 %p1 = alloca [1024 x i8]145 %p2 = alloca [1024 x i8]146 call void @init_mem(ptr %p1, i64 1024)147 call void @init_mem(ptr %p2, i64 1024)148 br label %loop149 150loop:151 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]152 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index153 %ld1 = load i8, ptr %arrayidx, align 1154 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index155 %ld2 = load i8, ptr %arrayidx1, align 1156 %cmp3 = icmp eq i8 %ld1, %ld2157 br i1 %cmp3, label %loop.inc, label %loop.end158 159loop.inc:160 %index.next = add i64 %index, 1161 %exitcond = icmp ne i64 %index.next, 67162 br label %loop163 164loop.end:165 %retval = phi i64 [ %index, %loop ]166 ret i64 %retval167}168 169 170define i64 @loop_contains_unsafe_call() {171; CHECK-LABEL: define i64 @loop_contains_unsafe_call() {172; CHECK-NEXT: entry:173; CHECK-NEXT: [[P1:%.*]] = alloca [1024 x i8], align 1174; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1175; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024)176; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024)177; CHECK-NEXT: br label [[LOOP:%.*]]178; CHECK: loop:179; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]180; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[P1]], i64 [[INDEX]]181; CHECK-NEXT: [[LD1:%.*]] = load i32, ptr [[ARRAYIDX]], align 1182; CHECK-NEXT: [[BAD_CALL:%.*]] = call i32 @foo(i32 [[LD1]]) #[[ATTR1:[0-9]+]]183; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[BAD_CALL]], 34184; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_INC]], label [[LOOP_END:%.*]]185; CHECK: loop.inc:186; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1187; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67188; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]]189; CHECK: loop.end:190; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ]191; CHECK-NEXT: ret i64 [[RETVAL]]192;193entry:194 %p1 = alloca [1024 x i8]195 %p2 = alloca [1024 x i8]196 call void @init_mem(ptr %p1, i64 1024)197 call void @init_mem(ptr %p2, i64 1024)198 br label %loop199 200loop:201 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]202 %arrayidx = getelementptr inbounds i32, ptr %p1, i64 %index203 %ld1 = load i32, ptr %arrayidx, align 1204 %bad_call = call i32 @foo(i32 %ld1) #0205 %cmp = icmp eq i32 %bad_call, 34206 br i1 %cmp, label %loop.inc, label %loop.end207 208loop.inc:209 %index.next = add i64 %index, 1210 %exitcond = icmp ne i64 %index.next, 67211 br i1 %exitcond, label %loop, label %loop.end212 213loop.end:214 %retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]215 ret i64 %retval216}217 218 219define i64 @loop_contains_unsafe_div() {220; CHECK-LABEL: define i64 @loop_contains_unsafe_div() {221; CHECK-NEXT: entry:222; CHECK-NEXT: [[P1:%.*]] = alloca [1024 x i8], align 1223; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1224; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024)225; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024)226; CHECK-NEXT: br label [[LOOP:%.*]]227; CHECK: loop:228; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]229; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]230; CHECK-NEXT: [[LD1:%.*]] = load i32, ptr [[ARRAYIDX]], align 1231; CHECK-NEXT: [[DIV:%.*]] = udiv i32 20000, [[LD1]]232; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[DIV]], 1233; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_INC]], label [[LOOP_END:%.*]]234; CHECK: loop.inc:235; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1236; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67237; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]]238; CHECK: loop.end:239; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ]240; CHECK-NEXT: ret i64 [[RETVAL]]241;242entry:243 %p1 = alloca [1024 x i8]244 %p2 = alloca [1024 x i8]245 call void @init_mem(ptr %p1, i64 1024)246 call void @init_mem(ptr %p2, i64 1024)247 br label %loop248 249loop:250 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]251 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index252 %ld1 = load i32, ptr %arrayidx, align 1253 %div = udiv i32 20000, %ld1254 %cmp = icmp eq i32 %div, 1255 br i1 %cmp, label %loop.inc, label %loop.end256 257loop.inc:258 %index.next = add i64 %index, 1259 %exitcond = icmp ne i64 %index.next, 67260 br i1 %exitcond, label %loop, label %loop.end261 262loop.end:263 %retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]264 ret i64 %retval265}266 267 268define i64 @loop_contains_store(ptr %dest) {269; CHECK-LABEL: define i64 @loop_contains_store(270; CHECK-SAME: ptr [[DEST:%.*]]) {271; CHECK-NEXT: entry:272; CHECK-NEXT: [[P1:%.*]] = alloca [1024 x i8], align 1273; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024)274; CHECK-NEXT: br label [[LOOP:%.*]]275; CHECK: loop:276; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]277; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[P1]], i64 [[INDEX]]278; CHECK-NEXT: [[LD1:%.*]] = load i32, ptr [[ARRAYIDX]], align 1279; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 [[INDEX]]280; CHECK-NEXT: store i32 [[LD1]], ptr [[ARRAYIDX2]], align 4281; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[LD1]], 1282; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_INC]], label [[LOOP_END:%.*]]283; CHECK: loop.inc:284; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1285; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67286; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]]287; CHECK: loop.end:288; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ]289; CHECK-NEXT: ret i64 [[RETVAL]]290;291entry:292 %p1 = alloca [1024 x i8]293 call void @init_mem(ptr %p1, i64 1024)294 br label %loop295 296loop:297 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]298 %arrayidx = getelementptr inbounds i32, ptr %p1, i64 %index299 %ld1 = load i32, ptr %arrayidx, align 1300 %arrayidx2 = getelementptr inbounds i32, ptr %dest, i64 %index301 store i32 %ld1, ptr %arrayidx2, align 4302 %cmp = icmp eq i32 %ld1, 1303 br i1 %cmp, label %loop.inc, label %loop.end304 305loop.inc:306 %index.next = add i64 %index, 1307 %exitcond = icmp ne i64 %index.next, 67308 br i1 %exitcond, label %loop, label %loop.end309 310loop.end:311 %retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]312 ret i64 %retval313}314 315 316define i64 @uncountable_exit_in_conditional_block(ptr %mask) {317; CHECK-LABEL: define i64 @uncountable_exit_in_conditional_block(318; CHECK-SAME: ptr [[MASK:%.*]]) {319; CHECK-NEXT: entry:320; CHECK-NEXT: [[P1:%.*]] = alloca [1024 x i8], align 1321; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1322; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024)323; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024)324; CHECK-NEXT: br label [[LOOP:%.*]]325; CHECK: loop:326; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]327; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[MASK]], i64 [[INDEX]]328; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1329; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[LD1]], 0330; CHECK-NEXT: br i1 [[CMP1]], label [[LOOP_SEARCH:%.*]], label [[LOOP_INC]]331; CHECK: loop.search:332; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]333; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1334; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]]335; CHECK-NEXT: [[LD3:%.*]] = load i8, ptr [[ARRAYIDX3]], align 1336; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[LD2]], [[LD3]]337; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP_INC]], label [[LOOP_END:%.*]]338; CHECK: loop.inc:339; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1340; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67341; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]]342; CHECK: loop.end:343; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP_SEARCH]] ], [ 67, [[LOOP_INC]] ]344; CHECK-NEXT: ret i64 [[RETVAL]]345;346entry:347 %p1 = alloca [1024 x i8]348 %p2 = alloca [1024 x i8]349 call void @init_mem(ptr %p1, i64 1024)350 call void @init_mem(ptr %p2, i64 1024)351 br label %loop352 353loop:354 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]355 %arrayidx1 = getelementptr inbounds i8, ptr %mask, i64 %index356 %ld1 = load i8, ptr %arrayidx1, align 1357 %cmp1 = icmp ne i8 %ld1, 0358 br i1 %cmp1, label %loop.search, label %loop.inc359 360loop.search:361 %arrayidx2 = getelementptr inbounds i8, ptr %p1, i64 %index362 %ld2 = load i8, ptr %arrayidx2, align 1363 %arrayidx3 = getelementptr inbounds i8, ptr %p2, i64 %index364 %ld3 = load i8, ptr %arrayidx3, align 1365 %cmp2 = icmp eq i8 %ld2, %ld3366 br i1 %cmp2, label %loop.inc, label %loop.end367 368loop.inc:369 %index.next = add i64 %index, 1370 %exitcond = icmp ne i64 %index.next, 67371 br i1 %exitcond, label %loop, label %loop.end372 373loop.end:374 %retval = phi i64 [ %index, %loop.search ], [ 67, %loop.inc ]375 ret i64 %retval376}377 378 379define i64 @same_exit_block_pre_inc_use1_with_reduction() {380; CHECK-LABEL: define i64 @same_exit_block_pre_inc_use1_with_reduction() {381; CHECK-NEXT: entry:382; CHECK-NEXT: [[P1:%.*]] = alloca [1024 x i8], align 1383; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1384; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024)385; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024)386; CHECK-NEXT: br label [[LAND_RHS:%.*]]387; CHECK: loop:388; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]389; CHECK-NEXT: [[RED:%.*]] = phi i64 [ [[RED_NEXT:%.*]], [[FOR_INC]] ], [ 0, [[ENTRY]] ]390; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]391; CHECK-NEXT: [[TMP38:%.*]] = load i8, ptr [[ARRAYIDX]], align 1392; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]]393; CHECK-NEXT: [[TMP39:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1394; CHECK-NEXT: [[LD2_ZEXT:%.*]] = zext i8 [[TMP39]] to i64395; CHECK-NEXT: [[RED_NEXT]] = add i64 [[RED]], [[LD2_ZEXT]]396; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[TMP38]], [[TMP39]]397; CHECK-NEXT: br i1 [[CMP3]], label [[FOR_INC]], label [[FOR_END_LOOPEXIT:%.*]]398; CHECK: loop.inc:399; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1400; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67401; CHECK-NEXT: br i1 [[EXITCOND]], label [[LAND_RHS]], label [[FOR_END_LOOPEXIT]]402; CHECK: loop.end:403; CHECK-NEXT: [[RED_NEXT_LCSSA:%.*]] = phi i64 [ [[RED_NEXT]], [[FOR_INC]] ], [ [[RED_NEXT]], [[LAND_RHS]] ]404; CHECK-NEXT: [[FINAL_IND:%.*]] = phi i64 [ [[INDEX]], [[LAND_RHS]] ], [ 67, [[FOR_INC]] ]405; CHECK-NEXT: [[START_0_LCSSA:%.*]] = add i64 [[RED_NEXT_LCSSA]], [[FINAL_IND]]406; CHECK-NEXT: ret i64 [[START_0_LCSSA]]407;408entry:409 %p1 = alloca [1024 x i8]410 %p2 = alloca [1024 x i8]411 call void @init_mem(ptr %p1, i64 1024)412 call void @init_mem(ptr %p2, i64 1024)413 br label %loop414 415loop:416 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]417 %red = phi i64 [ %red.next, %loop.inc ], [ 0, %entry ]418 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index419 %ld1 = load i8, ptr %arrayidx, align 1420 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index421 %ld2 = load i8, ptr %arrayidx1, align 1422 %ld2.zext = zext i8 %ld2 to i64423 %red.next = add i64 %red, %ld2.zext424 %cmp3 = icmp eq i8 %ld1, %ld2425 br i1 %cmp3, label %loop.inc, label %loop.end426 427loop.inc:428 %index.next = add i64 %index, 1429 %exitcond = icmp ne i64 %index.next, 67430 br i1 %exitcond, label %loop, label %loop.end431 432loop.end:433 %final.ind = phi i64 [ %index, %loop ], [ 67, %loop.inc ]434 %retval = add i64 %red.next, %final.ind435 ret i64 %retval436}437 438 439define i64 @uncountable_exit_has_multiple_outside_successors() {440; CHECK-LABEL: define i64 @uncountable_exit_has_multiple_outside_successors() {441; CHECK-NEXT: entry:442; CHECK-NEXT: [[P1:%.*]] = alloca [1024 x i8], align 1443; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024)444; CHECK-NEXT: br label [[LOOP:%.*]]445; CHECK: loop:446; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]447; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]448; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1449; CHECK-NEXT: switch i8 [[LD1]], label [[LOOP_INC]] [450; CHECK-NEXT: i8 2, label [[LOOP_END:%.*]]451; CHECK-NEXT: i8 3, label [[LOOP_SURPRISE:%.*]]452; CHECK-NEXT: ]453; CHECK: loop.inc:454; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1455; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67456; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]]457; CHECK: loop.surprise:458; CHECK-NEXT: ret i64 3459; CHECK: loop.end:460; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ]461; CHECK-NEXT: ret i64 [[RETVAL]]462;463entry:464 %p1 = alloca [1024 x i8]465 call void @init_mem(ptr %p1, i64 1024)466 br label %loop467 468loop:469 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]470 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index471 %ld1 = load i8, ptr %arrayidx, align 1472 switch i8 %ld1, label %loop.inc [473 i8 2, label %loop.end474 i8 3, label %loop.surprise475 ]476 477loop.inc:478 %index.next = add i64 %index, 1479 %exitcond = icmp ne i64 %index.next, 67480 br i1 %exitcond, label %loop, label %loop.end481 482loop.surprise:483 ret i64 3484 485loop.end:486 %retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]487 ret i64 %retval488}489 490 491declare i32 @foo(i32) readonly492declare <vscale x 4 x i32> @foo_vec(<vscale x 4 x i32>)493 494attributes #0 = { "vector-function-abi-variant"="_ZGVsNxv_foo(foo_vec)" }495