224 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=licm -S < %s | FileCheck %s3 4define void @f(i32 %ptr_i, ptr %ptr2, i1 %cond) {5; CHECK-LABEL: @f(6; CHECK-NEXT: entry:7; CHECK-NEXT: [[PTR:%.*]] = inttoptr i32 [[PTR_I:%.*]] to ptr, !nofree [[META0:![0-9]+]]8; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[PTR]], i32 16), "dereferenceable"(ptr [[PTR]], i32 16) ]9; CHECK-NEXT: br i1 [[COND:%.*]], label [[FOR_BODY_LR_PH:%.*]], label [[IF0:%.*]]10; CHECK: if0:11; CHECK-NEXT: store i32 0, ptr [[PTR2:%.*]], align 412; CHECK-NEXT: br label [[FOR_BODY_LR_PH]]13; CHECK: for.body.lr.ph:14; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR]], align 415; CHECK-NEXT: br label [[FOR_BODY:%.*]]16; CHECK: for.body:17; CHECK-NEXT: [[I_08:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END:%.*]] ]18; CHECK-NEXT: br i1 [[COND]], label [[IF_END]], label [[IF:%.*]]19; CHECK: if:20; CHECK-NEXT: store i32 [[TMP0]], ptr [[PTR2]], align 421; CHECK-NEXT: br label [[IF_END]]22; CHECK: if.end:23; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_08]], 124; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], 225; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[EXIT:%.*]]26; CHECK: exit:27; CHECK-NEXT: ret void28;29entry:30 %ptr = inttoptr i32 %ptr_i to ptr, !nofree !{}31 call void @llvm.assume(i1 true) [ "align"(ptr %ptr, i32 16), "dereferenceable"(ptr %ptr, i32 16) ]32 br i1 %cond, label %for.body.lr.ph, label %if033 34if0:35 store i32 0, ptr %ptr2, align 436 br label %for.body.lr.ph37 38for.body.lr.ph: ; preds = %entry39 br label %for.body40 41for.body: ; preds = %for.body.lr.ph, %if.end42 %i.08 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %if.end ]43 br i1 %cond, label %if.end, label %if44 45if:46 %0 = load i32, ptr %ptr, align 4, !invariant.load !{}47 store i32 %0, ptr %ptr2, align 448 br label %if.end49 50if.end: ; preds = %for.body51 %inc = add nuw nsw i32 %i.08, 152 %cmp = icmp slt i32 %inc, 253 br i1 %cmp, label %for.body, label %exit54 55exit: ; preds = %if.end, %entry56 ret void57}58 59define void @f_nofree_nosync(i32 %ptr_i, ptr %ptr2, i1 %cond) nofree nosync {60; CHECK-LABEL: @f_nofree_nosync(61; CHECK-NEXT: entry:62; CHECK-NEXT: [[PTR:%.*]] = inttoptr i32 [[PTR_I:%.*]] to ptr63; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[PTR]], i32 16), "dereferenceable"(ptr [[PTR]], i32 16) ]64; CHECK-NEXT: br i1 [[COND:%.*]], label [[FOR_BODY_LR_PH:%.*]], label [[IF0:%.*]]65; CHECK: if0:66; CHECK-NEXT: store i32 0, ptr [[PTR2:%.*]], align 467; CHECK-NEXT: br label [[FOR_BODY_LR_PH]]68; CHECK: for.body.lr.ph:69; CHECK-NEXT: br label [[FOR_BODY:%.*]]70; CHECK: for.body:71; CHECK-NEXT: [[I_08:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END:%.*]] ]72; CHECK-NEXT: br i1 [[COND]], label [[IF_END]], label [[IF:%.*]]73; CHECK: if:74; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR]], align 4, !invariant.load [[META0]]75; CHECK-NEXT: store i32 [[TMP0]], ptr [[PTR2]], align 476; CHECK-NEXT: br label [[IF_END]]77; CHECK: if.end:78; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_08]], 179; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], 280; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[EXIT:%.*]]81; CHECK: exit:82; CHECK-NEXT: ret void83;84entry:85 %ptr = inttoptr i32 %ptr_i to ptr86 call void @llvm.assume(i1 true) [ "align"(ptr %ptr, i32 16), "dereferenceable"(ptr %ptr, i32 16) ]87 br i1 %cond, label %for.body.lr.ph, label %if088 89if0:90 store i32 0, ptr %ptr2, align 491 br label %for.body.lr.ph92 93for.body.lr.ph: ; preds = %entry94 br label %for.body95 96for.body: ; preds = %for.body.lr.ph, %if.end97 %i.08 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %if.end ]98 br i1 %cond, label %if.end, label %if99 100if:101 %0 = load i32, ptr %ptr, align 4, !invariant.load !{}102 store i32 %0, ptr %ptr2, align 4103 br label %if.end104 105if.end: ; preds = %for.body106 %inc = add nuw nsw i32 %i.08, 1107 %cmp = icmp slt i32 %inc, 2108 br i1 %cmp, label %for.body, label %exit109 110exit: ; preds = %if.end, %entry111 ret void112}113 114define void @f_without_ptrtoint_and_with_nofree_nosync(ptr %ptr, ptr %ptr2, i1 %cond) nofree nosync {115; CHECK-LABEL: @f_without_ptrtoint_and_with_nofree_nosync(116; CHECK-NEXT: entry:117; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[PTR:%.*]], i32 16), "dereferenceable"(ptr [[PTR]], i32 16) ]118; CHECK-NEXT: br i1 [[COND:%.*]], label [[FOR_BODY_LR_PH:%.*]], label [[IF0:%.*]]119; CHECK: if0:120; CHECK-NEXT: store i32 0, ptr [[PTR2:%.*]], align 4121; CHECK-NEXT: br label [[FOR_BODY_LR_PH]]122; CHECK: for.body.lr.ph:123; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR]], align 4124; CHECK-NEXT: br label [[FOR_BODY:%.*]]125; CHECK: for.body:126; CHECK-NEXT: [[I_08:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END:%.*]] ]127; CHECK-NEXT: br i1 [[COND]], label [[IF_END]], label [[IF:%.*]]128; CHECK: if:129; CHECK-NEXT: store i32 [[TMP0]], ptr [[PTR2]], align 4130; CHECK-NEXT: br label [[IF_END]]131; CHECK: if.end:132; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_08]], 1133; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], 2134; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[EXIT:%.*]]135; CHECK: exit:136; CHECK-NEXT: ret void137;138entry:139 call void @llvm.assume(i1 true) [ "align"(ptr %ptr, i32 16), "dereferenceable"(ptr %ptr, i32 16) ]140 br i1 %cond, label %for.body.lr.ph, label %if0141 142if0:143 store i32 0, ptr %ptr2, align 4144 br label %for.body.lr.ph145 146for.body.lr.ph: ; preds = %entry147 br label %for.body148 149for.body: ; preds = %for.body.lr.ph, %if.end150 %i.08 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %if.end ]151 br i1 %cond, label %if.end, label %if152 153if:154 %0 = load i32, ptr %ptr, align 4, !invariant.load !{}155 store i32 %0, ptr %ptr2, align 4156 br label %if.end157 158if.end: ; preds = %for.body159 %inc = add nuw nsw i32 %i.08, 1160 %cmp = icmp slt i32 %inc, 2161 br i1 %cmp, label %for.body, label %exit162 163exit: ; preds = %if.end, %entry164 ret void165}166 167define void @f_chained_gep_with_nofree_nosync(ptr %ptr, ptr %ptr2, i1 %cond) nofree nosync {168; CHECK-LABEL: @f_chained_gep_with_nofree_nosync(169; CHECK-NEXT: entry:170; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1171; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[GEP]], i32 16), "dereferenceable"(ptr [[GEP]], i32 16) ]172; CHECK-NEXT: br i1 [[COND:%.*]], label [[FOR_BODY_LR_PH:%.*]], label [[IF0:%.*]]173; CHECK: if0:174; CHECK-NEXT: store i32 0, ptr [[PTR2:%.*]], align 4175; CHECK-NEXT: br label [[FOR_BODY_LR_PH]]176; CHECK: for.body.lr.ph:177; CHECK-NEXT: br label [[FOR_BODY:%.*]]178; CHECK: for.body:179; CHECK-NEXT: [[I_08:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END:%.*]] ]180; CHECK-NEXT: br i1 [[COND]], label [[IF_END]], label [[IF:%.*]]181; CHECK: if:182; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[GEP]], align 4, !invariant.load [[META0]]183; CHECK-NEXT: store i32 [[TMP0]], ptr [[PTR2]], align 4184; CHECK-NEXT: br label [[IF_END]]185; CHECK: if.end:186; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_08]], 1187; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], 2188; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[EXIT:%.*]]189; CHECK: exit:190; CHECK-NEXT: ret void191;192entry:193 %gep = getelementptr inbounds i32, ptr %ptr, i64 1194 call void @llvm.assume(i1 true) [ "align"(ptr %gep, i32 16), "dereferenceable"(ptr %gep, i32 16) ]195 br i1 %cond, label %for.body.lr.ph, label %if0196 197if0:198 store i32 0, ptr %ptr2, align 4199 br label %for.body.lr.ph200 201for.body.lr.ph: ; preds = %entry202 br label %for.body203 204for.body: ; preds = %for.body.lr.ph, %if.end205 %i.08 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %if.end ]206 br i1 %cond, label %if.end, label %if207 208if:209 %0 = load i32, ptr %gep, align 4, !invariant.load !{}210 store i32 %0, ptr %ptr2, align 4211 br label %if.end212 213if.end: ; preds = %for.body214 %inc = add nuw nsw i32 %i.08, 1215 %cmp = icmp slt i32 %inc, 2216 br i1 %cmp, label %for.body, label %exit217 218exit: ; preds = %if.end, %entry219 ret void220}221 222 223declare void @llvm.assume(i1 noundef)224