brintos

brintos / llvm-project-archived public Read only

0
0
Text · 27.7 KiB · 1c48b0e Raw
658 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 32; RUN: opt -S -disable-output -passes='print<access-info>' %s 2>&1 | FileCheck %s3 4;5target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"6 7; A forwarding in the presence of symbolic strides.8define void @single_stride(ptr noalias %A, ptr noalias %B, i64 %N, i64 %stride) {9; CHECK-LABEL: 'single_stride'10; CHECK-NEXT:    loop:11; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop12; CHECK-NEXT:  Backward loop carried data dependence.13; CHECK-NEXT:      Dependences:14; CHECK-NEXT:        Backward:15; CHECK-NEXT:            %load = load i32, ptr %gep.A, align 4 ->16; CHECK-NEXT:            store i32 %add, ptr %gep.A.next, align 417; CHECK-EMPTY:18; CHECK-NEXT:      Run-time memory checks:19; CHECK-NEXT:      Grouped accesses:20; CHECK-EMPTY:21; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.22; CHECK-NEXT:      SCEV assumptions:23; CHECK-NEXT:      Equal predicate: %stride == 124; CHECK-EMPTY:25; CHECK-NEXT:      Expressions re-written:26; CHECK-NEXT:      [PSE] %gep.A = getelementptr inbounds i32, ptr %A, i64 %mul:27; CHECK-NEXT:        {%A,+,(4 * %stride)}<%loop>28; CHECK-NEXT:        --> {%A,+,4}<%loop>29;30entry:31  br label %loop32 33loop:34  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]35  %mul = mul i64 %iv, %stride36  %gep.A = getelementptr inbounds i32, ptr %A, i64 %mul37  %load = load i32, ptr %gep.A, align 438  %gep.B = getelementptr inbounds i32, ptr %B, i64 %iv39  %load_1 = load i32, ptr %gep.B, align 440  %add = add i32 %load_1, %load41  %iv.next = add nuw nsw i64 %iv, 142  %gep.A.next = getelementptr inbounds i32, ptr %A, i64 %iv.next43  store i32 %add, ptr %gep.A.next, align 444  %exitcond = icmp eq i64 %iv.next, %N45  br i1 %exitcond, label %exit, label %loop46 47exit:                                          ; preds = %loop48  ret void49}50 51; A forwarding in the presence of symbolic strides,52; with nusw instead of inbounds on the GEPs.53define void @single_stride_nusw(ptr noalias %A, ptr noalias %B, i64 %N, i64 %stride) {54; CHECK-LABEL: 'single_stride_nusw'55; CHECK-NEXT:    loop:56; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop57; CHECK-NEXT:  Backward loop carried data dependence.58; CHECK-NEXT:      Dependences:59; CHECK-NEXT:        Backward:60; CHECK-NEXT:            %load = load i32, ptr %gep.A, align 4 ->61; CHECK-NEXT:            store i32 %add, ptr %gep.A.next, align 462; CHECK-EMPTY:63; CHECK-NEXT:      Run-time memory checks:64; CHECK-NEXT:      Grouped accesses:65; CHECK-EMPTY:66; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.67; CHECK-NEXT:      SCEV assumptions:68; CHECK-NEXT:      Equal predicate: %stride == 169; CHECK-EMPTY:70; CHECK-NEXT:      Expressions re-written:71; CHECK-NEXT:      [PSE] %gep.A = getelementptr nusw i32, ptr %A, i64 %mul:72; CHECK-NEXT:        {%A,+,(4 * %stride)}<%loop>73; CHECK-NEXT:        --> {%A,+,4}<%loop>74;75entry:76  br label %loop77 78loop:79  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]80  %mul = mul i64 %iv, %stride81  %gep.A = getelementptr nusw i32, ptr %A, i64 %mul82  %load = load i32, ptr %gep.A, align 483  %gep.B = getelementptr nusw i32, ptr %B, i64 %iv84  %load_1 = load i32, ptr %gep.B, align 485  %add = add i32 %load_1, %load86  %iv.next = add nuw nsw i64 %iv, 187  %gep.A.next = getelementptr nusw i32, ptr %A, i64 %iv.next88  store i32 %add, ptr %gep.A.next, align 489  %exitcond = icmp eq i64 %iv.next, %N90  br i1 %exitcond, label %exit, label %loop91 92exit:                                          ; preds = %loop93  ret void94}95 96; Similar to @single_stride, but with struct types.97define void @single_stride_struct(ptr noalias %A, ptr noalias %B, i64 %N, i64 %stride) {98; CHECK-LABEL: 'single_stride_struct'99; CHECK-NEXT:    loop:100; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop101; CHECK-NEXT:  Backward loop carried data dependence.102; CHECK-NEXT:      Dependences:103; CHECK-NEXT:        Backward:104; CHECK-NEXT:            %load = load { i32, i8 }, ptr %gep.A, align 4 ->105; CHECK-NEXT:            store { i32, i8 } %ins, ptr %gep.A.next, align 4106; CHECK-EMPTY:107; CHECK-NEXT:      Run-time memory checks:108; CHECK-NEXT:      Grouped accesses:109; CHECK-EMPTY:110; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.111; CHECK-NEXT:      SCEV assumptions:112; CHECK-NEXT:      Equal predicate: %stride == 1113; CHECK-EMPTY:114; CHECK-NEXT:      Expressions re-written:115; CHECK-NEXT:      [PSE] %gep.A = getelementptr inbounds { i32, i8 }, ptr %A, i64 %mul:116; CHECK-NEXT:        {%A,+,(8 * %stride)}<%loop>117; CHECK-NEXT:        --> {%A,+,8}<%loop>118;119entry:120  br label %loop121 122loop:123  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]124  %mul = mul i64 %iv, %stride125  %gep.A = getelementptr inbounds { i32, i8 }, ptr %A, i64 %mul126  %load = load { i32, i8 }, ptr %gep.A, align 4127  %gep.B = getelementptr inbounds { i32, i8 }, ptr %B, i64 %iv128  %load_1 = load { i32, i8 }, ptr %gep.B, align 4129  %v1 = extractvalue { i32, i8 } %load, 0130  %v2 = extractvalue { i32, i8} %load_1, 0131  %add = add i32 %v1, %v2132  %ins = insertvalue { i32, i8 } undef, i32 %add, 0133  %iv.next = add nuw nsw i64 %iv, 1134  %gep.A.next = getelementptr inbounds { i32, i8 }, ptr %A, i64 %iv.next135  store { i32, i8 } %ins, ptr %gep.A.next, align 4136  %exitcond = icmp eq i64 %iv.next, %N137  br i1 %exitcond, label %exit, label %loop138 139exit:140  ret void141}142 143; Test with multiple GEP indices144define void @single_stride_array(ptr noalias %A, ptr noalias %B, i64 %N, i64 %stride) {145; CHECK-LABEL: 'single_stride_array'146; CHECK-NEXT:    loop:147; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop148; CHECK-NEXT:  Backward loop carried data dependence.149; CHECK-NEXT:      Dependences:150; CHECK-NEXT:        Backward:151; CHECK-NEXT:            %load = load [2 x i32], ptr %gep.A, align 4 ->152; CHECK-NEXT:            store [2 x i32] %ins, ptr %gep.A.next, align 4153; CHECK-EMPTY:154; CHECK-NEXT:      Run-time memory checks:155; CHECK-NEXT:      Grouped accesses:156; CHECK-EMPTY:157; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.158; CHECK-NEXT:      SCEV assumptions:159; CHECK-NEXT:      Equal predicate: %stride == 1160; CHECK-EMPTY:161; CHECK-NEXT:      Expressions re-written:162; CHECK-NEXT:      [PSE] %gep.A = getelementptr inbounds [2 x i32], ptr %A, i64 %mul, i64 1:163; CHECK-NEXT:        {(4 + %A),+,(8 * %stride)}<%loop>164; CHECK-NEXT:        --> {(4 + %A),+,8}<%loop>165;166entry:167  br label %loop168 169loop:170  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]171  %mul = mul i64 %iv, %stride172  %gep.A = getelementptr inbounds [2 x i32], ptr %A, i64 %mul, i64 1173  %load = load [2 x i32], ptr %gep.A, align 4174  %gep.B = getelementptr inbounds [2 x i32], ptr %B, i64 %iv175  %load_1 = load [2 x i32], ptr %gep.B, align 4176  %v1 = extractvalue [2 x i32] %load, 0177  %v2 = extractvalue [2 x i32] %load_1, 0178  %add = add i32 %v1, %v2179  %ins = insertvalue [2 x i32] poison, i32 %add, 0180  %iv.next = add nuw nsw i64 %iv, 1181  %gep.A.next = getelementptr inbounds [2 x i32], ptr %A, i64 %iv.next182  store [2 x i32] %ins, ptr %gep.A.next, align 4183  %exitcond = icmp eq i64 %iv.next, %N184  br i1 %exitcond, label %exit, label %loop185 186exit:187  ret void188}189 190define void @single_stride_castexpr(i32 %offset, ptr %src, ptr %dst, i1 %cond) {191; CHECK-LABEL: 'single_stride_castexpr'192; CHECK-NEXT:    inner.loop:193; CHECK-NEXT:      Memory dependences are safe with run-time checks194; CHECK-NEXT:      Dependences:195; CHECK-NEXT:      Run-time memory checks:196; CHECK-NEXT:      Check 0:197; CHECK-NEXT:        Comparing group GRP0:198; CHECK-NEXT:          %gep.dst = getelementptr i32, ptr %dst, i64 %iv.2199; CHECK-NEXT:        Against group GRP1:200; CHECK-NEXT:          %gep.src = getelementptr inbounds i32, ptr %src, i32 %iv.3201; CHECK-NEXT:      Grouped accesses:202; CHECK-NEXT:        Group GRP0:203; CHECK-NEXT:          (Low: ((4 * %iv.1) + %dst) High: (804 + (4 * %iv.1) + %dst))204; CHECK-NEXT:            Member: {((4 * %iv.1) + %dst),+,4}<%inner.loop>205; CHECK-NEXT:        Group GRP1:206; CHECK-NEXT:          (Low: %src High: (804 + %src))207; CHECK-NEXT:            Member: {%src,+,4}<nuw><%inner.loop>208; CHECK-EMPTY:209; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.210; CHECK-NEXT:      SCEV assumptions:211; CHECK-NEXT:      Equal predicate: %offset == 1212; CHECK-EMPTY:213; CHECK-NEXT:      Expressions re-written:214; CHECK-NEXT:      [PSE] %gep.dst = getelementptr i32, ptr %dst, i64 %iv.2:215; CHECK-NEXT:        {((4 * %iv.1) + %dst),+,(4 * (sext i32 %offset to i64))<nsw>}<%inner.loop>216; CHECK-NEXT:        --> {((4 * %iv.1) + %dst),+,4}<%inner.loop>217; CHECK-NEXT:    outer.header:218; CHECK-NEXT:      Report: loop is not the innermost loop219; CHECK-NEXT:      Dependences:220; CHECK-NEXT:      Run-time memory checks:221; CHECK-NEXT:      Grouped accesses:222; CHECK-EMPTY:223; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.224; CHECK-NEXT:      SCEV assumptions:225; CHECK-EMPTY:226; CHECK-NEXT:      Expressions re-written:227;228entry:229  %offset.ext = sext i32 %offset to i64230  br label %outer.header231 232outer.header:233  %iv.1 = phi i64 [ 0, %entry ], [ %iv.2.next, %inner.loop ]234  br i1 %cond, label %inner.loop, label %exit235 236inner.loop:237  %iv.2 = phi i64 [ %iv.1, %outer.header ], [ %iv.2.next, %inner.loop ]238  %iv.3 = phi i32 [ 0, %outer.header ], [ %iv.3.next, %inner.loop ]239  %gep.src = getelementptr inbounds i32, ptr %src, i32 %iv.3240  %load = load i32, ptr %gep.src, align 8241  %gep.dst = getelementptr i32, ptr %dst, i64 %iv.2242  store i32 %load, ptr %gep.dst, align 8243  %iv.2.next = add i64 %iv.2, %offset.ext244  %iv.3.next = add i32 %iv.3, 1245  %ec = icmp eq i32 %iv.3, 200246  br i1 %ec, label %outer.header, label %inner.loop247 248exit:249  ret void250}251 252define void @single_stride_castexpr_multiuse(i32 %offset, ptr %src, ptr %dst, i1 %cond) {253; CHECK-LABEL: 'single_stride_castexpr_multiuse'254; CHECK-NEXT:    inner.loop:255; CHECK-NEXT:      Memory dependences are safe with run-time checks256; CHECK-NEXT:      Dependences:257; CHECK-NEXT:      Run-time memory checks:258; CHECK-NEXT:      Check 0:259; CHECK-NEXT:        Comparing group GRP0:260; CHECK-NEXT:          %gep.dst = getelementptr i32, ptr %dst, i64 %iv.2261; CHECK-NEXT:        Against group GRP1:262; CHECK-NEXT:          %gep.src = getelementptr inbounds i32, ptr %src, i64 %iv.3263; CHECK-NEXT:      Grouped accesses:264; CHECK-NEXT:        Group GRP0:265; CHECK-NEXT:          (Low: ((4 * %iv.1) + %dst) High: (804 + (4 * %iv.1) + (-4 * (zext i32 %offset to i64))<nsw> + %dst))266; CHECK-NEXT:            Member: {((4 * %iv.1) + %dst),+,4}<%inner.loop>267; CHECK-NEXT:        Group GRP1:268; CHECK-NEXT:          (Low: (4 + %src) High: (808 + (-4 * (zext i32 %offset to i64))<nsw> + %src))269; CHECK-NEXT:            Member: {(4 + %src),+,4}<%inner.loop>270; CHECK-EMPTY:271; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.272; CHECK-NEXT:      SCEV assumptions:273; CHECK-NEXT:      Equal predicate: %offset == 1274; CHECK-EMPTY:275; CHECK-NEXT:      Expressions re-written:276; CHECK-NEXT:      [PSE] %gep.src = getelementptr inbounds i32, ptr %src, i64 %iv.3:277; CHECK-NEXT:        {((4 * (zext i32 %offset to i64))<nuw><nsw> + %src),+,4}<%inner.loop>278; CHECK-NEXT:        --> {(4 + %src),+,4}<%inner.loop>279; CHECK-NEXT:      [PSE] %gep.dst = getelementptr i32, ptr %dst, i64 %iv.2:280; CHECK-NEXT:        {((4 * %iv.1) + %dst),+,(4 * (sext i32 %offset to i64))<nsw>}<%inner.loop>281; CHECK-NEXT:        --> {((4 * %iv.1) + %dst),+,4}<%inner.loop>282; CHECK-NEXT:    outer.header:283; CHECK-NEXT:      Report: loop is not the innermost loop284; CHECK-NEXT:      Dependences:285; CHECK-NEXT:      Run-time memory checks:286; CHECK-NEXT:      Grouped accesses:287; CHECK-EMPTY:288; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.289; CHECK-NEXT:      SCEV assumptions:290; CHECK-EMPTY:291; CHECK-NEXT:      Expressions re-written:292;293entry:294  %offset.ext = sext i32 %offset to i64295  %offset.zext = zext i32 %offset to i64296  br label %outer.header297 298outer.header:299  %iv.1 = phi i64 [ 0, %entry ], [ %iv.2.next, %inner.loop ]300  br i1 %cond, label %inner.loop, label %exit301 302inner.loop:303  %iv.2 = phi i64 [ %iv.1, %outer.header ], [ %iv.2.next, %inner.loop ]304  %iv.3 = phi i64 [ %offset.zext, %outer.header ], [ %iv.3.next, %inner.loop ]305  %gep.src = getelementptr inbounds i32, ptr %src, i64 %iv.3306  %load = load i32, ptr %gep.src, align 8307  %gep.dst = getelementptr i32, ptr %dst, i64 %iv.2308  store i32 %load, ptr %gep.dst, align 8309  %iv.2.next = add i64 %iv.2, %offset.ext310  %iv.3.next = add i64 %iv.3, 1311  %ec = icmp eq i64 %iv.3, 200312  br i1 %ec, label %outer.header, label %inner.loop313 314exit:315  ret void316}317 318define double @single_iteration_unknown_stride(i32 %x, ptr %y, i1 %cond) {319; CHECK-LABEL: 'single_iteration_unknown_stride'320; CHECK-NEXT:    loop.body:321; CHECK-NEXT:      Memory dependences are safe322; CHECK-NEXT:      Dependences:323; CHECK-NEXT:      Run-time memory checks:324; CHECK-NEXT:      Grouped accesses:325; CHECK-EMPTY:326; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.327; CHECK-NEXT:      SCEV assumptions:328; CHECK-NEXT:      Equal predicate: %x == 1329; CHECK-EMPTY:330; CHECK-NEXT:      Expressions re-written:331; CHECK-NEXT:      [PSE] %gep10 = getelementptr double, ptr %gep8, i64 %mul:332; CHECK-NEXT:        {(8 + %y),+,(8 * (sext i32 %x to i64))<nsw>}<%loop.body>333; CHECK-NEXT:        --> {(8 + %y),+,8}<%loop.body>334;335entry:336  br i1 %cond, label %noloop.exit, label %loop.ph337 338loop.ph:                                          ; preds = %entry339  %sext7 = sext i32 %x to i64340  %gep8 = getelementptr i8, ptr %y, i64 8341  br label %loop.body342 343loop.body:                                        ; preds = %loop.body, %loop.ph344  %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.body ]345  %mul = mul i64 %iv, %sext7346  %gep10 = getelementptr double, ptr %gep8, i64 %mul347  %load11 = load double, ptr %gep10, align 8348  store double %load11, ptr %y, align 8349  %iv.next = add i64 %iv, 1350  %icmp = icmp eq i64 %iv, 0351  br i1 %icmp, label %loop.exit, label %loop.body352 353noloop.exit:                                      ; preds = %entry354  %sext = sext i32 %x to i64355  %gep = getelementptr double, ptr %y, i64 %sext356  %load5 = load double, ptr %gep, align 8357  ret double %load5358 359loop.exit:                                        ; preds = %loop.body360  %sext2 = sext i32 %x to i64361  %gep2 = getelementptr double, ptr %y, i64 %sext2362  %load6 = load double, ptr %gep2, align 8363  ret double %load6364}365 366; A loop with two symbolic strides.367define void @two_strides(ptr noalias %A, ptr noalias %B, i64 %N, i64 %stride.1, i64 %stride.2) {368; CHECK-LABEL: 'two_strides'369; CHECK-NEXT:    loop:370; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop371; CHECK-NEXT:  Backward loop carried data dependence.372; CHECK-NEXT:      Dependences:373; CHECK-NEXT:        Backward:374; CHECK-NEXT:            %load = load i32, ptr %gep.A, align 4 ->375; CHECK-NEXT:            store i32 %add, ptr %gep.A.next, align 4376; CHECK-EMPTY:377; CHECK-NEXT:      Run-time memory checks:378; CHECK-NEXT:      Grouped accesses:379; CHECK-EMPTY:380; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.381; CHECK-NEXT:      SCEV assumptions:382; CHECK-NEXT:      Equal predicate: %stride.2 == 1383; CHECK-NEXT:      Equal predicate: %stride.1 == 1384; CHECK-EMPTY:385; CHECK-NEXT:      Expressions re-written:386; CHECK-NEXT:      [PSE] %gep.A = getelementptr inbounds i32, ptr %A, i64 %mul:387; CHECK-NEXT:        {%A,+,(4 * %stride.1)}<%loop>388; CHECK-NEXT:        --> {%A,+,4}<%loop>389; CHECK-NEXT:      [PSE] %gep.A.next = getelementptr inbounds i32, ptr %A, i64 %mul.2:390; CHECK-NEXT:        {((4 * %stride.2) + %A),+,(4 * %stride.2)}<%loop>391; CHECK-NEXT:        --> {(4 + %A),+,4}<%loop>392;393entry:394  br label %loop395 396loop:397  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]398  %mul = mul i64 %iv, %stride.1399  %gep.A = getelementptr inbounds i32, ptr %A, i64 %mul400  %load = load i32, ptr %gep.A, align 4401  %gep.B = getelementptr inbounds i32, ptr %B, i64 %iv402  %load_1 = load i32, ptr %gep.B, align 4403  %add = add i32 %load_1, %load404  %iv.next = add nuw nsw i64 %iv, 1405  %mul.2 = mul i64 %iv.next, %stride.2406  %gep.A.next = getelementptr inbounds i32, ptr %A, i64 %mul.2407  store i32 %add, ptr %gep.A.next, align 4408  %exitcond = icmp eq i64 %iv.next, %N409  br i1 %exitcond, label %exit, label %loop410 411exit:412  ret void413}414 415define void @single_stride_used_for_trip_count(ptr noalias %A, ptr noalias %B, i64 %N, i64 %stride) {416; CHECK-LABEL: 'single_stride_used_for_trip_count'417; CHECK-NEXT:    loop:418; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop419; CHECK-NEXT:  Unsafe indirect dependence.420; CHECK-NEXT:      Dependences:421; CHECK-NEXT:        IndirectUnsafe:422; CHECK-NEXT:            %load = load i32, ptr %gep.A, align 4 ->423; CHECK-NEXT:            store i32 %add, ptr %gep.A.next, align 4424; CHECK-EMPTY:425; CHECK-NEXT:      Run-time memory checks:426; CHECK-NEXT:      Grouped accesses:427; CHECK-EMPTY:428; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.429; CHECK-NEXT:      SCEV assumptions:430; CHECK-EMPTY:431; CHECK-NEXT:      Expressions re-written:432;433entry:434  br label %loop435 436loop:437  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]438  %mul = mul i64 %iv, %stride439  %gep.A = getelementptr inbounds i32, ptr %A, i64 %mul440  %load = load i32, ptr %gep.A, align 4441  %gep.B = getelementptr inbounds i32, ptr %B, i64 %iv442  %load_1 = load i32, ptr %gep.B, align 4443  %add = add i32 %load_1, %load444  %iv.next = add nuw nsw i64 %iv, 1445  %gep.A.next = getelementptr inbounds i32, ptr %A, i64 %iv.next446  store i32 %add, ptr %gep.A.next, align 4447  %exitcond = icmp eq i64 %iv.next, %stride448  br i1 %exitcond, label %exit, label %loop449 450exit:                                          ; preds = %loop451  ret void452}453 454; Check the scenario where we have an unknown Stride, which happens to also be455; the loop iteration count. If we speculate Stride==1, it implies that the loop456; will iterate no more than a single iteration.457define void @unknown_stride_equalto_tc(i32 %N, ptr %A, ptr %B, i32 %j)  {458; CHECK-LABEL: 'unknown_stride_equalto_tc'459; CHECK-NEXT:    loop:460; CHECK-NEXT:      Memory dependences are safe with run-time checks461; CHECK-NEXT:      Dependences:462; CHECK-NEXT:      Run-time memory checks:463; CHECK-NEXT:      Check 0:464; CHECK-NEXT:        Comparing group GRP0:465; CHECK-NEXT:        ptr %A466; CHECK-NEXT:        Against group GRP1:467; CHECK-NEXT:          %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add468; CHECK-NEXT:      Grouped accesses:469; CHECK-NEXT:        Group GRP0:470; CHECK-NEXT:          (Low: %A High: (4 + %A))471; CHECK-NEXT:            Member: %A472; CHECK-NEXT:        Group GRP1:473; CHECK-NEXT:          (Low: (((2 * (sext i32 %j to i64))<nsw> + %B) umin ((2 * (sext i32 %j to i64))<nsw> + (2 * (zext i32 (-1 + %N) to i64) * (sext i32 %N to i64)) + %B)) High: (2 + (((2 * (sext i32 %j to i64))<nsw> + %B) umax ((2 * (sext i32 %j to i64))<nsw> + (2 * (zext i32 (-1 + %N) to i64) * (sext i32 %N to i64)) + %B))))474; CHECK-NEXT:            Member: {((2 * (sext i32 %j to i64))<nsw> + %B),+,(2 * (sext i32 %N to i64))<nsw>}<%loop>475; CHECK-EMPTY:476; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.477; CHECK-NEXT:      SCEV assumptions:478; CHECK-NEXT:      {%j,+,%N}<%loop> Added Flags: <nssw>479; CHECK-EMPTY:480; CHECK-NEXT:      Expressions re-written:481; CHECK-NEXT:      [PSE] %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add:482; CHECK-NEXT:        ((2 * (sext i32 {%j,+,%N}<%loop> to i64))<nsw> + %B)483; CHECK-NEXT:        --> {((2 * (sext i32 %j to i64))<nsw> + %B),+,(2 * (sext i32 %N to i64))<nsw>}<%loop>484;485entry:486  %cmp = icmp eq i32 %N, 0487  br i1 %cmp, label %exit, label %loop488 489loop:490  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]491  %mul = mul i32 %iv, %N492  %add = add i32 %mul, %j493  %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add494  %load = load i16, ptr %arrayidx495  %sext = sext i16 %load to i32496  store i32 %sext, ptr %A497  %iv.next = add nuw i32 %iv, 1498  %exitcond = icmp eq i32 %iv.next, %N499  br i1 %exitcond, label %exit, label %loop500 501exit:502  ret void503}504 505 506; Check the scenario where we have an unknown Stride, which happens to also be507; the loop iteration count, but the TC is zero-extended from a narrower type.508define void @unknown_stride_equalto_zext_tc(i16 zeroext %N, ptr %A, ptr %B, i32 %j) {509; CHECK-LABEL: 'unknown_stride_equalto_zext_tc'510; CHECK-NEXT:    loop:511; CHECK-NEXT:      Memory dependences are safe with run-time checks512; CHECK-NEXT:      Dependences:513; CHECK-NEXT:      Run-time memory checks:514; CHECK-NEXT:      Check 0:515; CHECK-NEXT:        Comparing group GRP0:516; CHECK-NEXT:        ptr %A517; CHECK-NEXT:        Against group GRP1:518; CHECK-NEXT:          %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add519; CHECK-NEXT:      Grouped accesses:520; CHECK-NEXT:        Group GRP0:521; CHECK-NEXT:          (Low: %A High: (4 + %A))522; CHECK-NEXT:            Member: %A523; CHECK-NEXT:        Group GRP1:524; CHECK-NEXT:          (Low: (((2 * (sext i32 %j to i64))<nsw> + %B) umin ((2 * (sext i32 %j to i64))<nsw> + (2 * (zext i32 (-1 + (zext i16 %N to i32))<nsw> to i64) * (zext i16 %N to i64)) + %B)) High: (2 + (((2 * (sext i32 %j to i64))<nsw> + %B) umax ((2 * (sext i32 %j to i64))<nsw> + (2 * (zext i32 (-1 + (zext i16 %N to i32))<nsw> to i64) * (zext i16 %N to i64)) + %B))))525; CHECK-NEXT:            Member: {((2 * (sext i32 %j to i64))<nsw> + %B),+,(2 * (zext i16 %N to i64))<nuw><nsw>}<%loop>526; CHECK-EMPTY:527; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.528; CHECK-NEXT:      SCEV assumptions:529; CHECK-NEXT:      {%j,+,(zext i16 %N to i32)}<nw><%loop> Added Flags: <nssw>530; CHECK-EMPTY:531; CHECK-NEXT:      Expressions re-written:532; CHECK-NEXT:      [PSE] %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add:533; CHECK-NEXT:        ((2 * (sext i32 {%j,+,(zext i16 %N to i32)}<nw><%loop> to i64))<nsw> + %B)534; CHECK-NEXT:        --> {((2 * (sext i32 %j to i64))<nsw> + %B),+,(2 * (zext i16 %N to i64))<nuw><nsw>}<%loop>535;536entry:537  %N.ext = zext i16 %N to i32538  %cmp = icmp eq i16 %N, 0539  br i1 %cmp, label %exit, label %loop540 541loop:542  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]543  %mul = mul nuw i32 %iv, %N.ext544  %add = add i32 %mul, %j545  %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add546  %load = load i16, ptr %arrayidx547  %sext = sext i16 %load to i32548  store i32 %sext, ptr %A549  %iv.next = add nuw nsw i32 %iv, 1550  %exitcond = icmp eq i32 %iv.next, %N.ext551  br i1 %exitcond, label %exit, label %loop552 553exit:554  ret void555}556 557; Check the scenario where we have an unknown Stride, which happens to also be558; the loop iteration count, but the TC is sign-extended from a narrower type.559define void @unknown_stride_equalto_sext_tc(i16 %N, ptr %A, ptr %B, i32 %j) {560; CHECK-LABEL: 'unknown_stride_equalto_sext_tc'561; CHECK-NEXT:    loop:562; CHECK-NEXT:      Memory dependences are safe with run-time checks563; CHECK-NEXT:      Dependences:564; CHECK-NEXT:      Run-time memory checks:565; CHECK-NEXT:      Check 0:566; CHECK-NEXT:        Comparing group GRP0:567; CHECK-NEXT:        ptr %A568; CHECK-NEXT:        Against group GRP1:569; CHECK-NEXT:          %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add570; CHECK-NEXT:      Grouped accesses:571; CHECK-NEXT:        Group GRP0:572; CHECK-NEXT:          (Low: %A High: (4 + %A))573; CHECK-NEXT:            Member: %A574; CHECK-NEXT:        Group GRP1:575; CHECK-NEXT:          (Low: (((2 * (sext i32 %j to i64))<nsw> + %B) umin ((2 * (sext i32 %j to i64))<nsw> + (2 * (zext i32 (-1 + (sext i16 %N to i32))<nsw> to i64) * (sext i16 %N to i64)) + %B)) High: (2 + (((2 * (sext i32 %j to i64))<nsw> + %B) umax ((2 * (sext i32 %j to i64))<nsw> + (2 * (zext i32 (-1 + (sext i16 %N to i32))<nsw> to i64) * (sext i16 %N to i64)) + %B))))576; CHECK-NEXT:            Member: {((2 * (sext i32 %j to i64))<nsw> + %B),+,(2 * (sext i16 %N to i64))<nsw>}<%loop>577; CHECK-EMPTY:578; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.579; CHECK-NEXT:      SCEV assumptions:580; CHECK-NEXT:      {%j,+,(sext i16 %N to i32)}<nw><%loop> Added Flags: <nssw>581; CHECK-EMPTY:582; CHECK-NEXT:      Expressions re-written:583; CHECK-NEXT:      [PSE] %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add:584; CHECK-NEXT:        ((2 * (sext i32 {%j,+,(sext i16 %N to i32)}<nw><%loop> to i64))<nsw> + %B)585; CHECK-NEXT:        --> {((2 * (sext i32 %j to i64))<nsw> + %B),+,(2 * (sext i16 %N to i64))<nsw>}<%loop>586;587entry:588  %N.ext = sext i16 %N to i32589  %cmp = icmp eq i16 %N, 0590  br i1 %cmp, label %exit, label %loop591 592loop:593  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]594  %mul = mul nuw i32 %iv, %N.ext595  %add = add i32 %mul, %j596  %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add597  %load = load i16, ptr %arrayidx598  %sext = sext i16 %load to i32599  store i32 %sext, ptr %A600  %iv.next = add nuw nsw i32 %iv, 1601  %exitcond = icmp eq i32 %iv.next, %N.ext602  br i1 %exitcond, label %exit, label %loop603 604exit:605  ret void606}607 608; Check the scenario where we have an unknown Stride, which happens to also be609; the loop iteration count, but the TC is truncated from a wider type.610define void @unknown_stride_equalto_trunc_tc(i64 %N, ptr %A, ptr %B, i32 %j) {611; CHECK-LABEL: 'unknown_stride_equalto_trunc_tc'612; CHECK-NEXT:    loop:613; CHECK-NEXT:      Memory dependences are safe with run-time checks614; CHECK-NEXT:      Dependences:615; CHECK-NEXT:      Run-time memory checks:616; CHECK-NEXT:      Check 0:617; CHECK-NEXT:        Comparing group GRP0:618; CHECK-NEXT:        ptr %A619; CHECK-NEXT:        Against group GRP1:620; CHECK-NEXT:          %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add621; CHECK-NEXT:      Grouped accesses:622; CHECK-NEXT:        Group GRP0:623; CHECK-NEXT:          (Low: %A High: (4 + %A))624; CHECK-NEXT:            Member: %A625; CHECK-NEXT:        Group GRP1:626; CHECK-NEXT:          (Low: (((2 * (sext i32 %j to i64))<nsw> + %B) umin ((2 * (sext i32 %j to i64))<nsw> + (2 * (zext i32 (-1 + (trunc i64 %N to i32)) to i64) * (sext i32 (trunc i64 %N to i32) to i64)) + %B)) High: (2 + (((2 * (sext i32 %j to i64))<nsw> + %B) umax ((2 * (sext i32 %j to i64))<nsw> + (2 * (zext i32 (-1 + (trunc i64 %N to i32)) to i64) * (sext i32 (trunc i64 %N to i32) to i64)) + %B))))627; CHECK-NEXT:            Member: {((2 * (sext i32 %j to i64))<nsw> + %B),+,(2 * (sext i32 (trunc i64 %N to i32) to i64))<nsw>}<%loop>628; CHECK-EMPTY:629; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.630; CHECK-NEXT:      SCEV assumptions:631; CHECK-NEXT:      {%j,+,(trunc i64 %N to i32)}<nw><%loop> Added Flags: <nssw>632; CHECK-EMPTY:633; CHECK-NEXT:      Expressions re-written:634; CHECK-NEXT:      [PSE] %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add:635; CHECK-NEXT:        ((2 * (sext i32 {%j,+,(trunc i64 %N to i32)}<nw><%loop> to i64))<nsw> + %B)636; CHECK-NEXT:        --> {((2 * (sext i32 %j to i64))<nsw> + %B),+,(2 * (sext i32 (trunc i64 %N to i32) to i64))<nsw>}<%loop>637;638entry:639  %N.trunc = trunc i64 %N to i32640  %cmp = icmp eq i64 %N, 0641  br i1 %cmp, label %exit, label %loop642 643loop:644  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]645  %mul = mul nuw i32 %iv, %N.trunc646  %add = add i32 %mul, %j647  %arrayidx = getelementptr inbounds i16, ptr %B, i32 %add648  %load = load i16, ptr %arrayidx649  %sext = sext i16 %load to i32650  store i32 %sext, ptr %A651  %iv.next = add nuw nsw i32 %iv, 1652  %exitcond = icmp eq i32 %iv.next, %N.trunc653  br i1 %exitcond, label %exit, label %loop654 655exit:656  ret void657}658