1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 3 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 3 11; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -1 12; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -3 13; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true 14; CHECK-NEXT: [[DST_SUB_4:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -4 15; 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, %lower 20 call void @llvm.assume(i1 %pre) 21 %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3 22 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.3, i64 -1 23 %cmp.sub.1 = icmp uge ptr %dst.sub.1, %lower 24 %dst.sub.3 = getelementptr inbounds i8, ptr %dst.add.3, i64 -3 25 %cmp.sub.3 = icmp uge ptr %dst.sub.3, %lower 26 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.3 27 %dst.sub.4 = getelementptr inbounds i8, ptr %dst.add.3, i64 -4 28 %cmp.sub.4 = icmp uge ptr %dst.sub.4, %lower 29 %res.2 = xor i1 %res.1, %cmp.sub.4 30 ret i1 %res.2 31} 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 3 38; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -1 39; 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 -3 41; 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 -4 44; 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, %lower 49 call void @llvm.assume(i1 %pre) 50 %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3 51 %dst.sub.1 = getelementptr i8, ptr %dst.add.3, i64 -1 52 %cmp.sub.1 = icmp uge ptr %dst.sub.1, %lower 53 %dst.sub.3 = getelementptr i8, ptr %dst.add.3, i64 -3 54 %cmp.sub.3 = icmp uge ptr %dst.sub.3, %lower 55 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.3 56 %dst.sub.4 = getelementptr i8, ptr %dst.add.3, i64 -4 57 %cmp.sub.4 = icmp uge ptr %dst.sub.4, %lower 58 %res.2 = xor i1 %res.1, %cmp.sub.4 59 ret i1 %res.2 60} 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 3 67; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -1 68; 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 -3 70; 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 -4 73; 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, %lower 78 call void @llvm.assume(i1 %pre) 79 %dst.add.3 = getelementptr i8, ptr %dst, i64 3 80 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.3, i64 -1 81 %cmp.sub.1 = icmp uge ptr %dst.sub.1, %lower 82 %dst.sub.3 = getelementptr inbounds i8, ptr %dst.add.3, i64 -3 83 %cmp.sub.3 = icmp uge ptr %dst.sub.3, %lower 84 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.3 85 %dst.sub.4 = getelementptr inbounds i8, ptr %dst.add.3, i64 -4 86 %cmp.sub.4 = icmp uge ptr %dst.sub.4, %lower 87 %res.2 = xor i1 %res.1, %cmp.sub.4 88 ret i1 %res.2 89} 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 3 96; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -1 97; 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 -3 99; 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 -4 102; 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, %lower 107 call void @llvm.assume(i1 %pre) 108 %dst.add.3 = getelementptr i8, ptr %dst, i64 3 109 %dst.sub.1 = getelementptr i8, ptr %dst.add.3, i64 -1 110 %cmp.sub.1 = icmp uge ptr %dst.sub.1, %lower 111 %dst.sub.3 = getelementptr i8, ptr %dst.add.3, i64 -3 112 %cmp.sub.3 = icmp uge ptr %dst.sub.3, %lower 113 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.3 114 %dst.sub.4 = getelementptr i8, ptr %dst.add.3, i64 -4 115 %cmp.sub.4 = icmp uge ptr %dst.sub.4, %lower 116 %res.2 = xor i1 %res.1, %cmp.sub.4 117 ret i1 %res.2 118} 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 4 123; 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 3 126; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -1 127; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -3 128; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true 129; CHECK-NEXT: ret i1 [[RES_1]] 130; 131 %dst.add.4 = getelementptr inbounds i8, ptr %dst, i64 4 132 %pre = icmp ult ptr %dst.add.4, %upper 133 call void @llvm.assume(i1 %pre) 134 %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3 135 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.3, i64 -1 136 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper 137 %dst.sub.3 = getelementptr inbounds i8, ptr %dst.add.3, i64 -3 138 %cmp.sub.3 = icmp ult ptr %dst.sub.3, %upper 139 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.3 140 ret i1 %res.1 141} 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:%.*]], 0 146; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]]) 147; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16 148; 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 -1 152; CHECK-NEXT: [[DST_SUB_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -2 153; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true 154; CHECK-NEXT: [[DST_SUB_1_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_SUB_1]], i64 -1 155; 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, 0 162 call void @llvm.assume(i1 %not.zero) 163 %idx.ext = zext i8 %idx to i16 164 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext 165 %pre = icmp ult ptr %dst.add.idx, %upper 166 call void @llvm.assume(i1 %pre) 167 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -1 168 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper 169 %dst.sub.2 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -2 170 %cmp.sub.2 = icmp ult ptr %dst.sub.2, %upper 171 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.2 172 %dst.sub.1.sub.1 = getelementptr inbounds i8, ptr %dst.sub.1, i64 -1 173 %cmp.sub.1.sub.1 = icmp ult ptr %dst.sub.1.sub.1, %upper 174 %cmp.sub.1.sub.1.eq = icmp eq ptr %dst.sub.1.sub.1, %dst.sub.2 175 %res.2 = xor i1 %res.1, %cmp.sub.1.sub.1 176 %res.3 = xor i1 %res.2, %cmp.sub.1.sub.1.eq 177 ret i1 %res.3 178} 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:%.*]], 1 183; CHECK-NEXT: call void @llvm.assume(i1 [[SGT_1]]) 184; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16 185; 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 -1 189; CHECK-NEXT: [[DST_SUB_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -2 190; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true 191; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -3 192; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], true 193; CHECK-NEXT: ret i1 [[RES_2]] 194; 195 %sgt.1 = icmp sgt i8 %idx, 1 196 call void @llvm.assume(i1 %sgt.1) 197 %idx.ext = zext i8 %idx to i16 198 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext 199 %pre = icmp ult ptr %dst.add.idx, %upper 200 call void @llvm.assume(i1 %pre) 201 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -1 202 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper 203 %dst.sub.2 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -2 204 %cmp.sub.2 = icmp ult ptr %dst.sub.2, %upper 205 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.2 206 %dst.sub.3 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -3 207 %cmp.sub.3 = icmp ult ptr %dst.sub.3, %upper 208 %res.2 = xor i1 %res.1, %cmp.sub.3 209 ret i1 %res.2 210} 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:%.*]], 0 215; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]]) 216; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16 217; 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 -1 219; 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 i16 224; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]] 225; CHECK-NEXT: ret i1 true 226; 227 %not.zero = icmp ne i8 %len, 0 228 call void @llvm.assume(i1 %not.zero) 229 %len.ext = zext i8 %len to i16 230 %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext 231 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -1 232 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper 233 call void @llvm.assume(i1 %cmp.sub.1) 234 %cmp.idx.ult.len = icmp ult i8 %idx, %len 235 call void @llvm.assume(i1 %cmp.idx.ult.len) 236 %idx.ext = zext i8 %idx to i16 237 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext 238 %cmp.idx = icmp ult ptr %dst.add.idx, %upper 239 ret i1 %cmp.idx 240} 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:%.*]], 0 245; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]]) 246; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16 247; 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 -1 249; 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 i16 254; 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, 0 259 call void @llvm.assume(i1 %not.zero) 260 %len.ext = zext i8 %len to i16 261 %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext 262 %dst.sub.1 = getelementptr i8, ptr %dst.add.len, i64 -1 263 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper 264 call void @llvm.assume(i1 %cmp.sub.1) 265 %cmp.idx.ult.len = icmp ult i8 %idx, %len 266 call void @llvm.assume(i1 %cmp.idx.ult.len) 267 %idx.ext = zext i8 %idx to i16 268 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext 269 %cmp.idx = icmp ult ptr %dst.add.idx, %upper 270 ret i1 %cmp.idx 271} 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:%.*]], 0 276; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]]) 277; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16 278; 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 -1 280; 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 i16 285; 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, 0 290 call void @llvm.assume(i1 %not.zero) 291 %len.ext = zext i8 %len to i16 292 %dst.add.len = getelementptr i8, ptr %dst, i16 %len.ext 293 %dst.sub.1 = getelementptr i8, ptr %dst.add.len, i64 -1 294 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper 295 call void @llvm.assume(i1 %cmp.sub.1) 296 %cmp.idx.ult.len = icmp ult i8 %idx, %len 297 call void @llvm.assume(i1 %cmp.idx.ult.len) 298 %idx.ext = zext i8 %idx to i16 299 %dst.add.idx = getelementptr i8, ptr %dst, i16 %idx.ext 300 %cmp.idx = icmp ult ptr %dst.add.idx, %upper 301 ret i1 %cmp.idx 302} 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:%.*]], 0 307; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_ZERO]]) 308; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16 309; 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 -2 311; 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 i16 316; 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, 0 321 call void @llvm.assume(i1 %not.zero) 322 %len.ext = zext i8 %len to i16 323 %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext 324 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -2 325 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper 326 call void @llvm.assume(i1 %cmp.sub.1) 327 %cmp.idx.ult.len = icmp ult i8 %idx, %len 328 call void @llvm.assume(i1 %cmp.idx.ult.len) 329 %idx.ext = zext i8 %idx to i16 330 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext 331 %cmp.idx = icmp ult ptr %dst.add.idx, %upper 332 ret i1 %cmp.idx 333} 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:%.*]], 2 338; CHECK-NEXT: call void @llvm.assume(i1 [[SGE_2]]) 339; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16 340; 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 -1 342; 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 i16 347; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]] 348; CHECK-NEXT: ret i1 true 349; 350 %sge.2 = icmp sge i8 %len, 2 351 call void @llvm.assume(i1 %sge.2) 352 %len.ext = zext i8 %len to i16 353 %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext 354 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -1 355 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper 356 call void @llvm.assume(i1 %cmp.sub.1) 357 %cmp.idx.ult.len = icmp ult i8 %idx, %len 358 call void @llvm.assume(i1 %cmp.idx.ult.len) 359 %idx.ext = zext i8 %idx to i16 360 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext 361 %cmp.idx = icmp ult ptr %dst.add.idx, %upper 362 ret i1 %cmp.idx 363} 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:%.*]], 2 368; CHECK-NEXT: call void @llvm.assume(i1 [[UGE_2]]) 369; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16 370; 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 -1 372; 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 i16 377; CHECK-NEXT: [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]] 378; CHECK-NEXT: ret i1 true 379; 380 %uge.2 = icmp uge i8 %len, 2 381 call void @llvm.assume(i1 %uge.2) 382 %len.ext = zext i8 %len to i16 383 %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext 384 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -1 385 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper 386 call void @llvm.assume(i1 %cmp.sub.1) 387 %cmp.idx.ult.len = icmp ult i8 %idx, %len 388 call void @llvm.assume(i1 %cmp.idx.ult.len) 389 %idx.ext = zext i8 %idx to i16 390 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext 391 %cmp.idx = icmp ult ptr %dst.add.idx, %upper 392 ret i1 %cmp.idx 393} 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:%.*]], 1 398; CHECK-NEXT: call void @llvm.assume(i1 [[SGT_1]]) 399; CHECK-NEXT: [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16 400; 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 -2 402; 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 i16 407; 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, 1 412 call void @llvm.assume(i1 %sgt.1) 413 %len.ext = zext i8 %len to i16 414 %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext 415 %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -2 416 %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper 417 call void @llvm.assume(i1 %cmp.sub.1) 418 %cmp.idx.ult.len = icmp ult i8 %idx, %len 419 call void @llvm.assume(i1 %cmp.idx.ult.len) 420 %idx.ext = zext i8 %idx to i16 421 %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext 422 %cmp.idx = icmp ult ptr %dst.add.idx, %upper 423 ret i1 %cmp.idx 424} 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:%.*]], 0 432; 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 -1 435; 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, %lower 440 call void @llvm.assume(i1 %src.uge.lower) 441 442 %len.pos = icmp sge i8 %len, 0 443 call void @llvm.assume(i1 %len.pos) 444 445 %gep.len = getelementptr inbounds i8, ptr %src, i8 %len 446 %gep.sub.1 = getelementptr inbounds i8, ptr %gep.len, i8 -1 447 %res = icmp ult ptr %gep.sub.1, %lower 448 ret i1 %res 449} 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:%.*]], 0 455; 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]], 0 459; 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 -1 462; CHECK-NEXT: ret i1 false 463; 464entry: 465 %len.ne.0 = icmp ne i8 %len, 0 466 call void @llvm.assume(i1 %len.ne.0) 467 468 %src.uge.lower = icmp uge ptr %src, %lower 469 call void @llvm.assume(i1 %src.uge.lower) 470 471 %len.pos = icmp sge i8 %len, 0 472 call void @llvm.assume(i1 %len.pos) 473 474 %gep.len = getelementptr inbounds i8, ptr %src, i8 %len 475 %gep.sub.1 = getelementptr inbounds i8, ptr %gep.len, i8 -1 476 %res = icmp ult ptr %gep.sub.1, %lower 477 ret i1 %res 478} 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:%.*]], 0 484; 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]], 0 488; 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 -2 491; 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, 0 496 call void @llvm.assume(i1 %len.ne.0) 497 498 %src.uge.lower = icmp uge ptr %src, %lower 499 call void @llvm.assume(i1 %src.uge.lower) 500 501 %len.pos = icmp sge i8 %len, 0 502 call void @llvm.assume(i1 %len.pos) 503 504 %gep.len = getelementptr inbounds i8, ptr %src, i8 %len 505 %gep.sub.2 = getelementptr inbounds i8, ptr %gep.len, i8 -2 506 %res = icmp ult ptr %gep.sub.2, %lower 507 ret i1 %res 508} 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 3 515; CHECK-NEXT: [[DST_SUB_1:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -1 516; CHECK-NEXT: [[DST_SUB_2:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -2 517; CHECK-NEXT: [[RES_1:%.*]] = xor i1 false, true 518; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -3 519; 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, %lower 524 call void @llvm.assume(i1 %pre) 525 %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3 526 %dst.sub.1 = getelementptr inbounds i16, ptr %dst.add.3, i64 -1 527 %cmp.sub.1 = icmp ule ptr %dst.sub.1, %lower 528 %dst.sub.2 = getelementptr inbounds i16, ptr %dst.add.3, i64 -2 529 %cmp.sub.2 = icmp ule ptr %dst.sub.2, %dst 530 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.2 531 %dst.sub.3 = getelementptr inbounds i16, ptr %dst.add.3, i64 -3 532 %cmp.sub.3 = icmp ule ptr %dst.sub.3, %lower 533 %res.2 = xor i1 %res.1, %cmp.sub.3 534 ret i1 %res.2 535} 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:%.*]], 1 540; 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 -1 543; 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 -2 545; 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 -3 548; 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, 1 553 call void @llvm.assume(i1 %off.uge) 554 %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 %off 555 %dst.sub.1 = getelementptr inbounds i16, ptr %dst.add.3, i32 -1 556 %cmp.sub.1 = icmp ule ptr %dst.sub.1, %dst 557 %dst.sub.2 = getelementptr inbounds i16, ptr %dst.add.3, i64 -2 558 %cmp.sub.2 = icmp ule ptr %dst.sub.2, %dst 559 %res.1 = xor i1 %cmp.sub.1, %cmp.sub.2 560 %dst.sub.3 = getelementptr inbounds i16, ptr %dst.add.3, i64 -3 561 %cmp.sub.3 = icmp ule ptr %dst.sub.3, %dst 562 %res.2 = xor i1 %res.1, %cmp.sub.3 563 ret i1 %res.2 564} 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]], 0 571; CHECK-NEXT: [[IDX_2_POS:%.*]] = icmp sge i8 [[IDX_2]], 0 572; 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 -3 576; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i8 [[IDX_2]] 577; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, ptr [[GEP_3]], i8 -3 578; CHECK-NEXT: ret i1 true 579; 580 %lt = icmp ult i8 %idx.1, %idx.2 581 call void @llvm.assume(i1 %lt) 582 %idx.1.pos = icmp sge i8 %idx.1, 0 583 %idx.2.pos = icmp sge i8 %idx.2, 0 584 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.1 587 %gep.2 = getelementptr inbounds i32, ptr %gep.1, i8 -3 588 %gep.3 = getelementptr inbounds i32, ptr %a, i8 %idx.2 589 %gep.4 = getelementptr inbounds i32, ptr %gep.3, i8 -3 590 %c = icmp ult ptr %gep.2, %gep.4 591 ret i1 %c 592} 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 -3 600; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i8 [[IDX_2]] 601; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, ptr [[GEP_3]], i8 -3 602; 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.2 606 call void @llvm.assume(i1 %lt) 607 %gep.1 = getelementptr inbounds i32, ptr %a, i8 %idx.1 608 %gep.2 = getelementptr inbounds i32, ptr %gep.1, i8 -3 609 %gep.3 = getelementptr inbounds i32, ptr %a, i8 %idx.2 610 %gep.4 = getelementptr inbounds i32, ptr %gep.3, i8 -3 611 %c = icmp ult ptr %gep.2, %gep.4 612 ret i1 %c 613} 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:%.*]], 0 618; CHECK-NEXT: [[IDX_2_POS:%.*]] = icmp sge i8 [[IDX_2:%.*]], 0 619; 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 -3 623; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i8 [[IDX_2]] 624; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, ptr [[GEP_3]], i8 -3 625; 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, 0 629 %idx.2.pos = icmp sge i8 %idx.2, 0 630 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.1 633 %gep.2 = getelementptr inbounds i32, ptr %gep.1, i8 -3 634 %gep.3 = getelementptr inbounds i32, ptr %a, i8 %idx.2 635 %gep.4 = getelementptr inbounds i32, ptr %gep.3, i8 -3 636 %c = icmp ult ptr %gep.2, %gep.4 637 ret i1 %c 638} 639