brintos

brintos / llvm-project-archived public Read only

0
0
Text · 21.0 KiB · 648ebc7 Raw
496 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --filter-out-after "vector.ph" --version 52; RUN: opt %s -passes=loop-vectorize -hoist-runtime-checks=false -force-vector-width=4 -force-vector-interleave=1 -S | FileCheck %s3 4target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"5 6define void @same_step_and_size(ptr %a, ptr %b, i64 %n) {7; CHECK-LABEL: define void @same_step_and_size(8; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[N:%.*]]) {9; CHECK-NEXT:  [[ENTRY:.*:]]10; CHECK-NEXT:    [[A2:%.*]] = ptrtoint ptr [[A]] to i6411; CHECK-NEXT:    [[B1:%.*]] = ptrtoint ptr [[B]] to i6412; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 413; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], [[SCALAR_PH:label %.*]], label %[[VECTOR_MEMCHECK:.*]]14; CHECK:       [[VECTOR_MEMCHECK]]:15; CHECK-NEXT:    [[TMP0:%.*]] = sub i64 [[B1]], [[A2]]16; CHECK-NEXT:    [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP0]], 1617; CHECK-NEXT:    br i1 [[DIFF_CHECK]], [[SCALAR_PH]], [[VECTOR_PH:label %.*]]18;19entry:20  br label %loop21 22loop:23  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]24  %gep.a = getelementptr inbounds i32, ptr %a, i64 %iv25  %l = load i32, ptr %gep.a26  %mul = mul nsw i32 %l, 327  %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv28  store i32 %mul, ptr %gep.b29  %iv.next = add nuw nsw i64 %iv, 130  %exitcond = icmp eq i64 %iv.next, %n31  br i1 %exitcond, label %exit, label %loop32 33exit:34  ret void35}36 37define void @same_step_and_size_no_dominance_between_accesses(ptr %a, ptr %b, i64 %n, i64 %x) {38; CHECK-LABEL: define void @same_step_and_size_no_dominance_between_accesses(39; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[N:%.*]], i64 [[X:%.*]]) {40; CHECK-NEXT:  [[ENTRY:.*:]]41; CHECK-NEXT:    [[B2:%.*]] = ptrtoint ptr [[B]] to i6442; CHECK-NEXT:    [[A1:%.*]] = ptrtoint ptr [[A]] to i6443; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 444; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], [[SCALAR_PH:label %.*]], label %[[VECTOR_MEMCHECK:.*]]45; CHECK:       [[VECTOR_MEMCHECK]]:46; CHECK-NEXT:    [[TMP0:%.*]] = sub i64 [[A1]], [[B2]]47; CHECK-NEXT:    [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP0]], 1648; CHECK-NEXT:    br i1 [[DIFF_CHECK]], [[SCALAR_PH]], [[VECTOR_PH:label %.*]]49;50entry:51  br label %loop52 53loop:54  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]55  %cmp = icmp ne i64 %iv, %x56  br i1 %cmp, label %then, label %else57 58then:59  %gep.a = getelementptr inbounds i32, ptr %a, i64 %iv60  store i32 0, ptr %gep.a61  br label %loop.latch62 63else:64  %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv65  store i32 10, ptr %gep.b66  br label %loop.latch67 68loop.latch:69  %iv.next = add nuw nsw i64 %iv, 170  %exitcond = icmp eq i64 %iv.next, %n71  br i1 %exitcond, label %exit, label %loop72 73exit:74  ret void75}76 77define void @different_steps_and_different_access_sizes(ptr %a, ptr %b, i64 %n) {78; CHECK-LABEL: define void @different_steps_and_different_access_sizes(79; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[N:%.*]]) {80; CHECK-NEXT:  [[ENTRY:.*:]]81; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 482; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], [[SCALAR_PH:label %.*]], label %[[VECTOR_MEMCHECK:.*]]83; CHECK:       [[VECTOR_MEMCHECK]]:84; CHECK-NEXT:    [[TMP0:%.*]] = shl i64 [[N]], 285; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP0]]86; CHECK-NEXT:    [[TMP1:%.*]] = shl i64 [[N]], 187; CHECK-NEXT:    [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP1]]88; CHECK-NEXT:    [[BOUND0:%.*]] = icmp ult ptr [[B]], [[SCEVGEP1]]89; CHECK-NEXT:    [[BOUND1:%.*]] = icmp ult ptr [[A]], [[SCEVGEP]]90; CHECK-NEXT:    [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]91; CHECK-NEXT:    br i1 [[FOUND_CONFLICT]], [[SCALAR_PH]], [[VECTOR_PH:label %.*]]92;93entry:94  br label %loop95 96loop:97  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]98  %gep.a = getelementptr inbounds i16, ptr %a, i64 %iv99  %l = load i16, ptr %gep.a100  %l.ext = sext i16 %l to i32101  %mul = mul nsw i32 %l.ext, 3102  %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv103  store i32 %mul, ptr %gep.b104  %iv.next = add nuw nsw i64 %iv, 1105  %exitcond = icmp eq i64 %iv.next, %n106  br i1 %exitcond, label %exit, label %loop107 108exit:109  ret void110}111 112define void @steps_match_but_different_access_sizes_1(ptr %a, ptr %b, i64 %n) {113; CHECK-LABEL: define void @steps_match_but_different_access_sizes_1(114; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[N:%.*]]) {115; CHECK-NEXT:  [[ENTRY:.*:]]116; CHECK-NEXT:    [[A2:%.*]] = ptrtoint ptr [[A]] to i64117; CHECK-NEXT:    [[B1:%.*]] = ptrtoint ptr [[B]] to i64118; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4119; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], [[SCALAR_PH:label %.*]], label %[[VECTOR_MEMCHECK:.*]]120; CHECK:       [[VECTOR_MEMCHECK]]:121; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[B1]], -2122; CHECK-NEXT:    [[TMP1:%.*]] = sub i64 [[TMP0]], [[A2]]123; CHECK-NEXT:    [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP1]], 16124; CHECK-NEXT:    br i1 [[DIFF_CHECK]], [[SCALAR_PH]], [[VECTOR_PH:label %.*]]125;126entry:127  br label %loop128 129loop:130  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]131  %gep.a = getelementptr inbounds [2 x i16], ptr %a, i64 %iv, i64 1132  %l = load i16, ptr %gep.a133  %l.ext = sext i16 %l to i32134  %mul = mul nsw i32 %l.ext, 3135  %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv136  store i32 %mul, ptr %gep.b137  %iv.next = add nuw nsw i64 %iv, 1138  %exitcond = icmp eq i64 %iv.next, %n139  br i1 %exitcond, label %exit, label %loop140 141exit:142  ret void143}144 145; Same as @steps_match_but_different_access_sizes_1, but with source and sink146; accesses flipped.147define void @steps_match_but_different_access_sizes_2(ptr %a, ptr %b, i64 %n) {148; CHECK-LABEL: define void @steps_match_but_different_access_sizes_2(149; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[N:%.*]]) {150; CHECK-NEXT:  [[ENTRY:.*:]]151; CHECK-NEXT:    [[B2:%.*]] = ptrtoint ptr [[B]] to i64152; CHECK-NEXT:    [[A1:%.*]] = ptrtoint ptr [[A]] to i64153; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4154; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], [[SCALAR_PH:label %.*]], label %[[VECTOR_MEMCHECK:.*]]155; CHECK:       [[VECTOR_MEMCHECK]]:156; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[A1]], 2157; CHECK-NEXT:    [[TMP1:%.*]] = sub i64 [[TMP0]], [[B2]]158; CHECK-NEXT:    [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP1]], 16159; CHECK-NEXT:    br i1 [[DIFF_CHECK]], [[SCALAR_PH]], [[VECTOR_PH:label %.*]]160;161entry:162  br label %loop163 164loop:165  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]166  %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv167  %l = load i32, ptr %gep.b168  %mul = mul nsw i32 %l, 3169  %gep.a = getelementptr inbounds [2 x i16], ptr %a, i64 %iv, i64 1170  %trunc = trunc i32 %mul to i16171  store i16 %trunc, ptr %gep.a172  %iv.next = add nuw nsw i64 %iv, 1173  %exitcond = icmp eq i64 %iv.next, %n174  br i1 %exitcond, label %exit, label %loop175 176exit:177  ret void178}179 180define void @steps_match_two_loadstores_different_access_sizes(ptr %src.1, ptr %src.2, ptr %dst.1, ptr %dst.2, i64 %n) {181; CHECK-LABEL: define void @steps_match_two_loadstores_different_access_sizes(182; CHECK-SAME: ptr [[SRC_1:%.*]], ptr [[SRC_2:%.*]], ptr [[DST_1:%.*]], ptr [[DST_2:%.*]], i64 [[N:%.*]]) {183; CHECK-NEXT:  [[ENTRY:.*:]]184; CHECK-NEXT:    [[SRC_25:%.*]] = ptrtoint ptr [[SRC_2]] to i64185; CHECK-NEXT:    [[SRC_13:%.*]] = ptrtoint ptr [[SRC_1]] to i64186; CHECK-NEXT:    [[DST_12:%.*]] = ptrtoint ptr [[DST_1]] to i64187; CHECK-NEXT:    [[DST_21:%.*]] = ptrtoint ptr [[DST_2]] to i64188; CHECK-NEXT:    [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[N]], i64 1)189; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[UMAX]], 4190; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], [[SCALAR_PH:label %.*]], label %[[VECTOR_MEMCHECK:.*]]191; CHECK:       [[VECTOR_MEMCHECK]]:192; CHECK-NEXT:    [[TMP0:%.*]] = sub i64 [[DST_21]], [[DST_12]]193; CHECK-NEXT:    [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP0]], 32194; CHECK-NEXT:    [[TMP1:%.*]] = sub i64 [[DST_12]], [[SRC_13]]195; CHECK-NEXT:    [[DIFF_CHECK4:%.*]] = icmp ult i64 [[TMP1]], 32196; CHECK-NEXT:    [[CONFLICT_RDX:%.*]] = or i1 [[DIFF_CHECK]], [[DIFF_CHECK4]]197; CHECK-NEXT:    [[TMP2:%.*]] = sub i64 [[DST_12]], [[SRC_25]]198; CHECK-NEXT:    [[DIFF_CHECK6:%.*]] = icmp ult i64 [[TMP2]], 32199; CHECK-NEXT:    [[CONFLICT_RDX7:%.*]] = or i1 [[CONFLICT_RDX]], [[DIFF_CHECK6]]200; CHECK-NEXT:    [[TMP3:%.*]] = sub i64 [[DST_21]], [[SRC_13]]201; CHECK-NEXT:    [[DIFF_CHECK8:%.*]] = icmp ult i64 [[TMP3]], 32202; CHECK-NEXT:    [[CONFLICT_RDX9:%.*]] = or i1 [[CONFLICT_RDX7]], [[DIFF_CHECK8]]203; CHECK-NEXT:    [[TMP4:%.*]] = sub i64 [[DST_21]], [[SRC_25]]204; CHECK-NEXT:    [[DIFF_CHECK10:%.*]] = icmp ult i64 [[TMP4]], 32205; CHECK-NEXT:    [[CONFLICT_RDX11:%.*]] = or i1 [[CONFLICT_RDX9]], [[DIFF_CHECK10]]206; CHECK-NEXT:    br i1 [[CONFLICT_RDX11]], [[SCALAR_PH]], [[VECTOR_PH:label %.*]]207;208entry:209  br label %loop210 211loop:212  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]213  %gep.src.1 = getelementptr i64, ptr %src.1, i64 %iv214  %ld.src.1 = load i64, ptr %gep.src.1215  %ld.src.1.i32 = trunc i64 %ld.src.1 to i32216  %gep.src.2 = getelementptr i64, ptr %src.2, i64 %iv217  %ld.src.2 = load i64, ptr %gep.src.2218  %add = add i64 %ld.src.1, %ld.src.2219  %gep.dst.1 = getelementptr nusw i64, ptr %dst.1, i64 %iv220  store i32 %ld.src.1.i32, ptr %gep.dst.1221  %gep.dst.2 = getelementptr nusw i64, ptr %dst.2, i64 %iv222  store i64 %add, ptr %gep.dst.2223  %iv.next = add nuw nsw i64 %iv, 1224  %cond = icmp ult i64 %iv.next, %n225  br i1 %cond, label %loop, label %exit226 227exit:228  ret void229}230 231; Full no-overlap checks are required instead of difference checks, as232; one of the add-recs used is invariant in the inner loop.233; Test case for PR57315.234define void @nested_loop_outer_iv_addrec_invariant_in_inner1(ptr %a, ptr %b, i64 %n) {235; CHECK-LABEL: define void @nested_loop_outer_iv_addrec_invariant_in_inner1(236; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[N:%.*]]) {237; CHECK-NEXT:  [[ENTRY:.*]]:238; CHECK-NEXT:    [[TMP0:%.*]] = shl i64 [[N]], 2239; CHECK-NEXT:    [[SCEVGEP2:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP0]]240; CHECK-NEXT:    br label %[[OUTER_HEADER:.*]]241; CHECK:       [[OUTER_HEADER]]:242; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i64 [ [[OUTER_IV_NEXT:%.*]], [[OUTER_LATCH:%.*]] ], [ 0, %[[ENTRY]] ]243; CHECK-NEXT:    [[TMP1:%.*]] = shl i64 [[OUTER_IV]], 2244; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr nuw i8, ptr [[A]], i64 [[TMP1]]245; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[TMP1]], 4246; CHECK-NEXT:    [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP2]]247; CHECK-NEXT:    [[GEP_A:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[OUTER_IV]]248; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4249; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], [[SCALAR_PH:label %.*]], label %[[VECTOR_MEMCHECK:.*]]250; CHECK:       [[VECTOR_MEMCHECK]]:251; CHECK-NEXT:    [[BOUND0:%.*]] = icmp ult ptr [[SCEVGEP]], [[SCEVGEP2]]252; CHECK-NEXT:    [[BOUND1:%.*]] = icmp ult ptr [[B]], [[SCEVGEP1]]253; CHECK-NEXT:    [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]254; CHECK-NEXT:    br i1 [[FOUND_CONFLICT]], [[SCALAR_PH]], [[VECTOR_PH:label %.*]]255;256 257 258entry:259  br label %outer.header260 261outer.header:262  %outer.iv = phi i64 [ %outer.iv.next, %outer.latch ], [ 0, %entry ]263  %gep.a = getelementptr inbounds i32, ptr %a, i64 %outer.iv264  br label %inner.body265 266inner.body:267  %inner.iv = phi i64 [ 0, %outer.header ], [ %inner.iv.next, %inner.body ]268  %gep.b = getelementptr inbounds i32, ptr %b, i64 %inner.iv269  %l = load i32, ptr %gep.b, align 4270  %sub = sub i32 %l, 10271  store i32 %sub, ptr %gep.a, align 4272  %inner.iv.next = add nuw nsw i64 %inner.iv, 1273  %inner.cond = icmp eq i64 %inner.iv.next, %n274  br i1 %inner.cond, label %outer.latch, label %inner.body275 276outer.latch:277  %outer.iv.next = add nuw nsw i64 %outer.iv, 1278  %outer.cond = icmp eq i64 %outer.iv.next, %n279  br i1 %outer.cond, label %exit, label %outer.header280 281exit:282  ret void283}284 285; Same as @nested_loop_outer_iv_addrec_invariant_in_inner1 but with dependence286; sink and source swapped.287define void @nested_loop_outer_iv_addrec_invariant_in_inner2(ptr %a, ptr %b, i64 %n) {288; CHECK-LABEL: define void @nested_loop_outer_iv_addrec_invariant_in_inner2(289; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[N:%.*]]) {290; CHECK-NEXT:  [[ENTRY:.*]]:291; CHECK-NEXT:    [[TMP0:%.*]] = shl i64 [[N]], 2292; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr [[B]], i64 [[TMP0]]293; CHECK-NEXT:    br label %[[OUTER_HEADER:.*]]294; CHECK:       [[OUTER_HEADER]]:295; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i64 [ [[OUTER_IV_NEXT:%.*]], [[OUTER_LATCH:%.*]] ], [ 0, %[[ENTRY]] ]296; CHECK-NEXT:    [[TMP1:%.*]] = shl i64 [[OUTER_IV]], 2297; CHECK-NEXT:    [[SCEVGEP1:%.*]] = getelementptr nuw i8, ptr [[A]], i64 [[TMP1]]298; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[TMP1]], 4299; CHECK-NEXT:    [[SCEVGEP2:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP2]]300; CHECK-NEXT:    [[GEP_A:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[OUTER_IV]]301; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4302; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], [[SCALAR_PH:label %.*]], label %[[VECTOR_MEMCHECK:.*]]303; CHECK:       [[VECTOR_MEMCHECK]]:304; CHECK-NEXT:    [[BOUND0:%.*]] = icmp ult ptr [[B]], [[SCEVGEP2]]305; CHECK-NEXT:    [[BOUND1:%.*]] = icmp ult ptr [[SCEVGEP1]], [[SCEVGEP]]306; CHECK-NEXT:    [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]307; CHECK-NEXT:    br i1 [[FOUND_CONFLICT]], [[SCALAR_PH]], [[VECTOR_PH:label %.*]]308;309 310 311entry:312  br label %outer.header313 314outer.header:315  %outer.iv = phi i64 [ %outer.iv.next, %outer.latch ], [ 0, %entry ]316  %gep.a = getelementptr inbounds i32, ptr %a, i64 %outer.iv317  br label %inner.body318 319inner.body:320  %inner.iv = phi i64 [ 0, %outer.header ], [ %inner.iv.next, %inner.body ]321  %l = load i32, ptr %gep.a, align 4322  %sub = sub i32 %l, 10323  %gep.b = getelementptr inbounds i32, ptr %b, i64 %inner.iv324  store i32 %sub, ptr %gep.b, align 4325  %inner.iv.next = add nuw nsw i64 %inner.iv, 1326  %inner.cond = icmp eq i64 %inner.iv.next, %n327  br i1 %inner.cond, label %outer.latch, label %inner.body328 329outer.latch:330  %outer.iv.next = add nuw nsw i64 %outer.iv, 1331  %outer.cond = icmp eq i64 %outer.iv.next, %n332  br i1 %outer.cond, label %exit, label %outer.header333 334exit:335  ret void336}337 338; Test case where the AddRec for the pointers in the inner loop have the AddRec339; of the outer loop as start value. It is sufficient to subtract the start340; values (%dst, %src) of the outer AddRecs.341define void @nested_loop_start_of_inner_ptr_addrec_is_same_outer_addrec(ptr nocapture noundef %dst, ptr nocapture noundef readonly %src, i64 noundef %m, i64 noundef %n) {342; CHECK-LABEL: define void @nested_loop_start_of_inner_ptr_addrec_is_same_outer_addrec(343; CHECK-SAME: ptr noundef captures(none) [[DST:%.*]], ptr noundef readonly captures(none) [[SRC:%.*]], i64 noundef [[M:%.*]], i64 noundef [[N:%.*]]) {344; CHECK-NEXT:  [[ENTRY:.*]]:345; CHECK-NEXT:    [[SRC2:%.*]] = ptrtoint ptr [[SRC]] to i64346; CHECK-NEXT:    [[DST1:%.*]] = ptrtoint ptr [[DST]] to i64347; CHECK-NEXT:    [[SUB:%.*]] = sub i64 [[DST1]], [[SRC2]]348; CHECK-NEXT:    br label %[[OUTER_LOOP:.*]]349; CHECK:       [[OUTER_LOOP]]:350; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[OUTER_IV_NEXT:%.*]], [[INNER_EXIT:%.*]] ]351; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i64 [[OUTER_IV]], [[N]]352; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4353; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], [[SCALAR_PH:label %.*]], label %[[VECTOR_MEMCHECK:.*]]354; CHECK:       [[VECTOR_MEMCHECK]]:355; CHECK-NEXT:    [[DIFF_CHECK:%.*]] = icmp ult i64 [[SUB]], 16356; CHECK-NEXT:    br i1 [[DIFF_CHECK]], [[SCALAR_PH]], [[VECTOR_PH:label %.*]]357;358entry:359  br label %outer.loop360 361outer.loop:362  %outer.iv = phi i64 [ 0, %entry ], [ %outer.iv.next, %inner.exit ]363  %mul = mul nsw i64 %outer.iv, %n364  br label %inner.loop365 366inner.loop:367  %iv.inner = phi i64 [ 0, %outer.loop ], [ %iv.inner.next, %inner.loop ]368  %idx = add nuw nsw i64 %iv.inner, %mul369  %gep.src = getelementptr inbounds i32, ptr %src, i64 %idx370  %l = load i32, ptr %gep.src, align 4371  %gep.dst = getelementptr inbounds i32, ptr %dst, i64 %idx372  %add = add nsw i32 %l, 10373  store i32 %add, ptr %gep.dst, align 4374  %iv.inner.next = add nuw nsw i64 %iv.inner, 1375  %inner.exit.cond = icmp eq i64 %iv.inner.next, %n376  br i1 %inner.exit.cond, label %inner.exit, label %inner.loop377 378inner.exit:379  %outer.iv.next = add nuw nsw i64 %outer.iv, 1380  %outer.exit.cond = icmp eq i64 %outer.iv.next, %m381  br i1 %outer.exit.cond, label %outer.exit, label %outer.loop382 383outer.exit:384  ret void385}386 387define void @use_diff_checks_when_retrying_with_rt_checks(i64 %off, ptr %dst, ptr %src) {388; CHECK-LABEL: define void @use_diff_checks_when_retrying_with_rt_checks(389; CHECK-SAME: i64 [[OFF:%.*]], ptr [[DST:%.*]], ptr [[SRC:%.*]]) {390; CHECK-NEXT:  [[ENTRY:.*:]]391; CHECK-NEXT:    [[SRC2:%.*]] = ptrtoint ptr [[SRC]] to i64392; CHECK-NEXT:    [[DST1:%.*]] = ptrtoint ptr [[DST]] to i64393; CHECK-NEXT:    br label %[[VECTOR_MEMCHECK:.*]]394; CHECK:       [[VECTOR_MEMCHECK]]:395; CHECK-NEXT:    [[TMP0:%.*]] = mul i64 [[OFF]], -8396; CHECK-NEXT:    [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP0]], 32397; CHECK-NEXT:    [[TMP1:%.*]] = shl i64 [[OFF]], 3398; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[DST1]], [[TMP1]]399; CHECK-NEXT:    [[TMP3:%.*]] = sub i64 [[TMP2]], [[SRC2]]400; CHECK-NEXT:    [[DIFF_CHECK3:%.*]] = icmp ult i64 [[TMP3]], 32401; CHECK-NEXT:    [[CONFLICT_RDX:%.*]] = or i1 [[DIFF_CHECK]], [[DIFF_CHECK3]]402; CHECK-NEXT:    [[TMP4:%.*]] = add i64 [[SRC2]], 8403; CHECK-NEXT:    [[TMP5:%.*]] = sub i64 [[TMP4]], [[DST1]]404; CHECK-NEXT:    [[TMP6:%.*]] = sub i64 [[TMP5]], [[TMP1]]405; CHECK-NEXT:    [[DIFF_CHECK4:%.*]] = icmp ult i64 [[TMP6]], 32406; CHECK-NEXT:    [[CONFLICT_RDX5:%.*]] = or i1 [[CONFLICT_RDX]], [[DIFF_CHECK4]]407; CHECK-NEXT:    [[TMP7:%.*]] = sub i64 [[DST1]], [[SRC2]]408; CHECK-NEXT:    [[DIFF_CHECK6:%.*]] = icmp ult i64 [[TMP7]], 32409; CHECK-NEXT:    [[CONFLICT_RDX7:%.*]] = or i1 [[CONFLICT_RDX5]], [[DIFF_CHECK6]]410; CHECK-NEXT:    [[TMP8:%.*]] = add i64 [[DST1]], -8411; CHECK-NEXT:    [[TMP9:%.*]] = sub i64 [[TMP8]], [[SRC2]]412; CHECK-NEXT:    [[DIFF_CHECK8:%.*]] = icmp ult i64 [[TMP9]], 32413; CHECK-NEXT:    [[CONFLICT_RDX9:%.*]] = or i1 [[CONFLICT_RDX7]], [[DIFF_CHECK8]]414; CHECK-NEXT:    br i1 [[CONFLICT_RDX9]], [[SCALAR_PH:label %.*]], [[VECTOR_PH:label %.*]]415;416entry:417  br label %loop418 419loop:420  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]421  %iv.off = add i64 %off, %iv422  %gep.src = getelementptr i64, ptr %src, i64 %iv423  %l.0 = load i64, ptr %gep.src, align 8424  %gep.dst.off = getelementptr i64, ptr %dst, i64 %iv.off425  store i64 %l.0, ptr %gep.dst.off, align 8426  %gep.src.8 = getelementptr i8, ptr %gep.src, i64 8427  %l.1 = load i64, ptr %gep.src.8, align 8428  %gep.dst.iv = getelementptr i64, ptr %dst, i64 %iv429  store i64 %l.1, ptr %gep.dst.iv, align 8430  %iv.next = add i64 %iv, 1431  %ec = icmp eq i64 %iv.next, 1000432  br i1 %ec, label %exit, label %loop433 434exit:435  ret void436}437 438 439define void @remove_diff_checks_via_guards(i32 %x, i32 %y, ptr %A) {440; CHECK-LABEL: define void @remove_diff_checks_via_guards(441; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], ptr [[A:%.*]]) {442; CHECK-NEXT:  [[ENTRY:.*:]]443; CHECK-NEXT:    [[OFFSET:%.*]] = sub i32 [[X]], [[Y]]444; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[OFFSET]], 0445; CHECK-NEXT:    br i1 [[CMP]], [[EXIT:label %.*]], label %[[LOOP_PREHEADER:.*]]446; CHECK:       [[LOOP_PREHEADER]]:447; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[X]] to i64448; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[TMP0]], 1449; CHECK-NEXT:    [[SMAX2:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP1]], i64 0)450; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[SMAX2]] to i32451; CHECK-NEXT:    [[TMP3:%.*]] = add nuw i32 [[TMP2]], 1452; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[TMP3]], 4453; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], [[SCALAR_PH:label %.*]], label %[[VECTOR_SCEVCHECK:.*]]454; CHECK:       [[VECTOR_SCEVCHECK]]:455; CHECK-NEXT:    [[TMP4:%.*]] = sext i32 [[X]] to i64456; CHECK-NEXT:    [[TMP5:%.*]] = add nsw i64 [[TMP4]], 1457; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP5]], i64 0)458; CHECK-NEXT:    [[TMP6:%.*]] = trunc i64 [[SMAX]] to i32459; CHECK-NEXT:    [[TMP7:%.*]] = icmp slt i32 [[TMP6]], 0460; CHECK-NEXT:    [[TMP8:%.*]] = icmp ugt i64 [[SMAX]], 4294967295461; CHECK-NEXT:    [[TMP9:%.*]] = or i1 [[TMP7]], [[TMP8]]462; CHECK-NEXT:    [[TMP10:%.*]] = trunc i64 [[SMAX]] to i32463; CHECK-NEXT:    [[TMP11:%.*]] = add i32 [[OFFSET]], [[TMP10]]464; CHECK-NEXT:    [[TMP12:%.*]] = icmp slt i32 [[TMP11]], [[OFFSET]]465; CHECK-NEXT:    [[TMP13:%.*]] = icmp ugt i64 [[SMAX]], 4294967295466; CHECK-NEXT:    [[TMP14:%.*]] = or i1 [[TMP12]], [[TMP13]]467; CHECK-NEXT:    [[TMP15:%.*]] = or i1 [[TMP9]], [[TMP14]]468; CHECK-NEXT:    br i1 [[TMP15]], [[SCALAR_PH]], label %[[VECTOR_MEMCHECK:.*]]469; CHECK:       [[VECTOR_MEMCHECK]]:470; CHECK-NEXT:    [[TMP16:%.*]] = sext i32 [[OFFSET]] to i64471; CHECK-NEXT:    [[TMP17:%.*]] = shl nsw i64 [[TMP16]], 2472; CHECK-NEXT:    [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP17]], 16473; CHECK-NEXT:    br i1 [[DIFF_CHECK]], [[SCALAR_PH]], [[VECTOR_PH1:label %.*]]474;475entry:476  %offset = sub i32 %x, %y477  %cmp = icmp sge i32 %offset, 0478  br i1 %cmp, label %exit, label %loop479 480loop:481  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]482  %iv.ext = sext i32 %iv to i64483  %gep.A = getelementptr i32, ptr %A, i64 %iv.ext484  %l = load i32, ptr %gep.A, align 1485  %iv.offset = add i32 %iv, %offset486  %iv.offset.ext = sext i32 %iv.offset to i64487  %gep.A.offset = getelementptr i32, ptr %A, i64 %iv.offset.ext488  store i32 %l, ptr %gep.A.offset, align 1489  %iv.next = add i32 %iv, 1490  %ec = icmp sgt i32 %iv, %x491  br i1 %ec, label %exit, label %loop492 493exit:494  ret void495}496