639 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s3 4declare void @llvm.assume(i1 noundef)5 6define i1 @gep_sub_1_uge_inbounds(ptr %dst, ptr %lower) {7; CHECK-LABEL: @gep_sub_1_uge_inbounds(8; CHECK-NEXT: [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]9; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])10; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 311; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -112; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -313; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true14; CHECK-NEXT: [[DST_SUB_4:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -415; CHECK-NEXT: [[CMP_SUB_4:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]]16; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_4]]17; CHECK-NEXT: ret i1 [[RES_2]]18;19 %pre = icmp uge ptr %dst, %lower20 call void @llvm.assume(i1 %pre)21 %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 322 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.3, i64 -123 %cmp.sub.1 = icmp uge ptr %dst.sub.1, %lower24 %dst.sub.3 = getelementptr inbounds i8, ptr %dst.add.3, i64 -325 %cmp.sub.3 = icmp uge ptr %dst.sub.3, %lower26 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.327 %dst.sub.4 = getelementptr inbounds i8, ptr %dst.add.3, i64 -428 %cmp.sub.4 = icmp uge ptr %dst.sub.4, %lower29 %res.2 = xor i1 %res.1, %cmp.sub.430 ret i1 %res.231}32 33define i1 @gep_sub_1_uge_only_inner_inbounds(ptr %dst, ptr %lower) {34; CHECK-LABEL: @gep_sub_1_uge_only_inner_inbounds(35; CHECK-NEXT: [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]36; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])37; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 338; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -139; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp uge ptr [[DST_SUB_1]], [[LOWER]]40; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -341; CHECK-NEXT: [[CMP_SUB_3:%.*]] = icmp uge ptr [[DST_SUB_3]], [[LOWER]]42; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_SUB_1]], [[CMP_SUB_3]]43; CHECK-NEXT: [[DST_SUB_4:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -444; CHECK-NEXT: [[CMP_SUB_4:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]]45; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_4]]46; CHECK-NEXT: ret i1 [[RES_2]]47;48 %pre = icmp uge ptr %dst, %lower49 call void @llvm.assume(i1 %pre)50 %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 351 %dst.sub.1 = getelementptr i8, ptr %dst.add.3, i64 -152 %cmp.sub.1 = icmp uge ptr %dst.sub.1, %lower53 %dst.sub.3 = getelementptr i8, ptr %dst.add.3, i64 -354 %cmp.sub.3 = icmp uge ptr %dst.sub.3, %lower55 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.356 %dst.sub.4 = getelementptr i8, ptr %dst.add.3, i64 -457 %cmp.sub.4 = icmp uge ptr %dst.sub.4, %lower58 %res.2 = xor i1 %res.1, %cmp.sub.459 ret i1 %res.260}61 62define i1 @gep_sub_1_uge_only_outer_inbounds(ptr %dst, ptr %lower) {63; CHECK-LABEL: @gep_sub_1_uge_only_outer_inbounds(64; CHECK-NEXT: [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]65; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])66; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr i8, ptr [[DST]], i64 367; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -168; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp uge ptr [[DST_SUB_1]], [[LOWER]]69; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -370; CHECK-NEXT: [[CMP_SUB_3:%.*]] = icmp uge ptr [[DST_SUB_3]], [[LOWER]]71; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_SUB_1]], [[CMP_SUB_3]]72; CHECK-NEXT: [[DST_SUB_4:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -473; CHECK-NEXT: [[CMP_SUB_4:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]]74; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_4]]75; CHECK-NEXT: ret i1 [[RES_2]]76;77 %pre = icmp uge ptr %dst, %lower78 call void @llvm.assume(i1 %pre)79 %dst.add.3 = getelementptr i8, ptr %dst, i64 380 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.3, i64 -181 %cmp.sub.1 = icmp uge ptr %dst.sub.1, %lower82 %dst.sub.3 = getelementptr inbounds i8, ptr %dst.add.3, i64 -383 %cmp.sub.3 = icmp uge ptr %dst.sub.3, %lower84 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.385 %dst.sub.4 = getelementptr inbounds i8, ptr %dst.add.3, i64 -486 %cmp.sub.4 = icmp uge ptr %dst.sub.4, %lower87 %res.2 = xor i1 %res.1, %cmp.sub.488 ret i1 %res.289}90 91define i1 @gep_sub_1_uge_no_inbounds(ptr %dst, ptr %lower) {92; CHECK-LABEL: @gep_sub_1_uge_no_inbounds(93; CHECK-NEXT: [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]94; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])95; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr i8, ptr [[DST]], i64 396; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -197; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp uge ptr [[DST_SUB_1]], [[LOWER]]98; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -399; CHECK-NEXT: [[CMP_SUB_3:%.*]] = icmp uge ptr [[DST_SUB_3]], [[LOWER]]100; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_SUB_1]], [[CMP_SUB_3]]101; CHECK-NEXT: [[DST_SUB_4:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -4102; CHECK-NEXT: [[CMP_SUB_4:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]]103; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_4]]104; CHECK-NEXT: ret i1 [[RES_2]]105;106 %pre = icmp uge ptr %dst, %lower107 call void @llvm.assume(i1 %pre)108 %dst.add.3 = getelementptr i8, ptr %dst, i64 3109 %dst.sub.1 = getelementptr i8, ptr %dst.add.3, i64 -1110 %cmp.sub.1 = icmp uge ptr %dst.sub.1, %lower111 %dst.sub.3 = getelementptr i8, ptr %dst.add.3, i64 -3112 %cmp.sub.3 = icmp uge ptr %dst.sub.3, %lower113 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.3114 %dst.sub.4 = getelementptr i8, ptr %dst.add.3, i64 -4115 %cmp.sub.4 = icmp uge ptr %dst.sub.4, %lower116 %res.2 = xor i1 %res.1, %cmp.sub.4117 ret i1 %res.2118}119 120define i1 @gep_sub_1_ult(ptr %dst, ptr %upper) {121; CHECK-LABEL: @gep_sub_1_ult(122; CHECK-NEXT: [[DST_ADD_4:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 4123; CHECK-NEXT: [[PRE:%.*]] = icmp ult ptr [[DST_ADD_4]], [[UPPER:%.*]]124; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])125; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3126; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -1127; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -3128; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true129; CHECK-NEXT: ret i1 [[RES_1]]130;131 %dst.add.4 = getelementptr inbounds i8, ptr %dst, i64 4132 %pre = icmp ult ptr %dst.add.4, %upper133 call void @llvm.assume(i1 %pre)134 %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3135 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.3, i64 -1136 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper137 %dst.sub.3 = getelementptr inbounds i8, ptr %dst.add.3, i64 -3138 %cmp.sub.3 = icmp ult ptr %dst.sub.3, %upper139 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.3140 ret i1 %res.1141}142 143define i1 @gep_sub_ult_var_idx(ptr %dst, ptr %upper, i8 %idx) {144; CHECK-LABEL: @gep_sub_ult_var_idx(145; CHECK-NEXT: [[NOT_ZERO:%.*]] = icmp ne i8 [[IDX:%.*]], 0146; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]])147; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16148; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[IDX_EXT]]149; CHECK-NEXT: [[PRE:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER:%.*]]150; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])151; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -1152; CHECK-NEXT: [[DST_SUB_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -2153; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true154; CHECK-NEXT: [[DST_SUB_1_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_SUB_1]], i64 -1155; CHECK-NEXT: [[CMP_SUB_1_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1_SUB_1]], [[UPPER]]156; CHECK-NEXT: [[CMP_SUB_1_SUB_1_EQ:%.*]] = icmp eq ptr [[DST_SUB_1_SUB_1]], [[DST_SUB_2]]157; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_1_SUB_1]]158; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[RES_2]], [[CMP_SUB_1_SUB_1_EQ]]159; CHECK-NEXT: ret i1 [[RES_3]]160;161 %not.zero = icmp ne i8 %idx, 0162 call void @llvm.assume(i1 %not.zero)163 %idx.ext = zext i8 %idx to i16164 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext165 %pre = icmp ult ptr %dst.add.idx, %upper166 call void @llvm.assume(i1 %pre)167 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -1168 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper169 %dst.sub.2 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -2170 %cmp.sub.2 = icmp ult ptr %dst.sub.2, %upper171 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.2172 %dst.sub.1.sub.1 = getelementptr inbounds i8, ptr %dst.sub.1, i64 -1173 %cmp.sub.1.sub.1 = icmp ult ptr %dst.sub.1.sub.1, %upper174 %cmp.sub.1.sub.1.eq = icmp eq ptr %dst.sub.1.sub.1, %dst.sub.2175 %res.2 = xor i1 %res.1, %cmp.sub.1.sub.1176 %res.3 = xor i1 %res.2, %cmp.sub.1.sub.1.eq177 ret i1 %res.3178}179 180define i1 @gep_sub_ult_var_idx_sgt_1(ptr %dst, ptr %upper, i8 %idx) {181; CHECK-LABEL: @gep_sub_ult_var_idx_sgt_1(182; CHECK-NEXT: [[SGT_1:%.*]] = icmp sgt i8 [[IDX:%.*]], 1183; CHECK-NEXT: call void @llvm.assume(i1 [[SGT_1]])184; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16185; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[IDX_EXT]]186; CHECK-NEXT: [[PRE:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER:%.*]]187; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])188; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -1189; CHECK-NEXT: [[DST_SUB_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -2190; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true191; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -3192; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], true193; CHECK-NEXT: ret i1 [[RES_2]]194;195 %sgt.1 = icmp sgt i8 %idx, 1196 call void @llvm.assume(i1 %sgt.1)197 %idx.ext = zext i8 %idx to i16198 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext199 %pre = icmp ult ptr %dst.add.idx, %upper200 call void @llvm.assume(i1 %pre)201 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -1202 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper203 %dst.sub.2 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -2204 %cmp.sub.2 = icmp ult ptr %dst.sub.2, %upper205 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.2206 %dst.sub.3 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -3207 %cmp.sub.3 = icmp ult ptr %dst.sub.3, %upper208 %res.2 = xor i1 %res.1, %cmp.sub.3209 ret i1 %res.2210}211 212define i1 @gep_sub_1_ult_var_idx_inbounds(ptr %dst, ptr %upper, i8 %len, i8 %idx) {213; CHECK-LABEL: @gep_sub_1_ult_var_idx_inbounds(214; CHECK-NEXT: [[NOT_ZERO:%.*]] = icmp ne i8 [[LEN:%.*]], 0215; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]])216; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16217; CHECK-NEXT: [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]218; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 -1219; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]220; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_SUB_1]])221; CHECK-NEXT: [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]222; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])223; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16224; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]225; CHECK-NEXT: ret i1 true226;227 %not.zero = icmp ne i8 %len, 0228 call void @llvm.assume(i1 %not.zero)229 %len.ext = zext i8 %len to i16230 %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext231 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -1232 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper233 call void @llvm.assume(i1 %cmp.sub.1)234 %cmp.idx.ult.len = icmp ult i8 %idx, %len235 call void @llvm.assume(i1 %cmp.idx.ult.len)236 %idx.ext = zext i8 %idx to i16237 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext238 %cmp.idx = icmp ult ptr %dst.add.idx, %upper239 ret i1 %cmp.idx240}241 242define i1 @gep_sub_1_ult_var_idx_only_inner_inbounds(ptr %dst, ptr %upper, i8 %len, i8 %idx) {243; CHECK-LABEL: @gep_sub_1_ult_var_idx_only_inner_inbounds(244; CHECK-NEXT: [[NOT_ZERO:%.*]] = icmp ne i8 [[LEN:%.*]], 0245; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]])246; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16247; CHECK-NEXT: [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]248; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr i8, ptr [[DST_ADD_LEN]], i64 -1249; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]250; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_SUB_1]])251; CHECK-NEXT: [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]252; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])253; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16254; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]255; CHECK-NEXT: [[CMP_IDX:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER]]256; CHECK-NEXT: ret i1 [[CMP_IDX]]257;258 %not.zero = icmp ne i8 %len, 0259 call void @llvm.assume(i1 %not.zero)260 %len.ext = zext i8 %len to i16261 %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext262 %dst.sub.1 = getelementptr i8, ptr %dst.add.len, i64 -1263 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper264 call void @llvm.assume(i1 %cmp.sub.1)265 %cmp.idx.ult.len = icmp ult i8 %idx, %len266 call void @llvm.assume(i1 %cmp.idx.ult.len)267 %idx.ext = zext i8 %idx to i16268 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext269 %cmp.idx = icmp ult ptr %dst.add.idx, %upper270 ret i1 %cmp.idx271}272 273define i1 @gep_sub_1_ult_var_idx_no_inbounds(ptr %dst, ptr %upper, i8 %len, i8 %idx) {274; CHECK-LABEL: @gep_sub_1_ult_var_idx_no_inbounds(275; CHECK-NEXT: [[NOT_ZERO:%.*]] = icmp ne i8 [[LEN:%.*]], 0276; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]])277; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16278; CHECK-NEXT: [[DST_ADD_LEN:%.*]] = getelementptr i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]279; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr i8, ptr [[DST_ADD_LEN]], i64 -1280; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]281; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_SUB_1]])282; CHECK-NEXT: [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]283; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])284; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16285; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr i8, ptr [[DST]], i16 [[IDX_EXT]]286; CHECK-NEXT: [[CMP_IDX:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER]]287; CHECK-NEXT: ret i1 [[CMP_IDX]]288;289 %not.zero = icmp ne i8 %len, 0290 call void @llvm.assume(i1 %not.zero)291 %len.ext = zext i8 %len to i16292 %dst.add.len = getelementptr i8, ptr %dst, i16 %len.ext293 %dst.sub.1 = getelementptr i8, ptr %dst.add.len, i64 -1294 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper295 call void @llvm.assume(i1 %cmp.sub.1)296 %cmp.idx.ult.len = icmp ult i8 %idx, %len297 call void @llvm.assume(i1 %cmp.idx.ult.len)298 %idx.ext = zext i8 %idx to i16299 %dst.add.idx = getelementptr i8, ptr %dst, i16 %idx.ext300 %cmp.idx = icmp ult ptr %dst.add.idx, %upper301 ret i1 %cmp.idx302}303 304define i1 @gep_sub_2_ult_var_idx(ptr %dst, ptr %upper, i8 %len, i8 %idx) {305; CHECK-LABEL: @gep_sub_2_ult_var_idx(306; CHECK-NEXT: [[NOT_ZERO:%.*]] = icmp ne i8 [[LEN:%.*]], 0307; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]])308; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16309; CHECK-NEXT: [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]310; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 -2311; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]312; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_SUB_1]])313; CHECK-NEXT: [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]314; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])315; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16316; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]317; CHECK-NEXT: [[CMP_IDX:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER]]318; CHECK-NEXT: ret i1 [[CMP_IDX]]319;320 %not.zero = icmp ne i8 %len, 0321 call void @llvm.assume(i1 %not.zero)322 %len.ext = zext i8 %len to i16323 %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext324 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -2325 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper326 call void @llvm.assume(i1 %cmp.sub.1)327 %cmp.idx.ult.len = icmp ult i8 %idx, %len328 call void @llvm.assume(i1 %cmp.idx.ult.len)329 %idx.ext = zext i8 %idx to i16330 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext331 %cmp.idx = icmp ult ptr %dst.add.idx, %upper332 ret i1 %cmp.idx333}334 335define i1 @gep_sub_2_ult_var_idx_inbounds_len_sge_2(ptr %dst, ptr %upper, i8 %len, i8 %idx) {336; CHECK-LABEL: @gep_sub_2_ult_var_idx_inbounds_len_sge_2(337; CHECK-NEXT: [[SGE_2:%.*]] = icmp sge i8 [[LEN:%.*]], 2338; CHECK-NEXT: call void @llvm.assume(i1 [[SGE_2]])339; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16340; CHECK-NEXT: [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]341; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 -1342; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]343; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_SUB_1]])344; CHECK-NEXT: [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]345; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])346; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16347; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]348; CHECK-NEXT: ret i1 true349;350 %sge.2 = icmp sge i8 %len, 2351 call void @llvm.assume(i1 %sge.2)352 %len.ext = zext i8 %len to i16353 %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext354 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -1355 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper356 call void @llvm.assume(i1 %cmp.sub.1)357 %cmp.idx.ult.len = icmp ult i8 %idx, %len358 call void @llvm.assume(i1 %cmp.idx.ult.len)359 %idx.ext = zext i8 %idx to i16360 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext361 %cmp.idx = icmp ult ptr %dst.add.idx, %upper362 ret i1 %cmp.idx363}364 365define i1 @gep_sub_2_ult_var_idx_inbounds_len_uge_2(ptr %dst, ptr %upper, i8 %len, i8 %idx) {366; CHECK-LABEL: @gep_sub_2_ult_var_idx_inbounds_len_uge_2(367; CHECK-NEXT: [[UGE_2:%.*]] = icmp uge i8 [[LEN:%.*]], 2368; CHECK-NEXT: call void @llvm.assume(i1 [[UGE_2]])369; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16370; CHECK-NEXT: [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]371; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 -1372; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]373; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_SUB_1]])374; CHECK-NEXT: [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]375; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])376; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16377; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]378; CHECK-NEXT: ret i1 true379;380 %uge.2 = icmp uge i8 %len, 2381 call void @llvm.assume(i1 %uge.2)382 %len.ext = zext i8 %len to i16383 %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext384 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -1385 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper386 call void @llvm.assume(i1 %cmp.sub.1)387 %cmp.idx.ult.len = icmp ult i8 %idx, %len388 call void @llvm.assume(i1 %cmp.idx.ult.len)389 %idx.ext = zext i8 %idx to i16390 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext391 %cmp.idx = icmp ult ptr %dst.add.idx, %upper392 ret i1 %cmp.idx393}394 395define i1 @gep_sub_ult_var_idx_len_sgt_1(ptr %dst, ptr %upper, i8 %len, i8 %idx) {396; CHECK-LABEL: @gep_sub_ult_var_idx_len_sgt_1(397; CHECK-NEXT: [[SGT_1:%.*]] = icmp sgt i8 [[LEN:%.*]], 1398; CHECK-NEXT: call void @llvm.assume(i1 [[SGT_1]])399; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16400; CHECK-NEXT: [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]401; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 -2402; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]403; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_SUB_1]])404; CHECK-NEXT: [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]405; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])406; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16407; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]408; CHECK-NEXT: [[CMP_IDX:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER]]409; CHECK-NEXT: ret i1 [[CMP_IDX]]410;411 %sgt.1 = icmp sgt i8 %len, 1412 call void @llvm.assume(i1 %sgt.1)413 %len.ext = zext i8 %len to i16414 %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext415 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -2416 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper417 call void @llvm.assume(i1 %cmp.sub.1)418 %cmp.idx.ult.len = icmp ult i8 %idx, %len419 call void @llvm.assume(i1 %cmp.idx.ult.len)420 %idx.ext = zext i8 %idx to i16421 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext422 %cmp.idx = icmp ult ptr %dst.add.idx, %upper423 ret i1 %cmp.idx424}425 426define i1 @gep_sub_1_ult_var_idx_lower_bound(ptr %lower, ptr %src, i8 %len) {427; CHECK-LABEL: @gep_sub_1_ult_var_idx_lower_bound(428; CHECK-NEXT: entry:429; CHECK-NEXT: [[SRC_UGE_LOWER:%.*]] = icmp uge ptr [[SRC:%.*]], [[LOWER:%.*]]430; CHECK-NEXT: call void @llvm.assume(i1 [[SRC_UGE_LOWER]])431; CHECK-NEXT: [[LEN_POS:%.*]] = icmp sge i8 [[LEN:%.*]], 0432; CHECK-NEXT: call void @llvm.assume(i1 [[LEN_POS]])433; CHECK-NEXT: [[GEP_LEN:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[LEN]]434; CHECK-NEXT: [[GEP_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[GEP_LEN]], i8 -1435; CHECK-NEXT: [[RES:%.*]] = icmp ult ptr [[GEP_SUB_1]], [[LOWER]]436; CHECK-NEXT: ret i1 [[RES]]437;438entry:439 %src.uge.lower = icmp uge ptr %src, %lower440 call void @llvm.assume(i1 %src.uge.lower)441 442 %len.pos = icmp sge i8 %len, 0443 call void @llvm.assume(i1 %len.pos)444 445 %gep.len = getelementptr inbounds i8, ptr %src, i8 %len446 %gep.sub.1 = getelementptr inbounds i8, ptr %gep.len, i8 -1447 %res = icmp ult ptr %gep.sub.1, %lower448 ret i1 %res449}450 451define i1 @gep_sub_1_ult_var_idx_lower_bound_len_ne_0(ptr %lower, ptr %src, i8 %len) {452; CHECK-LABEL: @gep_sub_1_ult_var_idx_lower_bound_len_ne_0(453; CHECK-NEXT: entry:454; CHECK-NEXT: [[LEN_NE_0:%.*]] = icmp ne i8 [[LEN:%.*]], 0455; CHECK-NEXT: call void @llvm.assume(i1 [[LEN_NE_0]])456; CHECK-NEXT: [[SRC_UGE_LOWER:%.*]] = icmp uge ptr [[SRC:%.*]], [[LOWER:%.*]]457; CHECK-NEXT: call void @llvm.assume(i1 [[SRC_UGE_LOWER]])458; CHECK-NEXT: [[LEN_POS:%.*]] = icmp sge i8 [[LEN]], 0459; CHECK-NEXT: call void @llvm.assume(i1 [[LEN_POS]])460; CHECK-NEXT: [[GEP_LEN:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[LEN]]461; CHECK-NEXT: [[GEP_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[GEP_LEN]], i8 -1462; CHECK-NEXT: ret i1 false463;464entry:465 %len.ne.0 = icmp ne i8 %len, 0466 call void @llvm.assume(i1 %len.ne.0)467 468 %src.uge.lower = icmp uge ptr %src, %lower469 call void @llvm.assume(i1 %src.uge.lower)470 471 %len.pos = icmp sge i8 %len, 0472 call void @llvm.assume(i1 %len.pos)473 474 %gep.len = getelementptr inbounds i8, ptr %src, i8 %len475 %gep.sub.1 = getelementptr inbounds i8, ptr %gep.len, i8 -1476 %res = icmp ult ptr %gep.sub.1, %lower477 ret i1 %res478}479 480define i1 @gep_sub_2_ult_var_idx_lower_bound_len_ne_0(ptr %lower, ptr %src, i8 %len) {481; CHECK-LABEL: @gep_sub_2_ult_var_idx_lower_bound_len_ne_0(482; CHECK-NEXT: entry:483; CHECK-NEXT: [[LEN_NE_0:%.*]] = icmp ne i8 [[LEN:%.*]], 0484; CHECK-NEXT: call void @llvm.assume(i1 [[LEN_NE_0]])485; CHECK-NEXT: [[SRC_UGE_LOWER:%.*]] = icmp uge ptr [[SRC:%.*]], [[LOWER:%.*]]486; CHECK-NEXT: call void @llvm.assume(i1 [[SRC_UGE_LOWER]])487; CHECK-NEXT: [[LEN_POS:%.*]] = icmp sge i8 [[LEN]], 0488; CHECK-NEXT: call void @llvm.assume(i1 [[LEN_POS]])489; CHECK-NEXT: [[GEP_LEN:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[LEN]]490; CHECK-NEXT: [[GEP_SUB_2:%.*]] = getelementptr inbounds i8, ptr [[GEP_LEN]], i8 -2491; CHECK-NEXT: [[RES:%.*]] = icmp ult ptr [[GEP_SUB_2]], [[LOWER]]492; CHECK-NEXT: ret i1 [[RES]]493;494entry:495 %len.ne.0 = icmp ne i8 %len, 0496 call void @llvm.assume(i1 %len.ne.0)497 498 %src.uge.lower = icmp uge ptr %src, %lower499 call void @llvm.assume(i1 %src.uge.lower)500 501 %len.pos = icmp sge i8 %len, 0502 call void @llvm.assume(i1 %len.pos)503 504 %gep.len = getelementptr inbounds i8, ptr %src, i8 %len505 %gep.sub.2 = getelementptr inbounds i8, ptr %gep.len, i8 -2506 %res = icmp ult ptr %gep.sub.2, %lower507 ret i1 %res508}509 510define i1 @gep_i16_sub_1_uge_inbounds(ptr %dst, ptr %lower) {511; CHECK-LABEL: @gep_i16_sub_1_uge_inbounds(512; CHECK-NEXT: [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]513; CHECK-NEXT: call void @llvm.assume(i1 [[PRE]])514; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3515; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -1516; CHECK-NEXT: [[DST_SUB_2:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -2517; CHECK-NEXT: [[RES_1:%.*]] = xor i1 false, true518; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -3519; CHECK-NEXT: [[CMP_SUB_3:%.*]] = icmp ule ptr [[DST_SUB_3]], [[LOWER]]520; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_3]]521; CHECK-NEXT: ret i1 [[RES_2]]522;523 %pre = icmp uge ptr %dst, %lower524 call void @llvm.assume(i1 %pre)525 %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3526 %dst.sub.1 = getelementptr inbounds i16, ptr %dst.add.3, i64 -1527 %cmp.sub.1 = icmp ule ptr %dst.sub.1, %lower528 %dst.sub.2 = getelementptr inbounds i16, ptr %dst.add.3, i64 -2529 %cmp.sub.2 = icmp ule ptr %dst.sub.2, %dst530 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.2531 %dst.sub.3 = getelementptr inbounds i16, ptr %dst.add.3, i64 -3532 %cmp.sub.3 = icmp ule ptr %dst.sub.3, %lower533 %res.2 = xor i1 %res.1, %cmp.sub.3534 ret i1 %res.2535}536 537define i1 @gep_i16_sub_1_uge_inbounds_var_idx(ptr %dst, i64 %off) {538; CHECK-LABEL: @gep_i16_sub_1_uge_inbounds_var_idx(539; CHECK-NEXT: [[OFF_UGE:%.*]] = icmp sge i64 [[OFF:%.*]], 1540; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_UGE]])541; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 [[OFF]]542; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i32 -1543; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp ule ptr [[DST_SUB_1]], [[DST]]544; CHECK-NEXT: [[DST_SUB_2:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -2545; CHECK-NEXT: [[CMP_SUB_2:%.*]] = icmp ule ptr [[DST_SUB_2]], [[DST]]546; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_SUB_1]], [[CMP_SUB_2]]547; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -3548; CHECK-NEXT: [[CMP_SUB_3:%.*]] = icmp ule ptr [[DST_SUB_3]], [[DST]]549; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_3]]550; CHECK-NEXT: ret i1 [[RES_2]]551;552 %off.uge = icmp sge i64 %off, 1553 call void @llvm.assume(i1 %off.uge)554 %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 %off555 %dst.sub.1 = getelementptr inbounds i16, ptr %dst.add.3, i32 -1556 %cmp.sub.1 = icmp ule ptr %dst.sub.1, %dst557 %dst.sub.2 = getelementptr inbounds i16, ptr %dst.add.3, i64 -2558 %cmp.sub.2 = icmp ule ptr %dst.sub.2, %dst559 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.2560 %dst.sub.3 = getelementptr inbounds i16, ptr %dst.add.3, i64 -3561 %cmp.sub.3 = icmp ule ptr %dst.sub.3, %dst562 %res.2 = xor i1 %res.1, %cmp.sub.3563 ret i1 %res.2564}565 566define i1 @gep_i32_two_indices_known_lt_and_positive(ptr %a, i8 %idx.1, i8 %idx.2) {567; CHECK-LABEL: @gep_i32_two_indices_known_lt_and_positive(568; CHECK-NEXT: [[LT:%.*]] = icmp ult i8 [[IDX_1:%.*]], [[IDX_2:%.*]]569; CHECK-NEXT: call void @llvm.assume(i1 [[LT]])570; CHECK-NEXT: [[IDX_1_POS:%.*]] = icmp sge i8 [[IDX_1]], 0571; CHECK-NEXT: [[IDX_2_POS:%.*]] = icmp sge i8 [[IDX_2]], 0572; CHECK-NEXT: call void @llvm.assume(i1 [[IDX_1_POS]])573; CHECK-NEXT: call void @llvm.assume(i1 [[IDX_2_POS]])574; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i8 [[IDX_1]]575; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i32, ptr [[GEP_1]], i8 -3576; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i8 [[IDX_2]]577; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, ptr [[GEP_3]], i8 -3578; CHECK-NEXT: ret i1 true579;580 %lt = icmp ult i8 %idx.1, %idx.2581 call void @llvm.assume(i1 %lt)582 %idx.1.pos = icmp sge i8 %idx.1, 0583 %idx.2.pos = icmp sge i8 %idx.2, 0584 call void @llvm.assume(i1 %idx.1.pos)585 call void @llvm.assume(i1 %idx.2.pos)586 %gep.1 = getelementptr inbounds i32, ptr %a, i8 %idx.1587 %gep.2 = getelementptr inbounds i32, ptr %gep.1, i8 -3588 %gep.3 = getelementptr inbounds i32, ptr %a, i8 %idx.2589 %gep.4 = getelementptr inbounds i32, ptr %gep.3, i8 -3590 %c = icmp ult ptr %gep.2, %gep.4591 ret i1 %c592}593 594define i1 @gep_i32_two_indices_known_lt_and_not_known_positive(ptr %a, i8 %idx.1, i8 %idx.2) {595; CHECK-LABEL: @gep_i32_two_indices_known_lt_and_not_known_positive(596; CHECK-NEXT: [[LT:%.*]] = icmp ult i8 [[IDX_1:%.*]], [[IDX_2:%.*]]597; CHECK-NEXT: call void @llvm.assume(i1 [[LT]])598; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i8 [[IDX_1]]599; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i32, ptr [[GEP_1]], i8 -3600; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i8 [[IDX_2]]601; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, ptr [[GEP_3]], i8 -3602; CHECK-NEXT: [[C:%.*]] = icmp ult ptr [[GEP_2]], [[GEP_4]]603; CHECK-NEXT: ret i1 [[C]]604;605 %lt = icmp ult i8 %idx.1, %idx.2606 call void @llvm.assume(i1 %lt)607 %gep.1 = getelementptr inbounds i32, ptr %a, i8 %idx.1608 %gep.2 = getelementptr inbounds i32, ptr %gep.1, i8 -3609 %gep.3 = getelementptr inbounds i32, ptr %a, i8 %idx.2610 %gep.4 = getelementptr inbounds i32, ptr %gep.3, i8 -3611 %c = icmp ult ptr %gep.2, %gep.4612 ret i1 %c613}614 615define i1 @gep_i32_two_indices_known_positive_but_not_lt(ptr %a, i8 %idx.1, i8 %idx.2) {616; CHECK-LABEL: @gep_i32_two_indices_known_positive_but_not_lt(617; CHECK-NEXT: [[IDX_1_POS:%.*]] = icmp sge i8 [[IDX_1:%.*]], 0618; CHECK-NEXT: [[IDX_2_POS:%.*]] = icmp sge i8 [[IDX_2:%.*]], 0619; CHECK-NEXT: call void @llvm.assume(i1 [[IDX_1_POS]])620; CHECK-NEXT: call void @llvm.assume(i1 [[IDX_2_POS]])621; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i8 [[IDX_1]]622; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i32, ptr [[GEP_1]], i8 -3623; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i8 [[IDX_2]]624; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, ptr [[GEP_3]], i8 -3625; CHECK-NEXT: [[C:%.*]] = icmp ult ptr [[GEP_2]], [[GEP_4]]626; CHECK-NEXT: ret i1 [[C]]627;628 %idx.1.pos = icmp sge i8 %idx.1, 0629 %idx.2.pos = icmp sge i8 %idx.2, 0630 call void @llvm.assume(i1 %idx.1.pos)631 call void @llvm.assume(i1 %idx.2.pos)632 %gep.1 = getelementptr inbounds i32, ptr %a, i8 %idx.1633 %gep.2 = getelementptr inbounds i32, ptr %gep.1, i8 -3634 %gep.3 = getelementptr inbounds i32, ptr %a, i8 %idx.2635 %gep.4 = getelementptr inbounds i32, ptr %gep.3, i8 -3636 %c = icmp ult ptr %gep.2, %gep.4637 ret i1 %c638}639