11; 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 -use-dereferenceable-at-point-semantics=1 -S %s | FileCheck %s
2+ ; RUN: opt -p loop-vectorize -force-vector-width=2 -use-dereferenceable-at-point-semantics -S %s | FileCheck %s
33
44declare void @llvm.assume (i1 )
55
6- define void @deref_assumption_in_header_constant_trip_count (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree {
6+ define void @deref_assumption_in_header_constant_trip_count (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree nosync {
77; CHECK-LABEL: define void @deref_assumption_in_header_constant_trip_count(
88; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1:[0-9]+]] {
99; CHECK-NEXT: [[ENTRY:.*]]:
@@ -104,7 +104,7 @@ exit:
104104 ret void
105105}
106106
107- define void @align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree {
107+ define void @align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree nosync {
108108; CHECK-LABEL: define void @align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr(
109109; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
110110; CHECK-NEXT: [[ENTRY:.*]]:
@@ -181,7 +181,7 @@ exit:
181181 ret void
182182}
183183
184- define void @deref_assumption_too_small_in_header_constant_trip_count (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree {
184+ define void @deref_assumption_too_small_in_header_constant_trip_count (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree nosync {
185185; CHECK-LABEL: define void @deref_assumption_too_small_in_header_constant_trip_count(
186186; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
187187; CHECK-NEXT: [[ENTRY:.*]]:
@@ -282,7 +282,7 @@ exit:
282282 ret void
283283}
284284
285- define void @deref_assumption_in_header_constant_trip_count_align_1 (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree {
285+ define void @deref_assumption_in_header_constant_trip_count_align_1 (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree nosync {
286286; CHECK-LABEL: define void @deref_assumption_in_header_constant_trip_count_align_1(
287287; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
288288; CHECK-NEXT: [[ENTRY:.*]]:
@@ -383,7 +383,7 @@ exit:
383383 ret void
384384}
385385
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 {
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 nosync {
387387; CHECK-LABEL: define void @deref_assumption_in_header_constant_trip_count_align_via_arg_attribute(
388388; CHECK-SAME: ptr noalias align 4 [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
389389; CHECK-NEXT: [[ENTRY:.*]]:
@@ -484,7 +484,7 @@ exit:
484484 ret void
485485}
486486
487- define void @deref_assumption_in_header_constant_trip_count_align_not_known (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree {
487+ define void @deref_assumption_in_header_constant_trip_count_align_not_known (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree nosync {
488488; CHECK-LABEL: define void @deref_assumption_in_header_constant_trip_count_align_not_known(
489489; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
490490; CHECK-NEXT: [[ENTRY:.*]]:
@@ -585,7 +585,7 @@ exit:
585585 ret void
586586}
587587
588- define void @deref_assumption_in_then_constant_trip_count (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree {
588+ define void @deref_assumption_in_then_constant_trip_count (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree nosync {
589589; CHECK-LABEL: define void @deref_assumption_in_then_constant_trip_count(
590590; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
591591; CHECK-NEXT: [[ENTRY:.*]]:
@@ -682,7 +682,7 @@ exit:
682682 ret void
683683}
684684
685- define void @deref_assumption_in_latch_constant_trip_count (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree {
685+ define void @deref_assumption_in_latch_constant_trip_count (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree nosync {
686686; CHECK-LABEL: define void @deref_assumption_in_latch_constant_trip_count(
687687; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
688688; CHECK-NEXT: [[ENTRY:.*]]:
@@ -785,7 +785,7 @@ exit:
785785 ret void
786786}
787787
788- define void @deref_assumption_in_header_variable_trip_count (ptr noalias %a , ptr noalias %b , ptr noalias %c , i64 %N ) nofree {
788+ define void @deref_assumption_in_header_variable_trip_count (ptr noalias %a , ptr noalias %b , ptr noalias %c , i64 %N ) nofree nosync {
789789; CHECK-LABEL: define void @deref_assumption_in_header_variable_trip_count(
790790; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]], i64 [[N:%.*]]) #[[ATTR1]] {
791791; CHECK-NEXT: [[ENTRY:.*]]:
@@ -890,7 +890,7 @@ exit:
890890 ret void
891891}
892892
893- define void @deref_assumption_in_preheader_constant_trip_count_align_1 (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree {
893+ define void @deref_assumption_in_preheader_constant_trip_count_align_1 (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree nosync {
894894; CHECK-LABEL: define void @deref_assumption_in_preheader_constant_trip_count_align_1(
895895; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
896896; CHECK-NEXT: [[ENTRY:.*]]:
@@ -968,7 +968,7 @@ exit:
968968 ret void
969969}
970970
971- define void @deref_assumption_too_small_in_preheader_constant_trip_count_align_1 (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree {
971+ define void @deref_assumption_too_small_in_preheader_constant_trip_count_align_1 (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree nosync {
972972; CHECK-LABEL: define void @deref_assumption_too_small_in_preheader_constant_trip_count_align_1(
973973; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
974974; CHECK-NEXT: [[ENTRY:.*]]:
@@ -1063,7 +1063,7 @@ exit:
10631063 ret void
10641064}
10651065
1066- define void @align_and_deref_assumption_in_preheader_constant_trip_count_align_4 (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree {
1066+ define void @align_and_deref_assumption_in_preheader_constant_trip_count_align_4 (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree nosync {
10671067; CHECK-LABEL: define void @align_and_deref_assumption_in_preheader_constant_trip_count_align_4(
10681068; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
10691069; CHECK-NEXT: [[ENTRY:.*]]:
@@ -1142,7 +1142,7 @@ exit:
11421142}
11431143
11441144
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 {
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 nosync {
11461146; CHECK-LABEL: define void @deref_assumption_in_preheader_constant_trip_count_align_4_known_via_argument_attr(
11471147; CHECK-SAME: ptr noalias align 4 [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
11481148; CHECK-NEXT: [[ENTRY:.*]]:
@@ -1220,7 +1220,7 @@ exit:
12201220 ret void
12211221}
12221222
1223- define void @deref_assumption_in_preheader_constant_trip_count_align_4_not_known (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree {
1223+ define void @deref_assumption_in_preheader_constant_trip_count_align_4_not_known (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree nosync {
12241224; CHECK-LABEL: define void @deref_assumption_in_preheader_constant_trip_count_align_4_not_known(
12251225; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
12261226; CHECK-NEXT: [[ENTRY:.*]]:
@@ -1315,7 +1315,7 @@ exit:
13151315 ret void
13161316}
13171317
1318- define void @deref_assumption_too_small_in_preheader_constant_trip_count_align_4 (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree {
1318+ define void @deref_assumption_too_small_in_preheader_constant_trip_count_align_4 (ptr noalias %a , ptr noalias %b , ptr noalias %c ) nofree nosync {
13191319; CHECK-LABEL: define void @deref_assumption_too_small_in_preheader_constant_trip_count_align_4(
13201320; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
13211321; CHECK-NEXT: [[ENTRY:.*]]:
@@ -1410,8 +1410,8 @@ exit:
14101410 ret void
14111411}
14121412
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.
1413+ ; %a may be freed between the dereferenceable assumption and accesses.
1414+ ; It is not safe to use with -use-dereferenceable-at-point-semantics.
14151415define void @may_free_align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr (ptr noalias %a , ptr noalias %b , ptr noalias %c ) {
14161416; CHECK-LABEL: define void @may_free_align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr(
14171417; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) {
@@ -1422,16 +1422,29 @@ define void @may_free_align_deref_assumption_in_header_constant_trip_count_loop_
14221422; CHECK: [[VECTOR_PH]]:
14231423; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
14241424; CHECK: [[VECTOR_BODY]]:
1425- ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY ]] ]
1425+ ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.* ]] ]
14261426; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
14271427; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
14281428; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0
14291429; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4
14301430; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
1431- ; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[A]], align 4
1431+ ; CHECK-NEXT: [[TMP4:%.*]] = xor <2 x i1> [[TMP3]], splat (i1 true)
1432+ ; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP4]], i32 0
1433+ ; CHECK-NEXT: br i1 [[TMP5]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]
1434+ ; CHECK: [[PRED_LOAD_IF]]:
14321435; 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
1436+ ; CHECK-NEXT: [[TMP7:%.*]] = insertelement <2 x i32> poison, i32 [[TMP15]], i32 0
1437+ ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]]
1438+ ; CHECK: [[PRED_LOAD_CONTINUE]]:
1439+ ; CHECK-NEXT: [[TMP12:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP7]], %[[PRED_LOAD_IF]] ]
1440+ ; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i1> [[TMP4]], i32 1
1441+ ; CHECK-NEXT: br i1 [[TMP13]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]]
1442+ ; CHECK: [[PRED_LOAD_IF1]]:
1443+ ; CHECK-NEXT: [[TMP14:%.*]] = load i32, ptr [[A]], align 4
1444+ ; CHECK-NEXT: [[TMP16:%.*]] = insertelement <2 x i32> [[TMP12]], i32 [[TMP14]], i32 1
1445+ ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]]
1446+ ; CHECK: [[PRED_LOAD_CONTINUE2]]:
1447+ ; CHECK-NEXT: [[TMP11:%.*]] = phi <2 x i32> [ [[TMP12]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP16]], %[[PRED_LOAD_IF1]] ]
14351448; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP11]]
14361449; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
14371450; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, ptr [[TMP8]], i32 0
@@ -1491,6 +1504,103 @@ exit:
14911504 ret void
14921505}
14931506
1507+ ; %a may be freed between the dereferenceable assumption and accesses.
1508+ ; It is not safe to use with -use-dereferenceable-at-point-semantics.
1509+ define void @may_free_local_ptr_align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr (ptr noalias %b , ptr noalias %c ) nofree nosync {
1510+ ; CHECK-LABEL: define void @may_free_local_ptr_align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr(
1511+ ; CHECK-SAME: ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
1512+ ; CHECK-NEXT: [[ENTRY:.*]]:
1513+ ; CHECK-NEXT: [[A:%.*]] = call ptr @get_ptr()
1514+ ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 4), "dereferenceable"(ptr [[A]], i64 4) ]
1515+ ; CHECK-NEXT: call void @may_free()
1516+ ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
1517+ ; CHECK: [[VECTOR_PH]]:
1518+ ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
1519+ ; CHECK: [[VECTOR_BODY]]:
1520+ ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ]
1521+ ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
1522+ ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
1523+ ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0
1524+ ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4
1525+ ; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
1526+ ; CHECK-NEXT: [[TMP4:%.*]] = xor <2 x i1> [[TMP3]], splat (i1 true)
1527+ ; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP4]], i32 0
1528+ ; CHECK-NEXT: br i1 [[TMP5]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]
1529+ ; CHECK: [[PRED_LOAD_IF]]:
1530+ ; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[A]], align 4
1531+ ; CHECK-NEXT: [[TMP7:%.*]] = insertelement <2 x i32> poison, i32 [[TMP6]], i32 0
1532+ ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]]
1533+ ; CHECK: [[PRED_LOAD_CONTINUE]]:
1534+ ; CHECK-NEXT: [[TMP8:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP7]], %[[PRED_LOAD_IF]] ]
1535+ ; CHECK-NEXT: [[TMP9:%.*]] = extractelement <2 x i1> [[TMP4]], i32 1
1536+ ; CHECK-NEXT: br i1 [[TMP9]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]]
1537+ ; CHECK: [[PRED_LOAD_IF1]]:
1538+ ; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[A]], align 4
1539+ ; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> [[TMP8]], i32 [[TMP10]], i32 1
1540+ ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]]
1541+ ; CHECK: [[PRED_LOAD_CONTINUE2]]:
1542+ ; CHECK-NEXT: [[TMP12:%.*]] = phi <2 x i32> [ [[TMP8]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP11]], %[[PRED_LOAD_IF1]] ]
1543+ ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP12]]
1544+ ; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
1545+ ; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds i32, ptr [[TMP13]], i32 0
1546+ ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP14]], align 4
1547+ ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
1548+ ; CHECK-NEXT: [[TMP15:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
1549+ ; CHECK-NEXT: br i1 [[TMP15]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP34:![0-9]+]]
1550+ ; CHECK: [[MIDDLE_BLOCK]]:
1551+ ; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
1552+ ; CHECK: [[SCALAR_PH]]:
1553+ ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
1554+ ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
1555+ ; CHECK: [[LOOP_HEADER]]:
1556+ ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
1557+ ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
1558+ ; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4
1559+ ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0
1560+ ; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]]
1561+ ; CHECK: [[LOOP_THEN]]:
1562+ ; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[A]], align 4
1563+ ; CHECK-NEXT: br label %[[LOOP_LATCH]]
1564+ ; CHECK: [[LOOP_LATCH]]:
1565+ ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ]
1566+ ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]]
1567+ ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4
1568+ ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
1569+ ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
1570+ ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP35:![0-9]+]]
1571+ ; CHECK: [[EXIT]]:
1572+ ; CHECK-NEXT: ret void
1573+ ;
1574+ entry:
1575+ %a = call ptr @get_ptr ()
1576+ call void @llvm.assume (i1 true ) [ "align" (ptr %a , i64 4 ), "dereferenceable" (ptr %a , i64 4 ) ]
1577+ call void @may_free ()
1578+ br label %loop.header
1579+
1580+ loop.header:
1581+ %iv = phi i64 [ 0 , %entry ], [ %iv.next , %loop.latch ]
1582+ %gep.b = getelementptr inbounds i32 , ptr %b , i64 %iv
1583+ %l.b = load i32 , ptr %gep.b , align 4
1584+ %c.1 = icmp sge i32 %l.b , 0
1585+ br i1 %c.1 , label %loop.latch , label %loop.then
1586+
1587+ loop.then:
1588+ %l.a = load i32 , ptr %a , align 4
1589+ br label %loop.latch
1590+
1591+ loop.latch:
1592+ %merge = phi i32 [ %l.a , %loop.then ], [ %l.b , %loop.header ]
1593+ %gep.c = getelementptr inbounds i32 , ptr %c , i64 %iv
1594+ store i32 %merge , ptr %gep.c , align 4
1595+ %iv.next = add nuw nsw i64 %iv , 1
1596+ %ec = icmp eq i64 %iv.next , 1000
1597+ br i1 %ec , label %exit , label %loop.header
1598+
1599+ exit:
1600+ ret void
1601+ }
1602+
1603+ declare ptr @get_ptr ()
14941604declare void @may_free ()
14951605
14961606;.
@@ -1528,4 +1638,6 @@ declare void @may_free()
15281638; CHECK: [[LOOP31]] = distinct !{[[LOOP31]], [[META2]], [[META1]]}
15291639; CHECK: [[LOOP32]] = distinct !{[[LOOP32]], [[META1]], [[META2]]}
15301640; CHECK: [[LOOP33]] = distinct !{[[LOOP33]], [[META2]], [[META1]]}
1641+ ; CHECK: [[LOOP34]] = distinct !{[[LOOP34]], [[META1]], [[META2]]}
1642+ ; CHECK: [[LOOP35]] = distinct !{[[LOOP35]], [[META2]], [[META1]]}
15311643;.
0 commit comments