1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 3 4define void @test.not.uge.ult(i8 %start, i8 %low, i8 %high) { 5; CHECK-LABEL: @test.not.uge.ult( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: [[ADD_PTR_I:%.*]] = add nuw i8 [[START:%.*]], 3 8; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_PTR_I]], [[HIGH:%.*]] 9; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 10; CHECK: if.then: 11; CHECK-NEXT: ret void 12; CHECK: if.end: 13; CHECK-NEXT: call void @use(i1 true) 14; CHECK-NEXT: [[START_1:%.*]] = add nuw i8 [[START]], 1 15; CHECK-NEXT: call void @use(i1 true) 16; CHECK-NEXT: [[START_2:%.*]] = add nuw i8 [[START]], 2 17; CHECK-NEXT: call void @use(i1 true) 18; CHECK-NEXT: [[START_3:%.*]] = add nuw i8 [[START]], 3 19; CHECK-NEXT: call void @use(i1 true) 20; CHECK-NEXT: [[START_4:%.*]] = add nuw i8 [[START]], 4 21; CHECK-NEXT: [[C_4:%.*]] = icmp ult i8 [[START_4]], [[HIGH]] 22; CHECK-NEXT: call void @use(i1 [[C_4]]) 23; CHECK-NEXT: ret void 24; 25entry: 26 %add.ptr.i = add nuw i8 %start, 3 27 %c.1 = icmp uge i8 %add.ptr.i, %high 28 br i1 %c.1, label %if.then, label %if.end 29 30if.then: ; preds = %entry 31 ret void 32 33if.end: ; preds = %entry 34 %t.0 = icmp ult i8 %start, %high 35 call void @use(i1 %t.0) 36 %start.1 = add nuw i8 %start, 1 37 %t.1 = icmp ult i8 %start.1, %high 38 call void @use(i1 %t.1) 39 %start.2 = add nuw i8 %start, 2 40 %t.2 = icmp ult i8 %start.2, %high 41 call void @use(i1 %t.2) 42 %start.3 = add nuw i8 %start, 3 43 %t.3 = icmp ult i8 %start.3, %high 44 call void @use(i1 %t.3) 45 %start.4 = add nuw i8 %start, 4 46 %c.4 = icmp ult i8 %start.4, %high 47 call void @use(i1 %c.4) 48 ret void 49} 50 51define void @test.not.uge.ule(i8 %start, i8 %low, i8 %high) { 52; CHECK-LABEL: @test.not.uge.ule( 53; CHECK-NEXT: entry: 54; CHECK-NEXT: [[ADD_PTR_I:%.*]] = add nuw i8 [[START:%.*]], 3 55; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_PTR_I]], [[HIGH:%.*]] 56; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 57; CHECK: if.then: 58; CHECK-NEXT: ret void 59; CHECK: if.end: 60; CHECK-NEXT: call void @use(i1 true) 61; CHECK-NEXT: [[START_1:%.*]] = add nuw i8 [[START]], 1 62; CHECK-NEXT: call void @use(i1 true) 63; CHECK-NEXT: [[START_2:%.*]] = add nuw i8 [[START]], 2 64; CHECK-NEXT: call void @use(i1 true) 65; CHECK-NEXT: [[START_3:%.*]] = add nuw i8 [[START]], 3 66; CHECK-NEXT: call void @use(i1 true) 67; CHECK-NEXT: [[START_4:%.*]] = add nuw i8 [[START]], 4 68; CHECK-NEXT: call void @use(i1 true) 69; CHECK-NEXT: [[START_5:%.*]] = add nuw i8 [[START]], 5 70; CHECK-NEXT: [[C_5:%.*]] = icmp ule i8 [[START_5]], [[HIGH]] 71; CHECK-NEXT: call void @use(i1 [[C_5]]) 72; CHECK-NEXT: ret void 73; 74entry: 75 %add.ptr.i = add nuw i8 %start, 3 76 %c.1 = icmp uge i8 %add.ptr.i, %high 77 br i1 %c.1, label %if.then, label %if.end 78 79if.then: ; preds = %entry 80 ret void 81 82if.end: ; preds = %entry 83 %t.0 = icmp ule i8 %start, %high 84 call void @use(i1 %t.0) 85 %start.1 = add nuw i8 %start, 1 86 %t.1 = icmp ule i8 %start.1, %high 87 call void @use(i1 %t.1) 88 %start.2 = add nuw i8 %start, 2 89 %t.2 = icmp ule i8 %start.2, %high 90 call void @use(i1 %t.2) 91 %start.3 = add nuw i8 %start, 3 92 %t.3 = icmp ule i8 %start.3, %high 93 call void @use(i1 %t.3) 94 %start.4 = add nuw i8 %start, 4 95 %t.4 = icmp ule i8 %start.4, %high 96 call void @use(i1 %t.4) 97 98 %start.5 = add nuw i8 %start, 5 99 %c.5 = icmp ule i8 %start.5, %high 100 call void @use(i1 %c.5) 101 102 ret void 103} 104 105define void @test.not.uge.ugt(i8 %start, i8 %low, i8 %high) { 106; CHECK-LABEL: @test.not.uge.ugt( 107; CHECK-NEXT: entry: 108; CHECK-NEXT: [[ADD_PTR_I:%.*]] = add nuw i8 [[START:%.*]], 3 109; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_PTR_I]], [[HIGH:%.*]] 110; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 111; CHECK: if.then: 112; CHECK-NEXT: ret void 113; CHECK: if.end: 114; CHECK-NEXT: call void @use(i1 false) 115; CHECK-NEXT: [[START_1:%.*]] = add nuw i8 [[START]], 1 116; CHECK-NEXT: call void @use(i1 false) 117; CHECK-NEXT: [[START_2:%.*]] = add nuw i8 [[START]], 2 118; CHECK-NEXT: call void @use(i1 false) 119; CHECK-NEXT: [[START_3:%.*]] = add nuw i8 [[START]], 3 120; CHECK-NEXT: call void @use(i1 false) 121; CHECK-NEXT: [[START_4:%.*]] = add nuw i8 [[START]], 4 122; CHECK-NEXT: call void @use(i1 false) 123; CHECK-NEXT: [[START_5:%.*]] = add nuw i8 [[START]], 5 124; CHECK-NEXT: [[C_5:%.*]] = icmp ugt i8 [[START_5]], [[HIGH]] 125; CHECK-NEXT: call void @use(i1 [[C_5]]) 126; CHECK-NEXT: ret void 127; 128entry: 129 %add.ptr.i = add nuw i8 %start, 3 130 %c.1 = icmp uge i8 %add.ptr.i, %high 131 br i1 %c.1, label %if.then, label %if.end 132 133if.then: ; preds = %entry 134 ret void 135 136if.end: ; preds = %entry 137 %f.0 = icmp ugt i8 %start, %high 138 call void @use(i1 %f.0) 139 140 %start.1 = add nuw i8 %start, 1 141 %f.1 = icmp ugt i8 %start.1, %high 142 call void @use(i1 %f.1) 143 144 %start.2 = add nuw i8 %start, 2 145 %f.2 = icmp ugt i8 %start.2, %high 146 call void @use(i1 %f.2) 147 148 %start.3 = add nuw i8 %start, 3 149 %f.3 = icmp ugt i8 %start.3, %high 150 call void @use(i1 %f.3) 151 152 %start.4 = add nuw i8 %start, 4 153 %f.4 = icmp ugt i8 %start.4, %high 154 call void @use(i1 %f.4) 155 156 %start.5 = add nuw i8 %start, 5 157 %c.5 = icmp ugt i8 %start.5, %high 158 call void @use(i1 %c.5) 159 160 ret void 161} 162 163define void @test.not.uge.uge(i8 %start, i8 %low, i8 %high) { 164; CHECK-LABEL: @test.not.uge.uge( 165; CHECK-NEXT: entry: 166; CHECK-NEXT: [[ADD_PTR_I:%.*]] = add nuw i8 [[START:%.*]], 3 167; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_PTR_I]], [[HIGH:%.*]] 168; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 169; CHECK: if.then: 170; CHECK-NEXT: ret void 171; CHECK: if.end: 172; CHECK-NEXT: call void @use(i1 false) 173; CHECK-NEXT: [[START_1:%.*]] = add nuw i8 [[START]], 1 174; CHECK-NEXT: call void @use(i1 false) 175; CHECK-NEXT: [[START_2:%.*]] = add nuw i8 [[START]], 2 176; CHECK-NEXT: call void @use(i1 false) 177; CHECK-NEXT: [[START_3:%.*]] = add nuw i8 [[START]], 3 178; CHECK-NEXT: call void @use(i1 false) 179; CHECK-NEXT: [[START_4:%.*]] = add nuw i8 [[START]], 4 180; CHECK-NEXT: [[C_4:%.*]] = icmp uge i8 [[START_4]], [[HIGH]] 181; CHECK-NEXT: call void @use(i1 [[C_4]]) 182; CHECK-NEXT: [[START_5:%.*]] = add nuw i8 [[START]], 5 183; CHECK-NEXT: [[C_5:%.*]] = icmp uge i8 [[START_5]], [[HIGH]] 184; CHECK-NEXT: call void @use(i1 [[C_5]]) 185; CHECK-NEXT: ret void 186; 187entry: 188 %add.ptr.i = add nuw i8 %start, 3 189 %c.1 = icmp uge i8 %add.ptr.i, %high 190 br i1 %c.1, label %if.then, label %if.end 191 192if.then: ; preds = %entry 193 ret void 194 195if.end: ; preds = %entry 196 %f.0 = icmp ugt i8 %start, %high 197 call void @use(i1 %f.0) 198 199 %start.1 = add nuw i8 %start, 1 200 %f.1 = icmp uge i8 %start.1, %high 201 call void @use(i1 %f.1) 202 203 %start.2 = add nuw i8 %start, 2 204 %f.2 = icmp uge i8 %start.2, %high 205 call void @use(i1 %f.2) 206 207 %start.3 = add nuw i8 %start, 3 208 %f.3 = icmp uge i8 %start.3, %high 209 call void @use(i1 %f.3) 210 211 %start.4 = add nuw i8 %start, 4 212 %c.4 = icmp uge i8 %start.4, %high 213 call void @use(i1 %c.4) 214 215 %start.5 = add nuw i8 %start, 5 216 %c.5 = icmp uge i8 %start.5, %high 217 call void @use(i1 %c.5) 218 219 ret void 220} 221 222define void @test.decompose.nonconst(i8 %a, i8 %b, i8 %c, i8 %d) { 223; CHECK-LABEL: @test.decompose.nonconst( 224; CHECK-NEXT: entry: 225; CHECK-NEXT: [[C_0:%.*]] = icmp uge i8 [[A:%.*]], [[C:%.*]] 226; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[B:%.*]], [[C]] 227; CHECK-NEXT: [[AND_0:%.*]] = and i1 [[C_0]], [[C_1]] 228; CHECK-NEXT: br i1 [[AND_0]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 229; CHECK: if.then: 230; CHECK-NEXT: [[AND_1:%.*]] = and i1 true, true 231; CHECK-NEXT: br i1 [[AND_1]], label [[IF_THEN_2:%.*]], label [[IF_END]] 232; CHECK: if.then.2: 233; CHECK-NEXT: [[ADD_0:%.*]] = add nuw i8 [[A]], [[B]] 234; CHECK-NEXT: call void @use(i1 true) 235; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A]], [[A]] 236; CHECK-NEXT: call void @use(i1 true) 237; CHECK-NEXT: [[ADD_2:%.*]] = add nuw i8 [[A]], [[D:%.*]] 238; CHECK-NEXT: call void @use(i1 true) 239; CHECK-NEXT: ret void 240; CHECK: if.end: 241; CHECK-NEXT: ret void 242; 243entry: 244 %c.0 = icmp uge i8 %a, %c 245 %c.1 = icmp uge i8 %b, %c 246 %and.0 = and i1 %c.0, %c.1 247 br i1 %and.0, label %if.then, label %if.end 248 249if.then: ; preds = %entry 250 %c.2 = icmp uge i8 %a, 0 251 %c.3 = icmp uge i8 %b, 0 252 %and.1 = and i1 %c.2, %c.3 253 br i1 %and.1, label %if.then.2, label %if.end 254 255if.then.2: 256 %add.0 = add nuw i8 %a, %b 257 %t.0 = icmp uge i8 %add.0, %c 258 call void @use(i1 %t.0) 259 %add.1 = add nuw i8 %a, %a 260 %t.1 = icmp uge i8 %add.0, %c 261 call void @use(i1 %t.1) 262 %add.2 = add nuw i8 %a, %d 263 %c.4 = icmp uge i8 %add.2, %c 264 call void @use(i1 %c.4) 265 ret void 266 267if.end: ; preds = %entry 268 ret void 269} 270 271define void @test.decompose.nonconst.no.null.check(i8 %a, i8 %b, i8 %c, i8 %d) { 272; CHECK-LABEL: @test.decompose.nonconst.no.null.check( 273; CHECK-NEXT: entry: 274; CHECK-NEXT: [[C_0:%.*]] = icmp uge i8 [[A:%.*]], [[C:%.*]] 275; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[B:%.*]], [[C]] 276; CHECK-NEXT: [[AND_0:%.*]] = and i1 [[C_0]], [[C_1]] 277; CHECK-NEXT: br i1 [[AND_0]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 278; CHECK: if.then: 279; CHECK-NEXT: [[ADD_0:%.*]] = add nuw i8 [[A]], [[B]] 280; CHECK-NEXT: call void @use(i1 true) 281; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A]], [[A]] 282; CHECK-NEXT: call void @use(i1 true) 283; CHECK-NEXT: [[ADD_2:%.*]] = add nuw i8 [[A]], [[D:%.*]] 284; CHECK-NEXT: call void @use(i1 true) 285; CHECK-NEXT: ret void 286; CHECK: if.end: 287; CHECK-NEXT: ret void 288; 289entry: 290 %c.0 = icmp uge i8 %a, %c 291 %c.1 = icmp uge i8 %b, %c 292 %and.0 = and i1 %c.0, %c.1 293 br i1 %and.0, label %if.then, label %if.end 294 295if.then: ; preds = %entry 296 %add.0 = add nuw i8 %a, %b 297 %t.0 = icmp uge i8 %add.0, %c 298 call void @use(i1 %t.0) 299 %add.1 = add nuw i8 %a, %a 300 %t.1 = icmp uge i8 %add.0, %c 301 call void @use(i1 %t.1) 302 %add.2 = add nuw i8 %a, %d 303 %c.4 = icmp uge i8 %add.2, %c 304 call void @use(i1 %c.4) 305 ret void 306 307if.end: ; preds = %entry 308 ret void 309} 310 311 312define i1 @test_n_must_ule_1_due_to_nuw(i8 %n, i8 %i) { 313; CHECK-LABEL: @test_n_must_ule_1_due_to_nuw( 314; CHECK-NEXT: entry: 315; CHECK-NEXT: [[SUB_N_1:%.*]] = add nuw i8 [[N:%.*]], -1 316; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[I:%.*]], [[SUB_N_1]] 317; CHECK-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[IF_END:%.*]] 318; CHECK: if.then: 319; CHECK-NEXT: ret i1 true 320; CHECK: if.end: 321; CHECK-NEXT: [[F:%.*]] = icmp ule i8 [[N]], 1 322; CHECK-NEXT: ret i1 [[F]] 323; 324entry: 325 %sub.n.1 = add nuw i8 %n, -1 326 %add = add nuw i8 %i, %sub.n.1 327 %c.1 = icmp uge i8 %i, %add 328 br i1 %c.1, label %if.then, label %if.end 329 330if.then: ; preds = %entry 331 %t = icmp ule i8 %n, 1 332 ret i1 %t 333 334if.end: ; preds = %entry 335 %f = icmp ule i8 %n, 1 336 ret i1 %f 337} 338 339 340define i1 @test_n_unknown_missing_nuw(i8 %n, i8 %i) { 341; CHECK-LABEL: @test_n_unknown_missing_nuw( 342; CHECK-NEXT: entry: 343; CHECK-NEXT: [[SUB_N_1:%.*]] = add i8 [[N:%.*]], -1 344; CHECK-NEXT: [[ADD:%.*]] = add i8 [[I:%.*]], [[SUB_N_1]] 345; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[I]], [[ADD]] 346; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 347; CHECK: if.then: 348; CHECK-NEXT: [[T:%.*]] = icmp ule i8 [[N]], 1 349; CHECK-NEXT: ret i1 [[T]] 350; CHECK: if.end: 351; CHECK-NEXT: [[F:%.*]] = icmp ule i8 [[N]], 1 352; CHECK-NEXT: ret i1 [[F]] 353; 354entry: 355 %sub.n.1 = add i8 %n, -1 356 %add = add i8 %i, %sub.n.1 357 %c.1 = icmp uge i8 %i, %add 358 br i1 %c.1, label %if.then, label %if.end 359 360if.then: ; preds = %entry 361 %t = icmp ule i8 %n, 1 362 ret i1 %t 363 364if.end: ; preds = %entry 365 %f = icmp ule i8 %n, 1 366 ret i1 %f 367} 368 369define i1 @test_n_must_ule_2_due_to_nuw(i8 %n, i8 %i) { 370; CHECK-LABEL: @test_n_must_ule_2_due_to_nuw( 371; CHECK-NEXT: entry: 372; CHECK-NEXT: [[SUB_N_1:%.*]] = add nuw i8 [[N:%.*]], -2 373; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[I:%.*]], [[SUB_N_1]] 374; CHECK-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[IF_END:%.*]] 375; CHECK: if.then: 376; CHECK-NEXT: ret i1 true 377; CHECK: if.end: 378; CHECK-NEXT: [[F:%.*]] = icmp ule i8 [[N]], 2 379; CHECK-NEXT: ret i1 [[F]] 380; 381entry: 382 %sub.n.1 = add nuw i8 %n, -2 383 %add = add nuw i8 %i, %sub.n.1 384 %c.1 = icmp uge i8 %i, %add 385 br i1 %c.1, label %if.then, label %if.end 386 387if.then: ; preds = %entry 388 %t = icmp ule i8 %n, 2 389 ret i1 %t 390 391if.end: ; preds = %entry 392 %f = icmp ule i8 %n, 2 393 ret i1 %f 394} 395 396 397define i1 @test_n_unknown_missing_nuw2(i8 %n, i8 %i) { 398; CHECK-LABEL: @test_n_unknown_missing_nuw2( 399; CHECK-NEXT: entry: 400; CHECK-NEXT: [[SUB_N_1:%.*]] = add i8 [[N:%.*]], -2 401; CHECK-NEXT: [[ADD:%.*]] = add i8 [[I:%.*]], [[SUB_N_1]] 402; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[I]], [[ADD]] 403; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 404; CHECK: if.then: 405; CHECK-NEXT: [[T:%.*]] = icmp ule i8 [[N]], 1 406; CHECK-NEXT: ret i1 [[T]] 407; CHECK: if.end: 408; CHECK-NEXT: [[F:%.*]] = icmp ule i8 [[N]], 1 409; CHECK-NEXT: ret i1 [[F]] 410; 411entry: 412 %sub.n.1 = add i8 %n, -2 413 %add = add i8 %i, %sub.n.1 414 %c.1 = icmp uge i8 %i, %add 415 br i1 %c.1, label %if.then, label %if.end 416 417if.then: ; preds = %entry 418 %t = icmp ule i8 %n, 1 419 ret i1 %t 420 421if.end: ; preds = %entry 422 %f = icmp ule i8 %n, 1 423 ret i1 %f 424} 425 426declare void @use(i1) 427 428define i1 @add_nuw_neg_pr54224_i16(i16 %a) { 429; CHECK-LABEL: @add_nuw_neg_pr54224_i16( 430; CHECK-NEXT: entry: 431; CHECK-NEXT: [[NEG2:%.*]] = add nuw i16 [[A:%.*]], -305 432; CHECK-NEXT: br i1 false, label [[EXIT_1:%.*]], label [[EXIT_2:%.*]] 433; CHECK: exit.1: 434; CHECK-NEXT: ret i1 true 435; CHECK: exit.2: 436; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i16 [[A]], 0 437; CHECK-NEXT: ret i1 [[C_3]] 438; 439entry: 440 %neg2 = add nuw i16 %a, -305 441 %c.1 = icmp ugt i16 0, %neg2 442 br i1 %c.1, label %exit.1, label %exit.2 443 444exit.1: 445 %c.2 = icmp ugt i16 %a, 0 446 ret i1 %c.2 447 448exit.2: 449 %c.3 = icmp ugt i16 %a, 0 450 ret i1 %c.3 451} 452 453define i1 @add_nuw_neg_pr54224_i64(i64 %a) { 454; CHECK-LABEL: @add_nuw_neg_pr54224_i64( 455; CHECK-NEXT: entry: 456; CHECK-NEXT: [[NEG2:%.*]] = add nuw i64 [[A:%.*]], -305 457; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i64 0, [[NEG2]] 458; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_1:%.*]], label [[EXIT_2:%.*]] 459; CHECK: exit.1: 460; CHECK-NEXT: ret i1 true 461; CHECK: exit.2: 462; CHECK-NEXT: [[C_3:%.*]] = icmp ugt i64 [[A]], 0 463; CHECK-NEXT: ret i1 [[C_3]] 464; 465entry: 466 %neg2 = add nuw i64 %a, -305 467 %c.1 = icmp ugt i64 0, %neg2 468 br i1 %c.1, label %exit.1, label %exit.2 469 470exit.1: 471 %c.2 = icmp ugt i64 %a, 0 472 ret i1 %c.2 473 474exit.2: 475 %c.3 = icmp ugt i64 %a, 0 476 ret i1 %c.3 477} 478 479define i1 @add_nuw_neg2_i8(i8 %a) { 480; CHECK-LABEL: @add_nuw_neg2_i8( 481; CHECK-NEXT: entry: 482; CHECK-NEXT: [[NEG2:%.*]] = add nuw i8 [[A:%.*]], -4 483; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[NEG2]], -2 484; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_1:%.*]], label [[EXIT_2:%.*]] 485; CHECK: exit.1: 486; CHECK-NEXT: [[C_2:%.*]] = icmp ult i8 [[A]], 1 487; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[C_2]] 488; CHECK-NEXT: ret i1 [[RES_1]] 489; CHECK: exit.2: 490; CHECK-NEXT: [[C_3:%.*]] = icmp ult i8 [[A]], 3 491; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[C_3]], false 492; CHECK-NEXT: ret i1 [[RES_2]] 493; 494entry: 495 %neg2 = add nuw i8 %a, -4 496 %c.1 = icmp ult i8 %neg2, -2 497 br i1 %c.1, label %exit.1, label %exit.2 498 499exit.1: 500 %t.1 = icmp ult i8 %a, 2 501 %c.2 = icmp ult i8 %a, 1 502 %res.1 = xor i1 %t.1, %c.2 503 ret i1 %res.1 504 505exit.2: 506 %c.3 = icmp ult i8 %a, 3 507 %f.1 = icmp ult i8 %a, 2 508 %res.2 = xor i1 %c.3, %f.1 509 ret i1 %res.2 510} 511 512define i1 @add_nuw_neg2_i64(i64 %a) { 513; CHECK-LABEL: @add_nuw_neg2_i64( 514; CHECK-NEXT: entry: 515; CHECK-NEXT: [[NEG2:%.*]] = add nuw i64 [[A:%.*]], -4 516; CHECK-NEXT: [[C_1:%.*]] = icmp ult i64 [[NEG2]], -2 517; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_1:%.*]], label [[EXIT_2:%.*]] 518; CHECK: exit.1: 519; CHECK-NEXT: [[T_1:%.*]] = icmp ult i64 [[A]], 2 520; CHECK-NEXT: [[C_2:%.*]] = icmp ult i64 [[A]], 1 521; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[T_1]], [[C_2]] 522; CHECK-NEXT: ret i1 [[RES_1]] 523; CHECK: exit.2: 524; CHECK-NEXT: [[C_3:%.*]] = icmp ult i64 [[A]], 3 525; CHECK-NEXT: [[F_1:%.*]] = icmp ult i64 [[A]], 2 526; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[C_3]], [[F_1]] 527; CHECK-NEXT: ret i1 [[RES_2]] 528; 529entry: 530 %neg2 = add nuw i64 %a, -4 531 %c.1 = icmp ult i64 %neg2, -2 532 br i1 %c.1, label %exit.1, label %exit.2 533 534exit.1: 535 %t.1 = icmp ult i64 %a, 2 536 %c.2 = icmp ult i64 %a, 1 537 %res.1 = xor i1 %t.1, %c.2 538 ret i1 %res.1 539 540exit.2: 541 %c.3 = icmp ult i64 %a, 3 542 %f.1 = icmp ult i64 %a, 2 543 %res.2 = xor i1 %c.3, %f.1 544 ret i1 %res.2 545} 546 547define i1 @test_chained_adds_nuw_1(i8 %a, i8 %b) { 548; CHECK-LABEL: @test_chained_adds_nuw_1( 549; CHECK-NEXT: entry: 550; CHECK-NEXT: [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5 551; CHECK-NEXT: call void @llvm.assume(i1 [[C_A]]) 552; CHECK-NEXT: [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6 553; CHECK-NEXT: call void @llvm.assume(i1 [[C_B]]) 554; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A]], [[B]] 555; CHECK-NEXT: [[ADD_2:%.*]] = add nuw i8 [[ADD_1]], 2 556; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_2]], 14 557; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[C_1]] 558; CHECK-NEXT: ret i1 [[RES_1]] 559; 560entry: 561 %c.a = icmp uge i8 %a, 5 562 call void @llvm.assume(i1 %c.a) 563 %c.b = icmp uge i8 %b, 6 564 call void @llvm.assume(i1 %c.b) 565 %add.1 = add nuw i8 %a, %b 566 %add.2 = add nuw i8 %add.1, 2 567 %t.1 = icmp uge i8 %add.2, 13 568 %c.1 = icmp uge i8 %add.2, 14 569 %res.1 = xor i1 %t.1, %c.1 570 ret i1 %res.1 571} 572 573define i1 @test_chained_adds_nuw_2(i8 %a, i8 %b) { 574; CHECK-LABEL: @test_chained_adds_nuw_2( 575; CHECK-NEXT: entry: 576; CHECK-NEXT: [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5 577; CHECK-NEXT: call void @llvm.assume(i1 [[C_A]]) 578; CHECK-NEXT: [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6 579; CHECK-NEXT: call void @llvm.assume(i1 [[C_B]]) 580; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A]], [[B]] 581; CHECK-NEXT: [[ADD_2:%.*]] = add nuw i8 [[ADD_1]], 2 582; CHECK-NEXT: [[ADD_3:%.*]] = add nuw i8 [[ADD_2]], [[A]] 583; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_3]], 19 584; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[C_1]] 585; CHECK-NEXT: ret i1 [[RES_1]] 586; 587entry: 588 %c.a = icmp uge i8 %a, 5 589 call void @llvm.assume(i1 %c.a) 590 %c.b = icmp uge i8 %b, 6 591 call void @llvm.assume(i1 %c.b) 592 %add.1 = add nuw i8 %a, %b 593 %add.2 = add nuw i8 %add.1, 2 594 %add.3 = add nuw i8 %add.2, %a 595 %t.1 = icmp uge i8 %add.3, 18 596 %c.1 = icmp uge i8 %add.3, 19 597 %res.1 = xor i1 %t.1, %c.1 598 ret i1 %res.1 599} 600 601define i1 @test_chained_adds_nuw_3(i8 %a, i8 %b) { 602; CHECK-LABEL: @test_chained_adds_nuw_3( 603; CHECK-NEXT: entry: 604; CHECK-NEXT: [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5 605; CHECK-NEXT: call void @llvm.assume(i1 [[C_A]]) 606; CHECK-NEXT: [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6 607; CHECK-NEXT: call void @llvm.assume(i1 [[C_B]]) 608; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A]], 2 609; CHECK-NEXT: [[ADD_2:%.*]] = add nuw i8 [[ADD_1]], [[B]] 610; CHECK-NEXT: [[ADD_3:%.*]] = add nuw i8 [[ADD_2]], [[A]] 611; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_3]], 19 612; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[C_1]] 613; CHECK-NEXT: ret i1 [[RES_1]] 614; 615entry: 616 %c.a = icmp uge i8 %a, 5 617 call void @llvm.assume(i1 %c.a) 618 %c.b = icmp uge i8 %b, 6 619 call void @llvm.assume(i1 %c.b) 620 %add.1 = add nuw i8 %a, 2 621 %add.2 = add nuw i8 %add.1, %b 622 %add.3 = add nuw i8 %add.2, %a 623 %t.1 = icmp uge i8 %add.3, 18 624 %c.1 = icmp uge i8 %add.3, 19 625 %res.1 = xor i1 %t.1, %c.1 626 ret i1 %res.1 627} 628 629define i1 @test_chained_adds_nuw_4(i8 %a, i8 %b) { 630; CHECK-LABEL: @test_chained_adds_nuw_4( 631; CHECK-NEXT: entry: 632; CHECK-NEXT: [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5 633; CHECK-NEXT: call void @llvm.assume(i1 [[C_A]]) 634; CHECK-NEXT: [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6 635; CHECK-NEXT: call void @llvm.assume(i1 [[C_B]]) 636; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A]], 2 637; CHECK-NEXT: [[ADD_2:%.*]] = add nuw i8 [[ADD_1]], [[B]] 638; CHECK-NEXT: [[ADD_3:%.*]] = add nuw i8 [[ADD_2]], 10 639; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_3]], 24 640; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[C_1]] 641; CHECK-NEXT: ret i1 [[RES_1]] 642; 643entry: 644 %c.a = icmp uge i8 %a, 5 645 call void @llvm.assume(i1 %c.a) 646 %c.b = icmp uge i8 %b, 6 647 call void @llvm.assume(i1 %c.b) 648 %add.1 = add nuw i8 %a, 2 649 %add.2 = add nuw i8 %add.1, %b 650 %add.3 = add nuw i8 %add.2, 10 651 %t.1 = icmp uge i8 %add.3, 23 652 %c.1 = icmp uge i8 %add.3, 24 653 %res.1 = xor i1 %t.1, %c.1 654 ret i1 %res.1 655} 656 657define i1 @test_chained_adds_missing_nuw_1(i8 %a, i8 %b) { 658; CHECK-LABEL: @test_chained_adds_missing_nuw_1( 659; CHECK-NEXT: entry: 660; CHECK-NEXT: [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5 661; CHECK-NEXT: call void @llvm.assume(i1 [[C_A]]) 662; CHECK-NEXT: [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6 663; CHECK-NEXT: call void @llvm.assume(i1 [[C_B]]) 664; CHECK-NEXT: [[ADD_1:%.*]] = add i8 [[A]], 2 665; CHECK-NEXT: [[ADD_2:%.*]] = add nuw i8 [[ADD_1]], [[B]] 666; CHECK-NEXT: [[ADD_3:%.*]] = add nuw i8 [[ADD_2]], [[A]] 667; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_3]], 18 668; CHECK-NEXT: [[C_2:%.*]] = icmp uge i8 [[ADD_3]], 19 669; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[C_1]], [[C_2]] 670; CHECK-NEXT: ret i1 [[RES_1]] 671; 672entry: 673 %c.a = icmp uge i8 %a, 5 674 call void @llvm.assume(i1 %c.a) 675 %c.b = icmp uge i8 %b, 6 676 call void @llvm.assume(i1 %c.b) 677 %add.1 = add i8 %a, 2 678 %add.2 = add nuw i8 %add.1, %b 679 %add.3 = add nuw i8 %add.2, %a 680 %c.1 = icmp uge i8 %add.3, 18 681 %c.2 = icmp uge i8 %add.3, 19 682 %res.1 = xor i1 %c.1, %c.2 683 ret i1 %res.1 684} 685 686define i1 @test_chained_adds_missing_nuw_2(i8 %a, i8 %b) { 687; CHECK-LABEL: @test_chained_adds_missing_nuw_2( 688; CHECK-NEXT: entry: 689; CHECK-NEXT: [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5 690; CHECK-NEXT: call void @llvm.assume(i1 [[C_A]]) 691; CHECK-NEXT: [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6 692; CHECK-NEXT: call void @llvm.assume(i1 [[C_B]]) 693; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A]], 2 694; CHECK-NEXT: [[ADD_2:%.*]] = add i8 [[ADD_1]], [[B]] 695; CHECK-NEXT: [[ADD_3:%.*]] = add nuw i8 [[ADD_2]], [[A]] 696; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_3]], 18 697; CHECK-NEXT: [[C_2:%.*]] = icmp uge i8 [[ADD_3]], 19 698; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[C_1]], [[C_2]] 699; CHECK-NEXT: ret i1 [[RES_1]] 700; 701entry: 702 %c.a = icmp uge i8 %a, 5 703 call void @llvm.assume(i1 %c.a) 704 %c.b = icmp uge i8 %b, 6 705 call void @llvm.assume(i1 %c.b) 706 %add.1 = add nuw i8 %a, 2 707 %add.2 = add i8 %add.1, %b 708 %add.3 = add nuw i8 %add.2, %a 709 %c.1 = icmp uge i8 %add.3, 18 710 %c.2 = icmp uge i8 %add.3, 19 711 %res.1 = xor i1 %c.1, %c.2 712 ret i1 %res.1 713} 714 715define i1 @test_chained_adds_missing_nuw_3(i8 %a, i8 %b) { 716; CHECK-LABEL: @test_chained_adds_missing_nuw_3( 717; CHECK-NEXT: entry: 718; CHECK-NEXT: [[C_A:%.*]] = icmp uge i8 [[A:%.*]], 5 719; CHECK-NEXT: call void @llvm.assume(i1 [[C_A]]) 720; CHECK-NEXT: [[C_B:%.*]] = icmp uge i8 [[B:%.*]], 6 721; CHECK-NEXT: call void @llvm.assume(i1 [[C_B]]) 722; CHECK-NEXT: [[ADD_1:%.*]] = add nuw i8 [[A]], 2 723; CHECK-NEXT: [[ADD_2:%.*]] = add nuw i8 [[ADD_1]], [[B]] 724; CHECK-NEXT: [[ADD_3:%.*]] = add i8 [[ADD_2]], [[A]] 725; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[ADD_3]], 18 726; CHECK-NEXT: [[C_2:%.*]] = icmp uge i8 [[ADD_3]], 19 727; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[C_1]], [[C_2]] 728; CHECK-NEXT: ret i1 [[RES_1]] 729; 730entry: 731 %c.a = icmp uge i8 %a, 5 732 call void @llvm.assume(i1 %c.a) 733 %c.b = icmp uge i8 %b, 6 734 call void @llvm.assume(i1 %c.b) 735 %add.1 = add nuw i8 %a, 2 736 %add.2 = add nuw i8 %add.1, %b 737 %add.3 = add i8 %add.2, %a 738 %c.1 = icmp uge i8 %add.3, 18 739 %c.2 = icmp uge i8 %add.3, 19 740 %res.1 = xor i1 %c.1, %c.2 741 ret i1 %res.1 742} 743 744declare void @llvm.assume(i1) 745