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 @use(i1) 5declare void @llvm.assume(i1) 6 7define void @test.not.uge.ult(i8 %start, i8 %high) { 8; CHECK-LABEL: @test.not.uge.ult( 9; CHECK-NEXT: entry: 10; CHECK-NEXT: [[ADD_PTR_I:%.*]] = add nsw i8 [[START:%.*]], 3 11; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_PTR_I]], [[HIGH:%.*]] 12; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 13; CHECK: if.then: 14; CHECK-NEXT: ret void 15; CHECK: if.end: 16; CHECK-NEXT: [[T_0:%.*]] = icmp ult i8 [[START]], [[HIGH]] 17; CHECK-NEXT: call void @use(i1 [[T_0]]) 18; CHECK-NEXT: [[START_1:%.*]] = add nsw i8 [[START]], 1 19; CHECK-NEXT: [[T_1:%.*]] = icmp ult i8 [[START_1]], [[HIGH]] 20; CHECK-NEXT: call void @use(i1 [[T_1]]) 21; CHECK-NEXT: [[START_2:%.*]] = add nsw i8 [[START]], 2 22; CHECK-NEXT: [[T_2:%.*]] = icmp ult i8 [[START_2]], [[HIGH]] 23; CHECK-NEXT: call void @use(i1 [[T_2]]) 24; CHECK-NEXT: [[START_3:%.*]] = add nsw i8 [[START]], 3 25; CHECK-NEXT: [[T_3:%.*]] = icmp ult i8 [[START_3]], [[HIGH]] 26; CHECK-NEXT: call void @use(i1 [[T_3]]) 27; CHECK-NEXT: [[START_4:%.*]] = add nsw i8 [[START]], 4 28; CHECK-NEXT: [[C_4:%.*]] = icmp ult i8 [[START_4]], [[HIGH]] 29; CHECK-NEXT: call void @use(i1 [[C_4]]) 30; CHECK-NEXT: ret void 31; 32entry: 33 %add.ptr.i = add nsw i8 %start, 3 34 %c.1 = icmp uge i8 %add.ptr.i, %high 35 br i1 %c.1, label %if.then, label %if.end 36 37if.then: ; preds = %entry 38 ret void 39 40if.end: ; preds = %entry 41 %t.0 = icmp ult i8 %start, %high 42 call void @use(i1 %t.0) 43 %start.1 = add nsw i8 %start, 1 44 %t.1 = icmp ult i8 %start.1, %high 45 call void @use(i1 %t.1) 46 %start.2 = add nsw i8 %start, 2 47 %t.2 = icmp ult i8 %start.2, %high 48 call void @use(i1 %t.2) 49 %start.3 = add nsw i8 %start, 3 50 %t.3 = icmp ult i8 %start.3, %high 51 call void @use(i1 %t.3) 52 %start.4 = add nsw i8 %start, 4 53 %c.4 = icmp ult i8 %start.4, %high 54 call void @use(i1 %c.4) 55 ret void 56} 57 58define void @test.not.sge.slt(i8 %start, i8 %high) { 59; CHECK-LABEL: @test.not.sge.slt( 60; CHECK-NEXT: entry: 61; CHECK-NEXT: [[ADD_PTR_I:%.*]] = add nsw i8 [[START:%.*]], 3 62; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[ADD_PTR_I]], [[HIGH:%.*]] 63; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 64; CHECK: if.then: 65; CHECK-NEXT: ret void 66; CHECK: if.end: 67; CHECK-NEXT: call void @use(i1 true) 68; CHECK-NEXT: [[START_1:%.*]] = add nsw i8 [[START]], 1 69; CHECK-NEXT: call void @use(i1 true) 70; CHECK-NEXT: [[START_2:%.*]] = add nsw i8 [[START]], 2 71; CHECK-NEXT: call void @use(i1 true) 72; CHECK-NEXT: [[START_3:%.*]] = add nsw i8 [[START]], 3 73; CHECK-NEXT: call void @use(i1 true) 74; CHECK-NEXT: [[START_4:%.*]] = add nsw i8 [[START]], 4 75; CHECK-NEXT: [[C_4:%.*]] = icmp slt i8 [[START_4]], [[HIGH]] 76; CHECK-NEXT: call void @use(i1 [[C_4]]) 77; CHECK-NEXT: ret void 78; 79entry: 80 %add.ptr.i = add nsw i8 %start, 3 81 %c.1 = icmp sge i8 %add.ptr.i, %high 82 br i1 %c.1, label %if.then, label %if.end 83 84if.then: ; preds = %entry 85 ret void 86 87if.end: ; preds = %entry 88 %t.0 = icmp slt i8 %start, %high 89 call void @use(i1 %t.0) 90 %start.1 = add nsw i8 %start, 1 91 %t.1 = icmp slt i8 %start.1, %high 92 call void @use(i1 %t.1) 93 %start.2 = add nsw i8 %start, 2 94 %t.2 = icmp slt i8 %start.2, %high 95 call void @use(i1 %t.2) 96 %start.3 = add nsw i8 %start, 3 97 %t.3 = icmp slt i8 %start.3, %high 98 call void @use(i1 %t.3) 99 %start.4 = add nsw i8 %start, 4 100 %c.4 = icmp slt i8 %start.4, %high 101 call void @use(i1 %c.4) 102 ret void 103} 104 105define void @test.decompose.nonconst(i8 %a, i8 %b, i8 %c, i8 %d) { 106; CHECK-LABEL: @test.decompose.nonconst( 107; CHECK-NEXT: entry: 108; CHECK-NEXT: [[C_0:%.*]] = icmp sge i8 [[A:%.*]], [[C:%.*]] 109; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[C]] 110; CHECK-NEXT: [[AND_0:%.*]] = and i1 [[C_0]], [[C_1]] 111; CHECK-NEXT: br i1 [[AND_0]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 112; CHECK: if.then: 113; CHECK-NEXT: [[C_2:%.*]] = icmp sge i8 [[A]], 0 114; CHECK-NEXT: [[C_3:%.*]] = icmp sge i8 [[B]], 0 115; CHECK-NEXT: [[AND_1:%.*]] = and i1 [[C_2]], [[C_3]] 116; CHECK-NEXT: br i1 [[AND_1]], label [[IF_THEN_2:%.*]], label [[IF_END]] 117; CHECK: if.then.2: 118; CHECK-NEXT: [[ADD_0:%.*]] = add nsw i8 [[A]], [[B]] 119; CHECK-NEXT: call void @use(i1 true) 120; CHECK-NEXT: [[ADD_1:%.*]] = add nsw i8 [[A]], [[A]] 121; CHECK-NEXT: call void @use(i1 true) 122; CHECK-NEXT: [[ADD_2:%.*]] = add nsw i8 [[A]], [[D:%.*]] 123; CHECK-NEXT: [[C_4:%.*]] = icmp sge i8 [[ADD_2]], [[C]] 124; CHECK-NEXT: call void @use(i1 [[C_4]]) 125; CHECK-NEXT: ret void 126; CHECK: if.end: 127; CHECK-NEXT: ret void 128; 129entry: 130 %c.0 = icmp sge i8 %a, %c 131 %c.1 = icmp sge i8 %b, %c 132 %and.0 = and i1 %c.0, %c.1 133 br i1 %and.0, label %if.then, label %if.end 134 135if.then: ; preds = %entry 136 %c.2 = icmp sge i8 %a, 0 137 %c.3 = icmp sge i8 %b, 0 138 %and.1 = and i1 %c.2, %c.3 139 br i1 %and.1, label %if.then.2, label %if.end 140 141if.then.2: 142 %add.0 = add nsw i8 %a, %b 143 %t.0 = icmp sge i8 %add.0, %c 144 call void @use(i1 %t.0) 145 %add.1 = add nsw i8 %a, %a 146 %t.1 = icmp sge i8 %add.0, %c 147 call void @use(i1 %t.1) 148 %add.2 = add nsw i8 %a, %d 149 %c.4 = icmp sge i8 %add.2, %c 150 call void @use(i1 %c.4) 151 ret void 152 153if.end: ; preds = %entry 154 ret void 155} 156 157define void @test.decompose.nonconst.no.null.check(i8 %a, i8 %b, i8 %c, i8 %d) { 158; CHECK-LABEL: @test.decompose.nonconst.no.null.check( 159; CHECK-NEXT: entry: 160; CHECK-NEXT: [[C_0:%.*]] = icmp sge i8 [[A:%.*]], [[C:%.*]] 161; CHECK-NEXT: [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[C]] 162; CHECK-NEXT: [[AND_0:%.*]] = and i1 [[C_0]], [[C_1]] 163; CHECK-NEXT: br i1 [[AND_0]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 164; CHECK: if.then: 165; CHECK-NEXT: [[ADD_0:%.*]] = add nsw i8 [[A]], [[B]] 166; CHECK-NEXT: [[T_0:%.*]] = icmp sge i8 [[ADD_0]], [[C]] 167; CHECK-NEXT: call void @use(i1 [[T_0]]) 168; CHECK-NEXT: [[ADD_1:%.*]] = add nsw i8 [[A]], [[A]] 169; CHECK-NEXT: [[T_1:%.*]] = icmp sge i8 [[ADD_0]], [[C]] 170; CHECK-NEXT: call void @use(i1 [[T_1]]) 171; CHECK-NEXT: [[ADD_2:%.*]] = add nsw i8 [[A]], [[D:%.*]] 172; CHECK-NEXT: [[C_4:%.*]] = icmp sge i8 [[ADD_2]], [[C]] 173; CHECK-NEXT: call void @use(i1 [[C_4]]) 174; CHECK-NEXT: ret void 175; CHECK: if.end: 176; CHECK-NEXT: ret void 177; 178entry: 179 %c.0 = icmp sge i8 %a, %c 180 %c.1 = icmp sge i8 %b, %c 181 %and.0 = and i1 %c.0, %c.1 182 br i1 %and.0, label %if.then, label %if.end 183 184if.then: ; preds = %entry 185 %add.0 = add nsw i8 %a, %b 186 %t.0 = icmp sge i8 %add.0, %c 187 call void @use(i1 %t.0) 188 %add.1 = add nsw i8 %a, %a 189 %t.1 = icmp sge i8 %add.0, %c 190 call void @use(i1 %t.1) 191 %add.2 = add nsw i8 %a, %d 192 %c.4 = icmp sge i8 %add.2, %c 193 call void @use(i1 %c.4) 194 ret void 195 196if.end: ; preds = %entry 197 ret void 198} 199 200define void @test.sge.slt.add.neg(i8 %start, i8 %high) { 201; CHECK-LABEL: @test.sge.slt.add.neg( 202; CHECK-NEXT: entry: 203; CHECK-NEXT: [[ADD_PTR_I:%.*]] = add nsw i8 [[START:%.*]], -3 204; CHECK-NEXT: [[C_1:%.*]] = icmp slt i8 [[ADD_PTR_I]], [[HIGH:%.*]] 205; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 206; CHECK-NEXT: [[C_2:%.*]] = icmp slt i8 [[START]], [[HIGH]] 207; CHECK-NEXT: call void @use(i1 [[C_2]]) 208; CHECK-NEXT: [[START_1:%.*]] = add nsw i8 [[START]], 1 209; CHECK-NEXT: [[C_3:%.*]] = icmp slt i8 [[START_1]], [[HIGH]] 210; CHECK-NEXT: call void @use(i1 [[C_3]]) 211; CHECK-NEXT: [[START_2:%.*]] = add nsw i8 [[START]], -2 212; CHECK-NEXT: [[C_4:%.*]] = icmp slt i8 [[START_2]], [[HIGH]] 213; CHECK-NEXT: call void @use(i1 [[C_4]]) 214; CHECK-NEXT: [[START_3:%.*]] = add nsw i8 [[START]], -3 215; CHECK-NEXT: call void @use(i1 true) 216; CHECK-NEXT: [[START_4:%.*]] = add nsw i8 [[START]], -4 217; CHECK-NEXT: call void @use(i1 true) 218; CHECK-NEXT: ret void 219; 220entry: 221 %add.ptr.i = add nsw i8 %start, -3 222 %c.1 = icmp slt i8 %add.ptr.i, %high 223 call void @llvm.assume(i1 %c.1) 224 %c.2 = icmp slt i8 %start, %high 225 call void @use(i1 %c.2) 226 %start.1 = add nsw i8 %start, 1 227 %c.3 = icmp slt i8 %start.1, %high 228 call void @use(i1 %c.3) 229 %start.2 = add nsw i8 %start, -2 230 %c.4 = icmp slt i8 %start.2, %high 231 call void @use(i1 %c.4) 232 %start.3 = add nsw i8 %start, -3 233 %t.1 = icmp slt i8 %start.3, %high 234 call void @use(i1 %t.1) 235 %start.4 = add nsw i8 %start, -4 236 %t.2 = icmp slt i8 %start.4, %high 237 call void @use(i1 %t.2) 238 ret void 239} 240 241define i1 @test_ult_add_nsw_pos_1(i8 %start, i8 %high) { 242; CHECK-LABEL: @test_ult_add_nsw_pos_1( 243; CHECK-NEXT: entry: 244; CHECK-NEXT: [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16 245; CHECK-NEXT: [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16 246; CHECK-NEXT: [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3 247; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]] 248; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 249; CHECK-NEXT: ret i1 true 250; 251entry: 252 %high.ext = zext i8 %high to i16 253 %start.ext = zext i8 %start to i16 254 %add.ext = add nsw i16 %start.ext, 3 255 %c.1 = icmp ult i16 %add.ext, %high.ext 256 call void @llvm.assume(i1 %c.1) 257 258 %t = icmp ult i16 %start.ext, %high.ext 259 ret i1 %t 260} 261 262define i1 @test_ult_add_nsw_pos_1_assume_pos(i8 %start, i8 %high) { 263; CHECK-LABEL: @test_ult_add_nsw_pos_1_assume_pos( 264; CHECK-NEXT: entry: 265; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0 266; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]]) 267; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START]], 3 268; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]] 269; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 270; CHECK-NEXT: ret i1 true 271; 272entry: 273 %start.pos = icmp sge i8 %start, 0 274 call void @llvm.assume(i1 %start.pos) 275 %add = add nsw i8 %start, 3 276 %c.1 = icmp ult i8 %add, %high 277 call void @llvm.assume(i1 %c.1) 278 279 %t = icmp ult i8 %start, %high 280 ret i1 %t 281} 282 283define i1 @test_ult_add_nsw_pos_1_no_assume_pos(i8 %start, i8 %high) { 284; CHECK-LABEL: @test_ult_add_nsw_pos_1_no_assume_pos( 285; CHECK-NEXT: entry: 286; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START:%.*]], 3 287; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]] 288; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 289; CHECK-NEXT: [[T:%.*]] = icmp ult i8 [[START]], [[HIGH]] 290; CHECK-NEXT: ret i1 [[T]] 291; 292entry: 293 %add = add nsw i8 %start, 3 294 %c.1 = icmp ult i8 %add, %high 295 call void @llvm.assume(i1 %c.1) 296 297 %t = icmp ult i8 %start, %high 298 ret i1 %t 299} 300 301define i1 @test_ult_add_nsw_pos_1_cmp_no_ext(i8 %start, i8 %high) { 302; CHECK-LABEL: @test_ult_add_nsw_pos_1_cmp_no_ext( 303; CHECK-NEXT: entry: 304; CHECK-NEXT: [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16 305; CHECK-NEXT: [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16 306; CHECK-NEXT: [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3 307; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]] 308; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 309; CHECK-NEXT: ret i1 true 310; 311entry: 312 %high.ext = zext i8 %high to i16 313 %start.ext = zext i8 %start to i16 314 %add.ext = add nsw i16 %start.ext, 3 315 %c.1 = icmp ult i16 %add.ext, %high.ext 316 call void @llvm.assume(i1 %c.1) 317 318 %t = icmp ult i8 %start, %high 319 ret i1 %t 320} 321 322define i1 @test_ult_add_nsw_pos_2(i8 %start, i8 %high) { 323; CHECK-LABEL: @test_ult_add_nsw_pos_2( 324; CHECK-NEXT: entry: 325; CHECK-NEXT: [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16 326; CHECK-NEXT: [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16 327; CHECK-NEXT: [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3 328; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]] 329; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 330; CHECK-NEXT: ret i1 false 331; 332entry: 333 %high.ext = zext i8 %high to i16 334 %start.ext = zext i8 %start to i16 335 %add.ext = add nsw i16 %start.ext, 3 336 %c.1 = icmp ult i16 %add.ext, %high.ext 337 call void @llvm.assume(i1 %c.1) 338 339 %f = icmp uge i16 %start.ext, %high.ext 340 ret i1 %f 341} 342 343define i1 @test_ult_add_nsw_pos_2_assume_pos(i8 %start, i8 %high) { 344; CHECK-LABEL: @test_ult_add_nsw_pos_2_assume_pos( 345; CHECK-NEXT: entry: 346; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0 347; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]]) 348; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START]], 3 349; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]] 350; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 351; CHECK-NEXT: ret i1 false 352; 353entry: 354 %start.pos = icmp sge i8 %start, 0 355 call void @llvm.assume(i1 %start.pos) 356 %add = add nsw i8 %start, 3 357 %c.1 = icmp ult i8 %add, %high 358 call void @llvm.assume(i1 %c.1) 359 360 %f = icmp uge i8 %start, %high 361 ret i1 %f 362} 363 364define i1 @test_ult_add_nsw_pos_2_cmp_no_ext(i8 %start, i8 %high) { 365; CHECK-LABEL: @test_ult_add_nsw_pos_2_cmp_no_ext( 366; CHECK-NEXT: entry: 367; CHECK-NEXT: [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16 368; CHECK-NEXT: [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16 369; CHECK-NEXT: [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3 370; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]] 371; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 372; CHECK-NEXT: ret i1 false 373; 374entry: 375 %high.ext = zext i8 %high to i16 376 %start.ext = zext i8 %start to i16 377 %add.ext = add nsw i16 %start.ext, 3 378 %c.1 = icmp ult i16 %add.ext, %high.ext 379 call void @llvm.assume(i1 %c.1) 380 381 %c = icmp uge i8 %start, %high 382 ret i1 %c 383} 384 385define i1 @test_ult_add_nsw_pos_3(i8 %start, i8 %high) { 386; CHECK-LABEL: @test_ult_add_nsw_pos_3( 387; CHECK-NEXT: entry: 388; CHECK-NEXT: [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16 389; CHECK-NEXT: [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16 390; CHECK-NEXT: [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3 391; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]] 392; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 393; CHECK-NEXT: [[ADD_4:%.*]] = add nsw i16 [[START_EXT]], 4 394; CHECK-NEXT: [[C:%.*]] = icmp ult i16 [[ADD_4]], [[HIGH_EXT]] 395; CHECK-NEXT: ret i1 [[C]] 396; 397entry: 398 %high.ext = zext i8 %high to i16 399 %start.ext = zext i8 %start to i16 400 %add.ext = add nsw i16 %start.ext, 3 401 %c.1 = icmp ult i16 %add.ext, %high.ext 402 call void @llvm.assume(i1 %c.1) 403 404 %add.4 = add nsw i16 %start.ext, 4 405 %c = icmp ult i16 %add.4, %high.ext 406 ret i1 %c 407} 408 409define i1 @test_ult_add_nsw_pos_3_assume_pos(i8 %start, i8 %high) { 410; CHECK-LABEL: @test_ult_add_nsw_pos_3_assume_pos( 411; CHECK-NEXT: entry: 412; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0 413; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]]) 414; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START]], 3 415; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]] 416; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 417; CHECK-NEXT: [[ADD_4:%.*]] = add nsw i8 [[START]], 4 418; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[ADD_4]], [[HIGH]] 419; CHECK-NEXT: ret i1 [[C]] 420; 421entry: 422 %start.pos = icmp sge i8 %start, 0 423 call void @llvm.assume(i1 %start.pos) 424 %add = add nsw i8 %start, 3 425 %c.1 = icmp ult i8 %add, %high 426 call void @llvm.assume(i1 %c.1) 427 428 %add.4 = add nsw i8 %start, 4 429 %c = icmp ult i8 %add.4, %high 430 ret i1 %c 431} 432 433define i1 @test_ult_add_nsw_pos_4(i8 %start, i8 %high) { 434; CHECK-LABEL: @test_ult_add_nsw_pos_4( 435; CHECK-NEXT: entry: 436; CHECK-NEXT: [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16 437; CHECK-NEXT: [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16 438; CHECK-NEXT: [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3 439; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]] 440; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 441; CHECK-NEXT: [[ADD_2:%.*]] = add nsw i16 [[START_EXT]], 2 442; CHECK-NEXT: ret i1 true 443; 444entry: 445 %high.ext = zext i8 %high to i16 446 %start.ext = zext i8 %start to i16 447 %add.ext = add nsw i16 %start.ext, 3 448 %c.1 = icmp ult i16 %add.ext, %high.ext 449 call void @llvm.assume(i1 %c.1) 450 451 %add.2 = add nsw i16 %start.ext, 2 452 %c = icmp ult i16 %add.2, %high.ext 453 ret i1 %c 454} 455 456define i1 @test_ult_add_nsw_pos_4_assume_pos(i8 %start, i8 %high) { 457; CHECK-LABEL: @test_ult_add_nsw_pos_4_assume_pos( 458; CHECK-NEXT: entry: 459; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0 460; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]]) 461; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START]], 3 462; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]] 463; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 464; CHECK-NEXT: [[ADD_2:%.*]] = add nsw i8 [[START]], 2 465; CHECK-NEXT: ret i1 true 466; 467entry: 468 %start.pos = icmp sge i8 %start, 0 469 call void @llvm.assume(i1 %start.pos) 470 %add = add nsw i8 %start, 3 471 %c.1 = icmp ult i8 %add, %high 472 call void @llvm.assume(i1 %c.1) 473 474 %add.2 = add nsw i8 %start, 2 475 %c = icmp ult i8 %add.2, %high 476 ret i1 %c 477} 478 479define i1 @test_ult_add_nsw_neg_5(i8 %start, i8 %high) { 480; CHECK-LABEL: @test_ult_add_nsw_neg_5( 481; CHECK-NEXT: entry: 482; CHECK-NEXT: [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16 483; CHECK-NEXT: [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16 484; CHECK-NEXT: [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3 485; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]] 486; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 487; CHECK-NEXT: [[SUB_2:%.*]] = add nsw i16 [[START_EXT]], -2 488; CHECK-NEXT: [[C:%.*]] = icmp ult i16 [[SUB_2]], [[HIGH_EXT]] 489; CHECK-NEXT: ret i1 [[C]] 490; 491entry: 492 %high.ext = zext i8 %high to i16 493 %start.ext = zext i8 %start to i16 494 %add.ext = add nsw i16 %start.ext, 3 495 %c.1 = icmp ult i16 %add.ext, %high.ext 496 call void @llvm.assume(i1 %c.1) 497 498 %sub.2 = add nsw i16 %start.ext, -2 499 %c = icmp ult i16 %sub.2, %high.ext 500 ret i1 %c 501} 502 503define i1 @test_ult_add_nsw_neg_5_assume_pos(i8 %start, i8 %high) { 504; CHECK-LABEL: @test_ult_add_nsw_neg_5_assume_pos( 505; CHECK-NEXT: entry: 506; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0 507; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]]) 508; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START]], 3 509; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]] 510; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 511; CHECK-NEXT: [[SUB_2:%.*]] = add nsw i8 [[START]], -2 512; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[SUB_2]], [[HIGH]] 513; CHECK-NEXT: ret i1 [[C]] 514; 515entry: 516 %start.pos = icmp sge i8 %start, 0 517 call void @llvm.assume(i1 %start.pos) 518 %add = add nsw i8 %start, 3 519 %c.1 = icmp ult i8 %add, %high 520 call void @llvm.assume(i1 %c.1) 521 522 %sub.2 = add nsw i8 %start, -2 523 %c = icmp ult i8 %sub.2, %high 524 ret i1 %c 525} 526 527define i1 @test_ult_add_no_nsw_pos_6(i8 %start, i8 %high) { 528; CHECK-LABEL: @test_ult_add_no_nsw_pos_6( 529; CHECK-NEXT: entry: 530; CHECK-NEXT: [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16 531; CHECK-NEXT: [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16 532; CHECK-NEXT: [[ADD_EXT:%.*]] = add i16 [[START_EXT]], 3 533; CHECK-NEXT: [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]] 534; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 535; CHECK-NEXT: [[ADD_2:%.*]] = add i16 [[START_EXT]], 2 536; CHECK-NEXT: [[C:%.*]] = icmp ult i16 [[ADD_2]], [[HIGH_EXT]] 537; CHECK-NEXT: ret i1 [[C]] 538; 539entry: 540 %high.ext = zext i8 %high to i16 541 %start.ext = zext i8 %start to i16 542 %add.ext = add i16 %start.ext, 3 543 %c.1 = icmp ult i16 %add.ext, %high.ext 544 call void @llvm.assume(i1 %c.1) 545 546 %add.2 = add i16 %start.ext, 2 547 %c = icmp ult i16 %add.2, %high.ext 548 ret i1 %c 549} 550 551define i1 @test_ult_add_no_nsw_pos_6_assume_pos(i8 %start, i8 %high) { 552; CHECK-LABEL: @test_ult_add_no_nsw_pos_6_assume_pos( 553; CHECK-NEXT: entry: 554; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0 555; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]]) 556; CHECK-NEXT: [[ADD:%.*]] = add i8 [[START]], 3 557; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]] 558; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 559; CHECK-NEXT: [[ADD_2:%.*]] = add i8 [[START]], 2 560; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[ADD_2]], [[HIGH]] 561; CHECK-NEXT: ret i1 [[C]] 562; 563entry: 564 %start.pos = icmp sge i8 %start, 0 565 call void @llvm.assume(i1 %start.pos) 566 %add = add i8 %start, 3 567 %c.1 = icmp ult i8 %add, %high 568 call void @llvm.assume(i1 %c.1) 569 570 %add.2 = add i8 %start, 2 571 %c = icmp ult i8 %add.2, %high 572 ret i1 %c 573} 574 575define i1 @test_ult_add_nsw_var_7(i8 %start, i8 %off, i8 %high) { 576; CHECK-LABEL: @test_ult_add_nsw_var_7( 577; CHECK-NEXT: entry: 578; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START:%.*]], [[OFF:%.*]] 579; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]] 580; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 581; CHECK-NEXT: [[OFF_POS:%.*]] = icmp sge i8 [[OFF]], 0 582; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_POS]]) 583; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[START]], [[HIGH]] 584; CHECK-NEXT: ret i1 [[C]] 585; 586entry: 587 %add = add nsw i8 %start, %off 588 %c.1 = icmp ult i8 %add, %high 589 call void @llvm.assume(i1 %c.1) 590 %off.pos = icmp sge i8 %off, 0 591 call void @llvm.assume(i1 %off.pos) 592 593 %c = icmp ult i8 %start, %high 594 ret i1 %c 595} 596 597define i1 @test_ult_add_no_nsw_var_7(i8 %start, i8 %off, i8 %high) { 598; CHECK-LABEL: @test_ult_add_no_nsw_var_7( 599; CHECK-NEXT: entry: 600; CHECK-NEXT: [[ADD:%.*]] = add i8 [[START:%.*]], [[OFF:%.*]] 601; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]] 602; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 603; CHECK-NEXT: [[OFF_POS:%.*]] = icmp sge i8 [[OFF]], 0 604; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_POS]]) 605; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[START]], [[HIGH]] 606; CHECK-NEXT: ret i1 [[C]] 607; 608entry: 609 %add = add i8 %start, %off 610 %c.1 = icmp ult i8 %add, %high 611 call void @llvm.assume(i1 %c.1) 612 %off.pos = icmp sge i8 %off, 0 613 call void @llvm.assume(i1 %off.pos) 614 615 %c = icmp ult i8 %start, %high 616 ret i1 %c 617} 618 619define i1 @test_ult_add_nsw_var_8(i8 %start, i8 %off.1, i8 %off.2, i8 %high) { 620; CHECK-LABEL: @test_ult_add_nsw_var_8( 621; CHECK-NEXT: entry: 622; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START:%.*]], [[OFF_2:%.*]] 623; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]] 624; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 625; CHECK-NEXT: [[OFF_1_POS:%.*]] = icmp sge i8 [[OFF_1:%.*]], 0 626; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_POS]]) 627; CHECK-NEXT: [[OFF_2_POS:%.*]] = icmp sge i8 [[OFF_2]], 0 628; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_2_POS]]) 629; CHECK-NEXT: [[OFF_1_ULT:%.*]] = icmp ult i8 [[OFF_1]], [[OFF_2]] 630; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_ULT]]) 631; CHECK-NEXT: [[ADD_OFF_2:%.*]] = add nsw i8 [[START]], [[OFF_1]] 632; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[ADD_OFF_2]], [[HIGH]] 633; CHECK-NEXT: ret i1 [[C]] 634; 635entry: 636 %add = add nsw i8 %start, %off.2 637 %c.1 = icmp ult i8 %add, %high 638 call void @llvm.assume(i1 %c.1) 639 %off.1.pos = icmp sge i8 %off.1, 0 640 call void @llvm.assume(i1 %off.1.pos) 641 %off.2.pos = icmp sge i8 %off.2, 0 642 call void @llvm.assume(i1 %off.2.pos) 643 %off.1.ult = icmp ult i8 %off.1, %off.2 644 call void @llvm.assume(i1 %off.1.ult) 645 646 %add.off.2 = add nsw i8 %start, %off.1 647 %c = icmp ult i8 %add.off.2, %high 648 ret i1 %c 649} 650 651define i1 @test_ult_add_nsw_var_8_all_pos(i8 %start, i8 %off.1, i8 %off.2, i8 %high) { 652; CHECK-LABEL: @test_ult_add_nsw_var_8_all_pos( 653; CHECK-NEXT: entry: 654; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0 655; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]]) 656; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START]], [[OFF_2:%.*]] 657; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]] 658; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 659; CHECK-NEXT: [[OFF_1_POS:%.*]] = icmp sge i8 [[OFF_1:%.*]], 0 660; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_POS]]) 661; CHECK-NEXT: [[OFF_2_POS:%.*]] = icmp sge i8 [[OFF_2]], 0 662; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_2_POS]]) 663; CHECK-NEXT: [[OFF_1_ULT:%.*]] = icmp ult i8 [[OFF_1]], [[OFF_2]] 664; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_ULT]]) 665; CHECK-NEXT: [[ADD_OFF_2:%.*]] = add nsw i8 [[START]], [[OFF_1]] 666; CHECK-NEXT: ret i1 true 667; 668entry: 669 %start.pos = icmp sge i8 %start, 0 670 call void @llvm.assume(i1 %start.pos) 671 %add = add nsw i8 %start, %off.2 672 %c.1 = icmp ult i8 %add, %high 673 call void @llvm.assume(i1 %c.1) 674 %off.1.pos = icmp sge i8 %off.1, 0 675 call void @llvm.assume(i1 %off.1.pos) 676 %off.2.pos = icmp sge i8 %off.2, 0 677 call void @llvm.assume(i1 %off.2.pos) 678 %off.1.ult = icmp ult i8 %off.1, %off.2 679 call void @llvm.assume(i1 %off.1.ult) 680 681 %add.off.2 = add nsw i8 %start, %off.1 682 %c = icmp ult i8 %add.off.2, %high 683 ret i1 %c 684} 685 686define i1 @test_ult_add_no_nsw_var_8_all_pos(i8 %start, i8 %off.1, i8 %off.2, i8 %high) { 687; CHECK-LABEL: @test_ult_add_no_nsw_var_8_all_pos( 688; CHECK-NEXT: entry: 689; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0 690; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]]) 691; CHECK-NEXT: [[ADD:%.*]] = add i8 [[START]], [[OFF_2:%.*]] 692; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]] 693; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 694; CHECK-NEXT: [[OFF_1_POS:%.*]] = icmp sge i8 [[OFF_1:%.*]], 0 695; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_POS]]) 696; CHECK-NEXT: [[OFF_2_POS:%.*]] = icmp sge i8 [[OFF_2]], 0 697; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_2_POS]]) 698; CHECK-NEXT: [[OFF_1_ULT:%.*]] = icmp ult i8 [[OFF_1]], [[OFF_2]] 699; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_ULT]]) 700; CHECK-NEXT: [[ADD_OFF_2:%.*]] = add nsw i8 [[START]], [[OFF_1]] 701; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[ADD_OFF_2]], [[HIGH]] 702; CHECK-NEXT: ret i1 [[C]] 703; 704entry: 705 %start.pos = icmp sge i8 %start, 0 706 call void @llvm.assume(i1 %start.pos) 707 %add = add i8 %start, %off.2 708 %c.1 = icmp ult i8 %add, %high 709 call void @llvm.assume(i1 %c.1) 710 %off.1.pos = icmp sge i8 %off.1, 0 711 call void @llvm.assume(i1 %off.1.pos) 712 %off.2.pos = icmp sge i8 %off.2, 0 713 call void @llvm.assume(i1 %off.2.pos) 714 %off.1.ult = icmp ult i8 %off.1, %off.2 715 call void @llvm.assume(i1 %off.1.ult) 716 717 %add.off.2 = add nsw i8 %start, %off.1 718 %c = icmp ult i8 %add.off.2, %high 719 ret i1 %c 720} 721 722define i1 @test_ult_add_nsw_var_9_all_pos(i8 %start, i8 %off.1, i8 %off.2, i8 %high) { 723; CHECK-LABEL: @test_ult_add_nsw_var_9_all_pos( 724; CHECK-NEXT: entry: 725; CHECK-NEXT: [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0 726; CHECK-NEXT: call void @llvm.assume(i1 [[START_POS]]) 727; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[START]], [[OFF_2:%.*]] 728; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]] 729; CHECK-NEXT: call void @llvm.assume(i1 [[C_1]]) 730; CHECK-NEXT: [[OFF_1_POS:%.*]] = icmp sge i8 [[OFF_1:%.*]], 0 731; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_1_POS]]) 732; CHECK-NEXT: [[OFF_2_POS:%.*]] = icmp sge i8 [[OFF_2]], 0 733; CHECK-NEXT: call void @llvm.assume(i1 [[OFF_2_POS]]) 734; CHECK-NEXT: [[ADD_OFF_2:%.*]] = add nsw i8 [[START]], [[OFF_1]] 735; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[ADD_OFF_2]], [[HIGH]] 736; CHECK-NEXT: ret i1 [[C]] 737; 738entry: 739 %start.pos = icmp sge i8 %start, 0 740 call void @llvm.assume(i1 %start.pos) 741 %add = add nsw i8 %start, %off.2 742 %c.1 = icmp ult i8 %add, %high 743 call void @llvm.assume(i1 %c.1) 744 %off.1.pos = icmp sge i8 %off.1, 0 745 call void @llvm.assume(i1 %off.1.pos) 746 %off.2.pos = icmp sge i8 %off.2, 0 747 call void @llvm.assume(i1 %off.2.pos) 748 749 %add.off.2 = add nsw i8 %start, %off.1 750 %c = icmp ult i8 %add.off.2, %high 751 ret i1 %c 752} 753 754define i1 @add_neg_1_known_sge_ult_1(i32 %a) { 755; CHECK-LABEL: @add_neg_1_known_sge_ult_1( 756; CHECK-NEXT: entry: 757; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 1 758; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]]) 759; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -1 760; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[SUB]], [[A]] 761; CHECK-NEXT: ret i1 [[C]] 762; 763entry: 764 %a.sge = icmp sge i32 %a, 1 765 call void @llvm.assume(i1 %a.sge) 766 %sub = add nsw i32 %a, -1 767 %c = icmp ult i32 %sub, %a 768 ret i1 %c 769} 770 771define i1 @add_neg_1_known_sge_uge_1(i32 %a) { 772; CHECK-LABEL: @add_neg_1_known_sge_uge_1( 773; CHECK-NEXT: entry: 774; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 1 775; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]]) 776; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -1 777; CHECK-NEXT: ret i1 true 778; 779entry: 780 %a.sge = icmp sge i32 %a, 1 781 call void @llvm.assume(i1 %a.sge) 782 %sub = add nsw i32 %a, -1 783 %c = icmp uge i32 %sub, 0 784 ret i1 %c 785} 786 787define i1 @add_neg_1_not_known_sge_ult_1(i32 %a) { 788; CHECK-LABEL: @add_neg_1_not_known_sge_ult_1( 789; CHECK-NEXT: entry: 790; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 0 791; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]]) 792; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -1 793; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[SUB]], [[A]] 794; CHECK-NEXT: ret i1 [[C]] 795; 796entry: 797 %a.sge = icmp sge i32 %a, 0 798 call void @llvm.assume(i1 %a.sge) 799 %sub = add nsw i32 %a, -1 800 %c = icmp ult i32 %sub, %a 801 ret i1 %c 802} 803 804define i1 @add_neg_1_not_known_sge_uge_1(i32 %a) { 805; CHECK-LABEL: @add_neg_1_not_known_sge_uge_1( 806; CHECK-NEXT: entry: 807; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 0 808; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]]) 809; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -1 810; CHECK-NEXT: ret i1 true 811; 812entry: 813 %a.sge = icmp sge i32 %a, 0 814 call void @llvm.assume(i1 %a.sge) 815 %sub = add nsw i32 %a, -1 816 %c = icmp uge i32 %sub, 0 817 ret i1 %c 818} 819 820define i1 @add_neg_3_known_sge_ult_1(i32 %a) { 821; CHECK-LABEL: @add_neg_3_known_sge_ult_1( 822; CHECK-NEXT: entry: 823; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 3 824; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]]) 825; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -3 826; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[SUB]], [[A]] 827; CHECK-NEXT: ret i1 [[C]] 828; 829entry: 830 %a.sge = icmp sge i32 %a, 3 831 call void @llvm.assume(i1 %a.sge) 832 %sub = add nsw i32 %a, -3 833 %c = icmp ult i32 %sub, %a 834 ret i1 %c 835} 836 837define i1 @add_neg_3_known_sge_uge_1(i32 %a) { 838; CHECK-LABEL: @add_neg_3_known_sge_uge_1( 839; CHECK-NEXT: entry: 840; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 4 841; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]]) 842; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -3 843; CHECK-NEXT: ret i1 true 844; 845entry: 846 %a.sge = icmp sge i32 %a, 4 847 call void @llvm.assume(i1 %a.sge) 848 %sub = add nsw i32 %a, -3 849 %c = icmp uge i32 %sub, 0 850 ret i1 %c 851} 852 853define i1 @add_neg_3_not_known_sge_ult_1(i32 %a) { 854; CHECK-LABEL: @add_neg_3_not_known_sge_ult_1( 855; CHECK-NEXT: entry: 856; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 2 857; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]]) 858; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -3 859; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[SUB]], [[A]] 860; CHECK-NEXT: ret i1 [[C]] 861; 862entry: 863 %a.sge = icmp sge i32 %a, 2 864 call void @llvm.assume(i1 %a.sge) 865 %sub = add nsw i32 %a, -3 866 %c = icmp ult i32 %sub, %a 867 ret i1 %c 868} 869 870define i1 @add_neg_3_not_known_sge_uge_1(i32 %a) { 871; CHECK-LABEL: @add_neg_3_not_known_sge_uge_1( 872; CHECK-NEXT: entry: 873; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 2 874; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]]) 875; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -3 876; CHECK-NEXT: ret i1 true 877; 878entry: 879 %a.sge = icmp sge i32 %a, 2 880 call void @llvm.assume(i1 %a.sge) 881 %sub = add nsw i32 %a, -3 882 %c = icmp uge i32 %sub, 0 883 ret i1 %c 884} 885 886define i1 @add_neg_3_not_known_sge_ult_2(i32 %a, i32 %b) { 887; CHECK-LABEL: @add_neg_3_not_known_sge_ult_2( 888; CHECK-NEXT: entry: 889; CHECK-NEXT: [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], [[B:%.*]] 890; CHECK-NEXT: call void @llvm.assume(i1 [[A_SGE]]) 891; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[A]], -3 892; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[SUB]], [[A]] 893; CHECK-NEXT: ret i1 [[C]] 894; 895entry: 896 %a.sge = icmp sge i32 %a, %b 897 call void @llvm.assume(i1 %a.sge) 898 %sub = add nsw i32 %a, -3 899 %c = icmp ult i32 %sub, %a 900 ret i1 %c 901} 902