652 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s3 4define i32 @test.ult(ptr readonly %src, ptr readnone %min, ptr readnone %max) {5; CHECK-LABEL: @test.ult(6; CHECK-NEXT: check.0.min:7; CHECK-NEXT: [[C_MIN_0:%.*]] = icmp ult ptr [[SRC:%.*]], [[MIN:%.*]]8; CHECK-NEXT: br i1 [[C_MIN_0]], label [[TRAP:%.*]], label [[CHECK_0_MAX:%.*]]9; CHECK: trap:10; CHECK-NEXT: ret i32 1011; CHECK: check.0.max:12; CHECK-NEXT: [[C_MAX_0:%.*]] = icmp ult ptr [[SRC]], [[MAX:%.*]]13; CHECK-NEXT: br i1 [[C_MAX_0]], label [[CHECK_3_MIN:%.*]], label [[TRAP]]14; CHECK: check.3.min:15; CHECK-NEXT: [[L0:%.*]] = load i32, ptr [[SRC]], align 416; CHECK-NEXT: [[ADD_PTR_I36:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 317; CHECK-NEXT: br i1 false, label [[TRAP]], label [[CHECK_3_MAX:%.*]]18; CHECK: check.3.max:19; CHECK-NEXT: [[C_3_MAX:%.*]] = icmp ult ptr [[ADD_PTR_I36]], [[MAX]]20; CHECK-NEXT: br i1 [[C_3_MAX]], label [[CHECK_1_MIN:%.*]], label [[TRAP]]21; CHECK: check.1.min:22; CHECK-NEXT: [[L1:%.*]] = load i32, ptr [[ADD_PTR_I36]], align 423; CHECK-NEXT: [[ADD_PTR_I29:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 124; CHECK-NEXT: br i1 false, label [[TRAP]], label [[CHECK_1_MAX:%.*]]25; CHECK: check.1.max:26; CHECK-NEXT: br i1 true, label [[CHECK_2_MIN:%.*]], label [[TRAP]]27; CHECK: check.2.min:28; CHECK-NEXT: [[L2:%.*]] = load i32, ptr [[ADD_PTR_I29]], align 429; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 230; CHECK-NEXT: br i1 false, label [[TRAP]], label [[CHECK_2_MAX:%.*]]31; CHECK: check.2.max:32; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[TRAP]]33; CHECK: exit:34; CHECK-NEXT: [[L3:%.*]] = load i32, ptr [[ADD_PTR_I]], align 435; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[L1]], [[L0]]36; CHECK-NEXT: [[ADD8:%.*]] = add nsw i32 [[ADD]], [[L2]]37; CHECK-NEXT: [[ADD9:%.*]] = add nsw i32 [[ADD8]], [[L3]]38; CHECK-NEXT: ret i32 [[ADD9]]39;40check.0.min:41 %c.min.0 = icmp ult ptr %src, %min42 br i1 %c.min.0, label %trap, label %check.0.max43 44trap:45 ret i32 1046 47check.0.max:48 %c.max.0 = icmp ult ptr %src, %max49 br i1 %c.max.0, label %check.3.min, label %trap50 51check.3.min:52 %l0 = load i32, ptr %src, align 453 %add.ptr.i36 = getelementptr inbounds i32, ptr %src, i64 354 %c.3.min = icmp ult ptr %add.ptr.i36, %min55 br i1 %c.3.min, label %trap, label %check.3.max56 57check.3.max:58 %c.3.max = icmp ult ptr %add.ptr.i36, %max59 br i1 %c.3.max, label %check.1.min, label %trap60 61check.1.min:62 %l1 = load i32, ptr %add.ptr.i36, align 463 %add.ptr.i29 = getelementptr inbounds i32, ptr %src, i64 164 %c.1.min = icmp ult ptr %add.ptr.i29, %min65 br i1 %c.1.min, label %trap, label %check.1.max66 67check.1.max:68 %c.1.max = icmp ult ptr %add.ptr.i29, %max69 br i1 %c.1.max, label %check.2.min, label %trap70 71check.2.min:72 %l2 = load i32, ptr %add.ptr.i29, align 473 %add.ptr.i = getelementptr inbounds i32, ptr %src, i64 274 %c.2.min = icmp ult ptr %add.ptr.i, %min75 br i1 %c.2.min, label %trap, label %check.2.max76 77check.2.max:78 %c.2.max = icmp ult ptr %add.ptr.i, %max79 br i1 %c.2.max, label %exit, label %trap80 81exit:82 %l3 = load i32, ptr %add.ptr.i, align 483 %add = add nsw i32 %l1, %l084 %add8 = add nsw i32 %add, %l285 %add9 = add nsw i32 %add8, %l386 ret i32 %add987}88 89; Same as test.ult, but without inbounds.90define i32 @test.ult_no_inbounds(ptr readonly %src, ptr readnone %min, ptr readnone %max) {91; CHECK-LABEL: @test.ult_no_inbounds(92; CHECK-NEXT: check.0.min:93; CHECK-NEXT: [[C_MIN_0:%.*]] = icmp ult ptr [[SRC:%.*]], [[MIN:%.*]]94; CHECK-NEXT: br i1 [[C_MIN_0]], label [[TRAP:%.*]], label [[CHECK_0_MAX:%.*]]95; CHECK: trap:96; CHECK-NEXT: ret i32 1097; CHECK: check.0.max:98; CHECK-NEXT: [[C_MAX_0:%.*]] = icmp ult ptr [[SRC]], [[MAX:%.*]]99; CHECK-NEXT: br i1 [[C_MAX_0]], label [[CHECK_3_MIN:%.*]], label [[TRAP]]100; CHECK: check.3.min:101; CHECK-NEXT: [[L0:%.*]] = load i32, ptr [[SRC]], align 4102; CHECK-NEXT: [[ADD_PTR_I36:%.*]] = getelementptr i32, ptr [[SRC]], i64 3103; CHECK-NEXT: [[C_3_MIN:%.*]] = icmp ult ptr [[ADD_PTR_I36]], [[MIN]]104; CHECK-NEXT: br i1 [[C_3_MIN]], label [[TRAP]], label [[CHECK_3_MAX:%.*]]105; CHECK: check.3.max:106; CHECK-NEXT: [[C_3_MAX:%.*]] = icmp ult ptr [[ADD_PTR_I36]], [[MAX]]107; CHECK-NEXT: br i1 [[C_3_MAX]], label [[CHECK_1_MIN:%.*]], label [[TRAP]]108; CHECK: check.1.min:109; CHECK-NEXT: [[L1:%.*]] = load i32, ptr [[ADD_PTR_I36]], align 4110; CHECK-NEXT: [[ADD_PTR_I29:%.*]] = getelementptr i32, ptr [[SRC]], i64 1111; CHECK-NEXT: [[C_1_MIN:%.*]] = icmp ult ptr [[ADD_PTR_I29]], [[MIN]]112; CHECK-NEXT: br i1 [[C_1_MIN]], label [[TRAP]], label [[CHECK_1_MAX:%.*]]113; CHECK: check.1.max:114; CHECK-NEXT: [[C_1_MAX:%.*]] = icmp ult ptr [[ADD_PTR_I29]], [[MAX]]115; CHECK-NEXT: br i1 [[C_1_MAX]], label [[CHECK_2_MIN:%.*]], label [[TRAP]]116; CHECK: check.2.min:117; CHECK-NEXT: [[L2:%.*]] = load i32, ptr [[ADD_PTR_I29]], align 4118; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr i32, ptr [[SRC]], i64 2119; CHECK-NEXT: [[C_2_MIN:%.*]] = icmp ult ptr [[ADD_PTR_I]], [[MIN]]120; CHECK-NEXT: br i1 [[C_2_MIN]], label [[TRAP]], label [[CHECK_2_MAX:%.*]]121; CHECK: check.2.max:122; CHECK-NEXT: [[C_2_MAX:%.*]] = icmp ult ptr [[ADD_PTR_I]], [[MAX]]123; CHECK-NEXT: br i1 [[C_2_MAX]], label [[EXIT:%.*]], label [[TRAP]]124; CHECK: exit:125; CHECK-NEXT: [[L3:%.*]] = load i32, ptr [[ADD_PTR_I]], align 4126; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[L1]], [[L0]]127; CHECK-NEXT: [[ADD8:%.*]] = add nsw i32 [[ADD]], [[L2]]128; CHECK-NEXT: [[ADD9:%.*]] = add nsw i32 [[ADD8]], [[L3]]129; CHECK-NEXT: ret i32 [[ADD9]]130;131check.0.min:132 %c.min.0 = icmp ult ptr %src, %min133 br i1 %c.min.0, label %trap, label %check.0.max134 135trap:136 ret i32 10137 138check.0.max:139 %c.max.0 = icmp ult ptr %src, %max140 br i1 %c.max.0, label %check.3.min, label %trap141 142check.3.min:143 %l0 = load i32, ptr %src, align 4144 %add.ptr.i36 = getelementptr i32, ptr %src, i64 3145 %c.3.min = icmp ult ptr %add.ptr.i36, %min146 br i1 %c.3.min, label %trap, label %check.3.max147 148check.3.max:149 %c.3.max = icmp ult ptr %add.ptr.i36, %max150 br i1 %c.3.max, label %check.1.min, label %trap151 152check.1.min:153 %l1 = load i32, ptr %add.ptr.i36, align 4154 %add.ptr.i29 = getelementptr i32, ptr %src, i64 1155 %c.1.min = icmp ult ptr %add.ptr.i29, %min156 br i1 %c.1.min, label %trap, label %check.1.max157 158check.1.max:159 %c.1.max = icmp ult ptr %add.ptr.i29, %max160 br i1 %c.1.max, label %check.2.min, label %trap161 162check.2.min:163 %l2 = load i32, ptr %add.ptr.i29, align 4164 %add.ptr.i = getelementptr i32, ptr %src, i64 2165 %c.2.min = icmp ult ptr %add.ptr.i, %min166 br i1 %c.2.min, label %trap, label %check.2.max167 168check.2.max:169 %c.2.max = icmp ult ptr %add.ptr.i, %max170 br i1 %c.2.max, label %exit, label %trap171 172exit:173 %l3 = load i32, ptr %add.ptr.i, align 4174 %add = add nsw i32 %l1, %l0175 %add8 = add nsw i32 %add, %l2176 %add9 = add nsw i32 %add8, %l3177 ret i32 %add9178}179 180define void @test.not.uge.ult(ptr %start, ptr %low, ptr %high) {181; CHECK-LABEL: @test.not.uge.ult(182; CHECK-NEXT: entry:183; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i64 3184; CHECK-NEXT: [[C_1:%.*]] = icmp uge ptr [[ADD_PTR_I]], [[HIGH:%.*]]185; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]186; CHECK: if.then:187; CHECK-NEXT: ret void188; CHECK: if.end:189; CHECK-NEXT: call void @use(i1 true)190; CHECK-NEXT: [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1191; CHECK-NEXT: call void @use(i1 true)192; CHECK-NEXT: [[START_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 2193; CHECK-NEXT: call void @use(i1 true)194; CHECK-NEXT: [[START_3:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 3195; CHECK-NEXT: call void @use(i1 true)196; CHECK-NEXT: [[START_4:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 4197; CHECK-NEXT: [[C_4:%.*]] = icmp ult ptr [[START_4]], [[HIGH]]198; CHECK-NEXT: call void @use(i1 [[C_4]])199; CHECK-NEXT: ret void200;201entry:202 %add.ptr.i = getelementptr inbounds i8, ptr %start, i64 3203 %c.1 = icmp uge ptr %add.ptr.i, %high204 br i1 %c.1, label %if.then, label %if.end205 206if.then:207 ret void208 209if.end:210 %t.0 = icmp ult ptr %start, %high211 call void @use(i1 %t.0)212 %start.1 = getelementptr inbounds i8, ptr %start, i64 1213 %t.1 = icmp ult ptr %start.1, %high214 call void @use(i1 %t.1)215 %start.2 = getelementptr inbounds i8, ptr %start, i64 2216 %t.2 = icmp ult ptr %start.2, %high217 call void @use(i1 %t.2)218 %start.3 = getelementptr inbounds i8, ptr %start, i64 3219 %t.3 = icmp ult ptr %start.3, %high220 call void @use(i1 %t.3)221 %start.4 = getelementptr inbounds i8, ptr %start, i64 4222 %c.4 = icmp ult ptr %start.4, %high223 call void @use(i1 %c.4)224 ret void225}226 227; Same as test.not.uge.ult, but without inbounds GEPs.228define void @test.not.uge.ult_no_inbounds(ptr %start, ptr %low, ptr %high) {229; CHECK-LABEL: @test.not.uge.ult_no_inbounds(230; CHECK-NEXT: entry:231; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr i8, ptr [[START:%.*]], i64 3232; CHECK-NEXT: [[C_1:%.*]] = icmp uge ptr [[ADD_PTR_I]], [[HIGH:%.*]]233; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]234; CHECK: if.then:235; CHECK-NEXT: ret void236; CHECK: if.end:237; CHECK-NEXT: [[T_0:%.*]] = icmp ult ptr [[START]], [[HIGH]]238; CHECK-NEXT: call void @use(i1 [[T_0]])239; CHECK-NEXT: [[START_1:%.*]] = getelementptr i8, ptr [[START]], i64 1240; CHECK-NEXT: [[T_1:%.*]] = icmp ult ptr [[START_1]], [[HIGH]]241; CHECK-NEXT: call void @use(i1 [[T_1]])242; CHECK-NEXT: [[START_2:%.*]] = getelementptr i8, ptr [[START]], i64 2243; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[START_2]], [[HIGH]]244; CHECK-NEXT: call void @use(i1 [[T_2]])245; CHECK-NEXT: [[START_3:%.*]] = getelementptr i8, ptr [[START]], i64 3246; CHECK-NEXT: [[T_3:%.*]] = icmp ult ptr [[START_3]], [[HIGH]]247; CHECK-NEXT: call void @use(i1 [[T_3]])248; CHECK-NEXT: [[START_4:%.*]] = getelementptr i8, ptr [[START]], i64 4249; CHECK-NEXT: [[C_4:%.*]] = icmp ult ptr [[START_4]], [[HIGH]]250; CHECK-NEXT: call void @use(i1 [[C_4]])251; CHECK-NEXT: ret void252;253entry:254 %add.ptr.i = getelementptr i8, ptr %start, i64 3255 %c.1 = icmp uge ptr %add.ptr.i, %high256 br i1 %c.1, label %if.then, label %if.end257 258if.then:259 ret void260 261if.end:262 %t.0 = icmp ult ptr %start, %high263 call void @use(i1 %t.0)264 %start.1 = getelementptr i8, ptr %start, i64 1265 %t.1 = icmp ult ptr %start.1, %high266 call void @use(i1 %t.1)267 %start.2 = getelementptr i8, ptr %start, i64 2268 %t.2 = icmp ult ptr %start.2, %high269 call void @use(i1 %t.2)270 %start.3 = getelementptr i8, ptr %start, i64 3271 %t.3 = icmp ult ptr %start.3, %high272 call void @use(i1 %t.3)273 %start.4 = getelementptr i8, ptr %start, i64 4274 %c.4 = icmp ult ptr %start.4, %high275 call void @use(i1 %c.4)276 ret void277}278 279define void @test.not.uge.ule(ptr %start, ptr %low, ptr %high) {280; CHECK-LABEL: @test.not.uge.ule(281; CHECK-NEXT: entry:282; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i64 3283; CHECK-NEXT: [[C_1:%.*]] = icmp uge ptr [[ADD_PTR_I]], [[HIGH:%.*]]284; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]285; CHECK: if.then:286; CHECK-NEXT: ret void287; CHECK: if.end:288; CHECK-NEXT: call void @use(i1 true)289; CHECK-NEXT: [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1290; CHECK-NEXT: call void @use(i1 true)291; CHECK-NEXT: [[START_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 2292; CHECK-NEXT: call void @use(i1 true)293; CHECK-NEXT: [[START_3:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 3294; CHECK-NEXT: call void @use(i1 true)295; CHECK-NEXT: [[START_4:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 4296; CHECK-NEXT: call void @use(i1 true)297; CHECK-NEXT: [[START_5:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 5298; CHECK-NEXT: [[C_5:%.*]] = icmp ule ptr [[START_5]], [[HIGH]]299; CHECK-NEXT: call void @use(i1 [[C_5]])300; CHECK-NEXT: ret void301;302entry:303 %add.ptr.i = getelementptr inbounds i8, ptr %start, i64 3304 %c.1 = icmp uge ptr %add.ptr.i, %high305 br i1 %c.1, label %if.then, label %if.end306 307if.then:308 ret void309 310if.end:311 %t.0 = icmp ule ptr %start, %high312 call void @use(i1 %t.0)313 %start.1 = getelementptr inbounds i8, ptr %start, i64 1314 %t.1 = icmp ule ptr %start.1, %high315 call void @use(i1 %t.1)316 %start.2 = getelementptr inbounds i8, ptr %start, i64 2317 %t.2 = icmp ule ptr %start.2, %high318 call void @use(i1 %t.2)319 %start.3 = getelementptr inbounds i8, ptr %start, i64 3320 %t.3 = icmp ule ptr %start.3, %high321 call void @use(i1 %t.3)322 %start.4 = getelementptr inbounds i8, ptr %start, i64 4323 %t.4 = icmp ule ptr %start.4, %high324 call void @use(i1 %t.4)325 %start.5 = getelementptr inbounds i8, ptr %start, i64 5326 %c.5 = icmp ule ptr %start.5, %high327 call void @use(i1 %c.5)328 ret void329}330 331define void @test.not.uge.ugt(ptr %start, ptr %low, ptr %high) {332; CHECK-LABEL: @test.not.uge.ugt(333; CHECK-NEXT: entry:334; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i64 3335; CHECK-NEXT: [[C_1:%.*]] = icmp uge ptr [[ADD_PTR_I]], [[HIGH:%.*]]336; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]337; CHECK: if.then:338; CHECK-NEXT: ret void339; CHECK: if.end:340; CHECK-NEXT: call void @use(i1 false)341; CHECK-NEXT: [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1342; CHECK-NEXT: call void @use(i1 false)343; CHECK-NEXT: [[START_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 2344; CHECK-NEXT: call void @use(i1 false)345; CHECK-NEXT: [[START_3:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 3346; CHECK-NEXT: call void @use(i1 false)347; CHECK-NEXT: [[START_4:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 4348; CHECK-NEXT: call void @use(i1 false)349; CHECK-NEXT: [[START_5:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 5350; CHECK-NEXT: [[C_5:%.*]] = icmp ugt ptr [[START_5]], [[HIGH]]351; CHECK-NEXT: call void @use(i1 [[C_5]])352; CHECK-NEXT: ret void353;354entry:355 %add.ptr.i = getelementptr inbounds i8, ptr %start, i64 3356 %c.1 = icmp uge ptr %add.ptr.i, %high357 br i1 %c.1, label %if.then, label %if.end358 359if.then:360 ret void361 362if.end:363 %f.0 = icmp ugt ptr %start, %high364 call void @use(i1 %f.0)365 %start.1 = getelementptr inbounds i8, ptr %start, i64 1366 %f.1 = icmp ugt ptr %start.1, %high367 call void @use(i1 %f.1)368 %start.2 = getelementptr inbounds i8, ptr %start, i64 2369 %f.2 = icmp ugt ptr %start.2, %high370 call void @use(i1 %f.2)371 %start.3 = getelementptr inbounds i8, ptr %start, i64 3372 %f.3 = icmp ugt ptr %start.3, %high373 call void @use(i1 %f.3)374 %start.4 = getelementptr inbounds i8, ptr %start, i64 4375 %f.4 = icmp ugt ptr %start.4, %high376 call void @use(i1 %f.4)377 %start.5 = getelementptr inbounds i8, ptr %start, i64 5378 %c.5 = icmp ugt ptr %start.5, %high379 call void @use(i1 %c.5)380 ret void381}382 383define void @test.not.uge.uge(ptr %start, ptr %low, ptr %high) {384; CHECK-LABEL: @test.not.uge.uge(385; CHECK-NEXT: entry:386; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i64 3387; CHECK-NEXT: [[C_1:%.*]] = icmp uge ptr [[ADD_PTR_I]], [[HIGH:%.*]]388; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]389; CHECK: if.then:390; CHECK-NEXT: ret void391; CHECK: if.end:392; CHECK-NEXT: call void @use(i1 false)393; CHECK-NEXT: [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1394; CHECK-NEXT: call void @use(i1 false)395; CHECK-NEXT: [[START_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 2396; CHECK-NEXT: call void @use(i1 false)397; CHECK-NEXT: [[START_3:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 3398; CHECK-NEXT: call void @use(i1 false)399; CHECK-NEXT: [[START_4:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 4400; CHECK-NEXT: [[C_4:%.*]] = icmp uge ptr [[START_4]], [[HIGH]]401; CHECK-NEXT: call void @use(i1 [[C_4]])402; CHECK-NEXT: [[START_5:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 5403; CHECK-NEXT: [[C_5:%.*]] = icmp uge ptr [[START_5]], [[HIGH]]404; CHECK-NEXT: call void @use(i1 [[C_5]])405; CHECK-NEXT: ret void406;407entry:408 %add.ptr.i = getelementptr inbounds i8, ptr %start, i64 3409 %c.1 = icmp uge ptr %add.ptr.i, %high410 br i1 %c.1, label %if.then, label %if.end411 412if.then:413 ret void414 415if.end:416 %f.0 = icmp ugt ptr %start, %high417 call void @use(i1 %f.0)418 %start.1 = getelementptr inbounds i8, ptr %start, i64 1419 %f.1 = icmp uge ptr %start.1, %high420 call void @use(i1 %f.1)421 %start.2 = getelementptr inbounds i8, ptr %start, i64 2422 %f.2 = icmp uge ptr %start.2, %high423 call void @use(i1 %f.2)424 %start.3 = getelementptr inbounds i8, ptr %start, i64 3425 %f.3 = icmp uge ptr %start.3, %high426 call void @use(i1 %f.3)427 %start.4 = getelementptr inbounds i8, ptr %start, i64 4428 %c.4 = icmp uge ptr %start.4, %high429 call void @use(i1 %c.4)430 %start.5 = getelementptr inbounds i8, ptr %start, i64 5431 %c.5 = icmp uge ptr %start.5, %high432 call void @use(i1 %c.5)433 ret void434}435 436define void @test.not.uge.uge.nonconst(ptr %start, ptr %low, ptr %high, i8 %off) {437; CHECK-LABEL: @test.not.uge.uge.nonconst(438; CHECK-NEXT: entry:439; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i8 [[OFF:%.*]]440; CHECK-NEXT: [[C_1:%.*]] = icmp uge ptr [[ADD_PTR_I]], [[HIGH:%.*]]441; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]442; CHECK: if.then:443; CHECK-NEXT: [[START_OFF_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i8 [[OFF]]444; CHECK-NEXT: [[T_0:%.*]] = icmp uge ptr [[START_OFF_2]], [[HIGH]]445; CHECK-NEXT: call void @use(i1 [[T_0]])446; CHECK-NEXT: ret void447; CHECK: if.end:448; CHECK-NEXT: [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1449; CHECK-NEXT: [[C_0:%.*]] = icmp uge ptr [[START_1]], [[HIGH]]450; CHECK-NEXT: call void @use(i1 [[C_0]])451; CHECK-NEXT: [[START_OFF:%.*]] = getelementptr inbounds i8, ptr [[START]], i8 [[OFF]]452; CHECK-NEXT: [[F_0:%.*]] = icmp uge ptr [[START_OFF]], [[HIGH]]453; CHECK-NEXT: call void @use(i1 [[F_0]])454; CHECK-NEXT: ret void455;456entry:457 %add.ptr.i = getelementptr inbounds i8, ptr %start, i8 %off458 %c.1 = icmp uge ptr %add.ptr.i, %high459 br i1 %c.1, label %if.then, label %if.end460 461if.then:462 %start.off.2 = getelementptr inbounds i8, ptr %start, i8 %off463 %t.0 = icmp uge ptr %start.off.2, %high464 call void @use(i1 %t.0)465 ret void466 467if.end:468 %start.1 = getelementptr inbounds i8, ptr %start, i64 1469 %c.0 = icmp uge ptr %start.1, %high470 call void @use(i1 %c.0)471 %start.off = getelementptr inbounds i8, ptr %start, i8 %off472 %f.0 = icmp uge ptr %start.off, %high473 call void @use(i1 %f.0)474 ret void475}476 477; Test which requires decomposing GEP %ptr, SHL().478define void @test.ult.gep.shl(ptr readonly %src, ptr readnone %max, i8 %idx) {479; CHECK-LABEL: @test.ult.gep.shl(480; CHECK-NEXT: check.0.min:481; CHECK-NEXT: [[ADD_10:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i32 10482; CHECK-NEXT: [[C_ADD_10_MAX:%.*]] = icmp ugt ptr [[ADD_10]], [[MAX:%.*]]483; CHECK-NEXT: br i1 [[C_ADD_10_MAX]], label [[TRAP:%.*]], label [[CHECK_IDX:%.*]]484; CHECK: trap:485; CHECK-NEXT: ret void486; CHECK: check.idx:487; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[IDX:%.*]], 5488; CHECK-NEXT: br i1 [[CMP]], label [[CHECK_MAX:%.*]], label [[TRAP]]489; CHECK: check.max:490; CHECK-NEXT: [[IDX_SHL_1:%.*]] = shl nuw nsw i8 [[IDX]], 1491; CHECK-NEXT: [[ADD_PTR_SHL_1:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i8 [[IDX_SHL_1]]492; CHECK-NEXT: call void @use(i1 true)493; CHECK-NEXT: [[IDX_SHL_2:%.*]] = shl nuw i8 [[IDX]], 2494; CHECK-NEXT: [[ADD_PTR_SHL_2:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i8 [[IDX_SHL_2]]495; CHECK-NEXT: [[C_MAX_1:%.*]] = icmp ult ptr [[ADD_PTR_SHL_2]], [[MAX]]496; CHECK-NEXT: call void @use(i1 [[C_MAX_1]])497; CHECK-NEXT: [[IDX_SHL_NOT_NUW:%.*]] = shl i8 [[IDX]], 1498; CHECK-NEXT: [[ADD_PTR_SHL_NOT_NUW:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i8 [[IDX_SHL_NOT_NUW]]499; CHECK-NEXT: [[C_MAX_2:%.*]] = icmp ult ptr [[ADD_PTR_SHL_NOT_NUW]], [[MAX]]500; CHECK-NEXT: call void @use(i1 [[C_MAX_2]])501; CHECK-NEXT: [[IDX_SHL_3:%.*]] = shl nuw i8 [[IDX]], 3502; CHECK-NEXT: [[ADD_PTR_SHL_3:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i8 [[IDX_SHL_3]]503; CHECK-NEXT: [[C_MAX_3:%.*]] = icmp ult ptr [[ADD_PTR_SHL_3]], [[MAX]]504; CHECK-NEXT: call void @use(i1 [[C_MAX_3]])505; CHECK-NEXT: ret void506;507check.0.min:508 %add.10 = getelementptr inbounds i32, ptr %src, i32 10509 %c.add.10.max = icmp ugt ptr %add.10, %max510 br i1 %c.add.10.max, label %trap, label %check.idx511 512trap:513 ret void514 515check.idx:516 %cmp = icmp ult i8 %idx, 5517 br i1 %cmp, label %check.max, label %trap518 519check.max:520 %idx.shl.1 = shl nsw nuw i8 %idx, 1521 %add.ptr.shl.1 = getelementptr inbounds i32, ptr %src, i8 %idx.shl.1522 %c.max.0 = icmp ult ptr %add.ptr.shl.1, %max523 call void @use(i1 %c.max.0)524 %idx.shl.2 = shl nuw i8 %idx, 2525 %add.ptr.shl.2 = getelementptr inbounds i32, ptr %src, i8 %idx.shl.2526 %c.max.1 = icmp ult ptr %add.ptr.shl.2, %max527 call void @use(i1 %c.max.1)528 %idx.shl.not.nuw = shl i8 %idx, 1529 %add.ptr.shl.not.nuw = getelementptr inbounds i32, ptr %src, i8 %idx.shl.not.nuw530 %c.max.2 = icmp ult ptr %add.ptr.shl.not.nuw, %max531 call void @use(i1 %c.max.2)532 %idx.shl.3 = shl nuw i8 %idx, 3533 %add.ptr.shl.3 = getelementptr inbounds i32, ptr %src, i8 %idx.shl.3534 %c.max.3 = icmp ult ptr %add.ptr.shl.3, %max535 call void @use(i1 %c.max.3)536 ret void537}538 539; Test which requires decomposing GEP %ptr, ZEXT(SHL()).540define void @test.ult.gep.shl.zext(ptr readonly %src, ptr readnone %max, i32 %idx, i32 %j) {541; CHECK-LABEL: @test.ult.gep.shl.zext(542; CHECK-NEXT: check.0.min:543; CHECK-NEXT: [[ADD_10:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i32 10544; CHECK-NEXT: [[C_ADD_10_MAX:%.*]] = icmp ugt ptr [[ADD_10]], [[MAX:%.*]]545; CHECK-NEXT: br i1 [[C_ADD_10_MAX]], label [[TRAP:%.*]], label [[CHECK_IDX:%.*]]546; CHECK: trap:547; CHECK-NEXT: ret void548; CHECK: check.idx:549; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 5550; CHECK-NEXT: br i1 [[CMP]], label [[CHECK_MAX:%.*]], label [[TRAP]]551; CHECK: check.max:552; CHECK-NEXT: [[IDX_SHL:%.*]] = shl nuw i32 [[IDX]], 1553; CHECK-NEXT: [[EXT_1:%.*]] = zext i32 [[IDX_SHL]] to i64554; CHECK-NEXT: [[ADD_PTR_SHL:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[EXT_1]]555; CHECK-NEXT: call void @use(i1 true)556; CHECK-NEXT: [[IDX_SHL_NOT_NUW:%.*]] = shl i32 [[IDX]], 1557; CHECK-NEXT: [[EXT_2:%.*]] = zext i32 [[IDX_SHL_NOT_NUW]] to i64558; CHECK-NEXT: [[ADD_PTR_SHL_NOT_NUW:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[EXT_2]]559; CHECK-NEXT: [[C_MAX_1:%.*]] = icmp ult ptr [[ADD_PTR_SHL_NOT_NUW]], [[MAX]]560; CHECK-NEXT: call void @use(i1 [[C_MAX_1]])561; CHECK-NEXT: [[IDX_SHL_3:%.*]] = shl nuw i32 [[IDX]], 2562; CHECK-NEXT: [[EXT_3:%.*]] = zext i32 [[IDX_SHL_3]] to i64563; CHECK-NEXT: [[ADD_PTR_SHL_3:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[EXT_3]]564; CHECK-NEXT: [[C_MAX_2:%.*]] = icmp ult ptr [[ADD_PTR_SHL_3]], [[MAX]]565; CHECK-NEXT: call void @use(i1 [[C_MAX_2]])566; CHECK-NEXT: ret void567;568check.0.min:569 %add.10 = getelementptr inbounds i32, ptr %src, i32 10570 %c.add.10.max = icmp ugt ptr %add.10, %max571 br i1 %c.add.10.max, label %trap, label %check.idx572 573trap:574 ret void575 576check.idx:577 %cmp = icmp ult i32 %idx, 5578 br i1 %cmp, label %check.max, label %trap579 580check.max:581 %idx.shl = shl nuw i32 %idx, 1582 %ext.1 = zext i32 %idx.shl to i64583 %add.ptr.shl = getelementptr inbounds i32, ptr %src, i64 %ext.1584 %c.max.0 = icmp ult ptr %add.ptr.shl, %max585 call void @use(i1 %c.max.0)586 %idx.shl.not.nuw = shl i32 %idx, 1587 %ext.2 = zext i32 %idx.shl.not.nuw to i64588 %add.ptr.shl.not.nuw = getelementptr inbounds i32, ptr %src, i64 %ext.2589 %c.max.1 = icmp ult ptr %add.ptr.shl.not.nuw, %max590 call void @use(i1 %c.max.1)591 %idx.shl.3 = shl nuw i32 %idx, 2592 %ext.3 = zext i32 %idx.shl.3 to i64593 %add.ptr.shl.3 = getelementptr inbounds i32, ptr %src, i64 %ext.3594 %c.max.2 = icmp ult ptr %add.ptr.shl.3, %max595 call void @use(i1 %c.max.2)596 ret void597}598 599; Make sure non-constant shift amounts are handled correctly.600define i1 @test.ult.gep.shl.nonconst.zext(i16 %B, ptr readonly %src, ptr readnone %max, i16 %idx, i16 %j) {601; CHECK-LABEL: @test.ult.gep.shl.nonconst.zext(602; CHECK-NEXT: check.0.min:603; CHECK-NEXT: [[ADD_10:%.*]] = getelementptr inbounds i16, ptr [[SRC:%.*]], i16 10604; CHECK-NEXT: [[C_ADD_10_MAX:%.*]] = icmp ugt ptr [[ADD_10]], [[MAX:%.*]]605; CHECK-NEXT: br i1 [[C_ADD_10_MAX]], label [[EXIT_1:%.*]], label [[CHECK_IDX:%.*]]606; CHECK: exit.1:607; CHECK-NEXT: ret i1 true608; CHECK: check.idx:609; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[IDX:%.*]], 5610; CHECK-NEXT: br i1 [[CMP]], label [[CHECK_MAX:%.*]], label [[TRAP:%.*]]611; CHECK: check.max:612; CHECK-NEXT: [[IDX_SHL:%.*]] = shl nuw i16 [[IDX]], [[B:%.*]]613; CHECK-NEXT: [[EXT:%.*]] = zext i16 [[IDX_SHL]] to i64614; CHECK-NEXT: [[ADD_PTR_SHL:%.*]] = getelementptr inbounds i16, ptr [[SRC]], i64 [[EXT]]615; CHECK-NEXT: [[C_MAX:%.*]] = icmp ult ptr [[ADD_PTR_SHL]], [[MAX]]616; CHECK-NEXT: ret i1 [[C_MAX]]617; CHECK: trap:618; CHECK-NEXT: [[IDX_SHL_1:%.*]] = shl nuw i16 [[IDX]], [[B]]619; CHECK-NEXT: [[EXT_1:%.*]] = zext i16 [[IDX_SHL_1]] to i64620; CHECK-NEXT: [[ADD_PTR_SHL_1:%.*]] = getelementptr inbounds i16, ptr [[SRC]], i64 [[EXT_1]]621; CHECK-NEXT: [[C_MAX_1:%.*]] = icmp ult ptr [[ADD_PTR_SHL_1]], [[MAX]]622; CHECK-NEXT: ret i1 [[C_MAX_1]]623;624check.0.min:625 %add.10 = getelementptr inbounds i16, ptr %src, i16 10626 %c.add.10.max = icmp ugt ptr %add.10, %max627 br i1 %c.add.10.max, label %exit.1, label %check.idx628 629exit.1:630 ret i1 true631 632check.idx:633 %cmp = icmp ult i16 %idx, 5634 br i1 %cmp, label %check.max, label %trap635 636check.max:637 %idx.shl = shl nuw i16 %idx, %B638 %ext = zext i16 %idx.shl to i64639 %add.ptr.shl = getelementptr inbounds i16, ptr %src, i64 %ext640 %c.max = icmp ult ptr %add.ptr.shl, %max641 ret i1 %c.max642 643trap:644 %idx.shl.1 = shl nuw i16 %idx, %B645 %ext.1 = zext i16 %idx.shl.1 to i64646 %add.ptr.shl.1 = getelementptr inbounds i16, ptr %src, i64 %ext.1647 %c.max.1 = icmp ult ptr %add.ptr.shl.1, %max648 ret i1 %c.max.1649}650 651declare void @use(i1)652