|
1 | 1 | ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
2 |
| -; RUN: opt -p loop-vectorize -force-vector-width=2 -S %s | FileCheck %s |
| 2 | +; RUN: opt -p loop-vectorize -force-vector-width=2 -use-dereferenceable-at-point-semantics=1 -S %s | FileCheck %s |
3 | 3 |
|
4 | 4 | declare void @llvm.assume(i1)
|
5 | 5 |
|
6 |
| -define void @deref_assumption_in_header_constant_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c) { |
| 6 | +define void @deref_assumption_in_header_constant_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree { |
7 | 7 | ; CHECK-LABEL: define void @deref_assumption_in_header_constant_trip_count(
|
8 |
| -; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) { |
| 8 | +; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1:[0-9]+]] { |
9 | 9 | ; CHECK-NEXT: [[ENTRY:.*]]:
|
10 | 10 | ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
|
11 | 11 | ; CHECK: [[VECTOR_PH]]:
|
@@ -104,9 +104,9 @@ exit:
|
104 | 104 | ret void
|
105 | 105 | }
|
106 | 106 |
|
107 |
| -define void @align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr(ptr noalias %a, ptr noalias %b, ptr noalias %c) { |
| 107 | +define void @align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree { |
108 | 108 | ; CHECK-LABEL: define void @align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr(
|
109 |
| -; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) { |
| 109 | +; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] { |
110 | 110 | ; CHECK-NEXT: [[ENTRY:.*]]:
|
111 | 111 | ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 4), "dereferenceable"(ptr [[A]], i64 4) ]
|
112 | 112 | ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
|
@@ -181,9 +181,9 @@ exit:
|
181 | 181 | ret void
|
182 | 182 | }
|
183 | 183 |
|
184 |
| -define void @deref_assumption_too_small_in_header_constant_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c) { |
| 184 | +define void @deref_assumption_too_small_in_header_constant_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree { |
185 | 185 | ; CHECK-LABEL: define void @deref_assumption_too_small_in_header_constant_trip_count(
|
186 |
| -; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) { |
| 186 | +; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] { |
187 | 187 | ; CHECK-NEXT: [[ENTRY:.*]]:
|
188 | 188 | ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
|
189 | 189 | ; CHECK: [[VECTOR_PH]]:
|
@@ -282,9 +282,9 @@ exit:
|
282 | 282 | ret void
|
283 | 283 | }
|
284 | 284 |
|
285 |
| -define void @deref_assumption_in_header_constant_trip_count_align_1(ptr noalias %a, ptr noalias %b, ptr noalias %c) { |
| 285 | +define void @deref_assumption_in_header_constant_trip_count_align_1(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree { |
286 | 286 | ; CHECK-LABEL: define void @deref_assumption_in_header_constant_trip_count_align_1(
|
287 |
| -; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) { |
| 287 | +; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] { |
288 | 288 | ; CHECK-NEXT: [[ENTRY:.*]]:
|
289 | 289 | ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
|
290 | 290 | ; CHECK: [[VECTOR_PH]]:
|
@@ -383,9 +383,9 @@ exit:
|
383 | 383 | ret void
|
384 | 384 | }
|
385 | 385 |
|
386 |
| -define void @deref_assumption_in_header_constant_trip_count_align_via_arg_attribute(ptr noalias align 4 %a, ptr noalias %b, ptr noalias %c) { |
| 386 | +define void @deref_assumption_in_header_constant_trip_count_align_via_arg_attribute(ptr noalias align 4 %a, ptr noalias %b, ptr noalias %c) nofree { |
387 | 387 | ; CHECK-LABEL: define void @deref_assumption_in_header_constant_trip_count_align_via_arg_attribute(
|
388 |
| -; CHECK-SAME: ptr noalias align 4 [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) { |
| 388 | +; CHECK-SAME: ptr noalias align 4 [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] { |
389 | 389 | ; CHECK-NEXT: [[ENTRY:.*]]:
|
390 | 390 | ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
|
391 | 391 | ; CHECK: [[VECTOR_PH]]:
|
@@ -484,9 +484,9 @@ exit:
|
484 | 484 | ret void
|
485 | 485 | }
|
486 | 486 |
|
487 |
| -define void @deref_assumption_in_header_constant_trip_count_align_not_known(ptr noalias %a, ptr noalias %b, ptr noalias %c) { |
| 487 | +define void @deref_assumption_in_header_constant_trip_count_align_not_known(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree { |
488 | 488 | ; CHECK-LABEL: define void @deref_assumption_in_header_constant_trip_count_align_not_known(
|
489 |
| -; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) { |
| 489 | +; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] { |
490 | 490 | ; CHECK-NEXT: [[ENTRY:.*]]:
|
491 | 491 | ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
|
492 | 492 | ; CHECK: [[VECTOR_PH]]:
|
@@ -585,9 +585,9 @@ exit:
|
585 | 585 | ret void
|
586 | 586 | }
|
587 | 587 |
|
588 |
| -define void @deref_assumption_in_then_constant_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c) { |
| 588 | +define void @deref_assumption_in_then_constant_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree { |
589 | 589 | ; CHECK-LABEL: define void @deref_assumption_in_then_constant_trip_count(
|
590 |
| -; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) { |
| 590 | +; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] { |
591 | 591 | ; CHECK-NEXT: [[ENTRY:.*]]:
|
592 | 592 | ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
|
593 | 593 | ; CHECK: [[VECTOR_PH]]:
|
@@ -682,9 +682,9 @@ exit:
|
682 | 682 | ret void
|
683 | 683 | }
|
684 | 684 |
|
685 |
| -define void @deref_assumption_in_latch_constant_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c) { |
| 685 | +define void @deref_assumption_in_latch_constant_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree { |
686 | 686 | ; CHECK-LABEL: define void @deref_assumption_in_latch_constant_trip_count(
|
687 |
| -; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) { |
| 687 | +; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] { |
688 | 688 | ; CHECK-NEXT: [[ENTRY:.*]]:
|
689 | 689 | ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
|
690 | 690 | ; CHECK: [[VECTOR_PH]]:
|
@@ -785,9 +785,9 @@ exit:
|
785 | 785 | ret void
|
786 | 786 | }
|
787 | 787 |
|
788 |
| -define void @deref_assumption_in_header_variable_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c, i64 %N) { |
| 788 | +define void @deref_assumption_in_header_variable_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c, i64 %N) nofree { |
789 | 789 | ; CHECK-LABEL: define void @deref_assumption_in_header_variable_trip_count(
|
790 |
| -; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]], i64 [[N:%.*]]) { |
| 790 | +; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]], i64 [[N:%.*]]) #[[ATTR1]] { |
791 | 791 | ; CHECK-NEXT: [[ENTRY:.*]]:
|
792 | 792 | ; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 2
|
793 | 793 | ; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
|
@@ -890,9 +890,9 @@ exit:
|
890 | 890 | ret void
|
891 | 891 | }
|
892 | 892 |
|
893 |
| -define void @deref_assumption_in_preheader_constant_trip_count_align_1(ptr noalias %a, ptr noalias %b, ptr noalias %c) { |
| 893 | +define void @deref_assumption_in_preheader_constant_trip_count_align_1(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree { |
894 | 894 | ; CHECK-LABEL: define void @deref_assumption_in_preheader_constant_trip_count_align_1(
|
895 |
| -; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) { |
| 895 | +; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] { |
896 | 896 | ; CHECK-NEXT: [[ENTRY:.*]]:
|
897 | 897 | ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[A]], i64 4000) ]
|
898 | 898 | ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
|
@@ -968,9 +968,9 @@ exit:
|
968 | 968 | ret void
|
969 | 969 | }
|
970 | 970 |
|
971 |
| -define void @deref_assumption_too_small_in_preheader_constant_trip_count_align_1(ptr noalias %a, ptr noalias %b, ptr noalias %c) { |
| 971 | +define void @deref_assumption_too_small_in_preheader_constant_trip_count_align_1(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree { |
972 | 972 | ; CHECK-LABEL: define void @deref_assumption_too_small_in_preheader_constant_trip_count_align_1(
|
973 |
| -; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) { |
| 973 | +; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] { |
974 | 974 | ; CHECK-NEXT: [[ENTRY:.*]]:
|
975 | 975 | ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[A]], i64 3999) ]
|
976 | 976 | ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
|
@@ -1063,9 +1063,9 @@ exit:
|
1063 | 1063 | ret void
|
1064 | 1064 | }
|
1065 | 1065 |
|
1066 |
| -define void @align_and_deref_assumption_in_preheader_constant_trip_count_align_4(ptr noalias %a, ptr noalias %b, ptr noalias %c) { |
| 1066 | +define void @align_and_deref_assumption_in_preheader_constant_trip_count_align_4(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree { |
1067 | 1067 | ; CHECK-LABEL: define void @align_and_deref_assumption_in_preheader_constant_trip_count_align_4(
|
1068 |
| -; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) { |
| 1068 | +; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] { |
1069 | 1069 | ; CHECK-NEXT: [[ENTRY:.*]]:
|
1070 | 1070 | ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 4), "dereferenceable"(ptr [[A]], i64 4000) ]
|
1071 | 1071 | ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
|
@@ -1142,9 +1142,9 @@ exit:
|
1142 | 1142 | }
|
1143 | 1143 |
|
1144 | 1144 |
|
1145 |
| -define void @deref_assumption_in_preheader_constant_trip_count_align_4_known_via_argument_attr(ptr noalias align 4 %a, ptr noalias %b, ptr noalias %c) { |
| 1145 | +define void @deref_assumption_in_preheader_constant_trip_count_align_4_known_via_argument_attr(ptr noalias align 4 %a, ptr noalias %b, ptr noalias %c) nofree { |
1146 | 1146 | ; CHECK-LABEL: define void @deref_assumption_in_preheader_constant_trip_count_align_4_known_via_argument_attr(
|
1147 |
| -; CHECK-SAME: ptr noalias align 4 [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) { |
| 1147 | +; CHECK-SAME: ptr noalias align 4 [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] { |
1148 | 1148 | ; CHECK-NEXT: [[ENTRY:.*]]:
|
1149 | 1149 | ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[A]], i64 4000) ]
|
1150 | 1150 | ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
|
@@ -1220,9 +1220,9 @@ exit:
|
1220 | 1220 | ret void
|
1221 | 1221 | }
|
1222 | 1222 |
|
1223 |
| -define void @deref_assumption_in_preheader_constant_trip_count_align_4_not_known(ptr noalias %a, ptr noalias %b, ptr noalias %c) { |
| 1223 | +define void @deref_assumption_in_preheader_constant_trip_count_align_4_not_known(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree { |
1224 | 1224 | ; CHECK-LABEL: define void @deref_assumption_in_preheader_constant_trip_count_align_4_not_known(
|
1225 |
| -; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) { |
| 1225 | +; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] { |
1226 | 1226 | ; CHECK-NEXT: [[ENTRY:.*]]:
|
1227 | 1227 | ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[A]], i64 4000) ]
|
1228 | 1228 | ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
|
@@ -1315,9 +1315,9 @@ exit:
|
1315 | 1315 | ret void
|
1316 | 1316 | }
|
1317 | 1317 |
|
1318 |
| -define void @deref_assumption_too_small_in_preheader_constant_trip_count_align_4(ptr noalias %a, ptr noalias %b, ptr noalias %c) { |
| 1318 | +define void @deref_assumption_too_small_in_preheader_constant_trip_count_align_4(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree { |
1319 | 1319 | ; CHECK-LABEL: define void @deref_assumption_too_small_in_preheader_constant_trip_count_align_4(
|
1320 |
| -; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) { |
| 1320 | +; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] { |
1321 | 1321 | ; CHECK-NEXT: [[ENTRY:.*]]:
|
1322 | 1322 | ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[A]], i64 3999) ]
|
1323 | 1323 | ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
|
@@ -1409,6 +1409,90 @@ loop.latch:
|
1409 | 1409 | exit:
|
1410 | 1410 | ret void
|
1411 | 1411 | }
|
| 1412 | + |
| 1413 | +; %a may be freeed between the dereferenceable assumption and accesses. |
| 1414 | +; FIXME: It is not safe to use with -use-dereferenceable-at-point-semantics. |
| 1415 | +define void @may_free_align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr(ptr noalias %a, ptr noalias %b, ptr noalias %c) { |
| 1416 | +; CHECK-LABEL: define void @may_free_align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr( |
| 1417 | +; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) { |
| 1418 | +; CHECK-NEXT: [[ENTRY:.*]]: |
| 1419 | +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 4), "dereferenceable"(ptr [[A]], i64 4) ] |
| 1420 | +; CHECK-NEXT: call void @may_free() |
| 1421 | +; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] |
| 1422 | +; CHECK: [[VECTOR_PH]]: |
| 1423 | +; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] |
| 1424 | +; CHECK: [[VECTOR_BODY]]: |
| 1425 | +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] |
| 1426 | +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 |
| 1427 | +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]] |
| 1428 | +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0 |
| 1429 | +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4 |
| 1430 | +; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer |
| 1431 | +; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[A]], align 4 |
| 1432 | +; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[A]], align 4 |
| 1433 | +; CHECK-NEXT: [[TMP13:%.*]] = insertelement <2 x i32> poison, i32 [[TMP5]], i32 0 |
| 1434 | +; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> [[TMP13]], i32 [[TMP15]], i32 1 |
| 1435 | +; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP11]] |
| 1436 | +; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]] |
| 1437 | +; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, ptr [[TMP8]], i32 0 |
| 1438 | +; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP9]], align 4 |
| 1439 | +; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 |
| 1440 | +; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000 |
| 1441 | +; CHECK-NEXT: br i1 [[TMP10]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP32:![0-9]+]] |
| 1442 | +; CHECK: [[MIDDLE_BLOCK]]: |
| 1443 | +; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]] |
| 1444 | +; CHECK: [[SCALAR_PH]]: |
| 1445 | +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] |
| 1446 | +; CHECK-NEXT: br label %[[LOOP_HEADER:.*]] |
| 1447 | +; CHECK: [[LOOP_HEADER]]: |
| 1448 | +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] |
| 1449 | +; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]] |
| 1450 | +; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4 |
| 1451 | +; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0 |
| 1452 | +; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]] |
| 1453 | +; CHECK: [[LOOP_THEN]]: |
| 1454 | +; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[A]], align 4 |
| 1455 | +; CHECK-NEXT: br label %[[LOOP_LATCH]] |
| 1456 | +; CHECK: [[LOOP_LATCH]]: |
| 1457 | +; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ] |
| 1458 | +; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]] |
| 1459 | +; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4 |
| 1460 | +; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 |
| 1461 | +; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000 |
| 1462 | +; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP33:![0-9]+]] |
| 1463 | +; CHECK: [[EXIT]]: |
| 1464 | +; CHECK-NEXT: ret void |
| 1465 | +; |
| 1466 | +entry: |
| 1467 | + call void @llvm.assume(i1 true) [ "align"(ptr %a, i64 4), "dereferenceable"(ptr %a, i64 4) ] |
| 1468 | + call void @may_free() |
| 1469 | + br label %loop.header |
| 1470 | + |
| 1471 | +loop.header: |
| 1472 | + %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] |
| 1473 | + %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv |
| 1474 | + %l.b = load i32, ptr %gep.b, align 4 |
| 1475 | + %c.1 = icmp sge i32 %l.b, 0 |
| 1476 | + br i1 %c.1, label %loop.latch, label %loop.then |
| 1477 | + |
| 1478 | +loop.then: |
| 1479 | + %l.a = load i32, ptr %a, align 4 |
| 1480 | + br label %loop.latch |
| 1481 | + |
| 1482 | +loop.latch: |
| 1483 | + %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ] |
| 1484 | + %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv |
| 1485 | + store i32 %merge, ptr %gep.c, align 4 |
| 1486 | + %iv.next = add nuw nsw i64 %iv, 1 |
| 1487 | + %ec = icmp eq i64 %iv.next, 1000 |
| 1488 | + br i1 %ec, label %exit, label %loop.header |
| 1489 | + |
| 1490 | +exit: |
| 1491 | + ret void |
| 1492 | +} |
| 1493 | + |
| 1494 | +declare void @may_free() |
| 1495 | + |
1412 | 1496 | ;.
|
1413 | 1497 | ; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
|
1414 | 1498 | ; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
|
@@ -1442,4 +1526,6 @@ exit:
|
1442 | 1526 | ; CHECK: [[LOOP29]] = distinct !{[[LOOP29]], [[META2]], [[META1]]}
|
1443 | 1527 | ; CHECK: [[LOOP30]] = distinct !{[[LOOP30]], [[META1]], [[META2]]}
|
1444 | 1528 | ; CHECK: [[LOOP31]] = distinct !{[[LOOP31]], [[META2]], [[META1]]}
|
| 1529 | +; CHECK: [[LOOP32]] = distinct !{[[LOOP32]], [[META1]], [[META2]]} |
| 1530 | +; CHECK: [[LOOP33]] = distinct !{[[LOOP33]], [[META2]], [[META1]]} |
1445 | 1531 | ;.
|
0 commit comments