1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 3 2; RUN: opt -disable-output -passes='print<access-info>' %s 2>&1 | FileCheck %s 3; RUN: opt -disable-output -passes='print<access-info>' -max-forked-scev-depth=2 %s 2>&1 | FileCheck -check-prefix=RECURSE %s 4 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 checks 11; CHECK-NEXT: Dependences: 12; CHECK-NEXT: Run-time memory checks: 13; CHECK-NEXT: Check 0: 14; CHECK-NEXT: Comparing group ([[GRP1:0x[0-9a-f]+]]): 15; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv 16; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv 17; CHECK-NEXT: Against group ([[GRP2:0x[0-9a-f]+]]): 18; CHECK-NEXT: %select = select i1 %cmp, ptr %gep.1, ptr %gep.2 19; CHECK-NEXT: Check 1: 20; CHECK-NEXT: Comparing group ([[GRP1]]): 21; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv 22; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv 23; CHECK-NEXT: Against group ([[GRP3:0x[0-9a-f]+]]): 24; CHECK-NEXT: %select = select i1 %cmp, ptr %gep.1, ptr %gep.2 25; CHECK-NEXT: Grouped accesses: 26; CHECK-NEXT: Group [[GRP1]]: 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 [[GRP2]]: 31; CHECK-NEXT: (Low: %Base1 High: (400 + %Base1)) 32; CHECK-NEXT: Member: {%Base1,+,4}<nw><%loop> 33; CHECK-NEXT: Group [[GRP3]]: 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; 42; RECURSE-LABEL: 'forked_ptrs_simple' 43; RECURSE-NEXT: loop: 44; RECURSE-NEXT: Memory dependences are safe with run-time checks 45; RECURSE-NEXT: Dependences: 46; RECURSE-NEXT: Run-time memory checks: 47; RECURSE-NEXT: Check 0: 48; RECURSE-NEXT: Comparing group ([[GRP4:0x[0-9a-f]+]]): 49; RECURSE-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv 50; RECURSE-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv 51; RECURSE-NEXT: Against group ([[GRP5:0x[0-9a-f]+]]): 52; RECURSE-NEXT: %select = select i1 %cmp, ptr %gep.1, ptr %gep.2 53; RECURSE-NEXT: Check 1: 54; RECURSE-NEXT: Comparing group ([[GRP4]]): 55; RECURSE-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv 56; RECURSE-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv 57; RECURSE-NEXT: Against group ([[GRP6:0x[0-9a-f]+]]): 58; RECURSE-NEXT: %select = select i1 %cmp, ptr %gep.1, ptr %gep.2 59; RECURSE-NEXT: Grouped accesses: 60; RECURSE-NEXT: Group [[GRP4]]: 61; RECURSE-NEXT: (Low: %Dest High: (400 + %Dest)) 62; RECURSE-NEXT: Member: {%Dest,+,4}<nuw><%loop> 63; RECURSE-NEXT: Member: {%Dest,+,4}<nuw><%loop> 64; RECURSE-NEXT: Group [[GRP5]]: 65; RECURSE-NEXT: (Low: %Base1 High: (400 + %Base1)) 66; RECURSE-NEXT: Member: {%Base1,+,4}<nw><%loop> 67; RECURSE-NEXT: Group [[GRP6]]: 68; RECURSE-NEXT: (Low: %Base2 High: (400 + %Base2)) 69; RECURSE-NEXT: Member: {%Base2,+,4}<nw><%loop> 70; RECURSE-EMPTY: 71; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 72; RECURSE-NEXT: SCEV assumptions: 73; RECURSE-EMPTY: 74; RECURSE-NEXT: Expressions re-written: 75; 76entry: 77 br label %loop 78 79loop: 80 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 81 %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv 82 %l.Dest = load float, ptr %gep.Dest 83 %cmp = fcmp une float %l.Dest, 0.0 84 %gep.1 = getelementptr inbounds float, ptr %Base1, i64 %iv 85 %gep.2 = getelementptr inbounds float, ptr %Base2, i64 %iv 86 %select = select i1 %cmp, ptr %gep.1, ptr %gep.2 87 %sink = load float, ptr %select, align 4 88 store float %sink, ptr %gep.Dest, align 4 89 %iv.next = add nuw nsw i64 %iv, 1 90 %exitcond.not = icmp eq i64 %iv.next, 100 91 br i1 %exitcond.not, label %exit, label %loop 92 93exit: 94 ret void 95} 96 97;; We have a limit on the recursion depth for finding a loop invariant or 98;; addrec term; confirm we won't exceed that depth by forcing a lower 99;; limit via -max-forked-scev-depth=2 100 101;;;; Derived from the following C code 102;; void forked_ptrs_different_base_same_offset(float *A, float *B, float *C, int *D) { 103;; for (int i=0; i<100; i++) { 104;; if (D[i] != 0) { 105;; C[i] = A[i]; 106;; } else { 107;; C[i] = B[i]; 108;; } 109;; } 110;; } 111 112define 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) { 113; CHECK-LABEL: 'forked_ptrs_different_base_same_offset' 114; CHECK-NEXT: for.body: 115; CHECK-NEXT: Memory dependences are safe with run-time checks 116; CHECK-NEXT: Dependences: 117; CHECK-NEXT: Run-time memory checks: 118; CHECK-NEXT: Check 0: 119; CHECK-NEXT: Comparing group ([[GRP7:0x[0-9a-f]+]]): 120; CHECK-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 121; CHECK-NEXT: Against group ([[GRP8:0x[0-9a-f]+]]): 122; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 123; CHECK-NEXT: Check 1: 124; CHECK-NEXT: Comparing group ([[GRP7]]): 125; CHECK-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 126; CHECK-NEXT: Against group ([[GRP9:0x[0-9a-f]+]]): 127; CHECK-NEXT: %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv 128; CHECK-NEXT: Check 2: 129; CHECK-NEXT: Comparing group ([[GRP7]]): 130; CHECK-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 131; CHECK-NEXT: Against group ([[GRP10:0x[0-9a-f]+]]): 132; CHECK-NEXT: %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv 133; CHECK-NEXT: Grouped accesses: 134; CHECK-NEXT: Group [[GRP7]]: 135; CHECK-NEXT: (Low: %Dest High: (400 + %Dest)) 136; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%for.body> 137; CHECK-NEXT: Group [[GRP8]]: 138; CHECK-NEXT: (Low: %Preds High: (400 + %Preds)) 139; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body> 140; CHECK-NEXT: Group [[GRP9]]: 141; CHECK-NEXT: (Low: %Base2 High: (400 + %Base2)) 142; CHECK-NEXT: Member: {%Base2,+,4}<nw><%for.body> 143; CHECK-NEXT: Group [[GRP10]]: 144; CHECK-NEXT: (Low: %Base1 High: (400 + %Base1)) 145; CHECK-NEXT: Member: {%Base1,+,4}<nw><%for.body> 146; CHECK-EMPTY: 147; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 148; CHECK-NEXT: SCEV assumptions: 149; CHECK-EMPTY: 150; CHECK-NEXT: Expressions re-written: 151; 152; RECURSE-LABEL: 'forked_ptrs_different_base_same_offset' 153; RECURSE-NEXT: for.body: 154; RECURSE-NEXT: Memory dependences are safe with run-time checks 155; RECURSE-NEXT: Dependences: 156; RECURSE-NEXT: Run-time memory checks: 157; RECURSE-NEXT: Check 0: 158; RECURSE-NEXT: Comparing group ([[GRP11:0x[0-9a-f]+]]): 159; RECURSE-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 160; RECURSE-NEXT: Against group ([[GRP12:0x[0-9a-f]+]]): 161; RECURSE-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 162; RECURSE-NEXT: Check 1: 163; RECURSE-NEXT: Comparing group ([[GRP11]]): 164; RECURSE-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 165; RECURSE-NEXT: Against group ([[GRP13:0x[0-9a-f]+]]): 166; RECURSE-NEXT: %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv 167; RECURSE-NEXT: Check 2: 168; RECURSE-NEXT: Comparing group ([[GRP11]]): 169; RECURSE-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 170; RECURSE-NEXT: Against group ([[GRP14:0x[0-9a-f]+]]): 171; RECURSE-NEXT: %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv 172; RECURSE-NEXT: Grouped accesses: 173; RECURSE-NEXT: Group [[GRP11]]: 174; RECURSE-NEXT: (Low: %Dest High: (400 + %Dest)) 175; RECURSE-NEXT: Member: {%Dest,+,4}<nuw><%for.body> 176; RECURSE-NEXT: Group [[GRP12]]: 177; RECURSE-NEXT: (Low: %Preds High: (400 + %Preds)) 178; RECURSE-NEXT: Member: {%Preds,+,4}<nuw><%for.body> 179; RECURSE-NEXT: Group [[GRP13]]: 180; RECURSE-NEXT: (Low: %Base2 High: (400 + %Base2)) 181; RECURSE-NEXT: Member: {%Base2,+,4}<nw><%for.body> 182; RECURSE-NEXT: Group [[GRP14]]: 183; RECURSE-NEXT: (Low: %Base1 High: (400 + %Base1)) 184; RECURSE-NEXT: Member: {%Base1,+,4}<nw><%for.body> 185; RECURSE-EMPTY: 186; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 187; RECURSE-NEXT: SCEV assumptions: 188; RECURSE-EMPTY: 189; RECURSE-NEXT: Expressions re-written: 190; 191entry: 192 br label %for.body 193 194for.cond.cleanup: 195 ret void 196 197for.body: 198 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 199 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 200 %0 = load i32, ptr %arrayidx, align 4 201 %cmp1.not = icmp eq i32 %0, 0 202 %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1 203 %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv 204 %.sink = load float, ptr %.sink.in, align 4 205 %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 206 store float %.sink, ptr %1, align 4 207 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 208 %exitcond.not = icmp eq i64 %indvars.iv.next, 100 209 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 210} 211 212define 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) { 213; CHECK-LABEL: 'forked_ptrs_different_base_same_offset_64b' 214; CHECK-NEXT: for.body: 215; CHECK-NEXT: Memory dependences are safe with run-time checks 216; CHECK-NEXT: Dependences: 217; CHECK-NEXT: Run-time memory checks: 218; CHECK-NEXT: Check 0: 219; CHECK-NEXT: Comparing group ([[GRP15:0x[0-9a-f]+]]): 220; CHECK-NEXT: %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv 221; CHECK-NEXT: Against group ([[GRP16:0x[0-9a-f]+]]): 222; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 223; CHECK-NEXT: Check 1: 224; CHECK-NEXT: Comparing group ([[GRP15]]): 225; CHECK-NEXT: %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv 226; CHECK-NEXT: Against group ([[GRP17:0x[0-9a-f]+]]): 227; CHECK-NEXT: %.sink.in = getelementptr inbounds double, ptr %spec.select, i64 %indvars.iv 228; CHECK-NEXT: Check 2: 229; CHECK-NEXT: Comparing group ([[GRP15]]): 230; CHECK-NEXT: %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv 231; CHECK-NEXT: Against group ([[GRP18:0x[0-9a-f]+]]): 232; CHECK-NEXT: %.sink.in = getelementptr inbounds double, ptr %spec.select, i64 %indvars.iv 233; CHECK-NEXT: Grouped accesses: 234; CHECK-NEXT: Group [[GRP15]]: 235; CHECK-NEXT: (Low: %Dest High: (800 + %Dest)) 236; CHECK-NEXT: Member: {%Dest,+,8}<nuw><%for.body> 237; CHECK-NEXT: Group [[GRP16]]: 238; CHECK-NEXT: (Low: %Preds High: (400 + %Preds)) 239; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body> 240; CHECK-NEXT: Group [[GRP17]]: 241; CHECK-NEXT: (Low: %Base2 High: (800 + %Base2)) 242; CHECK-NEXT: Member: {%Base2,+,8}<nw><%for.body> 243; CHECK-NEXT: Group [[GRP18]]: 244; CHECK-NEXT: (Low: %Base1 High: (800 + %Base1)) 245; CHECK-NEXT: Member: {%Base1,+,8}<nw><%for.body> 246; CHECK-EMPTY: 247; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 248; CHECK-NEXT: SCEV assumptions: 249; CHECK-EMPTY: 250; CHECK-NEXT: Expressions re-written: 251; 252; RECURSE-LABEL: 'forked_ptrs_different_base_same_offset_64b' 253; RECURSE-NEXT: for.body: 254; RECURSE-NEXT: Memory dependences are safe with run-time checks 255; RECURSE-NEXT: Dependences: 256; RECURSE-NEXT: Run-time memory checks: 257; RECURSE-NEXT: Check 0: 258; RECURSE-NEXT: Comparing group ([[GRP19:0x[0-9a-f]+]]): 259; RECURSE-NEXT: %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv 260; RECURSE-NEXT: Against group ([[GRP20:0x[0-9a-f]+]]): 261; RECURSE-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 262; RECURSE-NEXT: Check 1: 263; RECURSE-NEXT: Comparing group ([[GRP19]]): 264; RECURSE-NEXT: %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv 265; RECURSE-NEXT: Against group ([[GRP21:0x[0-9a-f]+]]): 266; RECURSE-NEXT: %.sink.in = getelementptr inbounds double, ptr %spec.select, i64 %indvars.iv 267; RECURSE-NEXT: Check 2: 268; RECURSE-NEXT: Comparing group ([[GRP19]]): 269; RECURSE-NEXT: %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv 270; RECURSE-NEXT: Against group ([[GRP22:0x[0-9a-f]+]]): 271; RECURSE-NEXT: %.sink.in = getelementptr inbounds double, ptr %spec.select, i64 %indvars.iv 272; RECURSE-NEXT: Grouped accesses: 273; RECURSE-NEXT: Group [[GRP19]]: 274; RECURSE-NEXT: (Low: %Dest High: (800 + %Dest)) 275; RECURSE-NEXT: Member: {%Dest,+,8}<nuw><%for.body> 276; RECURSE-NEXT: Group [[GRP20]]: 277; RECURSE-NEXT: (Low: %Preds High: (400 + %Preds)) 278; RECURSE-NEXT: Member: {%Preds,+,4}<nuw><%for.body> 279; RECURSE-NEXT: Group [[GRP21]]: 280; RECURSE-NEXT: (Low: %Base2 High: (800 + %Base2)) 281; RECURSE-NEXT: Member: {%Base2,+,8}<nw><%for.body> 282; RECURSE-NEXT: Group [[GRP22]]: 283; RECURSE-NEXT: (Low: %Base1 High: (800 + %Base1)) 284; RECURSE-NEXT: Member: {%Base1,+,8}<nw><%for.body> 285; RECURSE-EMPTY: 286; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 287; RECURSE-NEXT: SCEV assumptions: 288; RECURSE-EMPTY: 289; RECURSE-NEXT: Expressions re-written: 290; 291entry: 292 br label %for.body 293 294for.cond.cleanup: 295 ret void 296 297for.body: 298 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 299 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 300 %0 = load i32, ptr %arrayidx, align 4 301 %cmp1.not = icmp eq i32 %0, 0 302 %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1 303 %.sink.in = getelementptr inbounds double, ptr %spec.select, i64 %indvars.iv 304 %.sink = load double, ptr %.sink.in, align 8 305 %1 = getelementptr inbounds double, ptr %Dest, i64 %indvars.iv 306 store double %.sink, ptr %1, align 8 307 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 308 %exitcond.not = icmp eq i64 %indvars.iv.next, 100 309 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 310} 311 312define 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) { 313; CHECK-LABEL: 'forked_ptrs_different_base_same_offset_23b' 314; CHECK-NEXT: for.body: 315; CHECK-NEXT: Memory dependences are safe with run-time checks 316; CHECK-NEXT: Dependences: 317; CHECK-NEXT: Run-time memory checks: 318; CHECK-NEXT: Check 0: 319; CHECK-NEXT: Comparing group ([[GRP23:0x[0-9a-f]+]]): 320; CHECK-NEXT: %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv 321; CHECK-NEXT: Against group ([[GRP24:0x[0-9a-f]+]]): 322; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 323; CHECK-NEXT: Check 1: 324; CHECK-NEXT: Comparing group ([[GRP23]]): 325; CHECK-NEXT: %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv 326; CHECK-NEXT: Against group ([[GRP25:0x[0-9a-f]+]]): 327; CHECK-NEXT: %.sink.in = getelementptr inbounds i23, ptr %spec.select, i64 %indvars.iv 328; CHECK-NEXT: Check 2: 329; CHECK-NEXT: Comparing group ([[GRP23]]): 330; CHECK-NEXT: %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv 331; CHECK-NEXT: Against group ([[GRP26:0x[0-9a-f]+]]): 332; CHECK-NEXT: %.sink.in = getelementptr inbounds i23, ptr %spec.select, i64 %indvars.iv 333; CHECK-NEXT: Grouped accesses: 334; CHECK-NEXT: Group [[GRP23]]: 335; CHECK-NEXT: (Low: %Dest High: (399 + %Dest)) 336; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%for.body> 337; CHECK-NEXT: Group [[GRP24]]: 338; CHECK-NEXT: (Low: %Preds High: (400 + %Preds)) 339; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body> 340; CHECK-NEXT: Group [[GRP25]]: 341; CHECK-NEXT: (Low: %Base2 High: (399 + %Base2)) 342; CHECK-NEXT: Member: {%Base2,+,4}<nw><%for.body> 343; CHECK-NEXT: Group [[GRP26]]: 344; CHECK-NEXT: (Low: %Base1 High: (399 + %Base1)) 345; CHECK-NEXT: Member: {%Base1,+,4}<nw><%for.body> 346; CHECK-EMPTY: 347; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 348; CHECK-NEXT: SCEV assumptions: 349; CHECK-EMPTY: 350; CHECK-NEXT: Expressions re-written: 351; 352; RECURSE-LABEL: 'forked_ptrs_different_base_same_offset_23b' 353; RECURSE-NEXT: for.body: 354; RECURSE-NEXT: Memory dependences are safe with run-time checks 355; RECURSE-NEXT: Dependences: 356; RECURSE-NEXT: Run-time memory checks: 357; RECURSE-NEXT: Check 0: 358; RECURSE-NEXT: Comparing group ([[GRP27:0x[0-9a-f]+]]): 359; RECURSE-NEXT: %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv 360; RECURSE-NEXT: Against group ([[GRP28:0x[0-9a-f]+]]): 361; RECURSE-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 362; RECURSE-NEXT: Check 1: 363; RECURSE-NEXT: Comparing group ([[GRP27]]): 364; RECURSE-NEXT: %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv 365; RECURSE-NEXT: Against group ([[GRP29:0x[0-9a-f]+]]): 366; RECURSE-NEXT: %.sink.in = getelementptr inbounds i23, ptr %spec.select, i64 %indvars.iv 367; RECURSE-NEXT: Check 2: 368; RECURSE-NEXT: Comparing group ([[GRP27]]): 369; RECURSE-NEXT: %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv 370; RECURSE-NEXT: Against group ([[GRP30:0x[0-9a-f]+]]): 371; RECURSE-NEXT: %.sink.in = getelementptr inbounds i23, ptr %spec.select, i64 %indvars.iv 372; RECURSE-NEXT: Grouped accesses: 373; RECURSE-NEXT: Group [[GRP27]]: 374; RECURSE-NEXT: (Low: %Dest High: (399 + %Dest)) 375; RECURSE-NEXT: Member: {%Dest,+,4}<nuw><%for.body> 376; RECURSE-NEXT: Group [[GRP28]]: 377; RECURSE-NEXT: (Low: %Preds High: (400 + %Preds)) 378; RECURSE-NEXT: Member: {%Preds,+,4}<nuw><%for.body> 379; RECURSE-NEXT: Group [[GRP29]]: 380; RECURSE-NEXT: (Low: %Base2 High: (399 + %Base2)) 381; RECURSE-NEXT: Member: {%Base2,+,4}<nw><%for.body> 382; RECURSE-NEXT: Group [[GRP30]]: 383; RECURSE-NEXT: (Low: %Base1 High: (399 + %Base1)) 384; RECURSE-NEXT: Member: {%Base1,+,4}<nw><%for.body> 385; RECURSE-EMPTY: 386; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 387; RECURSE-NEXT: SCEV assumptions: 388; RECURSE-EMPTY: 389; RECURSE-NEXT: Expressions re-written: 390; 391entry: 392 br label %for.body 393 394for.cond.cleanup: 395 ret void 396 397for.body: 398 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 399 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 400 %0 = load i32, ptr %arrayidx, align 4 401 %cmp1.not = icmp eq i32 %0, 0 402 %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1 403 %.sink.in = getelementptr inbounds i23, ptr %spec.select, i64 %indvars.iv 404 %.sink = load i23, ptr %.sink.in 405 %1 = getelementptr inbounds i23, ptr %Dest, i64 %indvars.iv 406 store i23 %.sink, ptr %1 407 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 408 %exitcond.not = icmp eq i64 %indvars.iv.next, 100 409 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 410} 411 412define 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) { 413; CHECK-LABEL: 'forked_ptrs_different_base_same_offset_6b' 414; CHECK-NEXT: for.body: 415; CHECK-NEXT: Memory dependences are safe with run-time checks 416; CHECK-NEXT: Dependences: 417; CHECK-NEXT: Run-time memory checks: 418; CHECK-NEXT: Check 0: 419; CHECK-NEXT: Comparing group ([[GRP31:0x[0-9a-f]+]]): 420; CHECK-NEXT: %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv 421; CHECK-NEXT: Against group ([[GRP32:0x[0-9a-f]+]]): 422; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 423; CHECK-NEXT: Check 1: 424; CHECK-NEXT: Comparing group ([[GRP31]]): 425; CHECK-NEXT: %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv 426; CHECK-NEXT: Against group ([[GRP33:0x[0-9a-f]+]]): 427; CHECK-NEXT: %.sink.in = getelementptr inbounds i6, ptr %spec.select, i64 %indvars.iv 428; CHECK-NEXT: Check 2: 429; CHECK-NEXT: Comparing group ([[GRP31]]): 430; CHECK-NEXT: %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv 431; CHECK-NEXT: Against group ([[GRP34:0x[0-9a-f]+]]): 432; CHECK-NEXT: %.sink.in = getelementptr inbounds i6, ptr %spec.select, i64 %indvars.iv 433; CHECK-NEXT: Grouped accesses: 434; CHECK-NEXT: Group [[GRP31]]: 435; CHECK-NEXT: (Low: %Dest High: (100 + %Dest)) 436; CHECK-NEXT: Member: {%Dest,+,1}<nuw><%for.body> 437; CHECK-NEXT: Group [[GRP32]]: 438; CHECK-NEXT: (Low: %Preds High: (400 + %Preds)) 439; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body> 440; CHECK-NEXT: Group [[GRP33]]: 441; CHECK-NEXT: (Low: %Base2 High: (100 + %Base2)) 442; CHECK-NEXT: Member: {%Base2,+,1}<nw><%for.body> 443; CHECK-NEXT: Group [[GRP34]]: 444; CHECK-NEXT: (Low: %Base1 High: (100 + %Base1)) 445; CHECK-NEXT: Member: {%Base1,+,1}<nw><%for.body> 446; CHECK-EMPTY: 447; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 448; CHECK-NEXT: SCEV assumptions: 449; CHECK-EMPTY: 450; CHECK-NEXT: Expressions re-written: 451; 452; RECURSE-LABEL: 'forked_ptrs_different_base_same_offset_6b' 453; RECURSE-NEXT: for.body: 454; RECURSE-NEXT: Memory dependences are safe with run-time checks 455; RECURSE-NEXT: Dependences: 456; RECURSE-NEXT: Run-time memory checks: 457; RECURSE-NEXT: Check 0: 458; RECURSE-NEXT: Comparing group ([[GRP35:0x[0-9a-f]+]]): 459; RECURSE-NEXT: %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv 460; RECURSE-NEXT: Against group ([[GRP36:0x[0-9a-f]+]]): 461; RECURSE-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 462; RECURSE-NEXT: Check 1: 463; RECURSE-NEXT: Comparing group ([[GRP35]]): 464; RECURSE-NEXT: %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv 465; RECURSE-NEXT: Against group ([[GRP37:0x[0-9a-f]+]]): 466; RECURSE-NEXT: %.sink.in = getelementptr inbounds i6, ptr %spec.select, i64 %indvars.iv 467; RECURSE-NEXT: Check 2: 468; RECURSE-NEXT: Comparing group ([[GRP35]]): 469; RECURSE-NEXT: %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv 470; RECURSE-NEXT: Against group ([[GRP38:0x[0-9a-f]+]]): 471; RECURSE-NEXT: %.sink.in = getelementptr inbounds i6, ptr %spec.select, i64 %indvars.iv 472; RECURSE-NEXT: Grouped accesses: 473; RECURSE-NEXT: Group [[GRP35]]: 474; RECURSE-NEXT: (Low: %Dest High: (100 + %Dest)) 475; RECURSE-NEXT: Member: {%Dest,+,1}<nuw><%for.body> 476; RECURSE-NEXT: Group [[GRP36]]: 477; RECURSE-NEXT: (Low: %Preds High: (400 + %Preds)) 478; RECURSE-NEXT: Member: {%Preds,+,4}<nuw><%for.body> 479; RECURSE-NEXT: Group [[GRP37]]: 480; RECURSE-NEXT: (Low: %Base2 High: (100 + %Base2)) 481; RECURSE-NEXT: Member: {%Base2,+,1}<nw><%for.body> 482; RECURSE-NEXT: Group [[GRP38]]: 483; RECURSE-NEXT: (Low: %Base1 High: (100 + %Base1)) 484; RECURSE-NEXT: Member: {%Base1,+,1}<nw><%for.body> 485; RECURSE-EMPTY: 486; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 487; RECURSE-NEXT: SCEV assumptions: 488; RECURSE-EMPTY: 489; RECURSE-NEXT: Expressions re-written: 490; 491entry: 492 br label %for.body 493 494for.cond.cleanup: 495 ret void 496 497for.body: 498 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 499 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 500 %0 = load i32, ptr %arrayidx, align 4 501 %cmp1.not = icmp eq i32 %0, 0 502 %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1 503 %.sink.in = getelementptr inbounds i6, ptr %spec.select, i64 %indvars.iv 504 %.sink = load i6, ptr %.sink.in 505 %1 = getelementptr inbounds i6, ptr %Dest, i64 %indvars.iv 506 store i6 %.sink, ptr %1 507 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 508 %exitcond.not = icmp eq i64 %indvars.iv.next, 100 509 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 510} 511 512define 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) { 513; CHECK-LABEL: 'forked_ptrs_different_base_same_offset_possible_poison' 514; CHECK-NEXT: for.body: 515; CHECK-NEXT: Memory dependences are safe with run-time checks 516; CHECK-NEXT: Dependences: 517; CHECK-NEXT: Run-time memory checks: 518; CHECK-NEXT: Check 0: 519; CHECK-NEXT: Comparing group ([[GRP39:0x[0-9a-f]+]]): 520; CHECK-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 521; CHECK-NEXT: Against group ([[GRP40:0x[0-9a-f]+]]): 522; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 523; CHECK-NEXT: Check 1: 524; CHECK-NEXT: Comparing group ([[GRP39]]): 525; CHECK-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 526; CHECK-NEXT: Against group ([[GRP41:0x[0-9a-f]+]]): 527; CHECK-NEXT: %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv 528; CHECK-NEXT: Check 2: 529; CHECK-NEXT: Comparing group ([[GRP39]]): 530; CHECK-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 531; CHECK-NEXT: Against group ([[GRP42:0x[0-9a-f]+]]): 532; CHECK-NEXT: %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv 533; CHECK-NEXT: Grouped accesses: 534; CHECK-NEXT: Group [[GRP39]]: 535; CHECK-NEXT: (Low: %Dest High: (400 + %Dest)) 536; CHECK-NEXT: Member: {%Dest,+,4}<nw><%for.body> 537; CHECK-NEXT: Group [[GRP40]]: 538; CHECK-NEXT: (Low: %Preds High: (400 + %Preds)) 539; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body> 540; CHECK-NEXT: Group [[GRP41]]: 541; CHECK-NEXT: (Low: %Base2 High: (400 + %Base2)) 542; CHECK-NEXT: Member: {%Base2,+,4}<nw><%for.body> 543; CHECK-NEXT: Group [[GRP42]]: 544; CHECK-NEXT: (Low: %Base1 High: (400 + %Base1)) 545; CHECK-NEXT: Member: {%Base1,+,4}<nw><%for.body> 546; CHECK-EMPTY: 547; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 548; CHECK-NEXT: SCEV assumptions: 549; CHECK-EMPTY: 550; CHECK-NEXT: Expressions re-written: 551; 552; RECURSE-LABEL: 'forked_ptrs_different_base_same_offset_possible_poison' 553; RECURSE-NEXT: for.body: 554; RECURSE-NEXT: Memory dependences are safe with run-time checks 555; RECURSE-NEXT: Dependences: 556; RECURSE-NEXT: Run-time memory checks: 557; RECURSE-NEXT: Check 0: 558; RECURSE-NEXT: Comparing group ([[GRP43:0x[0-9a-f]+]]): 559; RECURSE-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 560; RECURSE-NEXT: Against group ([[GRP44:0x[0-9a-f]+]]): 561; RECURSE-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 562; RECURSE-NEXT: Check 1: 563; RECURSE-NEXT: Comparing group ([[GRP43]]): 564; RECURSE-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 565; RECURSE-NEXT: Against group ([[GRP45:0x[0-9a-f]+]]): 566; RECURSE-NEXT: %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv 567; RECURSE-NEXT: Check 2: 568; RECURSE-NEXT: Comparing group ([[GRP43]]): 569; RECURSE-NEXT: %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 570; RECURSE-NEXT: Against group ([[GRP46:0x[0-9a-f]+]]): 571; RECURSE-NEXT: %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv 572; RECURSE-NEXT: Grouped accesses: 573; RECURSE-NEXT: Group [[GRP43]]: 574; RECURSE-NEXT: (Low: %Dest High: (400 + %Dest)) 575; RECURSE-NEXT: Member: {%Dest,+,4}<nw><%for.body> 576; RECURSE-NEXT: Group [[GRP44]]: 577; RECURSE-NEXT: (Low: %Preds High: (400 + %Preds)) 578; RECURSE-NEXT: Member: {%Preds,+,4}<nuw><%for.body> 579; RECURSE-NEXT: Group [[GRP45]]: 580; RECURSE-NEXT: (Low: %Base2 High: (400 + %Base2)) 581; RECURSE-NEXT: Member: {%Base2,+,4}<nw><%for.body> 582; RECURSE-NEXT: Group [[GRP46]]: 583; RECURSE-NEXT: (Low: %Base1 High: (400 + %Base1)) 584; RECURSE-NEXT: Member: {%Base1,+,4}<nw><%for.body> 585; RECURSE-EMPTY: 586; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 587; RECURSE-NEXT: SCEV assumptions: 588; RECURSE-EMPTY: 589; RECURSE-NEXT: Expressions re-written: 590; 591entry: 592 br label %for.body 593 594for.cond.cleanup: 595 ret void 596 597for.body: 598 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %latch ] 599 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 600 %0 = load i32, ptr %arrayidx, align 4 601 %cmp1.not = icmp eq i32 %0, 0 602 %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1 603 %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv 604 %.sink = load float, ptr %.sink.in, align 4 605 %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 606 br i1 %c, label %then, label %latch 607 608then: 609 store float %.sink, ptr %1, align 4 610 br label %latch 611 612latch: 613 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 614 %exitcond.not = icmp eq i64 %indvars.iv.next, 100 615 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 616} 617 618;;;; Derived from the following C code 619;; void forked_ptrs_same_base_different_offset(float *A, float *B, int *C) { 620;; int offset; 621;; for (int i = 0; i < 100; i++) { 622;; if (C[i] != 0) 623;; offset = i; 624;; else 625;; offset = i+1; 626;; B[i] = A[offset]; 627;; } 628;; } 629 630define dso_local void @forked_ptrs_same_base_different_offset(ptr nocapture readonly %Base, ptr nocapture %Dest, ptr nocapture readonly %Preds) { 631; CHECK-LABEL: 'forked_ptrs_same_base_different_offset' 632; CHECK-NEXT: for.body: 633; CHECK-NEXT: Report: cannot identify array bounds 634; CHECK-NEXT: Dependences: 635; CHECK-NEXT: Run-time memory checks: 636; CHECK-NEXT: Grouped accesses: 637; CHECK-EMPTY: 638; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 639; CHECK-NEXT: SCEV assumptions: 640; CHECK-EMPTY: 641; CHECK-NEXT: Expressions re-written: 642; 643; RECURSE-LABEL: 'forked_ptrs_same_base_different_offset' 644; RECURSE-NEXT: for.body: 645; RECURSE-NEXT: Report: cannot identify array bounds 646; RECURSE-NEXT: Dependences: 647; RECURSE-NEXT: Run-time memory checks: 648; RECURSE-NEXT: Grouped accesses: 649; RECURSE-EMPTY: 650; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 651; RECURSE-NEXT: SCEV assumptions: 652; RECURSE-EMPTY: 653; RECURSE-NEXT: Expressions re-written: 654; 655entry: 656 br label %for.body 657 658for.cond.cleanup: ; preds = %for.body 659 ret void 660 661for.body: ; preds = %entry, %for.body 662 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 663 %i.014 = phi i32 [ 0, %entry ], [ %add, %for.body ] 664 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 665 %0 = load i32, ptr %arrayidx, align 4 666 %cmp1.not = icmp eq i32 %0, 0 667 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 668 %add = add nuw nsw i32 %i.014, 1 669 %1 = trunc i64 %indvars.iv to i32 670 %offset.0 = select i1 %cmp1.not, i32 %add, i32 %1 671 %idxprom213 = zext i32 %offset.0 to i64 672 %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %idxprom213 673 %2 = load float, ptr %arrayidx3, align 4 674 %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 675 store float %2, ptr %arrayidx5, align 4 676 %exitcond.not = icmp eq i64 %indvars.iv.next, 100 677 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 678} 679 680define dso_local void @forked_ptrs_add_to_offset(ptr nocapture readonly %Base, ptr nocapture %Dest, ptr nocapture readonly %Preds, i64 %extra_offset) { 681; CHECK-LABEL: 'forked_ptrs_add_to_offset' 682; CHECK-NEXT: for.body: 683; CHECK-NEXT: Memory dependences are safe with run-time checks 684; CHECK-NEXT: Dependences: 685; CHECK-NEXT: Run-time memory checks: 686; CHECK-NEXT: Check 0: 687; CHECK-NEXT: Comparing group ([[GRP47:0x[0-9a-f]+]]): 688; CHECK-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 689; CHECK-NEXT: Against group ([[GRP48:0x[0-9a-f]+]]): 690; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 691; CHECK-NEXT: Check 1: 692; CHECK-NEXT: Comparing group ([[GRP47]]): 693; CHECK-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 694; CHECK-NEXT: Against group ([[GRP49:0x[0-9a-f]+]]): 695; CHECK-NEXT: %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset 696; CHECK-NEXT: %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset 697; CHECK-NEXT: Grouped accesses: 698; CHECK-NEXT: Group [[GRP47]]: 699; CHECK-NEXT: (Low: %Dest High: (400 + %Dest)) 700; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%for.body> 701; CHECK-NEXT: Group [[GRP48]]: 702; CHECK-NEXT: (Low: %Preds High: (400 + %Preds)) 703; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body> 704; CHECK-NEXT: Group [[GRP49]]: 705; CHECK-NEXT: (Low: ((4 * %extra_offset) + %Base) High: (404 + (4 * %extra_offset) + %Base)) 706; CHECK-NEXT: Member: {(4 + (4 * %extra_offset) + %Base),+,4}<%for.body> 707; CHECK-NEXT: Member: {((4 * %extra_offset) + %Base),+,4}<%for.body> 708; CHECK-EMPTY: 709; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 710; CHECK-NEXT: SCEV assumptions: 711; CHECK-EMPTY: 712; CHECK-NEXT: Expressions re-written: 713; 714; RECURSE-LABEL: 'forked_ptrs_add_to_offset' 715; RECURSE-NEXT: for.body: 716; RECURSE-NEXT: Report: cannot identify array bounds 717; RECURSE-NEXT: Dependences: 718; RECURSE-NEXT: Run-time memory checks: 719; RECURSE-NEXT: Grouped accesses: 720; RECURSE-EMPTY: 721; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 722; RECURSE-NEXT: SCEV assumptions: 723; RECURSE-EMPTY: 724; RECURSE-NEXT: Expressions re-written: 725; 726entry: 727 br label %for.body 728 729for.cond.cleanup: ; preds = %for.body 730 ret void 731 732for.body: ; preds = %entry, %for.body 733 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 734 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 735 %0 = load i32, ptr %arrayidx, align 4 736 %cmp.not = icmp eq i32 %0, 0 737 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 738 %sel = select i1 %cmp.not, i64 %indvars.iv.next, i64 %indvars.iv 739 %offset = add nuw nsw i64 %sel, %extra_offset 740 %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset 741 %1 = load float, ptr %arrayidx3, align 4 742 %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 743 store float %1, ptr %arrayidx5, align 4 744 %exitcond.not = icmp eq i64 %indvars.iv.next, 100 745 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 746} 747 748define dso_local void @forked_ptrs_sub_from_offset(ptr nocapture readonly %Base, ptr nocapture %Dest, ptr nocapture readonly %Preds, i64 %extra_offset) { 749; CHECK-LABEL: 'forked_ptrs_sub_from_offset' 750; CHECK-NEXT: for.body: 751; CHECK-NEXT: Memory dependences are safe with run-time checks 752; CHECK-NEXT: Dependences: 753; CHECK-NEXT: Run-time memory checks: 754; CHECK-NEXT: Check 0: 755; CHECK-NEXT: Comparing group ([[GRP50:0x[0-9a-f]+]]): 756; CHECK-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 757; CHECK-NEXT: Against group ([[GRP51:0x[0-9a-f]+]]): 758; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 759; CHECK-NEXT: Check 1: 760; CHECK-NEXT: Comparing group ([[GRP50]]): 761; CHECK-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 762; CHECK-NEXT: Against group ([[GRP52:0x[0-9a-f]+]]): 763; CHECK-NEXT: %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset 764; CHECK-NEXT: %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset 765; CHECK-NEXT: Grouped accesses: 766; CHECK-NEXT: Group [[GRP50]]: 767; CHECK-NEXT: (Low: %Dest High: (400 + %Dest)) 768; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%for.body> 769; CHECK-NEXT: Group [[GRP51]]: 770; CHECK-NEXT: (Low: %Preds High: (400 + %Preds)) 771; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body> 772; CHECK-NEXT: Group [[GRP52]]: 773; CHECK-NEXT: (Low: ((-4 * %extra_offset) + %Base) High: (404 + (-4 * %extra_offset) + %Base)) 774; CHECK-NEXT: Member: {(4 + (-4 * %extra_offset) + %Base),+,4}<%for.body> 775; CHECK-NEXT: Member: {((-4 * %extra_offset) + %Base),+,4}<%for.body> 776; CHECK-EMPTY: 777; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 778; CHECK-NEXT: SCEV assumptions: 779; CHECK-EMPTY: 780; CHECK-NEXT: Expressions re-written: 781; 782; RECURSE-LABEL: 'forked_ptrs_sub_from_offset' 783; RECURSE-NEXT: for.body: 784; RECURSE-NEXT: Report: cannot identify array bounds 785; RECURSE-NEXT: Dependences: 786; RECURSE-NEXT: Run-time memory checks: 787; RECURSE-NEXT: Grouped accesses: 788; RECURSE-EMPTY: 789; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 790; RECURSE-NEXT: SCEV assumptions: 791; RECURSE-EMPTY: 792; RECURSE-NEXT: Expressions re-written: 793; 794entry: 795 br label %for.body 796 797for.cond.cleanup: ; preds = %for.body 798 ret void 799 800for.body: ; preds = %entry, %for.body 801 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 802 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 803 %0 = load i32, ptr %arrayidx, align 4 804 %cmp.not = icmp eq i32 %0, 0 805 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 806 %sel = select i1 %cmp.not, i64 %indvars.iv.next, i64 %indvars.iv 807 %offset = sub nuw nsw i64 %sel, %extra_offset 808 %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset 809 %1 = load float, ptr %arrayidx3, align 4 810 %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 811 store float %1, ptr %arrayidx5, align 4 812 %exitcond.not = icmp eq i64 %indvars.iv.next, 100 813 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 814} 815 816define 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) { 817; CHECK-LABEL: 'forked_ptrs_add_sub_offset' 818; CHECK-NEXT: for.body: 819; CHECK-NEXT: Memory dependences are safe with run-time checks 820; CHECK-NEXT: Dependences: 821; CHECK-NEXT: Run-time memory checks: 822; CHECK-NEXT: Check 0: 823; CHECK-NEXT: Comparing group ([[GRP53:0x[0-9a-f]+]]): 824; CHECK-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 825; CHECK-NEXT: Against group ([[GRP54:0x[0-9a-f]+]]): 826; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 827; CHECK-NEXT: Check 1: 828; CHECK-NEXT: Comparing group ([[GRP53]]): 829; CHECK-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 830; CHECK-NEXT: Against group ([[GRP55:0x[0-9a-f]+]]): 831; CHECK-NEXT: %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset 832; CHECK-NEXT: %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset 833; CHECK-NEXT: Grouped accesses: 834; CHECK-NEXT: Group [[GRP53]]: 835; CHECK-NEXT: (Low: %Dest High: (400 + %Dest)) 836; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%for.body> 837; CHECK-NEXT: Group [[GRP54]]: 838; CHECK-NEXT: (Low: %Preds High: (400 + %Preds)) 839; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body> 840; CHECK-NEXT: Group [[GRP55]]: 841; CHECK-NEXT: (Low: ((4 * %to_add) + (-4 * %to_sub) + %Base) High: (404 + (4 * %to_add) + (-4 * %to_sub) + %Base)) 842; CHECK-NEXT: Member: {(4 + (4 * %to_add) + (-4 * %to_sub) + %Base),+,4}<%for.body> 843; CHECK-NEXT: Member: {((4 * %to_add) + (-4 * %to_sub) + %Base),+,4}<%for.body> 844; CHECK-EMPTY: 845; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 846; CHECK-NEXT: SCEV assumptions: 847; CHECK-EMPTY: 848; CHECK-NEXT: Expressions re-written: 849; 850; RECURSE-LABEL: 'forked_ptrs_add_sub_offset' 851; RECURSE-NEXT: for.body: 852; RECURSE-NEXT: Report: cannot identify array bounds 853; RECURSE-NEXT: Dependences: 854; RECURSE-NEXT: Run-time memory checks: 855; RECURSE-NEXT: Grouped accesses: 856; RECURSE-EMPTY: 857; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 858; RECURSE-NEXT: SCEV assumptions: 859; RECURSE-EMPTY: 860; RECURSE-NEXT: Expressions re-written: 861; 862entry: 863 br label %for.body 864 865for.cond.cleanup: ; preds = %for.body 866 ret void 867 868for.body: ; preds = %entry, %for.body 869 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 870 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 871 %0 = load i32, ptr %arrayidx, align 4 872 %cmp.not = icmp eq i32 %0, 0 873 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 874 %sel = select i1 %cmp.not, i64 %indvars.iv.next, i64 %indvars.iv 875 %add = add nuw nsw i64 %sel, %to_add 876 %offset = sub nuw nsw i64 %add, %to_sub 877 %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset 878 %1 = load float, ptr %arrayidx3, align 4 879 %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 880 store float %1, ptr %arrayidx5, align 4 881 %exitcond.not = icmp eq i64 %indvars.iv.next, 100 882 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 883} 884 885;;;; Cases that can be handled by a forked pointer but are not currently allowed. 886 887define dso_local void @forked_ptrs_mul_by_offset(ptr nocapture readonly %Base, ptr nocapture %Dest, ptr nocapture readonly %Preds, i64 %extra_offset) { 888; CHECK-LABEL: 'forked_ptrs_mul_by_offset' 889; CHECK-NEXT: for.body: 890; CHECK-NEXT: Report: cannot identify array bounds 891; CHECK-NEXT: Dependences: 892; CHECK-NEXT: Run-time memory checks: 893; CHECK-NEXT: Grouped accesses: 894; CHECK-EMPTY: 895; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 896; CHECK-NEXT: SCEV assumptions: 897; CHECK-EMPTY: 898; CHECK-NEXT: Expressions re-written: 899; 900; RECURSE-LABEL: 'forked_ptrs_mul_by_offset' 901; RECURSE-NEXT: for.body: 902; RECURSE-NEXT: Report: cannot identify array bounds 903; RECURSE-NEXT: Dependences: 904; RECURSE-NEXT: Run-time memory checks: 905; RECURSE-NEXT: Grouped accesses: 906; RECURSE-EMPTY: 907; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 908; RECURSE-NEXT: SCEV assumptions: 909; RECURSE-EMPTY: 910; RECURSE-NEXT: Expressions re-written: 911; 912entry: 913 br label %for.body 914 915for.cond.cleanup: ; preds = %for.body 916 ret void 917 918for.body: ; preds = %entry, %for.body 919 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 920 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 921 %0 = load i32, ptr %arrayidx, align 4 922 %cmp.not = icmp eq i32 %0, 0 923 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 924 %sel = select i1 %cmp.not, i64 %indvars.iv.next, i64 %indvars.iv 925 %offset = mul nuw nsw i64 %sel, %extra_offset 926 %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset 927 %1 = load float, ptr %arrayidx3, align 4 928 %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 929 store float %1, ptr %arrayidx5, align 4 930 %exitcond.not = icmp eq i64 %indvars.iv.next, 100 931 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 932} 933 934;;;; Derived from forked_ptrs_same_base_different_offset with a manually 935;;;; added uniform offset and a mul to provide a stride 936 937define dso_local void @forked_ptrs_uniform_and_strided_forks(ptr nocapture readonly %Base, ptr nocapture %Dest, ptr nocapture readonly %Preds) { 938; CHECK-LABEL: 'forked_ptrs_uniform_and_strided_forks' 939; CHECK-NEXT: for.body: 940; CHECK-NEXT: Report: cannot identify array bounds 941; CHECK-NEXT: Dependences: 942; CHECK-NEXT: Run-time memory checks: 943; CHECK-NEXT: Grouped accesses: 944; CHECK-EMPTY: 945; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 946; CHECK-NEXT: SCEV assumptions: 947; CHECK-EMPTY: 948; CHECK-NEXT: Expressions re-written: 949; 950; RECURSE-LABEL: 'forked_ptrs_uniform_and_strided_forks' 951; RECURSE-NEXT: for.body: 952; RECURSE-NEXT: Report: cannot identify array bounds 953; RECURSE-NEXT: Dependences: 954; RECURSE-NEXT: Run-time memory checks: 955; RECURSE-NEXT: Grouped accesses: 956; RECURSE-EMPTY: 957; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 958; RECURSE-NEXT: SCEV assumptions: 959; RECURSE-EMPTY: 960; RECURSE-NEXT: Expressions re-written: 961; 962entry: 963 br label %for.body 964 965for.cond.cleanup: ; preds = %for.body 966 ret void 967 968for.body: ; preds = %entry, %for.body 969 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 970 %i.014 = phi i32 [ 0, %entry ], [ %add, %for.body ] 971 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 972 %0 = load i32, ptr %arrayidx, align 4 973 %cmp1.not = icmp eq i32 %0, 0 974 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 975 %add = add nuw nsw i32 %i.014, 1 976 %1 = trunc i64 %indvars.iv to i32 977 %mul = mul i32 %1, 3 978 %offset.0 = select i1 %cmp1.not, i32 4, i32 %mul 979 %idxprom213 = sext i32 %offset.0 to i64 980 %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %idxprom213 981 %2 = load float, ptr %arrayidx3, align 4 982 %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 983 store float %2, ptr %arrayidx5, align 4 984 %exitcond.not = icmp eq i64 %indvars.iv.next, 100 985 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 986} 987 988;;;; Derived from forked_ptrs_same_base_different_offset with a gather 989;;;; added using Preds as an index array in addition to the per-iteration 990;;;; condition. 991 992define dso_local void @forked_ptrs_gather_and_contiguous_forks(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) { 993; CHECK-LABEL: 'forked_ptrs_gather_and_contiguous_forks' 994; CHECK-NEXT: for.body: 995; CHECK-NEXT: Report: cannot identify array bounds 996; CHECK-NEXT: Dependences: 997; CHECK-NEXT: Run-time memory checks: 998; CHECK-NEXT: Grouped accesses: 999; CHECK-EMPTY: 1000; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 1001; CHECK-NEXT: SCEV assumptions: 1002; CHECK-EMPTY: 1003; CHECK-NEXT: Expressions re-written: 1004; 1005; RECURSE-LABEL: 'forked_ptrs_gather_and_contiguous_forks' 1006; RECURSE-NEXT: for.body: 1007; RECURSE-NEXT: Report: cannot identify array bounds 1008; RECURSE-NEXT: Dependences: 1009; RECURSE-NEXT: Run-time memory checks: 1010; RECURSE-NEXT: Grouped accesses: 1011; RECURSE-EMPTY: 1012; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 1013; RECURSE-NEXT: SCEV assumptions: 1014; RECURSE-EMPTY: 1015; RECURSE-NEXT: Expressions re-written: 1016; 1017entry: 1018 br label %for.body 1019 1020for.cond.cleanup: ; preds = %for.body 1021 ret void 1022 1023for.body: ; preds = %entry, %for.body 1024 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 1025 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 1026 %0 = load i32, ptr %arrayidx, align 4 1027 %cmp1.not = icmp eq i32 %0, 0 1028 %arrayidx9 = getelementptr inbounds float, ptr %Base2, i64 %indvars.iv 1029 %idxprom4 = sext i32 %0 to i64 1030 %arrayidx5 = getelementptr inbounds float, ptr %Base1, i64 %idxprom4 1031 %.sink.in = select i1 %cmp1.not, ptr %arrayidx9, ptr %arrayidx5 1032 %.sink = load float, ptr %.sink.in, align 4 1033 %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 1034 store float %.sink, ptr %1, align 4 1035 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 1036 %exitcond.not = icmp eq i64 %indvars.iv.next, 100 1037 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 1038} 1039 1040;; We don't currently handle a fork in both the base and the offset of a 1041;; GEP instruction. 1042 1043define dso_local void @forked_ptrs_two_forks_gep(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) { 1044; CHECK-LABEL: 'forked_ptrs_two_forks_gep' 1045; CHECK-NEXT: for.body: 1046; CHECK-NEXT: Report: cannot identify array bounds 1047; CHECK-NEXT: Dependences: 1048; CHECK-NEXT: Run-time memory checks: 1049; CHECK-NEXT: Grouped accesses: 1050; CHECK-EMPTY: 1051; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 1052; CHECK-NEXT: SCEV assumptions: 1053; CHECK-EMPTY: 1054; CHECK-NEXT: Expressions re-written: 1055; 1056; RECURSE-LABEL: 'forked_ptrs_two_forks_gep' 1057; RECURSE-NEXT: for.body: 1058; RECURSE-NEXT: Report: cannot identify array bounds 1059; RECURSE-NEXT: Dependences: 1060; RECURSE-NEXT: Run-time memory checks: 1061; RECURSE-NEXT: Grouped accesses: 1062; RECURSE-EMPTY: 1063; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 1064; RECURSE-NEXT: SCEV assumptions: 1065; RECURSE-EMPTY: 1066; RECURSE-NEXT: Expressions re-written: 1067; 1068entry: 1069 br label %for.body 1070 1071for.cond.cleanup: 1072 ret void 1073 1074for.body: 1075 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 1076 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 1077 %0 = load i32, ptr %arrayidx, align 4 1078 %cmp1.not = icmp eq i32 %0, 0 1079 %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1 1080 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 1081 %offset = select i1 %cmp1.not, i64 %indvars.iv.next, i64 %indvars.iv 1082 %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %offset 1083 %.sink = load float, ptr %.sink.in, align 4 1084 %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 1085 store float %.sink, ptr %1, align 4 1086 %exitcond.not = icmp eq i64 %indvars.iv.next, 100 1087 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 1088} 1089 1090;; We don't handle forks as children of a select 1091 1092define void @forked_ptrs_two_select(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture readonly %Base3, ptr %Dest) { 1093; CHECK-LABEL: 'forked_ptrs_two_select' 1094; CHECK-NEXT: loop: 1095; CHECK-NEXT: Report: cannot identify array bounds 1096; CHECK-NEXT: Dependences: 1097; CHECK-NEXT: Run-time memory checks: 1098; CHECK-NEXT: Grouped accesses: 1099; CHECK-EMPTY: 1100; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 1101; CHECK-NEXT: SCEV assumptions: 1102; CHECK-EMPTY: 1103; CHECK-NEXT: Expressions re-written: 1104; 1105; RECURSE-LABEL: 'forked_ptrs_two_select' 1106; RECURSE-NEXT: loop: 1107; RECURSE-NEXT: Report: cannot identify array bounds 1108; RECURSE-NEXT: Dependences: 1109; RECURSE-NEXT: Run-time memory checks: 1110; RECURSE-NEXT: Grouped accesses: 1111; RECURSE-EMPTY: 1112; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 1113; RECURSE-NEXT: SCEV assumptions: 1114; RECURSE-EMPTY: 1115; RECURSE-NEXT: Expressions re-written: 1116; 1117entry: 1118 br label %loop 1119 1120loop: 1121 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] 1122 %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv 1123 %l.Dest = load float, ptr %gep.Dest 1124 %cmp = fcmp une float %l.Dest, 0.0 1125 %cmp1 = fcmp une float %l.Dest, 1.0 1126 %gep.1 = getelementptr inbounds float, ptr %Base1, i64 %iv 1127 %gep.2 = getelementptr inbounds float, ptr %Base2, i64 %iv 1128 %gep.3 = getelementptr inbounds float, ptr %Base3, i64 %iv 1129 %select = select i1 %cmp, ptr %gep.1, ptr %gep.2 1130 %select1 = select i1 %cmp1, ptr %select, ptr %gep.3 1131 %sink = load float, ptr %select1, align 4 1132 store float %sink, ptr %gep.Dest, align 4 1133 %iv.next = add nuw nsw i64 %iv, 1 1134 %exitcond.not = icmp eq i64 %iv.next, 100 1135 br i1 %exitcond.not, label %exit, label %loop 1136 1137exit: 1138 ret void 1139} 1140 1141;; We don't yet handle geps with more than 2 operands 1142 1143define void @forked_ptrs_too_many_gep_ops(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) { 1144; CHECK-LABEL: 'forked_ptrs_too_many_gep_ops' 1145; CHECK-NEXT: for.body: 1146; CHECK-NEXT: Report: cannot identify array bounds 1147; CHECK-NEXT: Dependences: 1148; CHECK-NEXT: Run-time memory checks: 1149; CHECK-NEXT: Grouped accesses: 1150; CHECK-EMPTY: 1151; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 1152; CHECK-NEXT: SCEV assumptions: 1153; CHECK-EMPTY: 1154; CHECK-NEXT: Expressions re-written: 1155; 1156; RECURSE-LABEL: 'forked_ptrs_too_many_gep_ops' 1157; RECURSE-NEXT: for.body: 1158; RECURSE-NEXT: Report: cannot identify array bounds 1159; RECURSE-NEXT: Dependences: 1160; RECURSE-NEXT: Run-time memory checks: 1161; RECURSE-NEXT: Grouped accesses: 1162; RECURSE-EMPTY: 1163; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 1164; RECURSE-NEXT: SCEV assumptions: 1165; RECURSE-EMPTY: 1166; RECURSE-NEXT: Expressions re-written: 1167; 1168entry: 1169 br label %for.body 1170 1171for.body: 1172 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 1173 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 1174 %0 = load i32, ptr %arrayidx, align 4 1175 %cmp1.not = icmp eq i32 %0, 0 1176 %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1 1177 %.sink.in = getelementptr inbounds [1000 x float], ptr %spec.select, i64 0, i64 %indvars.iv 1178 %.sink = load float, ptr %.sink.in, align 4 1179 %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv 1180 store float %.sink, ptr %1, align 4 1181 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 1182 %exitcond.not = icmp eq i64 %indvars.iv.next, 100 1183 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 1184 1185for.cond.cleanup: 1186 ret void 1187} 1188 1189;; We don't currently handle vector GEPs 1190 1191define void @forked_ptrs_vector_gep(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) { 1192; CHECK-LABEL: 'forked_ptrs_vector_gep' 1193; CHECK-NEXT: for.body: 1194; CHECK-NEXT: Report: cannot identify array bounds 1195; CHECK-NEXT: Dependences: 1196; CHECK-NEXT: Run-time memory checks: 1197; CHECK-NEXT: Grouped accesses: 1198; CHECK-EMPTY: 1199; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 1200; CHECK-NEXT: SCEV assumptions: 1201; CHECK-EMPTY: 1202; CHECK-NEXT: Expressions re-written: 1203; 1204; RECURSE-LABEL: 'forked_ptrs_vector_gep' 1205; RECURSE-NEXT: for.body: 1206; RECURSE-NEXT: Report: cannot identify array bounds 1207; RECURSE-NEXT: Dependences: 1208; RECURSE-NEXT: Run-time memory checks: 1209; RECURSE-NEXT: Grouped accesses: 1210; RECURSE-EMPTY: 1211; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 1212; RECURSE-NEXT: SCEV assumptions: 1213; RECURSE-EMPTY: 1214; RECURSE-NEXT: Expressions re-written: 1215; 1216entry: 1217 br label %for.body 1218 1219for.body: 1220 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 1221 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 1222 %0 = load i32, ptr %arrayidx, align 4 1223 %cmp1.not = icmp eq i32 %0, 0 1224 %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1 1225 %.sink.in = getelementptr inbounds <4 x float>, ptr %spec.select, i64 %indvars.iv 1226 %.sink = load <4 x float>, ptr %.sink.in, align 4 1227 %1 = getelementptr inbounds <4 x float>, ptr %Dest, i64 %indvars.iv 1228 store <4 x float> %.sink, ptr %1, align 4 1229 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 4 1230 %exitcond.not = icmp eq i64 %indvars.iv.next, 100 1231 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 1232 1233for.cond.cleanup: 1234 ret void 1235} 1236 1237;;; The following test caused an ICE with the initial forked pointers work. 1238;;; One fork is loop invariant (%Base2 + 0), the other is an scAddExpr that 1239;;; contains an scAddRecExpr inside it: 1240;;; ((8 * (zext i32 {0,+,1}<%for.body> to i64))<nuw><nsw> + %Base2)<nuw> 1241;;; 1242;;; RtCheck::insert was expecting either loop invariant or SAR, so asserted 1243;;; on a plain scAddExpr. For now we restrict to loop invariant or SAR 1244;;; forks only, but we should be able to do better. 1245 1246define void @sc_add_expr_ice(ptr %Base1, ptr %Base2, i64 %N) { 1247; CHECK-LABEL: 'sc_add_expr_ice' 1248; CHECK-NEXT: for.body: 1249; CHECK-NEXT: Memory dependences are safe with run-time checks 1250; CHECK-NEXT: Dependences: 1251; CHECK-NEXT: Run-time memory checks: 1252; CHECK-NEXT: Check 0: 1253; CHECK-NEXT: Comparing group ([[GRP56:0x[0-9a-f]+]]): 1254; CHECK-NEXT: ptr %Base1 1255; CHECK-NEXT: Against group ([[GRP57:0x[0-9a-f]+]]): 1256; CHECK-NEXT: %fptr = getelementptr inbounds double, ptr %Base2, i64 %sel 1257; CHECK-NEXT: Grouped accesses: 1258; CHECK-NEXT: Group [[GRP56]]: 1259; CHECK-NEXT: (Low: %Base1 High: (8 + %Base1)) 1260; CHECK-NEXT: Member: %Base1 1261; CHECK-NEXT: Group [[GRP57]]: 1262; CHECK-NEXT: (Low: %Base2 High: ((8 * %N) + %Base2)) 1263; CHECK-NEXT: Member: {%Base2,+,8}<%for.body> 1264; CHECK-EMPTY: 1265; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 1266; CHECK-NEXT: SCEV assumptions: 1267; CHECK-NEXT: {0,+,1}<%for.body> Added Flags: <nusw> 1268; CHECK-EMPTY: 1269; CHECK-NEXT: Expressions re-written: 1270; CHECK-NEXT: [PSE] %fptr = getelementptr inbounds double, ptr %Base2, i64 %sel: 1271; CHECK-NEXT: ((8 * (zext i32 {0,+,1}<%for.body> to i64))<nuw><nsw> + %Base2)<nuw> 1272; CHECK-NEXT: --> {%Base2,+,8}<%for.body> 1273; 1274; RECURSE-LABEL: 'sc_add_expr_ice' 1275; RECURSE-NEXT: for.body: 1276; RECURSE-NEXT: Memory dependences are safe with run-time checks 1277; RECURSE-NEXT: Dependences: 1278; RECURSE-NEXT: Run-time memory checks: 1279; RECURSE-NEXT: Check 0: 1280; RECURSE-NEXT: Comparing group ([[GRP58:0x[0-9a-f]+]]): 1281; RECURSE-NEXT: ptr %Base1 1282; RECURSE-NEXT: Against group ([[GRP59:0x[0-9a-f]+]]): 1283; RECURSE-NEXT: %fptr = getelementptr inbounds double, ptr %Base2, i64 %sel 1284; RECURSE-NEXT: Grouped accesses: 1285; RECURSE-NEXT: Group [[GRP58]]: 1286; RECURSE-NEXT: (Low: %Base1 High: (8 + %Base1)) 1287; RECURSE-NEXT: Member: %Base1 1288; RECURSE-NEXT: Group [[GRP59]]: 1289; RECURSE-NEXT: (Low: %Base2 High: ((8 * %N) + %Base2)) 1290; RECURSE-NEXT: Member: {%Base2,+,8}<%for.body> 1291; RECURSE-EMPTY: 1292; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 1293; RECURSE-NEXT: SCEV assumptions: 1294; RECURSE-NEXT: {0,+,1}<%for.body> Added Flags: <nusw> 1295; RECURSE-EMPTY: 1296; RECURSE-NEXT: Expressions re-written: 1297; RECURSE-NEXT: [PSE] %fptr = getelementptr inbounds double, ptr %Base2, i64 %sel: 1298; RECURSE-NEXT: ((8 * (zext i32 {0,+,1}<%for.body> to i64))<nuw><nsw> + %Base2)<nuw> 1299; RECURSE-NEXT: --> {%Base2,+,8}<%for.body> 1300; 1301entry: 1302 br label %for.body 1303 1304for.body: 1305 %iv = phi i64 [ %iv.next, %for.body ], [ 0, %entry ] 1306 %iv.trunc = trunc i64 %iv to i32 1307 store double 0.000000e+00, ptr %Base1, align 8 1308 %iv.zext = zext i32 %iv.trunc to i64 1309 %sel = select i1 true, i64 %iv.zext, i64 0 1310 %fptr = getelementptr inbounds double, ptr %Base2, i64 %sel 1311 %dummy.load = load double, ptr %fptr, align 8 1312 %iv.next = add nuw nsw i64 %iv, 1 1313 %exitcond = icmp eq i64 %iv.next, %N 1314 br i1 %exitcond, label %exit, label %for.body 1315 1316exit: 1317 ret void 1318} 1319 1320define void @forked_ptrs_with_different_base(ptr nocapture readonly %Preds, ptr nocapture %a, ptr nocapture %b, ptr nocapture readonly %c) { 1321; CHECK-LABEL: 'forked_ptrs_with_different_base' 1322; CHECK-NEXT: for.body: 1323; CHECK-NEXT: Memory dependences are safe with run-time checks 1324; CHECK-NEXT: Dependences: 1325; CHECK-NEXT: Run-time memory checks: 1326; CHECK-NEXT: Check 0: 1327; CHECK-NEXT: Comparing group ([[GRP60:0x[0-9a-f]+]]): 1328; CHECK-NEXT: %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv 1329; CHECK-NEXT: Against group ([[GRP61:0x[0-9a-f]+]]): 1330; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 1331; CHECK-NEXT: Check 1: 1332; CHECK-NEXT: Comparing group ([[GRP60]]): 1333; CHECK-NEXT: %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv 1334; CHECK-NEXT: Against group ([[GRP62:0x[0-9a-f]+]]): 1335; CHECK-NEXT: %arrayidx5 = getelementptr inbounds double, ptr %0, i64 %indvars.iv 1336; CHECK-NEXT: Check 2: 1337; CHECK-NEXT: Comparing group ([[GRP63:0x[0-9a-f]+]]): 1338; CHECK-NEXT: %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv 1339; CHECK-NEXT: Against group ([[GRP61]]): 1340; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 1341; CHECK-NEXT: Check 3: 1342; CHECK-NEXT: Comparing group ([[GRP63]]): 1343; CHECK-NEXT: %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv 1344; CHECK-NEXT: Against group ([[GRP62]]): 1345; CHECK-NEXT: %arrayidx5 = getelementptr inbounds double, ptr %0, i64 %indvars.iv 1346; CHECK-NEXT: Grouped accesses: 1347; CHECK-NEXT: Group [[GRP60]]: 1348; CHECK-NEXT: (Low: %1 High: (63992 + %1)) 1349; CHECK-NEXT: Member: {%1,+,8}<nw><%for.body> 1350; CHECK-NEXT: Group [[GRP63]]: 1351; CHECK-NEXT: (Low: %2 High: (63992 + %2)) 1352; CHECK-NEXT: Member: {%2,+,8}<nw><%for.body> 1353; CHECK-NEXT: Group [[GRP61]]: 1354; CHECK-NEXT: (Low: %Preds High: (31996 + %Preds)) 1355; CHECK-NEXT: Member: {%Preds,+,4}<nuw><%for.body> 1356; CHECK-NEXT: Group [[GRP62]]: 1357; CHECK-NEXT: (Low: %0 High: (63992 + %0)) 1358; CHECK-NEXT: Member: {%0,+,8}<nw><%for.body> 1359; CHECK-EMPTY: 1360; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 1361; CHECK-NEXT: SCEV assumptions: 1362; CHECK-EMPTY: 1363; CHECK-NEXT: Expressions re-written: 1364; 1365; RECURSE-LABEL: 'forked_ptrs_with_different_base' 1366; RECURSE-NEXT: for.body: 1367; RECURSE-NEXT: Memory dependences are safe with run-time checks 1368; RECURSE-NEXT: Dependences: 1369; RECURSE-NEXT: Run-time memory checks: 1370; RECURSE-NEXT: Check 0: 1371; RECURSE-NEXT: Comparing group ([[GRP64:0x[0-9a-f]+]]): 1372; RECURSE-NEXT: %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv 1373; RECURSE-NEXT: Against group ([[GRP65:0x[0-9a-f]+]]): 1374; RECURSE-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 1375; RECURSE-NEXT: Check 1: 1376; RECURSE-NEXT: Comparing group ([[GRP64]]): 1377; RECURSE-NEXT: %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv 1378; RECURSE-NEXT: Against group ([[GRP66:0x[0-9a-f]+]]): 1379; RECURSE-NEXT: %arrayidx5 = getelementptr inbounds double, ptr %0, i64 %indvars.iv 1380; RECURSE-NEXT: Check 2: 1381; RECURSE-NEXT: Comparing group ([[GRP67:0x[0-9a-f]+]]): 1382; RECURSE-NEXT: %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv 1383; RECURSE-NEXT: Against group ([[GRP65]]): 1384; RECURSE-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 1385; RECURSE-NEXT: Check 3: 1386; RECURSE-NEXT: Comparing group ([[GRP67]]): 1387; RECURSE-NEXT: %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv 1388; RECURSE-NEXT: Against group ([[GRP66]]): 1389; RECURSE-NEXT: %arrayidx5 = getelementptr inbounds double, ptr %0, i64 %indvars.iv 1390; RECURSE-NEXT: Grouped accesses: 1391; RECURSE-NEXT: Group [[GRP64]]: 1392; RECURSE-NEXT: (Low: %1 High: (63992 + %1)) 1393; RECURSE-NEXT: Member: {%1,+,8}<nw><%for.body> 1394; RECURSE-NEXT: Group [[GRP67]]: 1395; RECURSE-NEXT: (Low: %2 High: (63992 + %2)) 1396; RECURSE-NEXT: Member: {%2,+,8}<nw><%for.body> 1397; RECURSE-NEXT: Group [[GRP65]]: 1398; RECURSE-NEXT: (Low: %Preds High: (31996 + %Preds)) 1399; RECURSE-NEXT: Member: {%Preds,+,4}<nuw><%for.body> 1400; RECURSE-NEXT: Group [[GRP66]]: 1401; RECURSE-NEXT: (Low: %0 High: (63992 + %0)) 1402; RECURSE-NEXT: Member: {%0,+,8}<nw><%for.body> 1403; RECURSE-EMPTY: 1404; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 1405; RECURSE-NEXT: SCEV assumptions: 1406; RECURSE-EMPTY: 1407; RECURSE-NEXT: Expressions re-written: 1408; 1409entry: 1410 %0 = load ptr, ptr %c, align 64 1411 %1 = load ptr, ptr %a, align 64 1412 %2 = load ptr, ptr %b, align 64 1413 br label %for.body 1414 1415for.cond.cleanup: ; preds = %for.inc 1416 ret void 1417 1418for.body: ; preds = %entry, %for.inc 1419 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.inc ] 1420 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 1421 %3 = load i32, ptr %arrayidx, align 4 1422 %cmp2.not = icmp eq i32 %3, 0 1423 br i1 %cmp2.not, label %if.else, label %if.then 1424 1425if.then: ; preds = %for.body 1426 %arrayidx5 = getelementptr inbounds double, ptr %0, i64 %indvars.iv 1427 %4 = load double, ptr %arrayidx5, align 8 1428 %add = fadd fast double %4, 1.000000e+00 1429 br label %for.inc 1430 1431if.else: ; preds = %for.body 1432 %5 = mul nuw nsw i64 %indvars.iv, %indvars.iv 1433 %6 = trunc i64 %5 to i32 1434 %conv8 = sitofp i32 %6 to double 1435 br label %for.inc 1436 1437for.inc: ; preds = %if.then, %if.else 1438 %.sink = phi ptr [ %1, %if.then ], [ %2, %if.else ] 1439 %add.sink = phi double [ %add, %if.then ], [ %conv8, %if.else ] 1440 %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv 1441 store double %add.sink, ptr %arrayidx7, align 8 1442 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 1443 %exitcond.not = icmp eq i64 %indvars.iv.next, 7999 1444 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 1445} 1446 1447; Negative test: the operator number of PhiNode is not 2. 1448define void @forked_ptrs_with_different_base3(ptr nocapture readonly %Preds, ptr nocapture %a, ptr nocapture %b, ptr nocapture readonly %c) { 1449; CHECK-LABEL: 'forked_ptrs_with_different_base3' 1450; CHECK-NEXT: for.body: 1451; CHECK-NEXT: Report: cannot identify array bounds 1452; CHECK-NEXT: Dependences: 1453; CHECK-NEXT: Run-time memory checks: 1454; CHECK-NEXT: Grouped accesses: 1455; CHECK-EMPTY: 1456; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. 1457; CHECK-NEXT: SCEV assumptions: 1458; CHECK-EMPTY: 1459; CHECK-NEXT: Expressions re-written: 1460; 1461; RECURSE-LABEL: 'forked_ptrs_with_different_base3' 1462; RECURSE-NEXT: for.body: 1463; RECURSE-NEXT: Report: cannot identify array bounds 1464; RECURSE-NEXT: Dependences: 1465; RECURSE-NEXT: Run-time memory checks: 1466; RECURSE-NEXT: Grouped accesses: 1467; RECURSE-EMPTY: 1468; RECURSE-NEXT: Non vectorizable stores to invariant address were not found in loop. 1469; RECURSE-NEXT: SCEV assumptions: 1470; RECURSE-EMPTY: 1471; RECURSE-NEXT: Expressions re-written: 1472; 1473entry: 1474 %ld.c = load ptr, ptr %c, align 64 1475 %ld.a = load ptr, ptr %a, align 64 1476 %ld.b = load ptr, ptr %b, align 64 1477 br label %for.body 1478 1479for.body: ; preds = %entry, %for.inc 1480 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.inc ] 1481 %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv 1482 %ld.preds = load i32, ptr %arrayidx, align 4 1483 switch i32 %ld.preds, label %if.else [ 1484 i32 0, label %if.br0 1485 i32 1, label %if.br1 1486 ] 1487 1488if.br0: ; preds = %for.body 1489 br label %for.inc 1490 1491if.br1: ; preds = %for.body 1492 br label %for.inc 1493 1494if.else: ; preds = %for.body 1495 br label %for.inc 1496 1497for.inc: ; preds = %if.br1, %if.br0 1498 %.sink = phi ptr [ %ld.a, %if.br0 ], [ %ld.b, %if.br1 ], [ %ld.c, %if.else ] 1499 %arrayidx7 = getelementptr inbounds double, ptr %.sink, i64 %indvars.iv 1500 store double 1.000000e+00, ptr %arrayidx7, align 8 1501 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 1502 %exitcond.not = icmp eq i64 %indvars.iv.next, 7999 1503 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 1504 1505for.cond.cleanup: ; preds = %for.inc 1506 ret void 1507} 1508