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 -use-dereferenceable-at-point-semantics -S %s | FileCheck %s 3 4declare void @llvm.assume(i1) 5 6define void @deref_assumption_in_header_constant_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{ 7; CHECK-LABEL: define void @deref_assumption_in_header_constant_trip_count( 8; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1:[0-9]+]] { 9; CHECK-NEXT: [[ENTRY:.*]]: 10; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] 11; CHECK: [[VECTOR_PH]]: 12; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] 13; CHECK: [[VECTOR_BODY]]: 14; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ] 15; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2]] ] 16; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 17; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[A]], <2 x i64> [[VEC_IND]] 18; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0 19; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP4]], i64 4), "dereferenceable"(ptr [[TMP4]], i64 4) ] 20; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1 21; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP5]], i64 4), "dereferenceable"(ptr [[TMP5]], i64 4) ] 22; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]] 23; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, ptr [[TMP6]], i32 0 24; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP7]], align 4 25; CHECK-NEXT: [[TMP9:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer 26; CHECK-NEXT: [[TMP10:%.*]] = xor <2 x i1> [[TMP9]], splat (i1 true) 27; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP10]], i32 0 28; CHECK-NEXT: br i1 [[TMP8]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]] 29; CHECK: [[PRED_LOAD_IF]]: 30; CHECK-NEXT: [[TMP21:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0 31; CHECK-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 32; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> poison, i32 [[TMP22]], i32 0 33; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]] 34; CHECK: [[PRED_LOAD_CONTINUE]]: 35; CHECK-NEXT: [[TMP12:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP11]], %[[PRED_LOAD_IF]] ] 36; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i1> [[TMP10]], i32 1 37; CHECK-NEXT: br i1 [[TMP13]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]] 38; CHECK: [[PRED_LOAD_IF1]]: 39; CHECK-NEXT: [[TMP26:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1 40; CHECK-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4 41; CHECK-NEXT: [[TMP16:%.*]] = insertelement <2 x i32> [[TMP12]], i32 [[TMP27]], i32 1 42; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]] 43; CHECK: [[PRED_LOAD_CONTINUE2]]: 44; CHECK-NEXT: [[TMP17:%.*]] = phi <2 x i32> [ [[TMP12]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP16]], %[[PRED_LOAD_IF1]] ] 45; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP9]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP17]] 46; CHECK-NEXT: [[TMP30:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]] 47; CHECK-NEXT: [[TMP31:%.*]] = getelementptr inbounds i32, ptr [[TMP30]], i32 0 48; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP31]], align 4 49; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 50; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2) 51; CHECK-NEXT: [[TMP32:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000 52; CHECK-NEXT: br i1 [[TMP32]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] 53; CHECK: [[MIDDLE_BLOCK]]: 54; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]] 55; CHECK: [[SCALAR_PH]]: 56; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] 57; CHECK-NEXT: br label %[[LOOP_HEADER:.*]] 58; CHECK: [[LOOP_HEADER]]: 59; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] 60; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]] 61; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[GEP_A]], i64 4), "dereferenceable"(ptr [[GEP_A]], i64 4) ] 62; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]] 63; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4 64; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0 65; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]] 66; CHECK: [[LOOP_THEN]]: 67; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4 68; CHECK-NEXT: br label %[[LOOP_LATCH]] 69; CHECK: [[LOOP_LATCH]]: 70; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ] 71; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]] 72; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4 73; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 74; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000 75; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP3:![0-9]+]] 76; CHECK: [[EXIT]]: 77; CHECK-NEXT: ret void 78; 79entry: 80 br label %loop.header 81 82loop.header: 83 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 84 %gep.a = getelementptr i32, ptr %a, i64 %iv 85 call void @llvm.assume(i1 true) [ "align"(ptr %gep.a, i64 4), "dereferenceable"(ptr %gep.a, i64 4) ] 86 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv 87 %l.b = load i32, ptr %gep.b, align 4 88 %c.1 = icmp sge i32 %l.b, 0 89 br i1 %c.1, label %loop.latch, label %loop.then 90 91loop.then: 92 %l.a = load i32, ptr %gep.a, align 4 93 br label %loop.latch 94 95loop.latch: 96 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ] 97 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv 98 store i32 %merge, ptr %gep.c, align 4 99 %iv.next = add nuw nsw i64 %iv, 1 100 %ec = icmp eq i64 %iv.next, 1000 101 br i1 %ec, label %exit, label %loop.header 102 103exit: 104 ret void 105} 106 107define void @align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{ 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:%.*]]) #[[ATTR1]] { 110; CHECK-NEXT: [[ENTRY:.*]]: 111; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 4), "dereferenceable"(ptr [[A]], i64 4) ] 112; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] 113; CHECK: [[VECTOR_PH]]: 114; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] 115; CHECK: [[VECTOR_BODY]]: 116; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] 117; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 118; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]] 119; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0 120; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4 121; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer 122; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[A]], align 4 123; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[A]], align 4 124; CHECK-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> poison, i32 [[TMP4]], i32 0 125; CHECK-NEXT: [[TMP7:%.*]] = insertelement <2 x i32> [[TMP6]], i32 [[TMP5]], i32 1 126; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP7]] 127; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]] 128; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, ptr [[TMP8]], i32 0 129; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP9]], align 4 130; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 131; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000 132; CHECK-NEXT: br i1 [[TMP10]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]] 133; CHECK: [[MIDDLE_BLOCK]]: 134; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]] 135; CHECK: [[SCALAR_PH]]: 136; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] 137; CHECK-NEXT: br label %[[LOOP_HEADER:.*]] 138; CHECK: [[LOOP_HEADER]]: 139; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] 140; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]] 141; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4 142; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0 143; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]] 144; CHECK: [[LOOP_THEN]]: 145; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[A]], align 4 146; CHECK-NEXT: br label %[[LOOP_LATCH]] 147; CHECK: [[LOOP_LATCH]]: 148; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ] 149; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]] 150; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4 151; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 152; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000 153; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP5:![0-9]+]] 154; CHECK: [[EXIT]]: 155; CHECK-NEXT: ret void 156; 157entry: 158 call void @llvm.assume(i1 true) [ "align"(ptr %a, i64 4), "dereferenceable"(ptr %a, i64 4) ] 159 br label %loop.header 160 161loop.header: 162 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 163 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv 164 %l.b = load i32, ptr %gep.b, align 4 165 %c.1 = icmp sge i32 %l.b, 0 166 br i1 %c.1, label %loop.latch, label %loop.then 167 168loop.then: 169 %l.a = load i32, ptr %a, align 4 170 br label %loop.latch 171 172loop.latch: 173 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ] 174 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv 175 store i32 %merge, ptr %gep.c, align 4 176 %iv.next = add nuw nsw i64 %iv, 1 177 %ec = icmp eq i64 %iv.next, 1000 178 br i1 %ec, label %exit, label %loop.header 179 180exit: 181 ret void 182} 183 184define void @deref_assumption_too_small_in_header_constant_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{ 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:%.*]]) #[[ATTR1]] { 187; CHECK-NEXT: [[ENTRY:.*]]: 188; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] 189; CHECK: [[VECTOR_PH]]: 190; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] 191; CHECK: [[VECTOR_BODY]]: 192; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ] 193; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2]] ] 194; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 195; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[A]], <2 x i64> [[VEC_IND]] 196; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0 197; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP4]], i64 4), "dereferenceable"(ptr [[TMP4]], i64 2) ] 198; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1 199; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP5]], i64 4), "dereferenceable"(ptr [[TMP5]], i64 2) ] 200; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]] 201; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, ptr [[TMP6]], i32 0 202; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP7]], align 4 203; CHECK-NEXT: [[TMP9:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer 204; CHECK-NEXT: [[TMP10:%.*]] = xor <2 x i1> [[TMP9]], splat (i1 true) 205; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP10]], i32 0 206; CHECK-NEXT: br i1 [[TMP8]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]] 207; CHECK: [[PRED_LOAD_IF]]: 208; CHECK-NEXT: [[TMP21:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0 209; CHECK-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 210; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> poison, i32 [[TMP22]], i32 0 211; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]] 212; CHECK: [[PRED_LOAD_CONTINUE]]: 213; CHECK-NEXT: [[TMP12:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP11]], %[[PRED_LOAD_IF]] ] 214; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i1> [[TMP10]], i32 1 215; CHECK-NEXT: br i1 [[TMP13]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]] 216; CHECK: [[PRED_LOAD_IF1]]: 217; CHECK-NEXT: [[TMP26:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1 218; CHECK-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4 219; CHECK-NEXT: [[TMP16:%.*]] = insertelement <2 x i32> [[TMP12]], i32 [[TMP27]], i32 1 220; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]] 221; CHECK: [[PRED_LOAD_CONTINUE2]]: 222; CHECK-NEXT: [[TMP17:%.*]] = phi <2 x i32> [ [[TMP12]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP16]], %[[PRED_LOAD_IF1]] ] 223; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP9]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP17]] 224; CHECK-NEXT: [[TMP30:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]] 225; CHECK-NEXT: [[TMP31:%.*]] = getelementptr inbounds i32, ptr [[TMP30]], i32 0 226; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP31]], align 4 227; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 228; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2) 229; CHECK-NEXT: [[TMP32:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000 230; CHECK-NEXT: br i1 [[TMP32]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]] 231; CHECK: [[MIDDLE_BLOCK]]: 232; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]] 233; CHECK: [[SCALAR_PH]]: 234; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] 235; CHECK-NEXT: br label %[[LOOP_HEADER:.*]] 236; CHECK: [[LOOP_HEADER]]: 237; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] 238; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]] 239; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[GEP_A]], i64 4), "dereferenceable"(ptr [[GEP_A]], i64 2) ] 240; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]] 241; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4 242; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0 243; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]] 244; CHECK: [[LOOP_THEN]]: 245; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4 246; CHECK-NEXT: br label %[[LOOP_LATCH]] 247; CHECK: [[LOOP_LATCH]]: 248; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ] 249; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]] 250; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4 251; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 252; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000 253; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP7:![0-9]+]] 254; CHECK: [[EXIT]]: 255; CHECK-NEXT: ret void 256; 257entry: 258 br label %loop.header 259 260loop.header: 261 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 262 %gep.a = getelementptr i32, ptr %a, i64 %iv 263 call void @llvm.assume(i1 true) [ "align"(ptr %gep.a, i64 4), "dereferenceable"(ptr %gep.a, i64 2) ] 264 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv 265 %l.b = load i32, ptr %gep.b, align 4 266 %c.1 = icmp sge i32 %l.b, 0 267 br i1 %c.1, label %loop.latch, label %loop.then 268 269loop.then: 270 %l.a = load i32, ptr %gep.a, align 4 271 br label %loop.latch 272 273loop.latch: 274 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ] 275 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv 276 store i32 %merge, ptr %gep.c, align 4 277 %iv.next = add nuw nsw i64 %iv, 1 278 %ec = icmp eq i64 %iv.next, 1000 279 br i1 %ec, label %exit, label %loop.header 280 281exit: 282 ret void 283} 284 285define void @deref_assumption_in_header_constant_trip_count_align_1(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{ 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:%.*]]) #[[ATTR1]] { 288; CHECK-NEXT: [[ENTRY:.*]]: 289; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] 290; CHECK: [[VECTOR_PH]]: 291; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] 292; CHECK: [[VECTOR_BODY]]: 293; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ] 294; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2]] ] 295; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 296; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[A]], <2 x i64> [[VEC_IND]] 297; CHECK-NEXT: [[TMP2:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0 298; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[TMP2]], i64 4) ] 299; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1 300; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[TMP3]], i64 4) ] 301; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]] 302; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[TMP4]], i32 0 303; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP5]], align 4 304; CHECK-NEXT: [[TMP6:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer 305; CHECK-NEXT: [[TMP7:%.*]] = xor <2 x i1> [[TMP6]], splat (i1 true) 306; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP7]], i32 0 307; CHECK-NEXT: br i1 [[TMP8]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]] 308; CHECK: [[PRED_LOAD_IF]]: 309; CHECK-NEXT: [[TMP9:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0 310; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[TMP9]], align 1 311; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> poison, i32 [[TMP10]], i32 0 312; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]] 313; CHECK: [[PRED_LOAD_CONTINUE]]: 314; CHECK-NEXT: [[TMP12:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP11]], %[[PRED_LOAD_IF]] ] 315; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i1> [[TMP7]], i32 1 316; CHECK-NEXT: br i1 [[TMP13]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]] 317; CHECK: [[PRED_LOAD_IF1]]: 318; CHECK-NEXT: [[TMP14:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1 319; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[TMP14]], align 1 320; CHECK-NEXT: [[TMP16:%.*]] = insertelement <2 x i32> [[TMP12]], i32 [[TMP15]], i32 1 321; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]] 322; CHECK: [[PRED_LOAD_CONTINUE2]]: 323; CHECK-NEXT: [[TMP17:%.*]] = phi <2 x i32> [ [[TMP12]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP16]], %[[PRED_LOAD_IF1]] ] 324; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP6]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP17]] 325; CHECK-NEXT: [[TMP18:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]] 326; CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds i32, ptr [[TMP18]], i32 0 327; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP19]], align 4 328; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 329; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2) 330; CHECK-NEXT: [[TMP20:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000 331; CHECK-NEXT: br i1 [[TMP20]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]] 332; CHECK: [[MIDDLE_BLOCK]]: 333; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]] 334; CHECK: [[SCALAR_PH]]: 335; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] 336; CHECK-NEXT: br label %[[LOOP_HEADER:.*]] 337; CHECK: [[LOOP_HEADER]]: 338; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] 339; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]] 340; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[GEP_A]], i64 4) ] 341; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]] 342; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4 343; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0 344; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]] 345; CHECK: [[LOOP_THEN]]: 346; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 1 347; CHECK-NEXT: br label %[[LOOP_LATCH]] 348; CHECK: [[LOOP_LATCH]]: 349; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ] 350; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]] 351; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4 352; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 353; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000 354; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP9:![0-9]+]] 355; CHECK: [[EXIT]]: 356; CHECK-NEXT: ret void 357; 358entry: 359 br label %loop.header 360 361loop.header: 362 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 363 %gep.a = getelementptr i32, ptr %a, i64 %iv 364 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %gep.a, i64 4) ] 365 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv 366 %l.b = load i32, ptr %gep.b, align 4 367 %c.1 = icmp sge i32 %l.b, 0 368 br i1 %c.1, label %loop.latch, label %loop.then 369 370loop.then: 371 %l.a = load i32, ptr %gep.a, align 1 372 br label %loop.latch 373 374loop.latch: 375 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ] 376 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv 377 store i32 %merge, ptr %gep.c, align 4 378 %iv.next = add nuw nsw i64 %iv, 1 379 %ec = icmp eq i64 %iv.next, 1000 380 br i1 %ec, label %exit, label %loop.header 381 382exit: 383 ret void 384} 385 386define 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{ 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:%.*]]) #[[ATTR1]] { 389; CHECK-NEXT: [[ENTRY:.*]]: 390; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] 391; CHECK: [[VECTOR_PH]]: 392; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] 393; CHECK: [[VECTOR_BODY]]: 394; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ] 395; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2]] ] 396; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 397; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[A]], <2 x i64> [[VEC_IND]] 398; CHECK-NEXT: [[TMP2:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0 399; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[TMP2]], i64 4) ] 400; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1 401; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[TMP3]], i64 4) ] 402; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]] 403; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[TMP4]], i32 0 404; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP5]], align 4 405; CHECK-NEXT: [[TMP6:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer 406; CHECK-NEXT: [[TMP7:%.*]] = xor <2 x i1> [[TMP6]], splat (i1 true) 407; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP7]], i32 0 408; CHECK-NEXT: br i1 [[TMP8]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]] 409; CHECK: [[PRED_LOAD_IF]]: 410; CHECK-NEXT: [[TMP9:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0 411; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[TMP9]], align 4 412; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> poison, i32 [[TMP10]], i32 0 413; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]] 414; CHECK: [[PRED_LOAD_CONTINUE]]: 415; CHECK-NEXT: [[TMP12:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP11]], %[[PRED_LOAD_IF]] ] 416; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i1> [[TMP7]], i32 1 417; CHECK-NEXT: br i1 [[TMP13]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]] 418; CHECK: [[PRED_LOAD_IF1]]: 419; CHECK-NEXT: [[TMP14:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1 420; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[TMP14]], align 4 421; CHECK-NEXT: [[TMP16:%.*]] = insertelement <2 x i32> [[TMP12]], i32 [[TMP15]], i32 1 422; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]] 423; CHECK: [[PRED_LOAD_CONTINUE2]]: 424; CHECK-NEXT: [[TMP17:%.*]] = phi <2 x i32> [ [[TMP12]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP16]], %[[PRED_LOAD_IF1]] ] 425; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP6]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP17]] 426; CHECK-NEXT: [[TMP18:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]] 427; CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds i32, ptr [[TMP18]], i32 0 428; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP19]], align 4 429; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 430; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2) 431; CHECK-NEXT: [[TMP20:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000 432; CHECK-NEXT: br i1 [[TMP20]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]] 433; CHECK: [[MIDDLE_BLOCK]]: 434; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]] 435; CHECK: [[SCALAR_PH]]: 436; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] 437; CHECK-NEXT: br label %[[LOOP_HEADER:.*]] 438; CHECK: [[LOOP_HEADER]]: 439; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] 440; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]] 441; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[GEP_A]], i64 4) ] 442; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]] 443; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4 444; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0 445; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]] 446; CHECK: [[LOOP_THEN]]: 447; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4 448; CHECK-NEXT: br label %[[LOOP_LATCH]] 449; CHECK: [[LOOP_LATCH]]: 450; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ] 451; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]] 452; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4 453; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 454; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000 455; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP11:![0-9]+]] 456; CHECK: [[EXIT]]: 457; CHECK-NEXT: ret void 458; 459entry: 460 br label %loop.header 461 462loop.header: 463 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 464 %gep.a = getelementptr i32, ptr %a, i64 %iv 465 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %gep.a, i64 4) ] 466 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv 467 %l.b = load i32, ptr %gep.b, align 4 468 %c.1 = icmp sge i32 %l.b, 0 469 br i1 %c.1, label %loop.latch, label %loop.then 470 471loop.then: 472 %l.a = load i32, ptr %gep.a, align 4 473 br label %loop.latch 474 475loop.latch: 476 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ] 477 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv 478 store i32 %merge, ptr %gep.c, align 4 479 %iv.next = add nuw nsw i64 %iv, 1 480 %ec = icmp eq i64 %iv.next, 1000 481 br i1 %ec, label %exit, label %loop.header 482 483exit: 484 ret void 485} 486 487define void @deref_assumption_in_header_constant_trip_count_align_not_known(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{ 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:%.*]]) #[[ATTR1]] { 490; CHECK-NEXT: [[ENTRY:.*]]: 491; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] 492; CHECK: [[VECTOR_PH]]: 493; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] 494; CHECK: [[VECTOR_BODY]]: 495; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ] 496; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2]] ] 497; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 498; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[A]], <2 x i64> [[VEC_IND]] 499; CHECK-NEXT: [[TMP2:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0 500; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[TMP2]], i64 4) ] 501; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1 502; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[TMP3]], i64 4) ] 503; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]] 504; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[TMP4]], i32 0 505; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP5]], align 4 506; CHECK-NEXT: [[TMP6:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer 507; CHECK-NEXT: [[TMP7:%.*]] = xor <2 x i1> [[TMP6]], splat (i1 true) 508; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP7]], i32 0 509; CHECK-NEXT: br i1 [[TMP8]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]] 510; CHECK: [[PRED_LOAD_IF]]: 511; CHECK-NEXT: [[TMP9:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0 512; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[TMP9]], align 4 513; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> poison, i32 [[TMP10]], i32 0 514; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]] 515; CHECK: [[PRED_LOAD_CONTINUE]]: 516; CHECK-NEXT: [[TMP12:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP11]], %[[PRED_LOAD_IF]] ] 517; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i1> [[TMP7]], i32 1 518; CHECK-NEXT: br i1 [[TMP13]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]] 519; CHECK: [[PRED_LOAD_IF1]]: 520; CHECK-NEXT: [[TMP14:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1 521; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[TMP14]], align 4 522; CHECK-NEXT: [[TMP16:%.*]] = insertelement <2 x i32> [[TMP12]], i32 [[TMP15]], i32 1 523; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]] 524; CHECK: [[PRED_LOAD_CONTINUE2]]: 525; CHECK-NEXT: [[TMP17:%.*]] = phi <2 x i32> [ [[TMP12]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP16]], %[[PRED_LOAD_IF1]] ] 526; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP6]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP17]] 527; CHECK-NEXT: [[TMP18:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]] 528; CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds i32, ptr [[TMP18]], i32 0 529; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP19]], align 4 530; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 531; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2) 532; CHECK-NEXT: [[TMP20:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000 533; CHECK-NEXT: br i1 [[TMP20]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]] 534; CHECK: [[MIDDLE_BLOCK]]: 535; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]] 536; CHECK: [[SCALAR_PH]]: 537; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] 538; CHECK-NEXT: br label %[[LOOP_HEADER:.*]] 539; CHECK: [[LOOP_HEADER]]: 540; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] 541; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]] 542; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[GEP_A]], i64 4) ] 543; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]] 544; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4 545; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0 546; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]] 547; CHECK: [[LOOP_THEN]]: 548; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4 549; CHECK-NEXT: br label %[[LOOP_LATCH]] 550; CHECK: [[LOOP_LATCH]]: 551; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ] 552; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]] 553; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4 554; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 555; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000 556; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP13:![0-9]+]] 557; CHECK: [[EXIT]]: 558; CHECK-NEXT: ret void 559; 560entry: 561 br label %loop.header 562 563loop.header: 564 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 565 %gep.a = getelementptr i32, ptr %a, i64 %iv 566 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %gep.a, i64 4) ] 567 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv 568 %l.b = load i32, ptr %gep.b, align 4 569 %c.1 = icmp sge i32 %l.b, 0 570 br i1 %c.1, label %loop.latch, label %loop.then 571 572loop.then: 573 %l.a = load i32, ptr %gep.a, align 4 574 br label %loop.latch 575 576loop.latch: 577 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ] 578 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv 579 store i32 %merge, ptr %gep.c, align 4 580 %iv.next = add nuw nsw i64 %iv, 1 581 %ec = icmp eq i64 %iv.next, 1000 582 br i1 %ec, label %exit, label %loop.header 583 584exit: 585 ret void 586} 587 588define void @deref_assumption_in_then_constant_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{ 589; CHECK-LABEL: define void @deref_assumption_in_then_constant_trip_count( 590; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] { 591; CHECK-NEXT: [[ENTRY:.*]]: 592; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] 593; CHECK: [[VECTOR_PH]]: 594; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] 595; CHECK: [[VECTOR_BODY]]: 596; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ] 597; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2]] ] 598; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 599; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]] 600; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0 601; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4 602; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer 603; CHECK-NEXT: [[TMP4:%.*]] = xor <2 x i1> [[TMP3]], splat (i1 true) 604; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i32, ptr [[A]], <2 x i64> [[VEC_IND]] 605; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x i1> [[TMP4]], i32 0 606; CHECK-NEXT: br i1 [[TMP6]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]] 607; CHECK: [[PRED_LOAD_IF]]: 608; CHECK-NEXT: [[TMP17:%.*]] = extractelement <2 x ptr> [[TMP5]], i32 0 609; CHECK-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 4 610; CHECK-NEXT: [[TMP9:%.*]] = insertelement <2 x i32> poison, i32 [[TMP18]], i32 0 611; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]] 612; CHECK: [[PRED_LOAD_CONTINUE]]: 613; CHECK-NEXT: [[TMP10:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP9]], %[[PRED_LOAD_IF]] ] 614; CHECK-NEXT: [[TMP11:%.*]] = extractelement <2 x i1> [[TMP4]], i32 1 615; CHECK-NEXT: br i1 [[TMP11]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]] 616; CHECK: [[PRED_LOAD_IF1]]: 617; CHECK-NEXT: [[TMP22:%.*]] = extractelement <2 x ptr> [[TMP5]], i32 1 618; CHECK-NEXT: [[TMP23:%.*]] = load i32, ptr [[TMP22]], align 4 619; CHECK-NEXT: [[TMP14:%.*]] = insertelement <2 x i32> [[TMP10]], i32 [[TMP23]], i32 1 620; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]] 621; CHECK: [[PRED_LOAD_CONTINUE2]]: 622; CHECK-NEXT: [[TMP15:%.*]] = phi <2 x i32> [ [[TMP10]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP14]], %[[PRED_LOAD_IF1]] ] 623; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP15]] 624; CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]] 625; CHECK-NEXT: [[TMP27:%.*]] = getelementptr inbounds i32, ptr [[TMP26]], i32 0 626; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP27]], align 4 627; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 628; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2) 629; CHECK-NEXT: [[TMP28:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000 630; CHECK-NEXT: br i1 [[TMP28]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP14:![0-9]+]] 631; CHECK: [[MIDDLE_BLOCK]]: 632; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]] 633; CHECK: [[SCALAR_PH]]: 634; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] 635; CHECK-NEXT: br label %[[LOOP_HEADER:.*]] 636; CHECK: [[LOOP_HEADER]]: 637; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] 638; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]] 639; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4 640; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0 641; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]] 642; CHECK: [[LOOP_THEN]]: 643; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]] 644; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[GEP_A]], i64 4), "dereferenceable"(ptr [[GEP_A]], i64 4) ] 645; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4 646; CHECK-NEXT: br label %[[LOOP_LATCH]] 647; CHECK: [[LOOP_LATCH]]: 648; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ] 649; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]] 650; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4 651; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 652; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000 653; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP15:![0-9]+]] 654; CHECK: [[EXIT]]: 655; CHECK-NEXT: ret void 656; 657entry: 658 br label %loop.header 659 660loop.header: 661 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 662 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv 663 %l.b = load i32, ptr %gep.b, align 4 664 %c.1 = icmp sge i32 %l.b, 0 665 br i1 %c.1, label %loop.latch, label %loop.then 666 667loop.then: 668 %gep.a = getelementptr i32, ptr %a, i64 %iv 669 call void @llvm.assume(i1 true) [ "align"(ptr %gep.a, i64 4), "dereferenceable"(ptr %gep.a, i64 4) ] 670 %l.a = load i32, ptr %gep.a, align 4 671 br label %loop.latch 672 673loop.latch: 674 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ] 675 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv 676 store i32 %merge, ptr %gep.c, align 4 677 %iv.next = add nuw nsw i64 %iv, 1 678 %ec = icmp eq i64 %iv.next, 1000 679 br i1 %ec, label %exit, label %loop.header 680 681exit: 682 ret void 683} 684 685define void @deref_assumption_in_latch_constant_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{ 686; CHECK-LABEL: define void @deref_assumption_in_latch_constant_trip_count( 687; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] { 688; CHECK-NEXT: [[ENTRY:.*]]: 689; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] 690; CHECK: [[VECTOR_PH]]: 691; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] 692; CHECK: [[VECTOR_BODY]]: 693; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ] 694; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2]] ] 695; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 696; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[A]], <2 x i64> [[VEC_IND]] 697; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]] 698; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i32 0 699; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP3]], align 4 700; CHECK-NEXT: [[TMP4:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer 701; CHECK-NEXT: [[TMP5:%.*]] = xor <2 x i1> [[TMP4]], splat (i1 true) 702; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x i1> [[TMP5]], i32 0 703; CHECK-NEXT: br i1 [[TMP6]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]] 704; CHECK: [[PRED_LOAD_IF]]: 705; CHECK-NEXT: [[TMP17:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0 706; CHECK-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 4 707; CHECK-NEXT: [[TMP9:%.*]] = insertelement <2 x i32> poison, i32 [[TMP18]], i32 0 708; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]] 709; CHECK: [[PRED_LOAD_CONTINUE]]: 710; CHECK-NEXT: [[TMP10:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP9]], %[[PRED_LOAD_IF]] ] 711; CHECK-NEXT: [[TMP11:%.*]] = extractelement <2 x i1> [[TMP5]], i32 1 712; CHECK-NEXT: br i1 [[TMP11]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]] 713; CHECK: [[PRED_LOAD_IF1]]: 714; CHECK-NEXT: [[TMP22:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1 715; CHECK-NEXT: [[TMP23:%.*]] = load i32, ptr [[TMP22]], align 4 716; CHECK-NEXT: [[TMP14:%.*]] = insertelement <2 x i32> [[TMP10]], i32 [[TMP23]], i32 1 717; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]] 718; CHECK: [[PRED_LOAD_CONTINUE2]]: 719; CHECK-NEXT: [[TMP15:%.*]] = phi <2 x i32> [ [[TMP10]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP14]], %[[PRED_LOAD_IF1]] ] 720; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP4]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP15]] 721; CHECK-NEXT: [[TMP28:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0 722; CHECK-NEXT: [[TMP20:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0 723; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP28]], i64 4), "dereferenceable"(ptr [[TMP20]], i64 4) ] 724; CHECK-NEXT: [[TMP29:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1 725; CHECK-NEXT: [[TMP19:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1 726; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP29]], i64 4), "dereferenceable"(ptr [[TMP19]], i64 4) ] 727; CHECK-NEXT: [[TMP30:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]] 728; CHECK-NEXT: [[TMP31:%.*]] = getelementptr inbounds i32, ptr [[TMP30]], i32 0 729; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP31]], align 4 730; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 731; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2) 732; CHECK-NEXT: [[TMP32:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000 733; CHECK-NEXT: br i1 [[TMP32]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP16:![0-9]+]] 734; CHECK: [[MIDDLE_BLOCK]]: 735; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]] 736; CHECK: [[SCALAR_PH]]: 737; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] 738; CHECK-NEXT: br label %[[LOOP_HEADER:.*]] 739; CHECK: [[LOOP_HEADER]]: 740; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] 741; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]] 742; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]] 743; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4 744; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0 745; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]] 746; CHECK: [[LOOP_THEN]]: 747; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4 748; CHECK-NEXT: br label %[[LOOP_LATCH]] 749; CHECK: [[LOOP_LATCH]]: 750; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ] 751; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[GEP_A]], i64 4), "dereferenceable"(ptr [[GEP_A]], i64 4) ] 752; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]] 753; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4 754; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 755; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000 756; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP17:![0-9]+]] 757; CHECK: [[EXIT]]: 758; CHECK-NEXT: ret void 759; 760entry: 761 br label %loop.header 762 763loop.header: 764 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 765 %gep.a = getelementptr i32, ptr %a, i64 %iv 766 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv 767 %l.b = load i32, ptr %gep.b, align 4 768 %c.1 = icmp sge i32 %l.b, 0 769 br i1 %c.1, label %loop.latch, label %loop.then 770 771loop.then: 772 %l.a = load i32, ptr %gep.a, align 4 773 br label %loop.latch 774 775loop.latch: 776 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ] 777 call void @llvm.assume(i1 true) [ "align"(ptr %gep.a, i64 4), "dereferenceable"(ptr %gep.a, i64 4) ] 778 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv 779 store i32 %merge, ptr %gep.c, align 4 780 %iv.next = add nuw nsw i64 %iv, 1 781 %ec = icmp eq i64 %iv.next, 1000 782 br i1 %ec, label %exit, label %loop.header 783 784exit: 785 ret void 786} 787 788define void @deref_assumption_in_header_variable_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c, i64 %N) nofree nosync{ 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:%.*]]) #[[ATTR1]] { 791; CHECK-NEXT: [[ENTRY:.*]]: 792; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 2 793; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] 794; CHECK: [[VECTOR_PH]]: 795; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[N]], 2 796; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[N]], [[N_MOD_VF]] 797; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] 798; CHECK: [[VECTOR_BODY]]: 799; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ] 800; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2]] ] 801; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 802; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[A]], <2 x i64> [[VEC_IND]] 803; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0 804; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP4]], i64 4), "dereferenceable"(ptr [[TMP4]], i64 4) ] 805; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1 806; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP5]], i64 4), "dereferenceable"(ptr [[TMP5]], i64 4) ] 807; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]] 808; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, ptr [[TMP6]], i32 0 809; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP7]], align 4 810; CHECK-NEXT: [[TMP9:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer 811; CHECK-NEXT: [[TMP10:%.*]] = xor <2 x i1> [[TMP9]], splat (i1 true) 812; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP10]], i32 0 813; CHECK-NEXT: br i1 [[TMP8]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]] 814; CHECK: [[PRED_LOAD_IF]]: 815; CHECK-NEXT: [[TMP21:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0 816; CHECK-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 817; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> poison, i32 [[TMP22]], i32 0 818; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]] 819; CHECK: [[PRED_LOAD_CONTINUE]]: 820; CHECK-NEXT: [[TMP12:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP11]], %[[PRED_LOAD_IF]] ] 821; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i1> [[TMP10]], i32 1 822; CHECK-NEXT: br i1 [[TMP13]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]] 823; CHECK: [[PRED_LOAD_IF1]]: 824; CHECK-NEXT: [[TMP26:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1 825; CHECK-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4 826; CHECK-NEXT: [[TMP16:%.*]] = insertelement <2 x i32> [[TMP12]], i32 [[TMP27]], i32 1 827; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]] 828; CHECK: [[PRED_LOAD_CONTINUE2]]: 829; CHECK-NEXT: [[TMP17:%.*]] = phi <2 x i32> [ [[TMP12]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP16]], %[[PRED_LOAD_IF1]] ] 830; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP9]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP17]] 831; CHECK-NEXT: [[TMP30:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]] 832; CHECK-NEXT: [[TMP31:%.*]] = getelementptr inbounds i32, ptr [[TMP30]], i32 0 833; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP31]], align 4 834; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 835; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2) 836; CHECK-NEXT: [[TMP32:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] 837; CHECK-NEXT: br i1 [[TMP32]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP18:![0-9]+]] 838; CHECK: [[MIDDLE_BLOCK]]: 839; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]] 840; CHECK-NEXT: br i1 [[CMP_N]], label %[[EXIT:.*]], label %[[SCALAR_PH]] 841; CHECK: [[SCALAR_PH]]: 842; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] 843; CHECK-NEXT: br label %[[LOOP_HEADER:.*]] 844; CHECK: [[LOOP_HEADER]]: 845; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] 846; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]] 847; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[GEP_A]], i64 4), "dereferenceable"(ptr [[GEP_A]], i64 4) ] 848; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]] 849; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4 850; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0 851; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]] 852; CHECK: [[LOOP_THEN]]: 853; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4 854; CHECK-NEXT: br label %[[LOOP_LATCH]] 855; CHECK: [[LOOP_LATCH]]: 856; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ] 857; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]] 858; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4 859; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 860; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]] 861; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP19:![0-9]+]] 862; CHECK: [[EXIT]]: 863; CHECK-NEXT: ret void 864; 865entry: 866 br label %loop.header 867 868loop.header: 869 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 870 %gep.a = getelementptr i32, ptr %a, i64 %iv 871 call void @llvm.assume(i1 true) [ "align"(ptr %gep.a, i64 4), "dereferenceable"(ptr %gep.a, i64 4) ] 872 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv 873 %l.b = load i32, ptr %gep.b, align 4 874 %c.1 = icmp sge i32 %l.b, 0 875 br i1 %c.1, label %loop.latch, label %loop.then 876 877loop.then: 878 %l.a = load i32, ptr %gep.a, align 4 879 br label %loop.latch 880 881loop.latch: 882 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ] 883 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv 884 store i32 %merge, ptr %gep.c, align 4 885 %iv.next = add nuw nsw i64 %iv, 1 886 %ec = icmp eq i64 %iv.next, %N 887 br i1 %ec, label %exit, label %loop.header 888 889exit: 890 ret void 891} 892 893define void @deref_assumption_in_preheader_constant_trip_count_align_1(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{ 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:%.*]]) #[[ATTR1]] { 896; CHECK-NEXT: [[ENTRY:.*]]: 897; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[A]], i64 4000) ] 898; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] 899; CHECK: [[VECTOR_PH]]: 900; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] 901; CHECK: [[VECTOR_BODY]]: 902; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] 903; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 904; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]] 905; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0 906; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4 907; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer 908; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP0]] 909; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i32, ptr [[TMP6]], i32 0 910; CHECK-NEXT: [[TMP15:%.*]] = load <2 x i32>, ptr [[TMP5]], align 1 911; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP15]] 912; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]] 913; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i32, ptr [[TMP16]], i32 0 914; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP17]], align 4 915; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 916; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000 917; CHECK-NEXT: br i1 [[TMP18]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP20:![0-9]+]] 918; CHECK: [[MIDDLE_BLOCK]]: 919; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]] 920; CHECK: [[SCALAR_PH]]: 921; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] 922; CHECK-NEXT: br label %[[LOOP_HEADER:.*]] 923; CHECK: [[LOOP_HEADER]]: 924; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] 925; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]] 926; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4 927; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0 928; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]] 929; CHECK: [[LOOP_THEN]]: 930; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]] 931; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 1 932; CHECK-NEXT: br label %[[LOOP_LATCH]] 933; CHECK: [[LOOP_LATCH]]: 934; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ] 935; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]] 936; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4 937; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 938; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000 939; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP21:![0-9]+]] 940; CHECK: [[EXIT]]: 941; CHECK-NEXT: ret void 942; 943entry: 944 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %a, i64 4000) ] 945 br label %loop.header 946 947loop.header: 948 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 949 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv 950 %l.b = load i32, ptr %gep.b, align 4 951 %c.1 = icmp sge i32 %l.b, 0 952 br i1 %c.1, label %loop.latch, label %loop.then 953 954loop.then: 955 %gep.a = getelementptr i32, ptr %a, i64 %iv 956 %l.a = load i32, ptr %gep.a, align 1 957 br label %loop.latch 958 959loop.latch: 960 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ] 961 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv 962 store i32 %merge, ptr %gep.c, align 4 963 %iv.next = add nuw nsw i64 %iv, 1 964 %ec = icmp eq i64 %iv.next, 1000 965 br i1 %ec, label %exit, label %loop.header 966 967exit: 968 ret void 969} 970 971define void @deref_assumption_too_small_in_preheader_constant_trip_count_align_1(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{ 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:%.*]]) #[[ATTR1]] { 974; CHECK-NEXT: [[ENTRY:.*]]: 975; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[A]], i64 3999) ] 976; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] 977; CHECK: [[VECTOR_PH]]: 978; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] 979; CHECK: [[VECTOR_BODY]]: 980; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ] 981; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 982; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]] 983; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0 984; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4 985; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer 986; CHECK-NEXT: [[TMP4:%.*]] = xor <2 x i1> [[TMP3]], splat (i1 true) 987; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP4]], i32 0 988; CHECK-NEXT: br i1 [[TMP5]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]] 989; CHECK: [[PRED_LOAD_IF]]: 990; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP0]] 991; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[TMP6]], align 1 992; CHECK-NEXT: [[TMP8:%.*]] = insertelement <2 x i32> poison, i32 [[TMP7]], i32 0 993; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]] 994; CHECK: [[PRED_LOAD_CONTINUE]]: 995; CHECK-NEXT: [[TMP9:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP8]], %[[PRED_LOAD_IF]] ] 996; CHECK-NEXT: [[TMP10:%.*]] = extractelement <2 x i1> [[TMP4]], i32 1 997; CHECK-NEXT: br i1 [[TMP10]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]] 998; CHECK: [[PRED_LOAD_IF1]]: 999; CHECK-NEXT: [[TMP11:%.*]] = add i64 [[INDEX]], 1 1000; CHECK-NEXT: [[TMP12:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP11]] 1001; CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 1 1002; CHECK-NEXT: [[TMP14:%.*]] = insertelement <2 x i32> [[TMP9]], i32 [[TMP13]], i32 1 1003; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]] 1004; CHECK: [[PRED_LOAD_CONTINUE2]]: 1005; CHECK-NEXT: [[TMP15:%.*]] = phi <2 x i32> [ [[TMP9]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP14]], %[[PRED_LOAD_IF1]] ] 1006; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP15]] 1007; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]] 1008; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i32, ptr [[TMP16]], i32 0 1009; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP17]], align 4 1010; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 1011; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000 1012; CHECK-NEXT: br i1 [[TMP18]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP22:![0-9]+]] 1013; CHECK: [[MIDDLE_BLOCK]]: 1014; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]] 1015; CHECK: [[SCALAR_PH]]: 1016; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] 1017; CHECK-NEXT: br label %[[LOOP_HEADER:.*]] 1018; CHECK: [[LOOP_HEADER]]: 1019; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] 1020; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]] 1021; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4 1022; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0 1023; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]] 1024; CHECK: [[LOOP_THEN]]: 1025; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]] 1026; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 1 1027; CHECK-NEXT: br label %[[LOOP_LATCH]] 1028; CHECK: [[LOOP_LATCH]]: 1029; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ] 1030; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]] 1031; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4 1032; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 1033; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000 1034; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP23:![0-9]+]] 1035; CHECK: [[EXIT]]: 1036; CHECK-NEXT: ret void 1037; 1038entry: 1039 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %a, i64 3999) ] 1040 br label %loop.header 1041 1042loop.header: 1043 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 1044 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv 1045 %l.b = load i32, ptr %gep.b, align 4 1046 %c.1 = icmp sge i32 %l.b, 0 1047 br i1 %c.1, label %loop.latch, label %loop.then 1048 1049loop.then: 1050 %gep.a = getelementptr i32, ptr %a, i64 %iv 1051 %l.a = load i32, ptr %gep.a, align 1 1052 br label %loop.latch 1053 1054loop.latch: 1055 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ] 1056 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv 1057 store i32 %merge, ptr %gep.c, align 4 1058 %iv.next = add nuw nsw i64 %iv, 1 1059 %ec = icmp eq i64 %iv.next, 1000 1060 br i1 %ec, label %exit, label %loop.header 1061 1062exit: 1063 ret void 1064} 1065 1066define void @align_and_deref_assumption_in_preheader_constant_trip_count_align_4(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{ 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:%.*]]) #[[ATTR1]] { 1069; CHECK-NEXT: [[ENTRY:.*]]: 1070; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 4), "dereferenceable"(ptr [[A]], i64 4000) ] 1071; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] 1072; CHECK: [[VECTOR_PH]]: 1073; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] 1074; CHECK: [[VECTOR_BODY]]: 1075; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] 1076; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 1077; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]] 1078; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0 1079; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4 1080; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer 1081; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP0]] 1082; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i32, ptr [[TMP4]], i32 0 1083; CHECK-NEXT: [[WIDE_LOAD1:%.*]] = load <2 x i32>, ptr [[TMP5]], align 4 1084; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[WIDE_LOAD1]] 1085; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]] 1086; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, ptr [[TMP6]], i32 0 1087; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP7]], align 4 1088; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 1089; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000 1090; CHECK-NEXT: br i1 [[TMP8]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP24:![0-9]+]] 1091; CHECK: [[MIDDLE_BLOCK]]: 1092; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]] 1093; CHECK: [[SCALAR_PH]]: 1094; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] 1095; CHECK-NEXT: br label %[[LOOP_HEADER:.*]] 1096; CHECK: [[LOOP_HEADER]]: 1097; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] 1098; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]] 1099; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4 1100; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0 1101; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]] 1102; CHECK: [[LOOP_THEN]]: 1103; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]] 1104; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4 1105; CHECK-NEXT: br label %[[LOOP_LATCH]] 1106; CHECK: [[LOOP_LATCH]]: 1107; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ] 1108; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]] 1109; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4 1110; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 1111; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000 1112; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP25:![0-9]+]] 1113; CHECK: [[EXIT]]: 1114; CHECK-NEXT: ret void 1115; 1116entry: 1117 call void @llvm.assume(i1 true) [ "align"(ptr %a, i64 4), "dereferenceable"(ptr %a, i64 4000) ] 1118 br label %loop.header 1119 1120loop.header: 1121 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 1122 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv 1123 %l.b = load i32, ptr %gep.b, align 4 1124 %c.1 = icmp sge i32 %l.b, 0 1125 br i1 %c.1, label %loop.latch, label %loop.then 1126 1127loop.then: 1128 %gep.a = getelementptr i32, ptr %a, i64 %iv 1129 %l.a = load i32, ptr %gep.a, align 4 1130 br label %loop.latch 1131 1132loop.latch: 1133 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ] 1134 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv 1135 store i32 %merge, ptr %gep.c, align 4 1136 %iv.next = add nuw nsw i64 %iv, 1 1137 %ec = icmp eq i64 %iv.next, 1000 1138 br i1 %ec, label %exit, label %loop.header 1139 1140exit: 1141 ret void 1142} 1143 1144 1145define 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{ 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:%.*]]) #[[ATTR1]] { 1148; CHECK-NEXT: [[ENTRY:.*]]: 1149; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[A]], i64 4000) ] 1150; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] 1151; CHECK: [[VECTOR_PH]]: 1152; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] 1153; CHECK: [[VECTOR_BODY]]: 1154; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] 1155; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 1156; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]] 1157; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0 1158; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4 1159; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer 1160; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP0]] 1161; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i32, ptr [[TMP6]], i32 0 1162; CHECK-NEXT: [[TMP15:%.*]] = load <2 x i32>, ptr [[TMP5]], align 4 1163; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP15]] 1164; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]] 1165; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i32, ptr [[TMP16]], i32 0 1166; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP17]], align 4 1167; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 1168; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000 1169; CHECK-NEXT: br i1 [[TMP18]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP26:![0-9]+]] 1170; CHECK: [[MIDDLE_BLOCK]]: 1171; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]] 1172; CHECK: [[SCALAR_PH]]: 1173; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] 1174; CHECK-NEXT: br label %[[LOOP_HEADER:.*]] 1175; CHECK: [[LOOP_HEADER]]: 1176; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] 1177; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]] 1178; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4 1179; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0 1180; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]] 1181; CHECK: [[LOOP_THEN]]: 1182; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]] 1183; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4 1184; CHECK-NEXT: br label %[[LOOP_LATCH]] 1185; CHECK: [[LOOP_LATCH]]: 1186; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ] 1187; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]] 1188; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4 1189; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 1190; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000 1191; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP27:![0-9]+]] 1192; CHECK: [[EXIT]]: 1193; CHECK-NEXT: ret void 1194; 1195entry: 1196 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %a, i64 4000) ] 1197 br label %loop.header 1198 1199loop.header: 1200 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 1201 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv 1202 %l.b = load i32, ptr %gep.b, align 4 1203 %c.1 = icmp sge i32 %l.b, 0 1204 br i1 %c.1, label %loop.latch, label %loop.then 1205 1206loop.then: 1207 %gep.a = getelementptr i32, ptr %a, i64 %iv 1208 %l.a = load i32, ptr %gep.a, align 4 1209 br label %loop.latch 1210 1211loop.latch: 1212 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ] 1213 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv 1214 store i32 %merge, ptr %gep.c, align 4 1215 %iv.next = add nuw nsw i64 %iv, 1 1216 %ec = icmp eq i64 %iv.next, 1000 1217 br i1 %ec, label %exit, label %loop.header 1218 1219exit: 1220 ret void 1221} 1222 1223define void @deref_assumption_in_preheader_constant_trip_count_align_4_not_known(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{ 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:%.*]]) #[[ATTR1]] { 1226; CHECK-NEXT: [[ENTRY:.*]]: 1227; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[A]], i64 4000) ] 1228; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] 1229; CHECK: [[VECTOR_PH]]: 1230; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] 1231; CHECK: [[VECTOR_BODY]]: 1232; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ] 1233; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 1234; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]] 1235; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0 1236; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4 1237; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer 1238; CHECK-NEXT: [[TMP4:%.*]] = xor <2 x i1> [[TMP3]], splat (i1 true) 1239; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP4]], i32 0 1240; CHECK-NEXT: br i1 [[TMP5]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]] 1241; CHECK: [[PRED_LOAD_IF]]: 1242; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP0]] 1243; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[TMP6]], align 4 1244; CHECK-NEXT: [[TMP8:%.*]] = insertelement <2 x i32> poison, i32 [[TMP7]], i32 0 1245; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]] 1246; CHECK: [[PRED_LOAD_CONTINUE]]: 1247; CHECK-NEXT: [[TMP9:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP8]], %[[PRED_LOAD_IF]] ] 1248; CHECK-NEXT: [[TMP10:%.*]] = extractelement <2 x i1> [[TMP4]], i32 1 1249; CHECK-NEXT: br i1 [[TMP10]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]] 1250; CHECK: [[PRED_LOAD_IF1]]: 1251; CHECK-NEXT: [[TMP11:%.*]] = add i64 [[INDEX]], 1 1252; CHECK-NEXT: [[TMP12:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP11]] 1253; CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 1254; CHECK-NEXT: [[TMP14:%.*]] = insertelement <2 x i32> [[TMP9]], i32 [[TMP13]], i32 1 1255; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]] 1256; CHECK: [[PRED_LOAD_CONTINUE2]]: 1257; CHECK-NEXT: [[TMP15:%.*]] = phi <2 x i32> [ [[TMP9]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP14]], %[[PRED_LOAD_IF1]] ] 1258; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP15]] 1259; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]] 1260; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i32, ptr [[TMP16]], i32 0 1261; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP17]], align 4 1262; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 1263; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000 1264; CHECK-NEXT: br i1 [[TMP18]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP28:![0-9]+]] 1265; CHECK: [[MIDDLE_BLOCK]]: 1266; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]] 1267; CHECK: [[SCALAR_PH]]: 1268; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] 1269; CHECK-NEXT: br label %[[LOOP_HEADER:.*]] 1270; CHECK: [[LOOP_HEADER]]: 1271; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] 1272; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]] 1273; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4 1274; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0 1275; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]] 1276; CHECK: [[LOOP_THEN]]: 1277; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]] 1278; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4 1279; CHECK-NEXT: br label %[[LOOP_LATCH]] 1280; CHECK: [[LOOP_LATCH]]: 1281; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ] 1282; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]] 1283; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4 1284; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 1285; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000 1286; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP29:![0-9]+]] 1287; CHECK: [[EXIT]]: 1288; CHECK-NEXT: ret void 1289; 1290entry: 1291 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %a, i64 4000) ] 1292 br label %loop.header 1293 1294loop.header: 1295 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 1296 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv 1297 %l.b = load i32, ptr %gep.b, align 4 1298 %c.1 = icmp sge i32 %l.b, 0 1299 br i1 %c.1, label %loop.latch, label %loop.then 1300 1301loop.then: 1302 %gep.a = getelementptr i32, ptr %a, i64 %iv 1303 %l.a = load i32, ptr %gep.a, align 4 1304 br label %loop.latch 1305 1306loop.latch: 1307 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ] 1308 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv 1309 store i32 %merge, ptr %gep.c, align 4 1310 %iv.next = add nuw nsw i64 %iv, 1 1311 %ec = icmp eq i64 %iv.next, 1000 1312 br i1 %ec, label %exit, label %loop.header 1313 1314exit: 1315 ret void 1316} 1317 1318define void @deref_assumption_too_small_in_preheader_constant_trip_count_align_4(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{ 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:%.*]]) #[[ATTR1]] { 1321; CHECK-NEXT: [[ENTRY:.*]]: 1322; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[A]], i64 3999) ] 1323; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] 1324; CHECK: [[VECTOR_PH]]: 1325; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] 1326; CHECK: [[VECTOR_BODY]]: 1327; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ] 1328; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 1329; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]] 1330; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0 1331; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4 1332; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer 1333; CHECK-NEXT: [[TMP4:%.*]] = xor <2 x i1> [[TMP3]], splat (i1 true) 1334; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP4]], i32 0 1335; CHECK-NEXT: br i1 [[TMP5]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]] 1336; CHECK: [[PRED_LOAD_IF]]: 1337; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP0]] 1338; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[TMP6]], align 4 1339; CHECK-NEXT: [[TMP8:%.*]] = insertelement <2 x i32> poison, i32 [[TMP7]], i32 0 1340; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]] 1341; CHECK: [[PRED_LOAD_CONTINUE]]: 1342; CHECK-NEXT: [[TMP9:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP8]], %[[PRED_LOAD_IF]] ] 1343; CHECK-NEXT: [[TMP10:%.*]] = extractelement <2 x i1> [[TMP4]], i32 1 1344; CHECK-NEXT: br i1 [[TMP10]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]] 1345; CHECK: [[PRED_LOAD_IF1]]: 1346; CHECK-NEXT: [[TMP11:%.*]] = add i64 [[INDEX]], 1 1347; CHECK-NEXT: [[TMP12:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP11]] 1348; CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 1349; CHECK-NEXT: [[TMP14:%.*]] = insertelement <2 x i32> [[TMP9]], i32 [[TMP13]], i32 1 1350; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]] 1351; CHECK: [[PRED_LOAD_CONTINUE2]]: 1352; CHECK-NEXT: [[TMP15:%.*]] = phi <2 x i32> [ [[TMP9]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP14]], %[[PRED_LOAD_IF1]] ] 1353; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP15]] 1354; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]] 1355; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i32, ptr [[TMP16]], i32 0 1356; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP17]], align 4 1357; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 1358; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000 1359; CHECK-NEXT: br i1 [[TMP18]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP30:![0-9]+]] 1360; CHECK: [[MIDDLE_BLOCK]]: 1361; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]] 1362; CHECK: [[SCALAR_PH]]: 1363; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] 1364; CHECK-NEXT: br label %[[LOOP_HEADER:.*]] 1365; CHECK: [[LOOP_HEADER]]: 1366; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] 1367; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]] 1368; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4 1369; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0 1370; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]] 1371; CHECK: [[LOOP_THEN]]: 1372; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]] 1373; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4 1374; CHECK-NEXT: br label %[[LOOP_LATCH]] 1375; CHECK: [[LOOP_LATCH]]: 1376; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ] 1377; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]] 1378; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4 1379; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 1380; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000 1381; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP31:![0-9]+]] 1382; CHECK: [[EXIT]]: 1383; CHECK-NEXT: ret void 1384; 1385entry: 1386 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %a, i64 3999) ] 1387 br label %loop.header 1388 1389loop.header: 1390 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 1391 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv 1392 %l.b = load i32, ptr %gep.b, align 4 1393 %c.1 = icmp sge i32 %l.b, 0 1394 br i1 %c.1, label %loop.latch, label %loop.then 1395 1396loop.then: 1397 %gep.a = getelementptr i32, ptr %a, i64 %iv 1398 %l.a = load i32, ptr %gep.a, align 4 1399 br label %loop.latch 1400 1401loop.latch: 1402 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ] 1403 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv 1404 store i32 %merge, ptr %gep.c, align 4 1405 %iv.next = add nuw nsw i64 %iv, 1 1406 %ec = icmp eq i64 %iv.next, 1000 1407 br i1 %ec, label %exit, label %loop.header 1408 1409exit: 1410 ret void 1411} 1412 1413; %a may be freed between the dereferenceable assumption and accesses. 1414; It is not safe to use with -use-dereferenceable-at-point-semantics. 1415define 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:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ] 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: [[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]]: 1435; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[A]], align 4 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]] ] 1448; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP11]] 1449; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]] 1450; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, ptr [[TMP8]], i32 0 1451; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP9]], align 4 1452; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 1453; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000 1454; CHECK-NEXT: br i1 [[TMP10]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP32:![0-9]+]] 1455; CHECK: [[MIDDLE_BLOCK]]: 1456; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]] 1457; CHECK: [[SCALAR_PH]]: 1458; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] 1459; CHECK-NEXT: br label %[[LOOP_HEADER:.*]] 1460; CHECK: [[LOOP_HEADER]]: 1461; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] 1462; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]] 1463; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4 1464; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0 1465; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]] 1466; CHECK: [[LOOP_THEN]]: 1467; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[A]], align 4 1468; CHECK-NEXT: br label %[[LOOP_LATCH]] 1469; CHECK: [[LOOP_LATCH]]: 1470; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ] 1471; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]] 1472; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4 1473; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 1474; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000 1475; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP33:![0-9]+]] 1476; CHECK: [[EXIT]]: 1477; CHECK-NEXT: ret void 1478; 1479entry: 1480 call void @llvm.assume(i1 true) [ "align"(ptr %a, i64 4), "dereferenceable"(ptr %a, i64 4) ] 1481 call void @may_free() 1482 br label %loop.header 1483 1484loop.header: 1485 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 1486 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv 1487 %l.b = load i32, ptr %gep.b, align 4 1488 %c.1 = icmp sge i32 %l.b, 0 1489 br i1 %c.1, label %loop.latch, label %loop.then 1490 1491loop.then: 1492 %l.a = load i32, ptr %a, align 4 1493 br label %loop.latch 1494 1495loop.latch: 1496 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ] 1497 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv 1498 store i32 %merge, ptr %gep.c, align 4 1499 %iv.next = add nuw nsw i64 %iv, 1 1500 %ec = icmp eq i64 %iv.next, 1000 1501 br i1 %ec, label %exit, label %loop.header 1502 1503exit: 1504 ret void 1505} 1506 1507; %a may be freed between the dereferenceable assumption and accesses. 1508; It is not safe to use with -use-dereferenceable-at-point-semantics. 1509define 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; 1574entry: 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 1580loop.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 1587loop.then: 1588 %l.a = load i32, ptr %a, align 4 1589 br label %loop.latch 1590 1591loop.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 1599exit: 1600 ret void 1601} 1602 1603declare ptr @get_ptr() 1604declare void @may_free() 1605 1606;. 1607; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]} 1608; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1} 1609; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"} 1610; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META2]], [[META1]]} 1611; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META1]], [[META2]]} 1612; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META2]], [[META1]]} 1613; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[META1]], [[META2]]} 1614; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[META2]], [[META1]]} 1615; CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[META1]], [[META2]]} 1616; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[META2]], [[META1]]} 1617; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[META1]], [[META2]]} 1618; CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[META2]], [[META1]]} 1619; CHECK: [[LOOP12]] = distinct !{[[LOOP12]], [[META1]], [[META2]]} 1620; CHECK: [[LOOP13]] = distinct !{[[LOOP13]], [[META2]], [[META1]]} 1621; CHECK: [[LOOP14]] = distinct !{[[LOOP14]], [[META1]], [[META2]]} 1622; CHECK: [[LOOP15]] = distinct !{[[LOOP15]], [[META2]], [[META1]]} 1623; CHECK: [[LOOP16]] = distinct !{[[LOOP16]], [[META1]], [[META2]]} 1624; CHECK: [[LOOP17]] = distinct !{[[LOOP17]], [[META2]], [[META1]]} 1625; CHECK: [[LOOP18]] = distinct !{[[LOOP18]], [[META1]], [[META2]]} 1626; CHECK: [[LOOP19]] = distinct !{[[LOOP19]], [[META2]], [[META1]]} 1627; CHECK: [[LOOP20]] = distinct !{[[LOOP20]], [[META1]], [[META2]]} 1628; CHECK: [[LOOP21]] = distinct !{[[LOOP21]], [[META2]], [[META1]]} 1629; CHECK: [[LOOP22]] = distinct !{[[LOOP22]], [[META1]], [[META2]]} 1630; CHECK: [[LOOP23]] = distinct !{[[LOOP23]], [[META2]], [[META1]]} 1631; CHECK: [[LOOP24]] = distinct !{[[LOOP24]], [[META1]], [[META2]]} 1632; CHECK: [[LOOP25]] = distinct !{[[LOOP25]], [[META2]], [[META1]]} 1633; CHECK: [[LOOP26]] = distinct !{[[LOOP26]], [[META1]], [[META2]]} 1634; CHECK: [[LOOP27]] = distinct !{[[LOOP27]], [[META2]], [[META1]]} 1635; CHECK: [[LOOP28]] = distinct !{[[LOOP28]], [[META1]], [[META2]]} 1636; CHECK: [[LOOP29]] = distinct !{[[LOOP29]], [[META2]], [[META1]]} 1637; CHECK: [[LOOP30]] = distinct !{[[LOOP30]], [[META1]], [[META2]]} 1638; CHECK: [[LOOP31]] = distinct !{[[LOOP31]], [[META2]], [[META1]]} 1639; CHECK: [[LOOP32]] = distinct !{[[LOOP32]], [[META1]], [[META2]]} 1640; CHECK: [[LOOP33]] = distinct !{[[LOOP33]], [[META2]], [[META1]]} 1641; CHECK: [[LOOP34]] = distinct !{[[LOOP34]], [[META1]], [[META2]]} 1642; CHECK: [[LOOP35]] = distinct !{[[LOOP35]], [[META2]], [[META1]]} 1643;. 1644