blob: 5941eb6fa804649a5e2ebd30d82f09413b250d62 [file]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -O3 -S %s | FileCheck %s
target triple = "arm64-apple-macosx15.0.0"
define i64 @std_find_i16_constant_offset_with_assumptions(ptr %first.coerce, i16 noundef signext %s) nofree nosync {
; CHECK-LABEL: define i64 @std_find_i16_constant_offset_with_assumptions(
; CHECK-SAME: ptr [[FIRST_COERCE:%.*]], i16 noundef signext [[S:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[FIRST_COERCE]], i64 2) ]
; CHECK-NEXT: [[COERCE_VAL_IP:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 256
; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <8 x i16> poison, i16 [[S]], i64 0
; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <8 x i16> [[BROADCAST_SPLATINSERT]], <8 x i16> poison, <8 x i32> zeroinitializer
; CHECK-NEXT: [[WIDE_LOAD1:%.*]] = load <8 x i16>, ptr [[FIRST_COERCE]], align 2
; CHECK-NEXT: [[WIDE_LOAD_FR1:%.*]] = freeze <8 x i16> [[WIDE_LOAD1]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR1]], [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i1> [[TMP2]] to i8
; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i8 [[TMP3]], 0
; CHECK-NEXT: br i1 [[DOTNOT]], label %[[VECTOR_BODY_INTERIM:.*]], label %[[VECTOR_EARLY_EXIT:.*]]
; CHECK: [[VECTOR_BODY_INTERIM]]:
; CHECK-NEXT: [[NEXT_GEP:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 16
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <8 x i16>, ptr [[NEXT_GEP]], align 2
; CHECK-NEXT: [[WIDE_LOAD_FR:%.*]] = freeze <8 x i16> [[WIDE_LOAD]]
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR]], [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i1> [[TMP0]] to i8
; CHECK-NEXT: [[DOTNOT_1:%.*]] = icmp eq i8 [[TMP1]], 0
; CHECK-NEXT: br i1 [[DOTNOT_1]], label %[[VECTOR_BODY_INTERIM_1:.*]], label %[[VECTOR_EARLY_EXIT]]
; CHECK: [[VECTOR_BODY_INTERIM_1]]:
; CHECK-NEXT: [[NEXT_GEP_2:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 32
; CHECK-NEXT: [[WIDE_LOAD_2:%.*]] = load <8 x i16>, ptr [[NEXT_GEP_2]], align 2
; CHECK-NEXT: [[WIDE_LOAD_FR_2:%.*]] = freeze <8 x i16> [[WIDE_LOAD_2]]
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR_2]], [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[TMP32:%.*]] = bitcast <8 x i1> [[TMP4]] to i8
; CHECK-NEXT: [[DOTNOT_2:%.*]] = icmp eq i8 [[TMP32]], 0
; CHECK-NEXT: br i1 [[DOTNOT_2]], label %[[VECTOR_BODY_INTERIM_2:.*]], label %[[VECTOR_EARLY_EXIT]]
; CHECK: [[VECTOR_BODY_INTERIM_2]]:
; CHECK-NEXT: [[NEXT_GEP_3:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 48
; CHECK-NEXT: [[WIDE_LOAD_3:%.*]] = load <8 x i16>, ptr [[NEXT_GEP_3]], align 2
; CHECK-NEXT: [[WIDE_LOAD_FR_3:%.*]] = freeze <8 x i16> [[WIDE_LOAD_3]]
; CHECK-NEXT: [[TMP33:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR_3]], [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[TMP34:%.*]] = bitcast <8 x i1> [[TMP33]] to i8
; CHECK-NEXT: [[DOTNOT_3:%.*]] = icmp eq i8 [[TMP34]], 0
; CHECK-NEXT: br i1 [[DOTNOT_3]], label %[[VECTOR_BODY_INTERIM_3:.*]], label %[[VECTOR_EARLY_EXIT]]
; CHECK: [[VECTOR_BODY_INTERIM_3]]:
; CHECK-NEXT: [[NEXT_GEP_4:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 64
; CHECK-NEXT: [[WIDE_LOAD_4:%.*]] = load <8 x i16>, ptr [[NEXT_GEP_4]], align 2
; CHECK-NEXT: [[WIDE_LOAD_FR_4:%.*]] = freeze <8 x i16> [[WIDE_LOAD_4]]
; CHECK-NEXT: [[TMP35:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR_4]], [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[TMP9:%.*]] = bitcast <8 x i1> [[TMP35]] to i8
; CHECK-NEXT: [[DOTNOT_4:%.*]] = icmp eq i8 [[TMP9]], 0
; CHECK-NEXT: br i1 [[DOTNOT_4]], label %[[VECTOR_BODY_INTERIM_4:.*]], label %[[VECTOR_EARLY_EXIT]]
; CHECK: [[VECTOR_BODY_INTERIM_4]]:
; CHECK-NEXT: [[NEXT_GEP_5:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 80
; CHECK-NEXT: [[WIDE_LOAD_5:%.*]] = load <8 x i16>, ptr [[NEXT_GEP_5]], align 2
; CHECK-NEXT: [[WIDE_LOAD_FR_5:%.*]] = freeze <8 x i16> [[WIDE_LOAD_5]]
; CHECK-NEXT: [[TMP10:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR_5]], [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[TMP11:%.*]] = bitcast <8 x i1> [[TMP10]] to i8
; CHECK-NEXT: [[DOTNOT_5:%.*]] = icmp eq i8 [[TMP11]], 0
; CHECK-NEXT: br i1 [[DOTNOT_5]], label %[[VECTOR_BODY_INTERIM_5:.*]], label %[[VECTOR_EARLY_EXIT]]
; CHECK: [[VECTOR_BODY_INTERIM_5]]:
; CHECK-NEXT: [[NEXT_GEP_6:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 96
; CHECK-NEXT: [[WIDE_LOAD_6:%.*]] = load <8 x i16>, ptr [[NEXT_GEP_6]], align 2
; CHECK-NEXT: [[WIDE_LOAD_FR_6:%.*]] = freeze <8 x i16> [[WIDE_LOAD_6]]
; CHECK-NEXT: [[TMP12:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR_6]], [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[TMP13:%.*]] = bitcast <8 x i1> [[TMP12]] to i8
; CHECK-NEXT: [[DOTNOT_6:%.*]] = icmp eq i8 [[TMP13]], 0
; CHECK-NEXT: br i1 [[DOTNOT_6]], label %[[VECTOR_BODY_INTERIM_6:.*]], label %[[VECTOR_EARLY_EXIT]]
; CHECK: [[VECTOR_BODY_INTERIM_6]]:
; CHECK-NEXT: [[NEXT_GEP_7:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 112
; CHECK-NEXT: [[WIDE_LOAD_7:%.*]] = load <8 x i16>, ptr [[NEXT_GEP_7]], align 2
; CHECK-NEXT: [[WIDE_LOAD_FR_7:%.*]] = freeze <8 x i16> [[WIDE_LOAD_7]]
; CHECK-NEXT: [[TMP14:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR_7]], [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[TMP15:%.*]] = bitcast <8 x i1> [[TMP14]] to i8
; CHECK-NEXT: [[DOTNOT_7:%.*]] = icmp eq i8 [[TMP15]], 0
; CHECK-NEXT: br i1 [[DOTNOT_7]], label %[[VECTOR_BODY_INTERIM_7:.*]], label %[[VECTOR_EARLY_EXIT]]
; CHECK: [[VECTOR_BODY_INTERIM_7]]:
; CHECK-NEXT: [[NEXT_GEP_8:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 128
; CHECK-NEXT: [[WIDE_LOAD_8:%.*]] = load <8 x i16>, ptr [[NEXT_GEP_8]], align 2
; CHECK-NEXT: [[WIDE_LOAD_FR_8:%.*]] = freeze <8 x i16> [[WIDE_LOAD_8]]
; CHECK-NEXT: [[TMP16:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR_8]], [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[TMP17:%.*]] = bitcast <8 x i1> [[TMP16]] to i8
; CHECK-NEXT: [[DOTNOT_8:%.*]] = icmp eq i8 [[TMP17]], 0
; CHECK-NEXT: br i1 [[DOTNOT_8]], label %[[VECTOR_BODY_INTERIM_8:.*]], label %[[VECTOR_EARLY_EXIT]]
; CHECK: [[VECTOR_BODY_INTERIM_8]]:
; CHECK-NEXT: [[NEXT_GEP_9:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 144
; CHECK-NEXT: [[WIDE_LOAD_9:%.*]] = load <8 x i16>, ptr [[NEXT_GEP_9]], align 2
; CHECK-NEXT: [[WIDE_LOAD_FR_9:%.*]] = freeze <8 x i16> [[WIDE_LOAD_9]]
; CHECK-NEXT: [[TMP18:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR_9]], [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[TMP19:%.*]] = bitcast <8 x i1> [[TMP18]] to i8
; CHECK-NEXT: [[DOTNOT_9:%.*]] = icmp eq i8 [[TMP19]], 0
; CHECK-NEXT: br i1 [[DOTNOT_9]], label %[[VECTOR_BODY_INTERIM_9:.*]], label %[[VECTOR_EARLY_EXIT]]
; CHECK: [[VECTOR_BODY_INTERIM_9]]:
; CHECK-NEXT: [[NEXT_GEP_10:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 160
; CHECK-NEXT: [[WIDE_LOAD_10:%.*]] = load <8 x i16>, ptr [[NEXT_GEP_10]], align 2
; CHECK-NEXT: [[WIDE_LOAD_FR_10:%.*]] = freeze <8 x i16> [[WIDE_LOAD_10]]
; CHECK-NEXT: [[TMP20:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR_10]], [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[TMP21:%.*]] = bitcast <8 x i1> [[TMP20]] to i8
; CHECK-NEXT: [[DOTNOT_10:%.*]] = icmp eq i8 [[TMP21]], 0
; CHECK-NEXT: br i1 [[DOTNOT_10]], label %[[VECTOR_BODY_INTERIM_10:.*]], label %[[VECTOR_EARLY_EXIT]]
; CHECK: [[VECTOR_BODY_INTERIM_10]]:
; CHECK-NEXT: [[NEXT_GEP_11:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 176
; CHECK-NEXT: [[WIDE_LOAD_11:%.*]] = load <8 x i16>, ptr [[NEXT_GEP_11]], align 2
; CHECK-NEXT: [[WIDE_LOAD_FR_11:%.*]] = freeze <8 x i16> [[WIDE_LOAD_11]]
; CHECK-NEXT: [[TMP22:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR_11]], [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[TMP23:%.*]] = bitcast <8 x i1> [[TMP22]] to i8
; CHECK-NEXT: [[DOTNOT_11:%.*]] = icmp eq i8 [[TMP23]], 0
; CHECK-NEXT: br i1 [[DOTNOT_11]], label %[[VECTOR_BODY_INTERIM_11:.*]], label %[[VECTOR_EARLY_EXIT]]
; CHECK: [[VECTOR_BODY_INTERIM_11]]:
; CHECK-NEXT: [[NEXT_GEP_12:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 192
; CHECK-NEXT: [[WIDE_LOAD_12:%.*]] = load <8 x i16>, ptr [[NEXT_GEP_12]], align 2
; CHECK-NEXT: [[WIDE_LOAD_FR_12:%.*]] = freeze <8 x i16> [[WIDE_LOAD_12]]
; CHECK-NEXT: [[TMP24:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR_12]], [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[TMP25:%.*]] = bitcast <8 x i1> [[TMP24]] to i8
; CHECK-NEXT: [[DOTNOT_12:%.*]] = icmp eq i8 [[TMP25]], 0
; CHECK-NEXT: br i1 [[DOTNOT_12]], label %[[VECTOR_BODY_INTERIM_12:.*]], label %[[VECTOR_EARLY_EXIT]]
; CHECK: [[VECTOR_BODY_INTERIM_12]]:
; CHECK-NEXT: [[NEXT_GEP_13:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 208
; CHECK-NEXT: [[WIDE_LOAD_13:%.*]] = load <8 x i16>, ptr [[NEXT_GEP_13]], align 2
; CHECK-NEXT: [[WIDE_LOAD_FR_13:%.*]] = freeze <8 x i16> [[WIDE_LOAD_13]]
; CHECK-NEXT: [[TMP26:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR_13]], [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[TMP27:%.*]] = bitcast <8 x i1> [[TMP26]] to i8
; CHECK-NEXT: [[DOTNOT_13:%.*]] = icmp eq i8 [[TMP27]], 0
; CHECK-NEXT: br i1 [[DOTNOT_13]], label %[[VECTOR_BODY_INTERIM_13:.*]], label %[[VECTOR_EARLY_EXIT]]
; CHECK: [[VECTOR_BODY_INTERIM_13]]:
; CHECK-NEXT: [[NEXT_GEP_14:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 224
; CHECK-NEXT: [[WIDE_LOAD_14:%.*]] = load <8 x i16>, ptr [[NEXT_GEP_14]], align 2
; CHECK-NEXT: [[WIDE_LOAD_FR_14:%.*]] = freeze <8 x i16> [[WIDE_LOAD_14]]
; CHECK-NEXT: [[TMP28:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR_14]], [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[TMP29:%.*]] = bitcast <8 x i1> [[TMP28]] to i8
; CHECK-NEXT: [[DOTNOT_14:%.*]] = icmp eq i8 [[TMP29]], 0
; CHECK-NEXT: br i1 [[DOTNOT_14]], label %[[VECTOR_BODY_INTERIM_14:.*]], label %[[VECTOR_EARLY_EXIT]]
; CHECK: [[VECTOR_BODY_INTERIM_14]]:
; CHECK-NEXT: [[NEXT_GEP_15:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 240
; CHECK-NEXT: [[WIDE_LOAD_15:%.*]] = load <8 x i16>, ptr [[NEXT_GEP_15]], align 2
; CHECK-NEXT: [[WIDE_LOAD_FR_15:%.*]] = freeze <8 x i16> [[WIDE_LOAD_15]]
; CHECK-NEXT: [[TMP30:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR_15]], [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[TMP31:%.*]] = bitcast <8 x i1> [[TMP30]] to i8
; CHECK-NEXT: [[DOTNOT_15:%.*]] = icmp eq i8 [[TMP31]], 0
; CHECK-NEXT: br i1 [[DOTNOT_15]], label %[[RETURN:.*]], label %[[VECTOR_EARLY_EXIT]]
; CHECK: [[VECTOR_EARLY_EXIT]]:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ 8, %[[VECTOR_BODY_INTERIM]] ], [ 16, %[[VECTOR_BODY_INTERIM_1]] ], [ 24, %[[VECTOR_BODY_INTERIM_2]] ], [ 32, %[[VECTOR_BODY_INTERIM_3]] ], [ 40, %[[VECTOR_BODY_INTERIM_4]] ], [ 48, %[[VECTOR_BODY_INTERIM_5]] ], [ 56, %[[VECTOR_BODY_INTERIM_6]] ], [ 64, %[[VECTOR_BODY_INTERIM_7]] ], [ 72, %[[VECTOR_BODY_INTERIM_8]] ], [ 80, %[[VECTOR_BODY_INTERIM_9]] ], [ 88, %[[VECTOR_BODY_INTERIM_10]] ], [ 96, %[[VECTOR_BODY_INTERIM_11]] ], [ 104, %[[VECTOR_BODY_INTERIM_12]] ], [ 112, %[[VECTOR_BODY_INTERIM_13]] ], [ 120, %[[VECTOR_BODY_INTERIM_14]] ]
; CHECK-NEXT: [[DOTLCSSA:%.*]] = phi <8 x i1> [ [[TMP2]], %[[ENTRY]] ], [ [[TMP0]], %[[VECTOR_BODY_INTERIM]] ], [ [[TMP4]], %[[VECTOR_BODY_INTERIM_1]] ], [ [[TMP33]], %[[VECTOR_BODY_INTERIM_2]] ], [ [[TMP35]], %[[VECTOR_BODY_INTERIM_3]] ], [ [[TMP10]], %[[VECTOR_BODY_INTERIM_4]] ], [ [[TMP12]], %[[VECTOR_BODY_INTERIM_5]] ], [ [[TMP14]], %[[VECTOR_BODY_INTERIM_6]] ], [ [[TMP16]], %[[VECTOR_BODY_INTERIM_7]] ], [ [[TMP18]], %[[VECTOR_BODY_INTERIM_8]] ], [ [[TMP20]], %[[VECTOR_BODY_INTERIM_9]] ], [ [[TMP22]], %[[VECTOR_BODY_INTERIM_10]] ], [ [[TMP24]], %[[VECTOR_BODY_INTERIM_11]] ], [ [[TMP26]], %[[VECTOR_BODY_INTERIM_12]] ], [ [[TMP28]], %[[VECTOR_BODY_INTERIM_13]] ], [ [[TMP30]], %[[VECTOR_BODY_INTERIM_14]] ]
; CHECK-NEXT: [[TMP5:%.*]] = tail call i64 @llvm.experimental.cttz.elts.i64.v8i1(<8 x i1> [[DOTLCSSA]], i1 false)
; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[INDEX]], [[TMP5]]
; CHECK-NEXT: [[TMP7:%.*]] = shl i64 [[TMP6]], 1
; CHECK-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 [[TMP7]]
; CHECK-NEXT: br label %[[RETURN]]
; CHECK: [[RETURN]]:
; CHECK-NEXT: [[__FIRST_ADDR_0_LCSSA_I_I_PH:%.*]] = phi ptr [ [[TMP8]], %[[VECTOR_EARLY_EXIT]] ], [ [[COERCE_VAL_IP]], %[[VECTOR_BODY_INTERIM_14]] ]
; CHECK-NEXT: [[DOTPRE:%.*]] = ptrtoint ptr [[__FIRST_ADDR_0_LCSSA_I_I_PH]] to i64
; CHECK-NEXT: ret i64 [[DOTPRE]]
;
entry:
%first = alloca { ptr }, align 8
%s.addr = alloca i16, align 2
store ptr %first.coerce, ptr %first, align 8
store i16 %s, ptr %s.addr, align 2
%0 = load ptr, ptr %first, align 8
call void @llvm.assume(i1 true) [ "align"(ptr %0, i64 2) ]
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %0, i64 256) ]
%start.ptr = load ptr, ptr %first, align 8
%1 = load i64, ptr %first, align 8
%coerce.val.p = add i64 %1, 256
%coerce.val.ip = inttoptr i64 %coerce.val.p to ptr
%ec6. = icmp eq ptr %start.ptr, %coerce.val.ip
br i1 %ec6., label %return, label %loop.ph
loop.ph:
%2 = load i16, ptr %s.addr, align 2
br label %loop.header
loop.header:
%ptr.iv = phi ptr [ %start.ptr, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
%3 = load i16, ptr %ptr.iv, align 2
%cmp2. = icmp eq i16 %3, %2
br i1 %cmp2., label %return, label %loop.latch
loop.latch:
%ptr.iv.next = getelementptr inbounds nuw i8, ptr %ptr.iv, i64 2
%ec. = icmp eq ptr %ptr.iv.next, %coerce.val.ip
br i1 %ec., label %return, label %loop.header
return:
%merge = phi ptr [ %start.ptr, %entry ], [ %coerce.val.ip, %loop.latch ], [ %ptr.iv, %loop.header ]
%res = ptrtoint ptr %merge to i64
ret i64 %res
}
define i64 @std_find_i16_constant_offset_no_assumptions(ptr %first.coerce, i16 noundef signext %s) nofree nosync {
; CHECK-LABEL: define i64 @std_find_i16_constant_offset_no_assumptions(
; CHECK-SAME: ptr [[FIRST_COERCE:%.*]], i16 noundef signext [[S:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: [[COERCE_VAL_IP:%.*]] = getelementptr i8, ptr [[FIRST_COERCE]], i64 256
; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
; CHECK: [[LOOP_HEADER]]:
; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[FIRST_COERCE]], %[[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
; CHECK-NEXT: [[TMP1:%.*]] = load i16, ptr [[PTR_IV]], align 2
; CHECK-NEXT: [[CMP2_I_I:%.*]] = icmp eq i16 [[TMP1]], [[S]]
; CHECK-NEXT: br i1 [[CMP2_I_I]], label %[[RETURN:.*]], label %[[LOOP_LATCH]]
; CHECK: [[LOOP_LATCH]]:
; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds nuw i8, ptr [[PTR_IV]], i64 2
; CHECK-NEXT: [[CMP_NOT_I_I:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[COERCE_VAL_IP]]
; CHECK-NEXT: br i1 [[CMP_NOT_I_I]], label %[[RETURN]], label %[[LOOP_HEADER]]
; CHECK: [[RETURN]]:
; CHECK-NEXT: [[MERGE_PH:%.*]] = phi ptr [ [[PTR_IV]], %[[LOOP_HEADER]] ], [ [[COERCE_VAL_IP]], %[[LOOP_LATCH]] ]
; CHECK-NEXT: [[DOTPRE:%.*]] = ptrtoint ptr [[MERGE_PH]] to i64
; CHECK-NEXT: ret i64 [[DOTPRE]]
;
entry:
%first = alloca { ptr }, align 8
%s.addr = alloca i16, align 2
store ptr %first.coerce, ptr %first, align 8
store i16 %s, ptr %s.addr, align 2
%0 = load ptr, ptr %first, align 8
%start.ptr = load ptr, ptr %first, align 8
%1 = load i64, ptr %first, align 8
%coerce.val.p = add i64 %1, 256
%coerce.val.ip = inttoptr i64 %coerce.val.p to ptr
%ec6. = icmp eq ptr %start.ptr, %coerce.val.ip
br i1 %ec6., label %return, label %loop.ph
loop.ph:
%2 = load i16, ptr %s.addr, align 2
br label %loop.header
loop.header:
%ptr.iv = phi ptr [ %start.ptr, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
%3 = load i16, ptr %ptr.iv, align 2
%cmp2. = icmp eq i16 %3, %2
br i1 %cmp2., label %return, label %loop.latch
loop.latch:
%ptr.iv.next = getelementptr inbounds nuw i8, ptr %ptr.iv, i64 2
%ec. = icmp eq ptr %ptr.iv.next, %coerce.val.ip
br i1 %ec., label %return, label %loop.header
return:
%merge = phi ptr [ %start.ptr, %entry ], [ %coerce.val.ip, %loop.latch ], [ %ptr.iv, %loop.header ]
%res = ptrtoint ptr %merge to i64
ret i64 %res
}
define ptr @std_find_caller(ptr noundef %first, ptr noundef %last) {
; CHECK-LABEL: define noundef ptr @std_find_caller(
; CHECK-SAME: ptr noundef [[FIRST:%.*]], ptr noundef [[LAST:%.*]]) local_unnamed_addr #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[FIRST]], i64 2) ]
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[LAST]], i64 2) ]
; CHECK-NEXT: [[PRE_I:%.*]] = icmp eq ptr [[FIRST]], [[LAST]]
; CHECK-NEXT: br i1 [[PRE_I]], label %[[STD_FIND_GENERIC_IMPL_EXIT:.*]], label %[[LOOP_HEADER_I_PREHEADER:.*]]
; CHECK: [[LOOP_HEADER_I_PREHEADER]]:
; CHECK-NEXT: [[LAST_I64:%.*]] = ptrtoint ptr [[LAST]] to i64
; CHECK-NEXT: [[FIRST3:%.*]] = ptrtoint ptr [[FIRST]] to i64
; CHECK-NEXT: [[PTR_SUB:%.*]] = sub i64 [[LAST_I64]], [[FIRST3]]
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[FIRST]], i64 [[PTR_SUB]]
; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[LAST_I64]], -2
; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[TMP0]], [[FIRST3]]
; CHECK-NEXT: [[TMP2:%.*]] = lshr exact i64 [[TMP1]], 1
; CHECK-NEXT: [[TMP3:%.*]] = add nuw i64 [[TMP2]], 1
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP1]], 14
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[LOOP_HEADER_I_PREHEADER2:.*]], label %[[VECTOR_PH:.*]]
; CHECK: [[VECTOR_PH]]:
; CHECK-NEXT: [[XTRAITER:%.*]] = and i64 [[TMP3]], -8
; CHECK-NEXT: [[OFFSET_IDX:%.*]] = shl i64 [[XTRAITER]], 1
; CHECK-NEXT: [[NEXT_GEP:%.*]] = getelementptr i8, ptr [[FIRST]], i64 [[OFFSET_IDX]]
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
; CHECK: [[VECTOR_BODY]]:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[PROL_ITER_NEXT:%.*]], %[[VECTOR_BODY_INTERIM:.*]] ]
; CHECK-NEXT: [[OFFSET_IDX1:%.*]] = shl i64 [[INDEX]], 1
; CHECK-NEXT: [[NEXT_GEP1:%.*]] = getelementptr i8, ptr [[FIRST]], i64 [[OFFSET_IDX1]]
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <8 x i16>, ptr [[NEXT_GEP1]], align 2
; CHECK-NEXT: [[WIDE_LOAD_FR:%.*]] = freeze <8 x i16> [[WIDE_LOAD]]
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR]], splat (i16 1)
; CHECK-NEXT: [[TMP5:%.*]] = bitcast <8 x i1> [[TMP4]] to i8
; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i8 [[TMP5]], 0
; CHECK-NEXT: br i1 [[DOTNOT]], label %[[VECTOR_BODY_INTERIM]], label %[[VECTOR_EARLY_EXIT:.*]]
; CHECK: [[VECTOR_BODY_INTERIM]]:
; CHECK-NEXT: [[PROL_ITER_NEXT]] = add nuw i64 [[INDEX]], 8
; CHECK-NEXT: [[PROL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[PROL_ITER_NEXT]], [[XTRAITER]]
; CHECK-NEXT: br i1 [[PROL_ITER_CMP_NOT]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
; CHECK: [[MIDDLE_BLOCK]]:
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP3]], [[XTRAITER]]
; CHECK-NEXT: br i1 [[CMP_N]], label %[[STD_FIND_GENERIC_IMPL_EXIT]], label %[[LOOP_HEADER_I_PREHEADER2]]
; CHECK: [[LOOP_HEADER_I_PREHEADER2]]:
; CHECK-NEXT: [[PTR_IV_I_PH:%.*]] = phi ptr [ [[FIRST]], %[[LOOP_HEADER_I_PREHEADER]] ], [ [[NEXT_GEP]], %[[MIDDLE_BLOCK]] ]
; CHECK-NEXT: br label %[[LOOP_HEADER_I:.*]]
; CHECK: [[VECTOR_EARLY_EXIT]]:
; CHECK-NEXT: [[TMP11:%.*]] = tail call i64 @llvm.experimental.cttz.elts.i64.v8i1(<8 x i1> [[TMP4]], i1 false)
; CHECK-NEXT: [[TMP12:%.*]] = add i64 [[INDEX]], [[TMP11]]
; CHECK-NEXT: [[TMP13:%.*]] = shl i64 [[TMP12]], 1
; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr [[FIRST]], i64 [[TMP13]]
; CHECK-NEXT: br label %[[STD_FIND_GENERIC_IMPL_EXIT]]
; CHECK: [[LOOP_HEADER_I]]:
; CHECK-NEXT: [[PTR_IV_I:%.*]] = phi ptr [ [[PTR_IV_NEXT_I:%.*]], %[[LOOP_LATCH_I:.*]] ], [ [[PTR_IV_I_PH]], %[[LOOP_HEADER_I_PREHEADER2]] ]
; CHECK-NEXT: [[L_I:%.*]] = load i16, ptr [[PTR_IV_I]], align 2
; CHECK-NEXT: [[C_1_I:%.*]] = icmp eq i16 [[L_I]], 1
; CHECK-NEXT: br i1 [[C_1_I]], label %[[STD_FIND_GENERIC_IMPL_EXIT]], label %[[LOOP_LATCH_I]]
; CHECK: [[LOOP_LATCH_I]]:
; CHECK-NEXT: [[PTR_IV_NEXT_I]] = getelementptr inbounds nuw i8, ptr [[PTR_IV_I]], i64 2
; CHECK-NEXT: [[EC_I:%.*]] = icmp eq ptr [[PTR_IV_NEXT_I]], [[LAST]]
; CHECK-NEXT: br i1 [[EC_I]], label %[[STD_FIND_GENERIC_IMPL_EXIT]], label %[[LOOP_HEADER_I]], !llvm.loop [[LOOP3:![0-9]+]]
; CHECK: [[STD_FIND_GENERIC_IMPL_EXIT]]:
; 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]] ]
; CHECK-NEXT: ret ptr [[RES_I]]
;
entry:
%last.i64 = ptrtoint ptr %last to i64
%first.i64 = ptrtoint ptr %first to i64
%ptr.sub = sub i64 %last.i64, %first.i64
call void @llvm.assume(i1 true) [ "align"(ptr %first, i64 2) ]
call void @llvm.assume(i1 true) [ "align"(ptr %last, i64 2) ]
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %first, i64 %ptr.sub) ]
%call = call noundef ptr @std_find_generic_impl(ptr noundef nonnull %first, ptr noundef %last, i16 noundef signext 1)
ret ptr %call
}
define linkonce_odr noundef ptr @std_find_generic_impl(ptr noundef %first, ptr noundef %last, i16 noundef %value) {
entry:
%pre = icmp eq ptr %first, %last
br i1 %pre, label %exit, label %loop.header
loop.header:
%ptr.iv = phi ptr [ %ptr.iv.next, %loop.latch ], [ %first, %entry ]
%l = load i16, ptr %ptr.iv, align 2
%c.1 = icmp eq i16 %l, %value
br i1 %c.1, label %exit, label %loop.latch
loop.latch:
%ptr.iv.next = getelementptr inbounds nuw i8, ptr %ptr.iv, i64 2
%ec = icmp eq ptr %ptr.iv.next, %last
br i1 %ec, label %exit, label %loop.header
exit:
%res = phi ptr [ %first, %entry ], [ %ptr.iv, %loop.header ], [ %ptr.iv.next, %loop.latch ]
ret ptr %res
}
declare void @llvm.assume(i1 noundef)
;.
; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META2]], [[META1]]}
;.