235 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -O3 -S %s | FileCheck %s3 4target triple = "arm64-apple-macosx15.0.0"5 6define i64 @std_find_i16_constant_offset_with_assumptions(ptr %first.coerce, i16 noundef signext %s) nofree nosync {7; CHECK-LABEL: define i64 @std_find_i16_constant_offset_with_assumptions(8; CHECK-SAME: ptr [[FIRST_COERCE:%.*]], i16 noundef signext [[S:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {9; CHECK-NEXT: [[ENTRY:.*]]:10; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[FIRST_COERCE]], i64 2) ]11; CHECK-NEXT: [[COERCE_VAL_IP:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 25612; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <8 x i16> poison, i16 [[S]], i64 013; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <8 x i16> [[BROADCAST_SPLATINSERT]], <8 x i16> poison, <8 x i32> zeroinitializer14; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]15; CHECK: [[VECTOR_BODY]]:16; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]17; CHECK-NEXT: [[OFFSET_IDX:%.*]] = shl i64 [[INDEX]], 118; CHECK-NEXT: [[NEXT_GEP:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 [[OFFSET_IDX]]19; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <8 x i16>, ptr [[NEXT_GEP]], align 220; CHECK-NEXT: [[WIDE_LOAD_FR:%.*]] = freeze <8 x i16> [[WIDE_LOAD]]21; CHECK-NEXT: [[TMP0:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR]], [[BROADCAST_SPLAT]]22; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 823; CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i1> [[TMP0]] to i824; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[TMP1]], 025; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i64 [[INDEX_NEXT]], 12826; CHECK-NEXT: [[TMP4:%.*]] = or i1 [[TMP2]], [[TMP3]]27; CHECK-NEXT: br i1 [[TMP4]], label %[[MIDDLE_SPLIT:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]28; CHECK: [[MIDDLE_SPLIT]]:29; CHECK-NEXT: br i1 [[TMP2]], label %[[VECTOR_EARLY_EXIT:.*]], label %[[RETURN:.*]]30; CHECK: [[VECTOR_EARLY_EXIT]]:31; CHECK-NEXT: [[TMP5:%.*]] = tail call i64 @llvm.experimental.cttz.elts.i64.v8i1(<8 x i1> [[TMP0]], i1 false)32; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[INDEX]], [[TMP5]]33; CHECK-NEXT: [[TMP7:%.*]] = shl i64 [[TMP6]], 134; CHECK-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 [[TMP7]]35; CHECK-NEXT: br label %[[RETURN]]36; CHECK: [[RETURN]]:37; CHECK-NEXT: [[__FIRST_ADDR_0_LCSSA_I_I_PH:%.*]] = phi ptr [ [[TMP8]], %[[VECTOR_EARLY_EXIT]] ], [ [[COERCE_VAL_IP]], %[[MIDDLE_SPLIT]] ]38; CHECK-NEXT: [[DOTPRE:%.*]] = ptrtoint ptr [[__FIRST_ADDR_0_LCSSA_I_I_PH]] to i6439; CHECK-NEXT: ret i64 [[DOTPRE]]40;41entry:42 %first = alloca { ptr }, align 843 %s.addr = alloca i16, align 244 store ptr %first.coerce, ptr %first, align 845 store i16 %s, ptr %s.addr, align 246 %0 = load ptr, ptr %first, align 847 call void @llvm.assume(i1 true) [ "align"(ptr %0, i64 2) ]48 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %0, i64 256) ]49 %start.ptr = load ptr, ptr %first, align 850 %1 = load i64, ptr %first, align 851 %coerce.val.p = add i64 %1, 25652 %coerce.val.ip = inttoptr i64 %coerce.val.p to ptr53 %ec6. = icmp eq ptr %start.ptr, %coerce.val.ip54 br i1 %ec6., label %return, label %loop.ph55 56loop.ph:57 %2 = load i16, ptr %s.addr, align 258 br label %loop.header59 60loop.header:61 %ptr.iv = phi ptr [ %start.ptr, %loop.ph ], [ %ptr.iv.next, %loop.latch ]62 %3 = load i16, ptr %ptr.iv, align 263 %cmp2. = icmp eq i16 %3, %264 br i1 %cmp2., label %return, label %loop.latch65 66loop.latch:67 %ptr.iv.next = getelementptr inbounds nuw i8, ptr %ptr.iv, i64 268 %ec. = icmp eq ptr %ptr.iv.next, %coerce.val.ip69 br i1 %ec., label %return, label %loop.header70 71return:72 %merge = phi ptr [ %start.ptr, %entry ], [ %coerce.val.ip, %loop.latch ], [ %ptr.iv, %loop.header ]73 %res = ptrtoint ptr %merge to i6474 ret i64 %res75}76 77define i64 @std_find_i16_constant_offset_no_assumptions(ptr %first.coerce, i16 noundef signext %s) nofree nosync {78; CHECK-LABEL: define i64 @std_find_i16_constant_offset_no_assumptions(79; CHECK-SAME: ptr [[FIRST_COERCE:%.*]], i16 noundef signext [[S:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {80; CHECK-NEXT: [[ENTRY:.*]]:81; CHECK-NEXT: [[COERCE_VAL_IP:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 25682; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]83; CHECK: [[LOOP_HEADER]]:84; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[FIRST_COERCE]], %[[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]85; CHECK-NEXT: [[TMP1:%.*]] = load i16, ptr [[PTR_IV]], align 286; CHECK-NEXT: [[CMP2_I_I:%.*]] = icmp eq i16 [[TMP1]], [[S]]87; CHECK-NEXT: br i1 [[CMP2_I_I]], label %[[RETURN:.*]], label %[[LOOP_LATCH]]88; CHECK: [[LOOP_LATCH]]:89; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds nuw i8, ptr [[PTR_IV]], i64 290; CHECK-NEXT: [[CMP_NOT_I_I:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[COERCE_VAL_IP]]91; CHECK-NEXT: br i1 [[CMP_NOT_I_I]], label %[[RETURN]], label %[[LOOP_HEADER]]92; CHECK: [[RETURN]]:93; CHECK-NEXT: [[MERGE_PH:%.*]] = phi ptr [ [[COERCE_VAL_IP]], %[[LOOP_LATCH]] ], [ [[PTR_IV]], %[[LOOP_HEADER]] ]94; CHECK-NEXT: [[DOTPRE:%.*]] = ptrtoint ptr [[MERGE_PH]] to i6495; CHECK-NEXT: ret i64 [[DOTPRE]]96;97entry:98 %first = alloca { ptr }, align 899 %s.addr = alloca i16, align 2100 store ptr %first.coerce, ptr %first, align 8101 store i16 %s, ptr %s.addr, align 2102 %0 = load ptr, ptr %first, align 8103 %start.ptr = load ptr, ptr %first, align 8104 %1 = load i64, ptr %first, align 8105 %coerce.val.p = add i64 %1, 256106 %coerce.val.ip = inttoptr i64 %coerce.val.p to ptr107 %ec6. = icmp eq ptr %start.ptr, %coerce.val.ip108 br i1 %ec6., label %return, label %loop.ph109 110loop.ph:111 %2 = load i16, ptr %s.addr, align 2112 br label %loop.header113 114loop.header:115 %ptr.iv = phi ptr [ %start.ptr, %loop.ph ], [ %ptr.iv.next, %loop.latch ]116 %3 = load i16, ptr %ptr.iv, align 2117 %cmp2. = icmp eq i16 %3, %2118 br i1 %cmp2., label %return, label %loop.latch119 120loop.latch:121 %ptr.iv.next = getelementptr inbounds nuw i8, ptr %ptr.iv, i64 2122 %ec. = icmp eq ptr %ptr.iv.next, %coerce.val.ip123 br i1 %ec., label %return, label %loop.header124 125return:126 %merge = phi ptr [ %start.ptr, %entry ], [ %coerce.val.ip, %loop.latch ], [ %ptr.iv, %loop.header ]127 %res = ptrtoint ptr %merge to i64128 ret i64 %res129}130 131define ptr @std_find_caller(ptr noundef %first, ptr noundef %last) {132; CHECK-LABEL: define noundef ptr @std_find_caller(133; CHECK-SAME: ptr noundef [[FIRST:%.*]], ptr noundef [[LAST:%.*]]) local_unnamed_addr #[[ATTR0]] {134; CHECK-NEXT: [[ENTRY:.*]]:135; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[FIRST]], i64 2) ]136; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[LAST]], i64 2) ]137; CHECK-NEXT: [[PRE_I:%.*]] = icmp eq ptr [[FIRST]], [[LAST]]138; CHECK-NEXT: br i1 [[PRE_I]], label %[[STD_FIND_GENERIC_IMPL_EXIT:.*]], label %[[LOOP_HEADER_I_PREHEADER:.*]]139; CHECK: [[LOOP_HEADER_I_PREHEADER]]:140; CHECK-NEXT: [[LAST_I64:%.*]] = ptrtoint ptr [[LAST]] to i64141; CHECK-NEXT: [[FIRST3:%.*]] = ptrtoint ptr [[FIRST]] to i64142; CHECK-NEXT: [[PTR_SUB:%.*]] = sub i64 [[LAST_I64]], [[FIRST3]]143; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[FIRST]], i64 [[PTR_SUB]]144; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[LAST_I64]], -2145; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[TMP0]], [[FIRST3]]146; CHECK-NEXT: [[TMP2:%.*]] = lshr exact i64 [[TMP1]], 1147; CHECK-NEXT: [[TMP3:%.*]] = add nuw i64 [[TMP2]], 1148; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP1]], 158149; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[LOOP_HEADER_I_PREHEADER2:.*]], label %[[VECTOR_PH:.*]]150; CHECK: [[VECTOR_PH]]:151; CHECK-NEXT: [[XTRAITER:%.*]] = and i64 [[TMP3]], -8152; CHECK-NEXT: [[OFFSET_IDX:%.*]] = shl i64 [[XTRAITER]], 1153; CHECK-NEXT: [[NEXT_GEP:%.*]] = getelementptr i8, ptr [[FIRST]], i64 [[OFFSET_IDX]]154; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]155; CHECK: [[VECTOR_BODY]]:156; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[PROL_ITER_NEXT:%.*]], %[[VECTOR_BODY]] ]157; CHECK-NEXT: [[OFFSET_IDX1:%.*]] = shl i64 [[INDEX]], 1158; CHECK-NEXT: [[NEXT_GEP1:%.*]] = getelementptr i8, ptr [[FIRST]], i64 [[OFFSET_IDX1]]159; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <8 x i16>, ptr [[NEXT_GEP1]], align 2160; CHECK-NEXT: [[WIDE_LOAD_FR:%.*]] = freeze <8 x i16> [[WIDE_LOAD]]161; CHECK-NEXT: [[TMP4:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR]], splat (i16 1)162; CHECK-NEXT: [[PROL_ITER_NEXT]] = add nuw i64 [[INDEX]], 8163; CHECK-NEXT: [[TMP5:%.*]] = bitcast <8 x i1> [[TMP4]] to i8164; CHECK-NEXT: [[TMP6:%.*]] = icmp ne i8 [[TMP5]], 0165; CHECK-NEXT: [[PROL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[PROL_ITER_NEXT]], [[XTRAITER]]166; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[PROL_ITER_CMP_NOT]]167; CHECK-NEXT: br i1 [[TMP8]], label %[[MIDDLE_SPLIT:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]168; CHECK: [[MIDDLE_SPLIT]]:169; CHECK-NEXT: br i1 [[TMP6]], label %[[VECTOR_EARLY_EXIT:.*]], label %[[MIDDLE_BLOCK:.*]]170; CHECK: [[MIDDLE_BLOCK]]:171; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP3]], [[XTRAITER]]172; CHECK-NEXT: br i1 [[CMP_N]], label %[[STD_FIND_GENERIC_IMPL_EXIT]], label %[[LOOP_HEADER_I_PREHEADER2]]173; CHECK: [[LOOP_HEADER_I_PREHEADER2]]:174; CHECK-NEXT: [[PTR_IV_I_PH:%.*]] = phi ptr [ [[FIRST]], %[[LOOP_HEADER_I_PREHEADER]] ], [ [[NEXT_GEP]], %[[MIDDLE_BLOCK]] ]175; CHECK-NEXT: br label %[[LOOP_HEADER_I:.*]]176; CHECK: [[VECTOR_EARLY_EXIT]]:177; CHECK-NEXT: [[TMP11:%.*]] = tail call i64 @llvm.experimental.cttz.elts.i64.v8i1(<8 x i1> [[TMP4]], i1 false)178; CHECK-NEXT: [[TMP12:%.*]] = add i64 [[INDEX]], [[TMP11]]179; CHECK-NEXT: [[TMP13:%.*]] = shl i64 [[TMP12]], 1180; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr [[FIRST]], i64 [[TMP13]]181; CHECK-NEXT: br label %[[STD_FIND_GENERIC_IMPL_EXIT]]182; CHECK: [[LOOP_HEADER_I]]:183; CHECK-NEXT: [[PTR_IV_I:%.*]] = phi ptr [ [[PTR_IV_NEXT_I:%.*]], %[[LOOP_LATCH_I:.*]] ], [ [[PTR_IV_I_PH]], %[[LOOP_HEADER_I_PREHEADER2]] ]184; CHECK-NEXT: [[L_I:%.*]] = load i16, ptr [[PTR_IV_I]], align 2185; CHECK-NEXT: [[C_1_I:%.*]] = icmp eq i16 [[L_I]], 1186; CHECK-NEXT: br i1 [[C_1_I]], label %[[STD_FIND_GENERIC_IMPL_EXIT]], label %[[LOOP_LATCH_I]]187; CHECK: [[LOOP_LATCH_I]]:188; CHECK-NEXT: [[PTR_IV_NEXT_I]] = getelementptr inbounds nuw i8, ptr [[PTR_IV_I]], i64 2189; CHECK-NEXT: [[EC_I:%.*]] = icmp eq ptr [[PTR_IV_NEXT_I]], [[LAST]]190; CHECK-NEXT: br i1 [[EC_I]], label %[[STD_FIND_GENERIC_IMPL_EXIT]], label %[[LOOP_HEADER_I]], !llvm.loop [[LOOP4:![0-9]+]]191; CHECK: [[STD_FIND_GENERIC_IMPL_EXIT]]:192; CHECK-NEXT: [[RES_I:%.*]] = phi ptr [ [[FIRST]], %[[ENTRY]] ], [ [[SCEVGEP]], %[[MIDDLE_BLOCK]] ], [ [[TMP14]], %[[VECTOR_EARLY_EXIT]] ], [ [[SCEVGEP]], %[[LOOP_LATCH_I]] ], [ [[PTR_IV_I]], %[[LOOP_HEADER_I]] ]193; CHECK-NEXT: ret ptr [[RES_I]]194;195entry:196 %last.i64 = ptrtoint ptr %last to i64197 %first.i64 = ptrtoint ptr %first to i64198 %ptr.sub = sub i64 %last.i64, %first.i64199 call void @llvm.assume(i1 true) [ "align"(ptr %first, i64 2) ]200 call void @llvm.assume(i1 true) [ "align"(ptr %last, i64 2) ]201 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %first, i64 %ptr.sub) ]202 %call = call noundef ptr @std_find_generic_impl(ptr noundef nonnull %first, ptr noundef %last, i16 noundef signext 1)203 ret ptr %call204}205 206define linkonce_odr noundef ptr @std_find_generic_impl(ptr noundef %first, ptr noundef %last, i16 noundef %value) {207entry:208 %pre = icmp eq ptr %first, %last209 br i1 %pre, label %exit, label %loop.header210 211loop.header:212 %ptr.iv = phi ptr [ %ptr.iv.next, %loop.latch ], [ %first, %entry ]213 %l = load i16, ptr %ptr.iv, align 2214 %c.1 = icmp eq i16 %l, %value215 br i1 %c.1, label %exit, label %loop.latch216 217loop.latch:218 %ptr.iv.next = getelementptr inbounds nuw i8, ptr %ptr.iv, i64 2219 %ec = icmp eq ptr %ptr.iv.next, %last220 br i1 %ec, label %exit, label %loop.header221 222exit:223 %res = phi ptr [ %first, %entry ], [ %ptr.iv, %loop.header ], [ %ptr.iv.next, %loop.latch ]224 ret ptr %res225}226 227declare void @llvm.assume(i1 noundef)228;.229; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}230; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}231; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}232; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META1]], [[META2]]}233; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META2]], [[META1]]}234;.235