1229 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 32; RUN: opt -disable-output -passes='print<access-info><allow-partial>' %s 2>&1 | FileCheck %s --check-prefixes=CHECK,FULLDEPTH3; RUN: opt -disable-output -passes='print<access-info><allow-partial>' -max-forked-scev-depth=2 %s 2>&1 | FileCheck %s --check-prefixes=CHECK,DEPTH24 5target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"6 7define void @forked_ptrs_simple(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr %Dest) {8; CHECK-LABEL: 'forked_ptrs_simple'9; CHECK-NEXT: loop:10; CHECK-NEXT: Memory dependences are safe with run-time checks11; CHECK-NEXT: Dependences:12; CHECK-NEXT: Run-time memory checks:13; CHECK-NEXT: Check 0:14; CHECK-NEXT: Comparing group GRP0:15; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv16; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv17; CHECK-NEXT: Against group GRP1:18; CHECK-NEXT: %select = select i1 %cmp, ptr %gep.1, ptr %gep.219; CHECK-NEXT: Check 1:20; CHECK-NEXT: Comparing group GRP0:21; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv22; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv23; CHECK-NEXT: Against group GRP2:24; CHECK-NEXT: %select = select i1 %cmp, ptr %gep.1, ptr %gep.225; CHECK-NEXT: Grouped accesses:26; CHECK-NEXT: Group GRP0:27; CHECK-NEXT: (Low: %Dest High: (400 + %Dest))28; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%loop>29; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%loop>30; CHECK-NEXT: Group GRP1:31; CHECK-NEXT: (Low: %Base1 High: (400 + %Base1))32; CHECK-NEXT: Member: {%Base1,+,4}<nw><%loop>33; CHECK-NEXT: Group GRP2:34; CHECK-NEXT: (Low: %Base2 High: (400 + %Base2))35; CHECK-NEXT: Member: {%Base2,+,4}<nw><%loop>36; CHECK-EMPTY:37; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.38; CHECK-NEXT: SCEV assumptions:39; CHECK-EMPTY:40; CHECK-NEXT: Expressions re-written:41;42entry:43 br label %loop44 45loop:46 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]47 %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv48 %l.Dest = load float, ptr %gep.Dest49 %cmp = fcmp une float %l.Dest, 0.050 %gep.1 = getelementptr inbounds float, ptr %Base1, i64 %iv51 %gep.2 = getelementptr inbounds float, ptr %Base2, i64 %iv52 %select = select i1 %cmp, ptr %gep.1, ptr %gep.253 %sink = load float, ptr %select, align 454 store float %sink, ptr %gep.Dest, align 455 %iv.next = add nuw nsw i64 %iv, 156 %exitcond.not = icmp eq i64 %iv.next, 10057 br i1 %exitcond.not, label %exit, label %loop58 59exit:60 ret void61}62 63;; We have a limit on the recursion depth for finding a loop invariant or64;; addrec term; confirm we won't exceed that depth by forcing a lower65;; limit via -max-forked-scev-depth=266 67;;;; Derived from the following C code68;; void forked_ptrs_different_base_same_offset(float *A, float *B, float *C, int *D) {69;; for (int i=0; i<100; i++) {70;; if (D[i] != 0) {71;; C[i] = A[i];72;; } else {73;; C[i] = B[i];74;; }75;; }76;; }77 78define dso_local void @forked_ptrs_different_base_same_offset(ptr nocapture readonly nonnull %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {79; CHECK-LABEL: 'forked_ptrs_different_base_same_offset'80; CHECK-NEXT: for.body:81; CHECK-NEXT: Memory dependences are safe with run-time checks82; CHECK-NEXT: Dependences:83; CHECK-NEXT: Run-time memory checks:84; CHECK-NEXT: Check 0:85; CHECK-NEXT: Comparing group GRP0:86; CHECK-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv87; CHECK-NEXT: Against group GRP1:88; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv89; CHECK-NEXT: Check 1:90; CHECK-NEXT: Comparing group GRP0:91; CHECK-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv92; CHECK-NEXT: Against group GRP2:93; CHECK-NEXT: %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv94; CHECK-NEXT: Check 2:95; CHECK-NEXT: Comparing group GRP0:96; CHECK-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv97; CHECK-NEXT: Against group GRP3:98; CHECK-NEXT: %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv99; CHECK-NEXT: Grouped accesses:100; CHECK-NEXT: Group GRP0:101; CHECK-NEXT: (Low: %Dest High: (400 + %Dest))102; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%for.body>103; CHECK-NEXT: Group GRP1:104; CHECK-NEXT: (Low: %Preds High: (400 + %Preds))105; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body>106; CHECK-NEXT: Group GRP2:107; CHECK-NEXT: (Low: %Base2 High: (400 + %Base2))108; CHECK-NEXT: Member: {%Base2,+,4}<nw><%for.body>109; CHECK-NEXT: Group GRP3:110; CHECK-NEXT: (Low: %Base1 High: (400 + %Base1))111; CHECK-NEXT: Member: {%Base1,+,4}<nw><%for.body>112; CHECK-EMPTY:113; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.114; CHECK-NEXT: SCEV assumptions:115; CHECK-EMPTY:116; CHECK-NEXT: Expressions re-written:117;118entry:119 br label %for.body120 121for.cond.cleanup:122 ret void123 124for.body:125 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]126 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv127 %0 = load i32, ptr %arrayidx, align 4128 %cmp1.not = icmp eq i32 %0, 0129 %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1130 %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv131 %.sink = load float, ptr %.sink.in, align 4132 %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv133 store float %.sink, ptr %1, align 4134 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1135 %exitcond.not = icmp eq i64 %indvars.iv.next, 100136 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body137}138 139define dso_local void @forked_ptrs_different_base_same_offset_64b(ptr nocapture readonly nonnull %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {140; CHECK-LABEL: 'forked_ptrs_different_base_same_offset_64b'141; CHECK-NEXT: for.body:142; CHECK-NEXT: Memory dependences are safe with run-time checks143; CHECK-NEXT: Dependences:144; CHECK-NEXT: Run-time memory checks:145; CHECK-NEXT: Check 0:146; CHECK-NEXT: Comparing group GRP0:147; CHECK-NEXT: %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv148; CHECK-NEXT: Against group GRP1:149; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv150; CHECK-NEXT: Check 1:151; CHECK-NEXT: Comparing group GRP0:152; CHECK-NEXT: %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv153; CHECK-NEXT: Against group GRP2:154; CHECK-NEXT: %.sink.in = getelementptr inbounds double, ptr %spec.select, i64 %indvars.iv155; CHECK-NEXT: Check 2:156; CHECK-NEXT: Comparing group GRP0:157; CHECK-NEXT: %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv158; CHECK-NEXT: Against group GRP3:159; CHECK-NEXT: %.sink.in = getelementptr inbounds double, ptr %spec.select, i64 %indvars.iv160; CHECK-NEXT: Grouped accesses:161; CHECK-NEXT: Group GRP0:162; CHECK-NEXT: (Low: %Dest High: (800 + %Dest))163; CHECK-NEXT: Member: {%Dest,+,8}<nuw><%for.body>164; CHECK-NEXT: Group GRP1:165; CHECK-NEXT: (Low: %Preds High: (400 + %Preds))166; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body>167; CHECK-NEXT: Group GRP2:168; CHECK-NEXT: (Low: %Base2 High: (800 + %Base2))169; CHECK-NEXT: Member: {%Base2,+,8}<nw><%for.body>170; CHECK-NEXT: Group GRP3:171; CHECK-NEXT: (Low: %Base1 High: (800 + %Base1))172; CHECK-NEXT: Member: {%Base1,+,8}<nw><%for.body>173; CHECK-EMPTY:174; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.175; CHECK-NEXT: SCEV assumptions:176; CHECK-EMPTY:177; CHECK-NEXT: Expressions re-written:178;179entry:180 br label %for.body181 182for.cond.cleanup:183 ret void184 185for.body:186 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]187 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv188 %0 = load i32, ptr %arrayidx, align 4189 %cmp1.not = icmp eq i32 %0, 0190 %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1191 %.sink.in = getelementptr inbounds double, ptr %spec.select, i64 %indvars.iv192 %.sink = load double, ptr %.sink.in, align 8193 %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv194 store double %.sink, ptr %1, align 8195 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1196 %exitcond.not = icmp eq i64 %indvars.iv.next, 100197 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body198}199 200define dso_local void @forked_ptrs_different_base_same_offset_23b(ptr nocapture readonly nonnull %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {201; CHECK-LABEL: 'forked_ptrs_different_base_same_offset_23b'202; CHECK-NEXT: for.body:203; CHECK-NEXT: Memory dependences are safe with run-time checks204; CHECK-NEXT: Dependences:205; CHECK-NEXT: Run-time memory checks:206; CHECK-NEXT: Check 0:207; CHECK-NEXT: Comparing group GRP0:208; CHECK-NEXT: %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv209; CHECK-NEXT: Against group GRP1:210; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv211; CHECK-NEXT: Check 1:212; CHECK-NEXT: Comparing group GRP0:213; CHECK-NEXT: %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv214; CHECK-NEXT: Against group GRP2:215; CHECK-NEXT: %.sink.in = getelementptr inbounds i23, ptr %spec.select, i64 %indvars.iv216; CHECK-NEXT: Check 2:217; CHECK-NEXT: Comparing group GRP0:218; CHECK-NEXT: %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv219; CHECK-NEXT: Against group GRP3:220; CHECK-NEXT: %.sink.in = getelementptr inbounds i23, ptr %spec.select, i64 %indvars.iv221; CHECK-NEXT: Grouped accesses:222; CHECK-NEXT: Group GRP0:223; CHECK-NEXT: (Low: %Dest High: (399 + %Dest))224; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%for.body>225; CHECK-NEXT: Group GRP1:226; CHECK-NEXT: (Low: %Preds High: (400 + %Preds))227; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body>228; CHECK-NEXT: Group GRP2:229; CHECK-NEXT: (Low: %Base2 High: (399 + %Base2))230; CHECK-NEXT: Member: {%Base2,+,4}<nw><%for.body>231; CHECK-NEXT: Group GRP3:232; CHECK-NEXT: (Low: %Base1 High: (399 + %Base1))233; CHECK-NEXT: Member: {%Base1,+,4}<nw><%for.body>234; CHECK-EMPTY:235; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.236; CHECK-NEXT: SCEV assumptions:237; CHECK-EMPTY:238; CHECK-NEXT: Expressions re-written:239;240entry:241 br label %for.body242 243for.cond.cleanup:244 ret void245 246for.body:247 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]248 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv249 %0 = load i32, ptr %arrayidx, align 4250 %cmp1.not = icmp eq i32 %0, 0251 %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1252 %.sink.in = getelementptr inbounds i23, ptr %spec.select, i64 %indvars.iv253 %.sink = load i23, ptr %.sink.in254 %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv255 store i23 %.sink, ptr %1256 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1257 %exitcond.not = icmp eq i64 %indvars.iv.next, 100258 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body259}260 261define dso_local void @forked_ptrs_different_base_same_offset_6b(ptr nocapture readonly nonnull %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {262; CHECK-LABEL: 'forked_ptrs_different_base_same_offset_6b'263; CHECK-NEXT: for.body:264; CHECK-NEXT: Memory dependences are safe with run-time checks265; CHECK-NEXT: Dependences:266; CHECK-NEXT: Run-time memory checks:267; CHECK-NEXT: Check 0:268; CHECK-NEXT: Comparing group GRP0:269; CHECK-NEXT: %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv270; CHECK-NEXT: Against group GRP1:271; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv272; CHECK-NEXT: Check 1:273; CHECK-NEXT: Comparing group GRP0:274; CHECK-NEXT: %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv275; CHECK-NEXT: Against group GRP2:276; CHECK-NEXT: %.sink.in = getelementptr inbounds i6, ptr %spec.select, i64 %indvars.iv277; CHECK-NEXT: Check 2:278; CHECK-NEXT: Comparing group GRP0:279; CHECK-NEXT: %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv280; CHECK-NEXT: Against group GRP3:281; CHECK-NEXT: %.sink.in = getelementptr inbounds i6, ptr %spec.select, i64 %indvars.iv282; CHECK-NEXT: Grouped accesses:283; CHECK-NEXT: Group GRP0:284; CHECK-NEXT: (Low: %Dest High: (100 + %Dest))285; CHECK-NEXT: Member: {%Dest,+,1}<nuw><%for.body>286; CHECK-NEXT: Group GRP1:287; CHECK-NEXT: (Low: %Preds High: (400 + %Preds))288; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body>289; CHECK-NEXT: Group GRP2:290; CHECK-NEXT: (Low: %Base2 High: (100 + %Base2))291; CHECK-NEXT: Member: {%Base2,+,1}<nw><%for.body>292; CHECK-NEXT: Group GRP3:293; CHECK-NEXT: (Low: %Base1 High: (100 + %Base1))294; CHECK-NEXT: Member: {%Base1,+,1}<nw><%for.body>295; CHECK-EMPTY:296; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.297; CHECK-NEXT: SCEV assumptions:298; CHECK-EMPTY:299; CHECK-NEXT: Expressions re-written:300;301entry:302 br label %for.body303 304for.cond.cleanup:305 ret void306 307for.body:308 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]309 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv310 %0 = load i32, ptr %arrayidx, align 4311 %cmp1.not = icmp eq i32 %0, 0312 %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1313 %.sink.in = getelementptr inbounds i6, ptr %spec.select, i64 %indvars.iv314 %.sink = load i6, ptr %.sink.in315 %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv316 store i6 %.sink, ptr %1317 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1318 %exitcond.not = icmp eq i64 %indvars.iv.next, 100319 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body320}321 322define dso_local void @forked_ptrs_different_base_same_offset_possible_poison(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds, i1 %c) {323; CHECK-LABEL: 'forked_ptrs_different_base_same_offset_possible_poison'324; CHECK-NEXT: for.body:325; CHECK-NEXT: Memory dependences are safe with run-time checks326; CHECK-NEXT: Dependences:327; CHECK-NEXT: Run-time memory checks:328; CHECK-NEXT: Check 0:329; CHECK-NEXT: Comparing group GRP0:330; CHECK-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv331; CHECK-NEXT: Against group GRP1:332; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv333; CHECK-NEXT: Check 1:334; CHECK-NEXT: Comparing group GRP0:335; CHECK-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv336; CHECK-NEXT: Against group GRP2:337; CHECK-NEXT: %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv338; CHECK-NEXT: Check 2:339; CHECK-NEXT: Comparing group GRP0:340; CHECK-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv341; CHECK-NEXT: Against group GRP3:342; CHECK-NEXT: %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv343; CHECK-NEXT: Grouped accesses:344; CHECK-NEXT: Group GRP0:345; CHECK-NEXT: (Low: %Dest High: (400 + %Dest))346; CHECK-NEXT: Member: {%Dest,+,4}<nw><%for.body>347; CHECK-NEXT: Group GRP1:348; CHECK-NEXT: (Low: %Preds High: (400 + %Preds))349; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body>350; CHECK-NEXT: Group GRP2:351; CHECK-NEXT: (Low: %Base2 High: (400 + %Base2))352; CHECK-NEXT: Member: {%Base2,+,4}<nw><%for.body>353; CHECK-NEXT: Group GRP3:354; CHECK-NEXT: (Low: %Base1 High: (400 + %Base1))355; CHECK-NEXT: Member: {%Base1,+,4}<nw><%for.body>356; CHECK-EMPTY:357; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.358; CHECK-NEXT: SCEV assumptions:359; CHECK-EMPTY:360; CHECK-NEXT: Expressions re-written:361;362entry:363 br label %for.body364 365for.cond.cleanup:366 ret void367 368for.body:369 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %latch ]370 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv371 %0 = load i32, ptr %arrayidx, align 4372 %cmp1.not = icmp eq i32 %0, 0373 %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1374 %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv375 %.sink = load float, ptr %.sink.in, align 4376 %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv377 br i1 %c, label %then, label %latch378 379then:380 store float %.sink, ptr %1, align 4381 br label %latch382 383latch:384 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1385 %exitcond.not = icmp eq i64 %indvars.iv.next, 100386 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body387}388 389;;;; Derived from the following C code390;; void forked_ptrs_same_base_different_offset(float *A, float *B, int *C) {391;; int offset;392;; for (int i = 0; i < 100; i++) {393;; if (C[i] != 0)394;; offset = i;395;; else396;; offset = i+1;397;; B[i] = A[offset];398;; }399;; }400 401define dso_local void @forked_ptrs_same_base_different_offset(ptr nocapture readonly %Base, ptr nocapture %Dest, ptr nocapture readonly %Preds) {402; CHECK-LABEL: 'forked_ptrs_same_base_different_offset'403; CHECK-NEXT: for.body:404; CHECK-NEXT: Report: cannot identify array bounds405; CHECK-NEXT: Dependences:406; CHECK-NEXT: Run-time memory checks:407; CHECK-NEXT: Check 0:408; CHECK-NEXT: Comparing group GRP0:409; CHECK-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv410; CHECK-NEXT: Against group GRP1:411; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv412; CHECK-NEXT: Grouped accesses:413; CHECK-NEXT: Group GRP0:414; CHECK-NEXT: (Low: %Dest High: (400 + %Dest))415; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%for.body>416; CHECK-NEXT: Group GRP1:417; CHECK-NEXT: (Low: %Preds High: (400 + %Preds))418; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body>419; CHECK-NEXT: Generated run-time checks are incomplete420; CHECK-EMPTY:421; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.422; CHECK-NEXT: SCEV assumptions:423; CHECK-EMPTY:424; CHECK-NEXT: Expressions re-written:425;426entry:427 br label %for.body428 429for.cond.cleanup: ; preds = %for.body430 ret void431 432for.body: ; preds = %entry, %for.body433 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]434 %i.014 = phi i32 [ 0, %entry ], [ %add, %for.body ]435 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv436 %0 = load i32, ptr %arrayidx, align 4437 %cmp1.not = icmp eq i32 %0, 0438 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1439 %add = add nuw nsw i32 %i.014, 1440 %1 = trunc i64 %indvars.iv to i32441 %offset.0 = select i1 %cmp1.not, i32 %add, i32 %1442 %idxprom213 = zext i32 %offset.0 to i64443 %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %idxprom213444 %2 = load float, ptr %arrayidx3, align 4445 %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv446 store float %2, ptr %arrayidx5, align 4447 %exitcond.not = icmp eq i64 %indvars.iv.next, 100448 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body449}450 451define dso_local void @forked_ptrs_add_to_offset(ptr nocapture readonly %Base, ptr nocapture %Dest, ptr nocapture readonly %Preds, i64 %extra_offset) {452; FULLDEPTH-LABEL: 'forked_ptrs_add_to_offset'453; FULLDEPTH-NEXT: for.body:454; FULLDEPTH-NEXT: Memory dependences are safe with run-time checks455; FULLDEPTH-NEXT: Dependences:456; FULLDEPTH-NEXT: Run-time memory checks:457; FULLDEPTH-NEXT: Check 0:458; FULLDEPTH-NEXT: Comparing group GRP0:459; FULLDEPTH-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv460; FULLDEPTH-NEXT: Against group GRP1:461; FULLDEPTH-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv462; FULLDEPTH-NEXT: Check 1:463; FULLDEPTH-NEXT: Comparing group GRP0:464; FULLDEPTH-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv465; FULLDEPTH-NEXT: Against group GRP2:466; FULLDEPTH-NEXT: %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset467; FULLDEPTH-NEXT: %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset468; FULLDEPTH-NEXT: Grouped accesses:469; FULLDEPTH-NEXT: Group GRP0:470; FULLDEPTH-NEXT: (Low: %Dest High: (400 + %Dest))471; FULLDEPTH-NEXT: Member: {%Dest,+,4}<nuw><%for.body>472; FULLDEPTH-NEXT: Group GRP1:473; FULLDEPTH-NEXT: (Low: %Preds High: (400 + %Preds))474; FULLDEPTH-NEXT: Member: {%Preds,+,4}<nuw><%for.body>475; FULLDEPTH-NEXT: Group GRP2:476; FULLDEPTH-NEXT: (Low: ((4 * %extra_offset) + %Base) High: (404 + (4 * %extra_offset) + %Base))477; FULLDEPTH-NEXT: Member: {(4 + (4 * %extra_offset) + %Base),+,4}<%for.body>478; FULLDEPTH-NEXT: Member: {((4 * %extra_offset) + %Base),+,4}<%for.body>479; FULLDEPTH-EMPTY:480; FULLDEPTH-NEXT: Non vectorizable stores to invariant address were not found in loop.481; FULLDEPTH-NEXT: SCEV assumptions:482; FULLDEPTH-EMPTY:483; FULLDEPTH-NEXT: Expressions re-written:484;485; DEPTH2-LABEL: 'forked_ptrs_add_to_offset'486; DEPTH2-NEXT: for.body:487; DEPTH2-NEXT: Report: cannot identify array bounds488; DEPTH2-NEXT: Dependences:489; DEPTH2-NEXT: Run-time memory checks:490; DEPTH2-NEXT: Check 0:491; DEPTH2-NEXT: Comparing group GRP0:492; DEPTH2-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv493; DEPTH2-NEXT: Against group GRP1:494; DEPTH2-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv495; DEPTH2-NEXT: Grouped accesses:496; DEPTH2-NEXT: Group GRP0:497; DEPTH2-NEXT: (Low: %Dest High: (400 + %Dest))498; DEPTH2-NEXT: Member: {%Dest,+,4}<nuw><%for.body>499; DEPTH2-NEXT: Group GRP1:500; DEPTH2-NEXT: (Low: %Preds High: (400 + %Preds))501; DEPTH2-NEXT: Member: {%Preds,+,4}<nuw><%for.body>502; DEPTH2-NEXT: Generated run-time checks are incomplete503; DEPTH2-EMPTY:504; DEPTH2-NEXT: Non vectorizable stores to invariant address were not found in loop.505; DEPTH2-NEXT: SCEV assumptions:506; DEPTH2-EMPTY:507; DEPTH2-NEXT: Expressions re-written:508;509entry:510 br label %for.body511 512for.cond.cleanup: ; preds = %for.body513 ret void514 515for.body: ; preds = %entry, %for.body516 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]517 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv518 %0 = load i32, ptr %arrayidx, align 4519 %cmp.not = icmp eq i32 %0, 0520 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1521 %sel = select i1 %cmp.not, i64 %indvars.iv.next, i64 %indvars.iv522 %offset = add nuw nsw i64 %sel, %extra_offset523 %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset524 %1 = load float, ptr %arrayidx3, align 4525 %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv526 store float %1, ptr %arrayidx5, align 4527 %exitcond.not = icmp eq i64 %indvars.iv.next, 100528 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body529}530 531define dso_local void @forked_ptrs_sub_from_offset(ptr nocapture readonly %Base, ptr nocapture %Dest, ptr nocapture readonly %Preds, i64 %extra_offset) {532; FULLDEPTH-LABEL: 'forked_ptrs_sub_from_offset'533; FULLDEPTH-NEXT: for.body:534; FULLDEPTH-NEXT: Memory dependences are safe with run-time checks535; FULLDEPTH-NEXT: Dependences:536; FULLDEPTH-NEXT: Run-time memory checks:537; FULLDEPTH-NEXT: Check 0:538; FULLDEPTH-NEXT: Comparing group GRP0:539; FULLDEPTH-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv540; FULLDEPTH-NEXT: Against group GRP1:541; FULLDEPTH-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv542; FULLDEPTH-NEXT: Check 1:543; FULLDEPTH-NEXT: Comparing group GRP0:544; FULLDEPTH-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv545; FULLDEPTH-NEXT: Against group GRP2:546; FULLDEPTH-NEXT: %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset547; FULLDEPTH-NEXT: %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset548; FULLDEPTH-NEXT: Grouped accesses:549; FULLDEPTH-NEXT: Group GRP0:550; FULLDEPTH-NEXT: (Low: %Dest High: (400 + %Dest))551; FULLDEPTH-NEXT: Member: {%Dest,+,4}<nuw><%for.body>552; FULLDEPTH-NEXT: Group GRP1:553; FULLDEPTH-NEXT: (Low: %Preds High: (400 + %Preds))554; FULLDEPTH-NEXT: Member: {%Preds,+,4}<nuw><%for.body>555; FULLDEPTH-NEXT: Group GRP2:556; FULLDEPTH-NEXT: (Low: ((-4 * %extra_offset) + %Base) High: (404 + (-4 * %extra_offset) + %Base))557; FULLDEPTH-NEXT: Member: {(4 + (-4 * %extra_offset) + %Base),+,4}<%for.body>558; FULLDEPTH-NEXT: Member: {((-4 * %extra_offset) + %Base),+,4}<%for.body>559; FULLDEPTH-EMPTY:560; FULLDEPTH-NEXT: Non vectorizable stores to invariant address were not found in loop.561; FULLDEPTH-NEXT: SCEV assumptions:562; FULLDEPTH-EMPTY:563; FULLDEPTH-NEXT: Expressions re-written:564;565; DEPTH2-LABEL: 'forked_ptrs_sub_from_offset'566; DEPTH2-NEXT: for.body:567; DEPTH2-NEXT: Report: cannot identify array bounds568; DEPTH2-NEXT: Dependences:569; DEPTH2-NEXT: Run-time memory checks:570; DEPTH2-NEXT: Check 0:571; DEPTH2-NEXT: Comparing group GRP0:572; DEPTH2-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv573; DEPTH2-NEXT: Against group GRP1:574; DEPTH2-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv575; DEPTH2-NEXT: Grouped accesses:576; DEPTH2-NEXT: Group GRP0:577; DEPTH2-NEXT: (Low: %Dest High: (400 + %Dest))578; DEPTH2-NEXT: Member: {%Dest,+,4}<nuw><%for.body>579; DEPTH2-NEXT: Group GRP1:580; DEPTH2-NEXT: (Low: %Preds High: (400 + %Preds))581; DEPTH2-NEXT: Member: {%Preds,+,4}<nuw><%for.body>582; DEPTH2-NEXT: Generated run-time checks are incomplete583; DEPTH2-EMPTY:584; DEPTH2-NEXT: Non vectorizable stores to invariant address were not found in loop.585; DEPTH2-NEXT: SCEV assumptions:586; DEPTH2-EMPTY:587; DEPTH2-NEXT: Expressions re-written:588;589entry:590 br label %for.body591 592for.cond.cleanup: ; preds = %for.body593 ret void594 595for.body: ; preds = %entry, %for.body596 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]597 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv598 %0 = load i32, ptr %arrayidx, align 4599 %cmp.not = icmp eq i32 %0, 0600 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1601 %sel = select i1 %cmp.not, i64 %indvars.iv.next, i64 %indvars.iv602 %offset = sub nuw nsw i64 %sel, %extra_offset603 %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset604 %1 = load float, ptr %arrayidx3, align 4605 %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv606 store float %1, ptr %arrayidx5, align 4607 %exitcond.not = icmp eq i64 %indvars.iv.next, 100608 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body609}610 611define dso_local void @forked_ptrs_add_sub_offset(ptr nocapture readonly %Base, ptr nocapture %Dest, ptr nocapture readonly %Preds, i64 %to_add, i64 %to_sub) {612; FULLDEPTH-LABEL: 'forked_ptrs_add_sub_offset'613; FULLDEPTH-NEXT: for.body:614; FULLDEPTH-NEXT: Memory dependences are safe with run-time checks615; FULLDEPTH-NEXT: Dependences:616; FULLDEPTH-NEXT: Run-time memory checks:617; FULLDEPTH-NEXT: Check 0:618; FULLDEPTH-NEXT: Comparing group GRP0:619; FULLDEPTH-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv620; FULLDEPTH-NEXT: Against group GRP1:621; FULLDEPTH-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv622; FULLDEPTH-NEXT: Check 1:623; FULLDEPTH-NEXT: Comparing group GRP0:624; FULLDEPTH-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv625; FULLDEPTH-NEXT: Against group GRP2:626; FULLDEPTH-NEXT: %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset627; FULLDEPTH-NEXT: %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset628; FULLDEPTH-NEXT: Grouped accesses:629; FULLDEPTH-NEXT: Group GRP0:630; FULLDEPTH-NEXT: (Low: %Dest High: (400 + %Dest))631; FULLDEPTH-NEXT: Member: {%Dest,+,4}<nuw><%for.body>632; FULLDEPTH-NEXT: Group GRP1:633; FULLDEPTH-NEXT: (Low: %Preds High: (400 + %Preds))634; FULLDEPTH-NEXT: Member: {%Preds,+,4}<nuw><%for.body>635; FULLDEPTH-NEXT: Group GRP2:636; FULLDEPTH-NEXT: (Low: ((4 * %to_add) + (-4 * %to_sub) + %Base) High: (404 + (4 * %to_add) + (-4 * %to_sub) + %Base))637; FULLDEPTH-NEXT: Member: {(4 + (4 * %to_add) + (-4 * %to_sub) + %Base),+,4}<%for.body>638; FULLDEPTH-NEXT: Member: {((4 * %to_add) + (-4 * %to_sub) + %Base),+,4}<%for.body>639; FULLDEPTH-EMPTY:640; FULLDEPTH-NEXT: Non vectorizable stores to invariant address were not found in loop.641; FULLDEPTH-NEXT: SCEV assumptions:642; FULLDEPTH-EMPTY:643; FULLDEPTH-NEXT: Expressions re-written:644;645; DEPTH2-LABEL: 'forked_ptrs_add_sub_offset'646; DEPTH2-NEXT: for.body:647; DEPTH2-NEXT: Report: cannot identify array bounds648; DEPTH2-NEXT: Dependences:649; DEPTH2-NEXT: Run-time memory checks:650; DEPTH2-NEXT: Check 0:651; DEPTH2-NEXT: Comparing group GRP0:652; DEPTH2-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv653; DEPTH2-NEXT: Against group GRP1:654; DEPTH2-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv655; DEPTH2-NEXT: Grouped accesses:656; DEPTH2-NEXT: Group GRP0:657; DEPTH2-NEXT: (Low: %Dest High: (400 + %Dest))658; DEPTH2-NEXT: Member: {%Dest,+,4}<nuw><%for.body>659; DEPTH2-NEXT: Group GRP1:660; DEPTH2-NEXT: (Low: %Preds High: (400 + %Preds))661; DEPTH2-NEXT: Member: {%Preds,+,4}<nuw><%for.body>662; DEPTH2-NEXT: Generated run-time checks are incomplete663; DEPTH2-EMPTY:664; DEPTH2-NEXT: Non vectorizable stores to invariant address were not found in loop.665; DEPTH2-NEXT: SCEV assumptions:666; DEPTH2-EMPTY:667; DEPTH2-NEXT: Expressions re-written:668;669entry:670 br label %for.body671 672for.cond.cleanup: ; preds = %for.body673 ret void674 675for.body: ; preds = %entry, %for.body676 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]677 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv678 %0 = load i32, ptr %arrayidx, align 4679 %cmp.not = icmp eq i32 %0, 0680 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1681 %sel = select i1 %cmp.not, i64 %indvars.iv.next, i64 %indvars.iv682 %add = add nuw nsw i64 %sel, %to_add683 %offset = sub nuw nsw i64 %add, %to_sub684 %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset685 %1 = load float, ptr %arrayidx3, align 4686 %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv687 store float %1, ptr %arrayidx5, align 4688 %exitcond.not = icmp eq i64 %indvars.iv.next, 100689 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body690}691 692;;;; Cases that can be handled by a forked pointer but are not currently allowed.693 694define dso_local void @forked_ptrs_mul_by_offset(ptr nocapture readonly %Base, ptr nocapture %Dest, ptr nocapture readonly %Preds, i64 %extra_offset) {695; CHECK-LABEL: 'forked_ptrs_mul_by_offset'696; CHECK-NEXT: for.body:697; CHECK-NEXT: Report: cannot identify array bounds698; CHECK-NEXT: Dependences:699; CHECK-NEXT: Run-time memory checks:700; CHECK-NEXT: Check 0:701; CHECK-NEXT: Comparing group GRP0:702; CHECK-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv703; CHECK-NEXT: Against group GRP1:704; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv705; CHECK-NEXT: Grouped accesses:706; CHECK-NEXT: Group GRP0:707; CHECK-NEXT: (Low: %Dest High: (400 + %Dest))708; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%for.body>709; CHECK-NEXT: Group GRP1:710; CHECK-NEXT: (Low: %Preds High: (400 + %Preds))711; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body>712; CHECK-NEXT: Generated run-time checks are incomplete713; CHECK-EMPTY:714; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.715; CHECK-NEXT: SCEV assumptions:716; CHECK-EMPTY:717; CHECK-NEXT: Expressions re-written:718;719entry:720 br label %for.body721 722for.cond.cleanup: ; preds = %for.body723 ret void724 725for.body: ; preds = %entry, %for.body726 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]727 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv728 %0 = load i32, ptr %arrayidx, align 4729 %cmp.not = icmp eq i32 %0, 0730 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1731 %sel = select i1 %cmp.not, i64 %indvars.iv.next, i64 %indvars.iv732 %offset = mul nuw nsw i64 %sel, %extra_offset733 %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset734 %1 = load float, ptr %arrayidx3, align 4735 %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv736 store float %1, ptr %arrayidx5, align 4737 %exitcond.not = icmp eq i64 %indvars.iv.next, 100738 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body739}740 741;;;; Derived from forked_ptrs_same_base_different_offset with a manually742;;;; added uniform offset and a mul to provide a stride743 744define dso_local void @forked_ptrs_uniform_and_strided_forks(ptr nocapture readonly %Base, ptr nocapture %Dest, ptr nocapture readonly %Preds) {745; CHECK-LABEL: 'forked_ptrs_uniform_and_strided_forks'746; CHECK-NEXT: for.body:747; CHECK-NEXT: Report: cannot identify array bounds748; CHECK-NEXT: Dependences:749; CHECK-NEXT: Run-time memory checks:750; CHECK-NEXT: Check 0:751; CHECK-NEXT: Comparing group GRP0:752; CHECK-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv753; CHECK-NEXT: Against group GRP1:754; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv755; CHECK-NEXT: Grouped accesses:756; CHECK-NEXT: Group GRP0:757; CHECK-NEXT: (Low: %Dest High: (400 + %Dest))758; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%for.body>759; CHECK-NEXT: Group GRP1:760; CHECK-NEXT: (Low: %Preds High: (400 + %Preds))761; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body>762; CHECK-NEXT: Generated run-time checks are incomplete763; CHECK-EMPTY:764; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.765; CHECK-NEXT: SCEV assumptions:766; CHECK-EMPTY:767; CHECK-NEXT: Expressions re-written:768;769entry:770 br label %for.body771 772for.cond.cleanup: ; preds = %for.body773 ret void774 775for.body: ; preds = %entry, %for.body776 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]777 %i.014 = phi i32 [ 0, %entry ], [ %add, %for.body ]778 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv779 %0 = load i32, ptr %arrayidx, align 4780 %cmp1.not = icmp eq i32 %0, 0781 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1782 %add = add nuw nsw i32 %i.014, 1783 %1 = trunc i64 %indvars.iv to i32784 %mul = mul i32 %1, 3785 %offset.0 = select i1 %cmp1.not, i32 4, i32 %mul786 %idxprom213 = sext i32 %offset.0 to i64787 %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %idxprom213788 %2 = load float, ptr %arrayidx3, align 4789 %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv790 store float %2, ptr %arrayidx5, align 4791 %exitcond.not = icmp eq i64 %indvars.iv.next, 100792 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body793}794 795;;;; Derived from forked_ptrs_same_base_different_offset with a gather796;;;; added using Preds as an index array in addition to the per-iteration797;;;; condition.798 799define dso_local void @forked_ptrs_gather_and_contiguous_forks(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {800; CHECK-LABEL: 'forked_ptrs_gather_and_contiguous_forks'801; CHECK-NEXT: for.body:802; CHECK-NEXT: Report: cannot identify array bounds803; CHECK-NEXT: Dependences:804; CHECK-NEXT: Run-time memory checks:805; CHECK-NEXT: Check 0:806; CHECK-NEXT: Comparing group GRP0:807; CHECK-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv808; CHECK-NEXT: Against group GRP1:809; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv810; CHECK-NEXT: Grouped accesses:811; CHECK-NEXT: Group GRP0:812; CHECK-NEXT: (Low: %Dest High: (400 + %Dest))813; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%for.body>814; CHECK-NEXT: Group GRP1:815; CHECK-NEXT: (Low: %Preds High: (400 + %Preds))816; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body>817; CHECK-NEXT: Generated run-time checks are incomplete818; CHECK-EMPTY:819; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.820; CHECK-NEXT: SCEV assumptions:821; CHECK-EMPTY:822; CHECK-NEXT: Expressions re-written:823;824entry:825 br label %for.body826 827for.cond.cleanup: ; preds = %for.body828 ret void829 830for.body: ; preds = %entry, %for.body831 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]832 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv833 %0 = load i32, ptr %arrayidx, align 4834 %cmp1.not = icmp eq i32 %0, 0835 %arrayidx9 = getelementptr inbounds float, ptr %Base2, i64 %indvars.iv836 %idxprom4 = sext i32 %0 to i64837 %arrayidx5 = getelementptr inbounds float, ptr %Base1, i64 %idxprom4838 %.sink.in = select i1 %cmp1.not, ptr %arrayidx9, ptr %arrayidx5839 %.sink = load float, ptr %.sink.in, align 4840 %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv841 store float %.sink, ptr %1, align 4842 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1843 %exitcond.not = icmp eq i64 %indvars.iv.next, 100844 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body845}846 847;; We don't currently handle a fork in both the base and the offset of a848;; GEP instruction.849 850define dso_local void @forked_ptrs_two_forks_gep(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {851; CHECK-LABEL: 'forked_ptrs_two_forks_gep'852; CHECK-NEXT: for.body:853; CHECK-NEXT: Report: cannot identify array bounds854; CHECK-NEXT: Dependences:855; CHECK-NEXT: Run-time memory checks:856; CHECK-NEXT: Check 0:857; CHECK-NEXT: Comparing group GRP0:858; CHECK-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv859; CHECK-NEXT: Against group GRP1:860; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv861; CHECK-NEXT: Grouped accesses:862; CHECK-NEXT: Group GRP0:863; CHECK-NEXT: (Low: %Dest High: (400 + %Dest))864; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%for.body>865; CHECK-NEXT: Group GRP1:866; CHECK-NEXT: (Low: %Preds High: (400 + %Preds))867; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body>868; CHECK-NEXT: Generated run-time checks are incomplete869; CHECK-EMPTY:870; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.871; CHECK-NEXT: SCEV assumptions:872; CHECK-EMPTY:873; CHECK-NEXT: Expressions re-written:874;875entry:876 br label %for.body877 878for.cond.cleanup:879 ret void880 881for.body:882 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]883 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv884 %0 = load i32, ptr %arrayidx, align 4885 %cmp1.not = icmp eq i32 %0, 0886 %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1887 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1888 %offset = select i1 %cmp1.not, i64 %indvars.iv.next, i64 %indvars.iv889 %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %offset890 %.sink = load float, ptr %.sink.in, align 4891 %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv892 store float %.sink, ptr %1, align 4893 %exitcond.not = icmp eq i64 %indvars.iv.next, 100894 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body895}896 897;; We don't handle forks as children of a select898 899define void @forked_ptrs_two_select(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture readonly %Base3, ptr %Dest) {900; CHECK-LABEL: 'forked_ptrs_two_select'901; CHECK-NEXT: loop:902; CHECK-NEXT: Report: cannot identify array bounds903; CHECK-NEXT: Dependences:904; CHECK-NEXT: Run-time memory checks:905; CHECK-NEXT: Grouped accesses:906; CHECK-NEXT: Group GRP0:907; CHECK-NEXT: (Low: %Dest High: (400 + %Dest))908; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%loop>909; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%loop>910; CHECK-NEXT: Generated run-time checks are incomplete911; CHECK-EMPTY:912; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.913; CHECK-NEXT: SCEV assumptions:914; CHECK-EMPTY:915; CHECK-NEXT: Expressions re-written:916;917entry:918 br label %loop919 920loop:921 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]922 %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv923 %l.Dest = load float, ptr %gep.Dest924 %cmp = fcmp une float %l.Dest, 0.0925 %cmp1 = fcmp une float %l.Dest, 1.0926 %gep.1 = getelementptr inbounds float, ptr %Base1, i64 %iv927 %gep.2 = getelementptr inbounds float, ptr %Base2, i64 %iv928 %gep.3 = getelementptr inbounds float, ptr %Base3, i64 %iv929 %select = select i1 %cmp, ptr %gep.1, ptr %gep.2930 %select1 = select i1 %cmp1, ptr %select, ptr %gep.3931 %sink = load float, ptr %select1, align 4932 store float %sink, ptr %gep.Dest, align 4933 %iv.next = add nuw nsw i64 %iv, 1934 %exitcond.not = icmp eq i64 %iv.next, 100935 br i1 %exitcond.not, label %exit, label %loop936 937exit:938 ret void939}940 941;; We don't yet handle geps with more than 2 operands942 943define void @forked_ptrs_too_many_gep_ops(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {944; CHECK-LABEL: 'forked_ptrs_too_many_gep_ops'945; CHECK-NEXT: for.body:946; CHECK-NEXT: Report: cannot identify array bounds947; CHECK-NEXT: Dependences:948; CHECK-NEXT: Run-time memory checks:949; CHECK-NEXT: Check 0:950; CHECK-NEXT: Comparing group GRP0:951; CHECK-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv952; CHECK-NEXT: Against group GRP1:953; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv954; CHECK-NEXT: Grouped accesses:955; CHECK-NEXT: Group GRP0:956; CHECK-NEXT: (Low: %Dest High: (400 + %Dest))957; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%for.body>958; CHECK-NEXT: Group GRP1:959; CHECK-NEXT: (Low: %Preds High: (400 + %Preds))960; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body>961; CHECK-NEXT: Generated run-time checks are incomplete962; CHECK-EMPTY:963; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.964; CHECK-NEXT: SCEV assumptions:965; CHECK-EMPTY:966; CHECK-NEXT: Expressions re-written:967;968entry:969 br label %for.body970 971for.body:972 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]973 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv974 %0 = load i32, ptr %arrayidx, align 4975 %cmp1.not = icmp eq i32 %0, 0976 %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1977 %.sink.in = getelementptr inbounds [1000 x float], ptr %spec.select, i64 0, i64 %indvars.iv978 %.sink = load float, ptr %.sink.in, align 4979 %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv980 store float %.sink, ptr %1, align 4981 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1982 %exitcond.not = icmp eq i64 %indvars.iv.next, 100983 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body984 985for.cond.cleanup:986 ret void987}988 989;; We don't currently handle vector GEPs990 991define void @forked_ptrs_vector_gep(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {992; CHECK-LABEL: 'forked_ptrs_vector_gep'993; CHECK-NEXT: for.body:994; CHECK-NEXT: Report: cannot identify array bounds995; CHECK-NEXT: Dependences:996; CHECK-NEXT: Run-time memory checks:997; CHECK-NEXT: Check 0:998; CHECK-NEXT: Comparing group GRP0:999; CHECK-NEXT: %1 = getelementptr inbounds <4 x float>, ptr %Dest, i64 %indvars.iv1000; CHECK-NEXT: Against group GRP1:1001; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv1002; CHECK-NEXT: Grouped accesses:1003; CHECK-NEXT: Group GRP0:1004; CHECK-NEXT: (Low: %Dest High: (1552 + %Dest))1005; CHECK-NEXT: Member: {%Dest,+,64}<nuw><%for.body>1006; CHECK-NEXT: Group GRP1:1007; CHECK-NEXT: (Low: %Preds High: (388 + %Preds))1008; CHECK-NEXT: Member: {%Preds,+,16}<nuw><%for.body>1009; CHECK-NEXT: Generated run-time checks are incomplete1010; CHECK-EMPTY:1011; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.1012; CHECK-NEXT: SCEV assumptions:1013; CHECK-EMPTY:1014; CHECK-NEXT: Expressions re-written:1015;1016entry:1017 br label %for.body1018 1019for.body:1020 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]1021 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv1022 %0 = load i32, ptr %arrayidx, align 41023 %cmp1.not = icmp eq i32 %0, 01024 %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base11025 %.sink.in = getelementptr inbounds <4 x float>, ptr %spec.select, i64 %indvars.iv1026 %.sink = load <4 x float>, ptr %.sink.in, align 41027 %1 = getelementptr inbounds <4 x float>, ptr %Dest, i64 %indvars.iv1028 store <4 x float> %.sink, ptr %1, align 41029 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 41030 %exitcond.not = icmp eq i64 %indvars.iv.next, 1001031 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body1032 1033for.cond.cleanup:1034 ret void1035}1036 1037;;; The following test caused an ICE with the initial forked pointers work.1038;;; One fork is loop invariant (%Base2 + 0), the other is an scAddExpr that1039;;; contains an scAddRecExpr inside it:1040;;; ((8 * (zext i32 {0,+,1}<%for.body> to i64))<nuw><nsw> + %Base2)<nuw>1041;;;1042;;; RtCheck::insert was expecting either loop invariant or SAR, so asserted1043;;; on a plain scAddExpr. For now we restrict to loop invariant or SAR1044;;; forks only, but we should be able to do better.1045 1046define void @sc_add_expr_ice(ptr %Base1, ptr %Base2, i64 %N) {1047; CHECK-LABEL: 'sc_add_expr_ice'1048; CHECK-NEXT: for.body:1049; CHECK-NEXT: Memory dependences are safe with run-time checks1050; CHECK-NEXT: Dependences:1051; CHECK-NEXT: Run-time memory checks:1052; CHECK-NEXT: Check 0:1053; CHECK-NEXT: Comparing group GRP0:1054; CHECK-NEXT: ptr %Base11055; CHECK-NEXT: Against group GRP1:1056; CHECK-NEXT: %fptr = getelementptr inbounds double, ptr %Base2, i64 %sel1057; CHECK-NEXT: Grouped accesses:1058; CHECK-NEXT: Group GRP0:1059; CHECK-NEXT: (Low: %Base1 High: (8 + %Base1))1060; CHECK-NEXT: Member: %Base11061; CHECK-NEXT: Group GRP1:1062; CHECK-NEXT: (Low: %Base2 High: ((8 * %N) + %Base2))1063; CHECK-NEXT: Member: {%Base2,+,8}<%for.body>1064; CHECK-EMPTY:1065; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.1066; CHECK-NEXT: SCEV assumptions:1067; CHECK-NEXT: {0,+,1}<%for.body> Added Flags: <nusw>1068; CHECK-EMPTY:1069; CHECK-NEXT: Expressions re-written:1070; CHECK-NEXT: [PSE] %fptr = getelementptr inbounds double, ptr %Base2, i64 %sel:1071; CHECK-NEXT: ((8 * (zext i32 {0,+,1}<%for.body> to i64))<nuw><nsw> + %Base2)<nuw>1072; CHECK-NEXT: --> {%Base2,+,8}<%for.body>1073;1074entry:1075 br label %for.body1076 1077for.body:1078 %iv = phi i64 [ %iv.next, %for.body ], [ 0, %entry ]1079 %iv.trunc = trunc i64 %iv to i321080 store double 0.000000e+00, ptr %Base1, align 81081 %iv.zext = zext i32 %iv.trunc to i641082 %sel = select i1 true, i64 %iv.zext, i64 01083 %fptr = getelementptr inbounds double, ptr %Base2, i64 %sel1084 %dummy.load = load double, ptr %fptr, align 81085 %iv.next = add nuw nsw i64 %iv, 11086 %exitcond = icmp eq i64 %iv.next, %N1087 br i1 %exitcond, label %exit, label %for.body1088 1089exit:1090 ret void1091}1092 1093define void @forked_ptrs_with_different_base(ptr nocapture readonly %Preds, ptr nocapture %a, ptr nocapture %b, ptr nocapture readonly %c) {1094; CHECK-LABEL: 'forked_ptrs_with_different_base'1095; CHECK-NEXT: for.body:1096; CHECK-NEXT: Memory dependences are safe with run-time checks1097; CHECK-NEXT: Dependences:1098; CHECK-NEXT: Run-time memory checks:1099; CHECK-NEXT: Check 0:1100; CHECK-NEXT: Comparing group GRP0:1101; CHECK-NEXT: %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv1102; CHECK-NEXT: Against group GRP2:1103; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv1104; CHECK-NEXT: Check 1:1105; CHECK-NEXT: Comparing group GRP0:1106; CHECK-NEXT: %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv1107; CHECK-NEXT: Against group GRP3:1108; CHECK-NEXT: %arrayidx5 = getelementptr inbounds double, ptr %0, i64 %indvars.iv1109; CHECK-NEXT: Check 2:1110; CHECK-NEXT: Comparing group GRP1:1111; CHECK-NEXT: %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv1112; CHECK-NEXT: Against group GRP2:1113; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv1114; CHECK-NEXT: Check 3:1115; CHECK-NEXT: Comparing group GRP1:1116; CHECK-NEXT: %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv1117; CHECK-NEXT: Against group GRP3:1118; CHECK-NEXT: %arrayidx5 = getelementptr inbounds double, ptr %0, i64 %indvars.iv1119; CHECK-NEXT: Grouped accesses:1120; CHECK-NEXT: Group GRP0:1121; CHECK-NEXT: (Low: %1 High: (63992 + %1))1122; CHECK-NEXT: Member: {%1,+,8}<nw><%for.body>1123; CHECK-NEXT: Group GRP1:1124; CHECK-NEXT: (Low: %2 High: (63992 + %2))1125; CHECK-NEXT: Member: {%2,+,8}<nw><%for.body>1126; CHECK-NEXT: Group GRP2:1127; CHECK-NEXT: (Low: %Preds High: (31996 + %Preds))1128; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body>1129; CHECK-NEXT: Group GRP3:1130; CHECK-NEXT: (Low: %0 High: (63992 + %0))1131; CHECK-NEXT: Member: {%0,+,8}<nw><%for.body>1132; CHECK-EMPTY:1133; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.1134; CHECK-NEXT: SCEV assumptions:1135; CHECK-EMPTY:1136; CHECK-NEXT: Expressions re-written:1137;1138entry:1139 %0 = load ptr, ptr %c, align 641140 %1 = load ptr, ptr %a, align 641141 %2 = load ptr, ptr %b, align 641142 br label %for.body1143 1144for.cond.cleanup: ; preds = %for.inc1145 ret void1146 1147for.body: ; preds = %entry, %for.inc1148 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.inc ]1149 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv1150 %3 = load i32, ptr %arrayidx, align 41151 %cmp2.not = icmp eq i32 %3, 01152 br i1 %cmp2.not, label %if.else, label %if.then1153 1154if.then: ; preds = %for.body1155 %arrayidx5 = getelementptr inbounds double, ptr %0, i64 %indvars.iv1156 %4 = load double, ptr %arrayidx5, align 81157 %add = fadd fast double %4, 1.000000e+001158 br label %for.inc1159 1160if.else: ; preds = %for.body1161 %5 = mul nuw nsw i64 %indvars.iv, %indvars.iv1162 %6 = trunc i64 %5 to i321163 %conv8 = sitofp i32 %6 to double1164 br label %for.inc1165 1166for.inc: ; preds = %if.then, %if.else1167 %.sink = phi ptr [ %1, %if.then ], [ %2, %if.else ]1168 %add.sink = phi double [ %add, %if.then ], [ %conv8, %if.else ]1169 %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv1170 store double %add.sink, ptr %arrayidx7, align 81171 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 11172 %exitcond.not = icmp eq i64 %indvars.iv.next, 79991173 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body1174}1175 1176; Negative test: the operator number of PhiNode is not 2.1177define void @forked_ptrs_with_different_base3(ptr nocapture readonly %Preds, ptr nocapture %a, ptr nocapture %b, ptr nocapture readonly %c) {1178; CHECK-LABEL: 'forked_ptrs_with_different_base3'1179; CHECK-NEXT: for.body:1180; CHECK-NEXT: Report: cannot identify array bounds1181; CHECK-NEXT: Dependences:1182; CHECK-NEXT: Run-time memory checks:1183; CHECK-NEXT: Grouped accesses:1184; CHECK-NEXT: Group GRP0:1185; CHECK-NEXT: (Low: %Preds High: (31996 + %Preds))1186; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body>1187; CHECK-NEXT: Generated run-time checks are incomplete1188; CHECK-EMPTY:1189; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.1190; CHECK-NEXT: SCEV assumptions:1191; CHECK-EMPTY:1192; CHECK-NEXT: Expressions re-written:1193;1194entry:1195 %ld.c = load ptr, ptr %c, align 641196 %ld.a = load ptr, ptr %a, align 641197 %ld.b = load ptr, ptr %b, align 641198 br label %for.body1199 1200for.body: ; preds = %entry, %for.inc1201 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.inc ]1202 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv1203 %ld.preds = load i32, ptr %arrayidx, align 41204 switch i32 %ld.preds, label %if.else [1205 i32 0, label %if.br01206 i32 1, label %if.br11207 ]1208 1209if.br0: ; preds = %for.body1210 br label %for.inc1211 1212if.br1: ; preds = %for.body1213 br label %for.inc1214 1215if.else: ; preds = %for.body1216 br label %for.inc1217 1218for.inc: ; preds = %if.br1, %if.br01219 %.sink = phi ptr [ %ld.a, %if.br0 ], [ %ld.b, %if.br1 ], [ %ld.c, %if.else ]1220 %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv1221 store double 1.000000e+00, ptr %arrayidx7, align 81222 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 11223 %exitcond.not = icmp eq i64 %indvars.iv.next, 79991224 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body1225 1226for.cond.cleanup: ; preds = %for.inc1227 ret void1228}1229