1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4declare void @use(i32) 5 6; PR1949 7 8; negative test for zext/zext additions with i16 9define i1 @cvt_icmp_0_zext_plus_zext_eq_i16(i16 %arg, i16 %arg1) { 10; CHECK-LABEL: @cvt_icmp_0_zext_plus_zext_eq_i16( 11; CHECK-NEXT: bb: 12; CHECK-NEXT: [[TMP0:%.*]] = or i16 [[ARG1:%.*]], [[ARG:%.*]] 13; CHECK-NEXT: [[I4:%.*]] = icmp eq i16 [[TMP0]], 0 14; CHECK-NEXT: ret i1 [[I4]] 15; 16bb: 17 %i = zext i16 %arg to i32 18 %i2 = zext i16 %arg1 to i32 19 %i3 = add i32 %i2, %i 20 %i4 = icmp eq i32 %i3, 0 21 ret i1 %i4 22} 23 24; negative test for zext/zext addtions with i8 25define i1 @cvt_icmp_0_zext_plus_zext_eq_i8(i8 %arg, i8 %arg1) { 26; CHECK-LABEL: @cvt_icmp_0_zext_plus_zext_eq_i8( 27; CHECK-NEXT: bb: 28; CHECK-NEXT: [[TMP0:%.*]] = or i8 [[ARG1:%.*]], [[ARG:%.*]] 29; CHECK-NEXT: [[I4:%.*]] = icmp eq i8 [[TMP0]], 0 30; CHECK-NEXT: ret i1 [[I4]] 31; 32bb: 33 %i = zext i8 %arg to i32 34 %i2 = zext i8 %arg1 to i32 35 %i3 = add i32 %i2, %i 36 %i4 = icmp eq i32 %i3, 0 37 ret i1 %i4 38} 39 40; start of positive tests 41define i1 @cvt_icmp_neg_2_zext_plus_zext_eq(i1 %arg, i1 %arg1) { 42; CHECK-LABEL: @cvt_icmp_neg_2_zext_plus_zext_eq( 43; CHECK-NEXT: bb: 44; CHECK-NEXT: ret i1 false 45; 46bb: 47 %i = zext i1 %arg to i32 48 %i2 = zext i1 %arg1 to i32 49 %i3 = add i32 %i2, %i 50 %i4 = icmp eq i32 %i3, -2 51 ret i1 %i4 52} 53 54define i1 @cvt_icmp_neg_1_zext_plus_zext_eq(i1 %arg, i1 %arg1) { 55; CHECK-LABEL: @cvt_icmp_neg_1_zext_plus_zext_eq( 56; CHECK-NEXT: bb: 57; CHECK-NEXT: ret i1 false 58; 59bb: 60 %i = zext i1 %arg to i32 61 %i2 = zext i1 %arg1 to i32 62 %i3 = add i32 %i2, %i 63 %i4 = icmp eq i32 %i3, -1 64 ret i1 %i4 65} 66 67define i1 @cvt_icmp_0_zext_plus_zext_eq(i1 %arg, i1 %arg1) { 68; CHECK-LABEL: @cvt_icmp_0_zext_plus_zext_eq( 69; CHECK-NEXT: bb: 70; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]] 71; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true 72; CHECK-NEXT: ret i1 [[I4]] 73; 74bb: 75 %i = zext i1 %arg to i32 76 %i2 = zext i1 %arg1 to i32 77 %i3 = add i32 %i2, %i 78 %i4 = icmp eq i32 %i3, 0 79 ret i1 %i4 80} 81 82define i1 @cvt_icmp_0_zext_plus_zext_eq_i2(i1 %a, i1 %b) { 83; CHECK-LABEL: @cvt_icmp_0_zext_plus_zext_eq_i2( 84; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[A:%.*]], [[B:%.*]] 85; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[TMP1]], true 86; CHECK-NEXT: ret i1 [[CMP]] 87; 88 %a.ext = zext i1 %a to i2 89 %b.ext = zext i1 %b to i2 90 %add = add i2 %a.ext, %b.ext 91 %cmp = icmp eq i2 %add, 0 92 ret i1 %cmp 93} 94 95define i1 @cvt_icmp_1_zext_plus_zext_eq(i1 %arg, i1 %arg1) { 96; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_eq( 97; CHECK-NEXT: bb: 98; CHECK-NEXT: [[I4:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]] 99; CHECK-NEXT: ret i1 [[I4]] 100; 101bb: 102 %i = zext i1 %arg to i32 103 %i2 = zext i1 %arg1 to i32 104 %i3 = add i32 %i2, %i 105 %i4 = icmp eq i32 %i3, 1 106 ret i1 %i4 107} 108 109define <2 x i1> @cvt_icmp_1_zext_plus_zext_eq_vec(<2 x i1> %arg, <2 x i1> %arg1) { 110; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_eq_vec( 111; CHECK-NEXT: bb: 112; CHECK-NEXT: [[I4:%.*]] = xor <2 x i1> [[ARG1:%.*]], [[ARG:%.*]] 113; CHECK-NEXT: ret <2 x i1> [[I4]] 114; 115bb: 116 %i = zext <2 x i1> %arg to <2 x i32> 117 %i2 = zext <2 x i1> %arg1 to <2 x i32> 118 %i3 = add <2 x i32> %i2, %i 119 %i4 = icmp eq <2 x i32> %i3, <i32 1, i32 1> 120 ret <2 x i1> %i4 121} 122 123define i1 @cvt_icmp_2_zext_plus_zext_eq(i1 %arg, i1 %arg1) { 124; CHECK-LABEL: @cvt_icmp_2_zext_plus_zext_eq( 125; CHECK-NEXT: bb: 126; CHECK-NEXT: [[T:%.*]] = and i1 [[ARG:%.*]], [[ARG1:%.*]] 127; CHECK-NEXT: ret i1 [[T]] 128; 129bb: 130 %i = zext i1 %arg to i32 131 %i2 = zext i1 %arg1 to i32 132 %i3 = add i32 %i, %i2 133 %t = icmp eq i32 %i3, 2 134 ret i1 %t 135} 136 137define i1 @cvt_icmp_neg_2_sext_plus_sext_eq(i1 %arg, i1 %arg1) { 138; CHECK-LABEL: @cvt_icmp_neg_2_sext_plus_sext_eq( 139; CHECK-NEXT: bb: 140; CHECK-NEXT: [[T:%.*]] = and i1 [[ARG:%.*]], [[ARG1:%.*]] 141; CHECK-NEXT: ret i1 [[T]] 142; 143bb: 144 %i = sext i1 %arg to i32 145 %i2 = sext i1 %arg1 to i32 146 %i3 = add i32 %i, %i2 147 %t = icmp eq i32 %i3, -2 148 ret i1 %t 149} 150 151define i1 @cvt_icmp_neg_1_sext_plus_sext_eq(i1 %arg, i1 %arg1) { 152; CHECK-LABEL: @cvt_icmp_neg_1_sext_plus_sext_eq( 153; CHECK-NEXT: bb: 154; CHECK-NEXT: [[T:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]] 155; CHECK-NEXT: ret i1 [[T]] 156; 157bb: 158 %i = sext i1 %arg to i32 159 %i2 = sext i1 %arg1 to i32 160 %i3 = add i32 %i, %i2 161 %t = icmp eq i32 %i3, -1 162 ret i1 %t 163} 164 165define i1 @cvt_icmp_0_sext_plus_sext_eq(i1 %arg, i1 %arg1) { 166; CHECK-LABEL: @cvt_icmp_0_sext_plus_sext_eq( 167; CHECK-NEXT: bb: 168; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG:%.*]], [[ARG1:%.*]] 169; CHECK-NEXT: [[T:%.*]] = xor i1 [[TMP0]], true 170; CHECK-NEXT: ret i1 [[T]] 171; 172bb: 173 %i = sext i1 %arg to i32 174 %i2 = sext i1 %arg1 to i32 175 %i3 = add i32 %i, %i2 176 %t = icmp eq i32 %i3, 0 177 ret i1 %t 178} 179 180define i1 @cvt_icmp_1_sext_plus_sext_eq(i1 %arg, i1 %arg1) { 181; CHECK-LABEL: @cvt_icmp_1_sext_plus_sext_eq( 182; CHECK-NEXT: bb: 183; CHECK-NEXT: ret i1 false 184; 185bb: 186 %i = sext i1 %arg to i32 187 %i2 = sext i1 %arg1 to i32 188 %i3 = add i32 %i, %i2 189 %t = icmp eq i32 %i3, 1 190 ret i1 %t 191} 192 193define i1 @cvt_icmp_2_sext_plus_sext_eq(i1 %arg, i1 %arg1) { 194; CHECK-LABEL: @cvt_icmp_2_sext_plus_sext_eq( 195; CHECK-NEXT: bb: 196; CHECK-NEXT: ret i1 false 197; 198bb: 199 %i = sext i1 %arg to i32 200 %i2 = sext i1 %arg1 to i32 201 %i3 = add i32 %i, %i2 202 %t = icmp eq i32 %i3, 2 203 ret i1 %t 204} 205 206define i1 @cvt_icmp_neg_2_sext_plus_zext_eq(i1 %arg, i1 %arg1) { 207; CHECK-LABEL: @cvt_icmp_neg_2_sext_plus_zext_eq( 208; CHECK-NEXT: bb: 209; CHECK-NEXT: ret i1 false 210; 211bb: 212 %i = sext i1 %arg to i32 213 %i2 = zext i1 %arg1 to i32 214 %i3 = add i32 %i, %i2 215 %t = icmp eq i32 %i3, -2 216 ret i1 %t 217} 218 219define i1 @cvt_icmp_neg_1_sext_plus_zext_eq(i1 %arg, i1 %arg1) { 220; CHECK-LABEL: @cvt_icmp_neg_1_sext_plus_zext_eq( 221; CHECK-NEXT: bb: 222; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true 223; CHECK-NEXT: [[T:%.*]] = and i1 [[ARG:%.*]], [[TMP0]] 224; CHECK-NEXT: ret i1 [[T]] 225; 226bb: 227 %i = sext i1 %arg to i32 228 %i2 = zext i1 %arg1 to i32 229 %i3 = add i32 %i, %i2 230 %t = icmp eq i32 %i3, -1 231 ret i1 %t 232} 233 234define i1 @cvt_icmp_0_sext_plus_zext_eq(i1 %arg, i1 %arg1) { 235; CHECK-LABEL: @cvt_icmp_0_sext_plus_zext_eq( 236; CHECK-NEXT: bb: 237; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]] 238; CHECK-NEXT: [[T:%.*]] = xor i1 [[TMP0]], true 239; CHECK-NEXT: ret i1 [[T]] 240; 241bb: 242 %i = sext i1 %arg to i32 243 %i2 = zext i1 %arg1 to i32 244 %i3 = add i32 %i, %i2 245 %t = icmp eq i32 %i3, 0 246 ret i1 %t 247} 248 249define i1 @cvt_icmp_1_sext_plus_zext_eq(i1 %arg, i1 %arg1) { 250; CHECK-LABEL: @cvt_icmp_1_sext_plus_zext_eq( 251; CHECK-NEXT: bb: 252; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true 253; CHECK-NEXT: [[T:%.*]] = and i1 [[ARG1:%.*]], [[TMP0]] 254; CHECK-NEXT: ret i1 [[T]] 255; 256bb: 257 %i = sext i1 %arg to i32 258 %i2 = zext i1 %arg1 to i32 259 %i3 = add i32 %i, %i2 260 %t = icmp eq i32 %i3, 1 261 ret i1 %t 262} 263 264define i1 @cvt_icmp_2_sext_plus_zext_eq(i1 %arg, i1 %arg1) { 265; CHECK-LABEL: @cvt_icmp_2_sext_plus_zext_eq( 266; CHECK-NEXT: bb: 267; CHECK-NEXT: ret i1 false 268; 269bb: 270 %i = sext i1 %arg to i32 271 %i2 = zext i1 %arg1 to i32 272 %i3 = add i32 %i, %i2 273 %t = icmp eq i32 %i3, 2 274 ret i1 %t 275} 276 277define i1 @cvt_icmp_neg_2_zext_plus_zext_ne(i1 %arg, i1 %arg1) { 278; CHECK-LABEL: @cvt_icmp_neg_2_zext_plus_zext_ne( 279; CHECK-NEXT: bb: 280; CHECK-NEXT: ret i1 true 281; 282bb: 283 %i = zext i1 %arg to i32 284 %i2 = zext i1 %arg1 to i32 285 %i3 = add i32 %i2, %i 286 %i4 = icmp ne i32 %i3, -2 287 ret i1 %i4 288} 289 290define i1 @cvt_icmp_neg_1_zext_plus_zext_ne(i1 %arg, i1 %arg1) { 291; CHECK-LABEL: @cvt_icmp_neg_1_zext_plus_zext_ne( 292; CHECK-NEXT: bb: 293; CHECK-NEXT: ret i1 true 294; 295bb: 296 %i = zext i1 %arg to i32 297 %i2 = zext i1 %arg1 to i32 298 %i3 = add i32 %i2, %i 299 %i4 = icmp ne i32 %i3, -1 300 ret i1 %i4 301} 302 303define i1 @cvt_icmp_0_zext_plus_zext_ne(i1 %arg, i1 %arg1) { 304; CHECK-LABEL: @cvt_icmp_0_zext_plus_zext_ne( 305; CHECK-NEXT: bb: 306; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]] 307; CHECK-NEXT: ret i1 [[I4]] 308; 309bb: 310 %i = zext i1 %arg to i32 311 %i2 = zext i1 %arg1 to i32 312 %i3 = add i32 %i2, %i 313 %i4 = icmp ne i32 %i3, 0 314 ret i1 %i4 315} 316 317define i1 @cvt_icmp_1_zext_plus_zext_ne(i1 %arg, i1 %arg1) { 318; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_ne( 319; CHECK-NEXT: bb: 320; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]] 321; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true 322; CHECK-NEXT: ret i1 [[I4]] 323; 324bb: 325 %i = zext i1 %arg to i32 326 %i2 = zext i1 %arg1 to i32 327 %i3 = add i32 %i2, %i 328 %i4 = icmp ne i32 %i3, 1 329 ret i1 %i4 330} 331 332define i1 @cvt_icmp_1_zext_plus_zext_ne_extra_use_1(i1 %arg, i1 %arg1) { 333; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_ne_extra_use_1( 334; CHECK-NEXT: bb: 335; CHECK-NEXT: [[I:%.*]] = zext i1 [[ARG:%.*]] to i32 336; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32 337; CHECK-NEXT: [[I3:%.*]] = add nuw nsw i32 [[I2]], [[I]] 338; CHECK-NEXT: call void @use(i32 [[I3]]) 339; CHECK-NEXT: [[I4:%.*]] = icmp ne i32 [[I3]], 1 340; CHECK-NEXT: ret i1 [[I4]] 341; 342bb: 343 %i = zext i1 %arg to i32 344 %i2 = zext i1 %arg1 to i32 345 %i3 = add i32 %i2, %i 346 call void @use(i32 %i3) 347 %i4 = icmp ne i32 %i3, 1 348 ret i1 %i4 349} 350 351define i1 @cvt_icmp_1_zext_plus_zext_ne_extra_use_2(i1 %arg, i1 %arg1) { 352; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_ne_extra_use_2( 353; CHECK-NEXT: bb: 354; CHECK-NEXT: [[I:%.*]] = zext i1 [[ARG:%.*]] to i32 355; CHECK-NEXT: call void @use(i32 [[I]]) 356; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32 357; CHECK-NEXT: call void @use(i32 [[I2]]) 358; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1]], [[ARG]] 359; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true 360; CHECK-NEXT: ret i1 [[I4]] 361; 362bb: 363 %i = zext i1 %arg to i32 364 call void @use(i32 %i) 365 %i2 = zext i1 %arg1 to i32 366 call void @use(i32 %i2) 367 %i3 = add i32 %i2, %i 368 %i4 = icmp ne i32 %i3, 1 369 ret i1 %i4 370} 371 372define i1 @cvt_icmp_2_zext_plus_zext_ne(i1 %arg, i1 %arg1) { 373; CHECK-LABEL: @cvt_icmp_2_zext_plus_zext_ne( 374; CHECK-NEXT: bb: 375; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[ARG:%.*]], [[ARG1:%.*]] 376; CHECK-NEXT: [[T:%.*]] = xor i1 [[TMP0]], true 377; CHECK-NEXT: ret i1 [[T]] 378; 379bb: 380 %i = zext i1 %arg to i32 381 %i2 = zext i1 %arg1 to i32 382 %i3 = add i32 %i, %i2 383 %t = icmp ne i32 %i3, 2 384 ret i1 %t 385} 386 387define i1 @cvt_icmp_neg_2_sext_plus_sext_ne(i1 %arg, i1 %arg1) { 388; CHECK-LABEL: @cvt_icmp_neg_2_sext_plus_sext_ne( 389; CHECK-NEXT: bb: 390; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[ARG:%.*]], [[ARG1:%.*]] 391; CHECK-NEXT: [[T:%.*]] = xor i1 [[TMP0]], true 392; CHECK-NEXT: ret i1 [[T]] 393; 394bb: 395 %i = sext i1 %arg to i32 396 %i2 = sext i1 %arg1 to i32 397 %i3 = add i32 %i, %i2 398 %t = icmp ne i32 %i3, -2 399 ret i1 %t 400} 401 402define i1 @cvt_icmp_neg_1_sext_plus_sext_ne(i1 %arg, i1 %arg1) { 403; CHECK-LABEL: @cvt_icmp_neg_1_sext_plus_sext_ne( 404; CHECK-NEXT: bb: 405; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]] 406; CHECK-NEXT: [[T:%.*]] = xor i1 [[TMP0]], true 407; CHECK-NEXT: ret i1 [[T]] 408; 409bb: 410 %i = sext i1 %arg to i32 411 %i2 = sext i1 %arg1 to i32 412 %i3 = add i32 %i, %i2 413 %t = icmp ne i32 %i3, -1 414 ret i1 %t 415} 416 417define i1 @cvt_icmp_0_sext_plus_sext_ne(i1 %arg, i1 %arg1) { 418; CHECK-LABEL: @cvt_icmp_0_sext_plus_sext_ne( 419; CHECK-NEXT: bb: 420; CHECK-NEXT: [[T:%.*]] = or i1 [[ARG:%.*]], [[ARG1:%.*]] 421; CHECK-NEXT: ret i1 [[T]] 422; 423bb: 424 %i = sext i1 %arg to i32 425 %i2 = sext i1 %arg1 to i32 426 %i3 = add i32 %i, %i2 427 %t = icmp ne i32 %i3, 0 428 ret i1 %t 429} 430 431define i1 @cvt_icmp_1_sext_plus_sext_ne(i1 %arg, i1 %arg1) { 432; CHECK-LABEL: @cvt_icmp_1_sext_plus_sext_ne( 433; CHECK-NEXT: bb: 434; CHECK-NEXT: ret i1 true 435; 436bb: 437 %i = sext i1 %arg to i32 438 %i2 = sext i1 %arg1 to i32 439 %i3 = add i32 %i, %i2 440 %t = icmp ne i32 %i3, 1 441 ret i1 %t 442} 443 444define i1 @cvt_icmp_2_sext_plus_sext_ne(i1 %arg, i1 %arg1) { 445; CHECK-LABEL: @cvt_icmp_2_sext_plus_sext_ne( 446; CHECK-NEXT: bb: 447; CHECK-NEXT: ret i1 true 448; 449bb: 450 %i = sext i1 %arg to i32 451 %i2 = sext i1 %arg1 to i32 452 %i3 = add i32 %i, %i2 453 %t = icmp ne i32 %i3, 2 454 ret i1 %t 455} 456 457define i1 @cvt_icmp_neg_2_sext_plus_zext_ne(i1 %arg, i1 %arg1) { 458; CHECK-LABEL: @cvt_icmp_neg_2_sext_plus_zext_ne( 459; CHECK-NEXT: bb: 460; CHECK-NEXT: ret i1 true 461; 462bb: 463 %i = sext i1 %arg to i32 464 %i2 = zext i1 %arg1 to i32 465 %i3 = add i32 %i, %i2 466 %t = icmp ne i32 %i3, -2 467 ret i1 %t 468} 469 470define i1 @cvt_icmp_neg_1_sext_plus_zext_ne(i1 %arg, i1 %arg1) { 471; CHECK-LABEL: @cvt_icmp_neg_1_sext_plus_zext_ne( 472; CHECK-NEXT: bb: 473; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true 474; CHECK-NEXT: [[T:%.*]] = or i1 [[ARG1:%.*]], [[TMP0]] 475; CHECK-NEXT: ret i1 [[T]] 476; 477bb: 478 %i = sext i1 %arg to i32 479 %i2 = zext i1 %arg1 to i32 480 %i3 = add i32 %i, %i2 481 %t = icmp ne i32 %i3, -1 482 ret i1 %t 483} 484 485define i1 @cvt_icmp_0_sext_plus_zext_ne(i1 %arg, i1 %arg1) { 486; CHECK-LABEL: @cvt_icmp_0_sext_plus_zext_ne( 487; CHECK-NEXT: bb: 488; CHECK-NEXT: [[T:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]] 489; CHECK-NEXT: ret i1 [[T]] 490; 491bb: 492 %i = sext i1 %arg to i32 493 %i2 = zext i1 %arg1 to i32 494 %i3 = add i32 %i, %i2 495 %t = icmp ne i32 %i3, 0 496 ret i1 %t 497} 498 499define i1 @cvt_icmp_1_sext_plus_zext_ne(i1 %arg, i1 %arg1) { 500; CHECK-LABEL: @cvt_icmp_1_sext_plus_zext_ne( 501; CHECK-NEXT: bb: 502; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true 503; CHECK-NEXT: [[T:%.*]] = or i1 [[ARG:%.*]], [[TMP0]] 504; CHECK-NEXT: ret i1 [[T]] 505; 506bb: 507 %i = sext i1 %arg to i32 508 %i2 = zext i1 %arg1 to i32 509 %i3 = add i32 %i, %i2 510 %t = icmp ne i32 %i3, 1 511 ret i1 %t 512} 513 514define i1 @cvt_icmp_2_sext_plus_zext_ne(i1 %arg, i1 %arg1) { 515; CHECK-LABEL: @cvt_icmp_2_sext_plus_zext_ne( 516; CHECK-NEXT: bb: 517; CHECK-NEXT: ret i1 true 518; 519bb: 520 %i = sext i1 %arg to i32 521 %i2 = zext i1 %arg1 to i32 522 %i3 = add i32 %i, %i2 523 %t = icmp ne i32 %i3, 2 524 ret i1 %t 525} 526 527define <2 x i1> @cvt_icmp_2_sext_plus_zext_ne_vec(<2 x i1> %arg, <2 x i1> %arg1) { 528; CHECK-LABEL: @cvt_icmp_2_sext_plus_zext_ne_vec( 529; CHECK-NEXT: bb: 530; CHECK-NEXT: ret <2 x i1> splat (i1 true) 531; 532bb: 533 %i = sext <2 x i1> %arg to <2 x i32> 534 %i2 = zext <2 x i1> %arg1 to <2 x i32> 535 %i3 = add nsw <2 x i32> %i, %i2 536 %i4 = icmp ne <2 x i32> %i3, <i32 2, i32 2> 537 ret <2 x i1> %i4 538} 539 540; test if zext i1 X + sext i1 Y converted to sext i1 X + zext i1 Y 541; and then processed 542 543define i1 @cvt_icmp_neg_2_zext_plus_sext_eq(i1 %arg, i1 %arg1) { 544; CHECK-LABEL: @cvt_icmp_neg_2_zext_plus_sext_eq( 545; CHECK-NEXT: bb: 546; CHECK-NEXT: ret i1 false 547; 548bb: 549 %i = zext i1 %arg to i32 550 %i2 = sext i1 %arg1 to i32 551 %i3 = add i32 %i, %i2 552 %t = icmp eq i32 %i3, -2 553 ret i1 %t 554} 555 556define <2 x i1> @cvt_icmp_neg_2_zext_plus_sext_eq_vec(<2 x i1> %arg, <2 x i1> %arg1) { 557; CHECK-LABEL: @cvt_icmp_neg_2_zext_plus_sext_eq_vec( 558; CHECK-NEXT: bb: 559; CHECK-NEXT: ret <2 x i1> zeroinitializer 560; 561bb: 562 %i = zext <2 x i1> %arg to <2 x i32> 563 %i2 = sext <2 x i1> %arg1 to <2 x i32> 564 %i3 = add nsw <2 x i32> %i2, %i 565 %i4 = icmp eq <2 x i32> %i3, <i32 2, i32 2> 566 ret <2 x i1> %i4 567} 568 569define i1 @cvt_icmp_neg_1_zext_plus_sext_eq(i1 %arg, i1 %arg1) { 570; CHECK-LABEL: @cvt_icmp_neg_1_zext_plus_sext_eq( 571; CHECK-NEXT: bb: 572; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true 573; CHECK-NEXT: [[T:%.*]] = and i1 [[ARG1:%.*]], [[TMP0]] 574; CHECK-NEXT: ret i1 [[T]] 575; 576bb: 577 %i = zext i1 %arg to i32 578 %i2 = sext i1 %arg1 to i32 579 %i3 = add i32 %i, %i2 580 %t = icmp eq i32 %i3, -1 581 ret i1 %t 582} 583 584define i1 @cvt_icmp_0_zext_plus_sext_eq(i1 %arg, i1 %arg1) { 585; CHECK-LABEL: @cvt_icmp_0_zext_plus_sext_eq( 586; CHECK-NEXT: bb: 587; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]] 588; CHECK-NEXT: [[T:%.*]] = xor i1 [[TMP0]], true 589; CHECK-NEXT: ret i1 [[T]] 590; 591bb: 592 %i = zext i1 %arg to i32 593 %i2 = sext i1 %arg1 to i32 594 %i3 = add i32 %i, %i2 595 %t = icmp eq i32 %i3, 0 596 ret i1 %t 597} 598 599define i1 @cvt_icmp_1_zext_plus_sext_eq(i1 %arg, i1 %arg1) { 600; CHECK-LABEL: @cvt_icmp_1_zext_plus_sext_eq( 601; CHECK-NEXT: bb: 602; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true 603; CHECK-NEXT: [[T:%.*]] = and i1 [[ARG:%.*]], [[TMP0]] 604; CHECK-NEXT: ret i1 [[T]] 605; 606bb: 607 %i = zext i1 %arg to i32 608 %i2 = sext i1 %arg1 to i32 609 %i3 = add i32 %i, %i2 610 %t = icmp eq i32 %i3, 1 611 ret i1 %t 612} 613 614define i1 @cvt_icmp_2_zext_plus_sext_eq(i1 %arg, i1 %arg1) { 615; CHECK-LABEL: @cvt_icmp_2_zext_plus_sext_eq( 616; CHECK-NEXT: bb: 617; CHECK-NEXT: ret i1 false 618; 619bb: 620 %i = zext i1 %arg to i32 621 %i2 = sext i1 %arg1 to i32 622 %i3 = add i32 %i, %i2 623 %t = icmp eq i32 %i3, 2 624 ret i1 %t 625} 626 627define i1 @cvt_icmp_neg_2_zext_plus_sext_ne(i1 %arg, i1 %arg1) { 628; CHECK-LABEL: @cvt_icmp_neg_2_zext_plus_sext_ne( 629; CHECK-NEXT: bb: 630; CHECK-NEXT: ret i1 true 631; 632bb: 633 %i = zext i1 %arg to i32 634 %i2 = sext i1 %arg1 to i32 635 %i3 = add i32 %i, %i2 636 %t = icmp ne i32 %i3, -2 637 ret i1 %t 638} 639 640define i1 @cvt_icmp_neg_1_zext_plus_sext_ne(i1 %arg, i1 %arg1) { 641; CHECK-LABEL: @cvt_icmp_neg_1_zext_plus_sext_ne( 642; CHECK-NEXT: bb: 643; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true 644; CHECK-NEXT: [[T:%.*]] = or i1 [[ARG:%.*]], [[TMP0]] 645; CHECK-NEXT: ret i1 [[T]] 646; 647bb: 648 %i = zext i1 %arg to i32 649 %i2 = sext i1 %arg1 to i32 650 %i3 = add i32 %i, %i2 651 %t = icmp ne i32 %i3, -1 652 ret i1 %t 653} 654 655define i1 @cvt_icmp_0_zext_plus_sext_ne(i1 %arg, i1 %arg1) { 656; CHECK-LABEL: @cvt_icmp_0_zext_plus_sext_ne( 657; CHECK-NEXT: bb: 658; CHECK-NEXT: [[T:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]] 659; CHECK-NEXT: ret i1 [[T]] 660; 661bb: 662 %i = zext i1 %arg to i32 663 %i2 = sext i1 %arg1 to i32 664 %i3 = add i32 %i, %i2 665 %t = icmp ne i32 %i3, 0 666 ret i1 %t 667} 668 669define i1 @cvt_icmp_1_zext_plus_sext_ne(i1 %arg, i1 %arg1) { 670; CHECK-LABEL: @cvt_icmp_1_zext_plus_sext_ne( 671; CHECK-NEXT: bb: 672; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true 673; CHECK-NEXT: [[T:%.*]] = or i1 [[ARG1:%.*]], [[TMP0]] 674; CHECK-NEXT: ret i1 [[T]] 675; 676bb: 677 %i = zext i1 %arg to i32 678 %i2 = sext i1 %arg1 to i32 679 %i3 = add i32 %i, %i2 680 %t = icmp ne i32 %i3, 1 681 ret i1 %t 682} 683 684define i1 @cvt_icmp_2_zext_plus_sext_ne(i1 %arg, i1 %arg1) { 685; CHECK-LABEL: @cvt_icmp_2_zext_plus_sext_ne( 686; CHECK-NEXT: bb: 687; CHECK-NEXT: ret i1 true 688; 689bb: 690 %i = zext i1 %arg to i32 691 %i2 = sext i1 %arg1 to i32 692 %i3 = add i32 %i, %i2 693 %t = icmp ne i32 %i3, 2 694 ret i1 %t 695} 696 697; test zext/zext additions with more than one use 698 699define i1 @test_cvt_icmp1(i1 %arg, i1 %arg1, ptr %p) { 700; CHECK-LABEL: @test_cvt_icmp1( 701; CHECK-NEXT: bb: 702; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG:%.*]] to i32 703; CHECK-NEXT: store i32 [[I2]], ptr [[P:%.*]], align 4 704; CHECK-NEXT: ret i1 false 705; 706bb: 707 %i = zext i1 %arg to i32 708 %i2 = zext i1 %arg to i32 709 store i32 %i2, ptr %p 710 %i3 = load i32, ptr %p 711 %i4 = add i32 %i3, %i 712 %t = icmp eq i32 %i4, 1 713 ret i1 %t 714} 715 716define i1 @test_cvt_icmp2(i1 %arg, i1 %arg1, ptr %p) { 717; CHECK-LABEL: @test_cvt_icmp2( 718; CHECK-NEXT: bb: 719; CHECK-NEXT: [[I2:%.*]] = zext i1 [[ARG:%.*]] to i32 720; CHECK-NEXT: store i32 [[I2]], ptr [[P:%.*]], align 4 721; CHECK-NEXT: ret i1 false 722; 723bb: 724 %i = sext i1 %arg to i32 725 %i2 = zext i1 %arg to i32 726 store i32 %i2, ptr %p 727 %i3 = load i32, ptr %p 728 %i4 = add i32 %i3, %i 729 %t = icmp eq i32 %i4, 1 730 ret i1 %t 731} 732 733; tests for ult 734define i1 @test_zext_zext_cvt_neg_2_ult_icmp(i1 %arg, i1 %arg1) { 735; CHECK-LABEL: @test_zext_zext_cvt_neg_2_ult_icmp( 736; CHECK-NEXT: bb: 737; CHECK-NEXT: ret i1 true 738; 739bb: 740 %i = zext i1 %arg to i32 741 %i2 = zext i1 %arg1 to i32 742 %i3 = add i32 %i2, %i 743 %i4 = icmp ult i32 %i3, -2 744 ret i1 %i4 745} 746 747define i1 @test_zext_zext_cvt_neg_1_ult_icmp(i1 %arg, i1 %arg1) { 748; CHECK-LABEL: @test_zext_zext_cvt_neg_1_ult_icmp( 749; CHECK-NEXT: bb: 750; CHECK-NEXT: ret i1 true 751; 752bb: 753 %i = zext i1 %arg to i32 754 %i2 = zext i1 %arg1 to i32 755 %i3 = add i32 %i2, %i 756 %i4 = icmp ult i32 %i3, -1 757 ret i1 %i4 758} 759 760define i1 @test_zext_zext_cvt_0_ult_icmp(i1 %arg, i1 %arg1) { 761; CHECK-LABEL: @test_zext_zext_cvt_0_ult_icmp( 762; CHECK-NEXT: bb: 763; CHECK-NEXT: ret i1 false 764; 765bb: 766 %i = zext i1 %arg to i32 767 %i2 = zext i1 %arg1 to i32 768 %i3 = add i32 %i2, %i 769 %i4 = icmp ult i32 %i3, 0 770 ret i1 %i4 771} 772 773define i1 @test_zext_zext_cvt_2_ult_icmp(i1 %arg, i1 %arg1) { 774; CHECK-LABEL: @test_zext_zext_cvt_2_ult_icmp( 775; CHECK-NEXT: bb: 776; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]] 777; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true 778; CHECK-NEXT: ret i1 [[I4]] 779; 780bb: 781 %i = zext i1 %arg to i32 782 %i2 = zext i1 %arg1 to i32 783 %i3 = add i32 %i2, %i 784 %i4 = icmp ult i32 %i3, 2 785 ret i1 %i4 786} 787 788define i1 @test_sext_sext_cvt_neg_2_ult_icmp(i1 %arg, i1 %arg1) { 789; CHECK-LABEL: @test_sext_sext_cvt_neg_2_ult_icmp( 790; CHECK-NEXT: bb: 791; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]] 792; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true 793; CHECK-NEXT: ret i1 [[I4]] 794; 795bb: 796 %i = sext i1 %arg to i32 797 %i2 = sext i1 %arg1 to i32 798 %i3 = add i32 %i2, %i 799 %i4 = icmp ult i32 %i3, -2 800 ret i1 %i4 801} 802 803define i1 @test_sext_sext_cvt_neg_1_ult_icmp(i1 %arg, i1 %arg1) { 804; CHECK-LABEL: @test_sext_sext_cvt_neg_1_ult_icmp( 805; CHECK-NEXT: bb: 806; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]] 807; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true 808; CHECK-NEXT: ret i1 [[I4]] 809; 810bb: 811 %i = sext i1 %arg to i32 812 %i2 = sext i1 %arg1 to i32 813 %i3 = add i32 %i2, %i 814 %i4 = icmp ult i32 %i3, -1 815 ret i1 %i4 816} 817 818define i1 @test_sext_sext_cvt_0_ult_icmp(i1 %arg, i1 %arg1) { 819; CHECK-LABEL: @test_sext_sext_cvt_0_ult_icmp( 820; CHECK-NEXT: bb: 821; CHECK-NEXT: ret i1 false 822; 823bb: 824 %i = sext i1 %arg to i32 825 %i2 = sext i1 %arg1 to i32 826 %i3 = add i32 %i2, %i 827 %i4 = icmp ult i32 %i3, 0 828 ret i1 %i4 829} 830 831define i1 @test_sext_sext_cvt_1_ult_icmp(i1 %arg, i1 %arg1) { 832; CHECK-LABEL: @test_sext_sext_cvt_1_ult_icmp( 833; CHECK-NEXT: bb: 834; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]] 835; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true 836; CHECK-NEXT: ret i1 [[I4]] 837; 838bb: 839 %i = sext i1 %arg to i32 840 %i2 = sext i1 %arg1 to i32 841 %i3 = add i32 %i2, %i 842 %i4 = icmp ult i32 %i3, 1 843 ret i1 %i4 844} 845 846define i1 @test_sext_sext_cvt_2_ult_icmp(i1 %arg, i1 %arg1) { 847; CHECK-LABEL: @test_sext_sext_cvt_2_ult_icmp( 848; CHECK-NEXT: bb: 849; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]] 850; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true 851; CHECK-NEXT: ret i1 [[I4]] 852; 853bb: 854 %i = sext i1 %arg to i32 855 %i2 = sext i1 %arg1 to i32 856 %i3 = add i32 %i2, %i 857 %i4 = icmp ult i32 %i3, 2 858 ret i1 %i4 859} 860 861define i1 @test_sext_zext_cvt_neg_2_ult_icmp(i1 %arg, i1 %arg1) { 862; CHECK-LABEL: @test_sext_zext_cvt_neg_2_ult_icmp( 863; CHECK-NEXT: bb: 864; CHECK-NEXT: [[ARG_NOT:%.*]] = xor i1 [[ARG:%.*]], true 865; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG_NOT]] 866; CHECK-NEXT: ret i1 [[I4]] 867; 868bb: 869 %i = sext i1 %arg to i32 870 %i2 = zext i1 %arg1 to i32 871 %i3 = add i32 %i2, %i 872 %i4 = icmp ult i32 %i3, -2 873 ret i1 %i4 874} 875 876define i1 @test_sext_zext_cvt_neg_1_ult_icmp(i1 %arg, i1 %arg1) { 877; CHECK-LABEL: @test_sext_zext_cvt_neg_1_ult_icmp( 878; CHECK-NEXT: bb: 879; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true 880; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[TMP0]] 881; CHECK-NEXT: ret i1 [[I4]] 882; 883bb: 884 %i = sext i1 %arg to i32 885 %i2 = zext i1 %arg1 to i32 886 %i3 = add i32 %i2, %i 887 %i4 = icmp ult i32 %i3, -1 888 ret i1 %i4 889} 890 891define i1 @test_sext_zext_cvt_0_ult_icmp(i1 %arg, i1 %arg1) { 892; CHECK-LABEL: @test_sext_zext_cvt_0_ult_icmp( 893; CHECK-NEXT: bb: 894; CHECK-NEXT: ret i1 false 895; 896bb: 897 %i = sext i1 %arg to i32 898 %i2 = zext i1 %arg1 to i32 899 %i3 = add i32 %i2, %i 900 %i4 = icmp ult i32 %i3, 0 901 ret i1 %i4 902} 903 904define i1 @test_sext_zext_cvt_2_ult_icmp(i1 %arg, i1 %arg1) { 905; CHECK-LABEL: @test_sext_zext_cvt_2_ult_icmp( 906; CHECK-NEXT: bb: 907; CHECK-NEXT: [[ARG_NOT:%.*]] = xor i1 [[ARG:%.*]], true 908; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG_NOT]] 909; CHECK-NEXT: ret i1 [[I4]] 910; 911bb: 912 %i = sext i1 %arg to i32 913 %i2 = zext i1 %arg1 to i32 914 %i3 = add i32 %i2, %i 915 %i4 = icmp ult i32 %i3, 2 916 ret i1 %i4 917} 918 919define i1 @test_zext_sext_cvt_neg_1_ult_icmp(i1 %arg, i1 %arg1) { 920; CHECK-LABEL: @test_zext_sext_cvt_neg_1_ult_icmp( 921; CHECK-NEXT: bb: 922; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true 923; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG:%.*]], [[TMP0]] 924; CHECK-NEXT: ret i1 [[I4]] 925; 926bb: 927 %i = zext i1 %arg to i32 928 %i2 = sext i1 %arg1 to i32 929 %i3 = add i32 %i2, %i 930 %i4 = icmp ult i32 %i3, -1 931 ret i1 %i4 932} 933 934define i1 @test_zext_sext_cvt_0_ult_icmp(i1 %arg, i1 %arg1) { 935; CHECK-LABEL: @test_zext_sext_cvt_0_ult_icmp( 936; CHECK-NEXT: bb: 937; CHECK-NEXT: ret i1 false 938; 939bb: 940 %i = zext i1 %arg to i32 941 %i2 = sext i1 %arg1 to i32 942 %i3 = add i32 %i2, %i 943 %i4 = icmp ult i32 %i3, 0 944 ret i1 %i4 945} 946 947define i1 @test_zext_sext_cvt_1_ult_icmp(i1 %arg, i1 %arg1) { 948; CHECK-LABEL: @test_zext_sext_cvt_1_ult_icmp( 949; CHECK-NEXT: bb: 950; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]] 951; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true 952; CHECK-NEXT: ret i1 [[I4]] 953; 954bb: 955 %i = zext i1 %arg to i32 956 %i2 = sext i1 %arg1 to i32 957 %i3 = add i32 %i2, %i 958 %i4 = icmp ult i32 %i3, 1 959 ret i1 %i4 960} 961 962; tests for ugt 963define i1 @test_cvt_icmp4(i1 %arg, i1 %arg1) { 964; CHECK-LABEL: @test_cvt_icmp4( 965; CHECK-NEXT: bb: 966; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]] 967; CHECK-NEXT: ret i1 [[I4]] 968; 969bb: 970 %i = zext i1 %arg to i32 971 %i2 = zext i1 %arg1 to i32 972 %i3 = add i32 %i2, %i 973 %i4 = icmp ugt i32 %i3, 0 974 ret i1 %i4 975} 976 977define i1 @test_zext_zext_cvt_neg_2_ugt_icmp(i1 %arg, i1 %arg1) { 978; CHECK-LABEL: @test_zext_zext_cvt_neg_2_ugt_icmp( 979; CHECK-NEXT: bb: 980; CHECK-NEXT: ret i1 false 981; 982bb: 983 %i = zext i1 %arg to i32 984 %i2 = zext i1 %arg1 to i32 985 %i3 = add i32 %i2, %i 986 %i4 = icmp ugt i32 %i3, -2 987 ret i1 %i4 988} 989 990define i1 @test_zext_zext_cvt_1_ugt_icmp(i1 %arg, i1 %arg1) { 991; CHECK-LABEL: @test_zext_zext_cvt_1_ugt_icmp( 992; CHECK-NEXT: bb: 993; CHECK-NEXT: [[I4:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]] 994; CHECK-NEXT: ret i1 [[I4]] 995; 996bb: 997 %i = zext i1 %arg to i32 998 %i2 = zext i1 %arg1 to i32 999 %i3 = add i32 %i2, %i 1000 %i4 = icmp ugt i32 %i3, 1 1001 ret i1 %i4 1002} 1003 1004define i1 @test_zext_zext_cvt_2_ugt_icmp(i1 %arg, i1 %arg1) { 1005; CHECK-LABEL: @test_zext_zext_cvt_2_ugt_icmp( 1006; CHECK-NEXT: bb: 1007; CHECK-NEXT: ret i1 false 1008; 1009bb: 1010 %i = zext i1 %arg to i32 1011 %i2 = zext i1 %arg1 to i32 1012 %i3 = add i32 %i2, %i 1013 %i4 = icmp ugt i32 %i3, 2 1014 ret i1 %i4 1015} 1016 1017define i1 @test_sext_sext_cvt_neg_2_ugt_icmp(i1 %arg, i1 %arg1) { 1018; CHECK-LABEL: @test_sext_sext_cvt_neg_2_ugt_icmp( 1019; CHECK-NEXT: bb: 1020; CHECK-NEXT: [[I4:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]] 1021; CHECK-NEXT: ret i1 [[I4]] 1022; 1023bb: 1024 %i = sext i1 %arg to i32 1025 %i2 = sext i1 %arg1 to i32 1026 %i3 = add i32 %i2, %i 1027 %i4 = icmp ugt i32 %i3, -2 1028 ret i1 %i4 1029} 1030 1031define i1 @test_sext_sext_cvt_0_ugt_icmp(i1 %arg, i1 %arg1) { 1032; CHECK-LABEL: @test_sext_sext_cvt_0_ugt_icmp( 1033; CHECK-NEXT: bb: 1034; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]] 1035; CHECK-NEXT: ret i1 [[I4]] 1036; 1037bb: 1038 %i = sext i1 %arg to i32 1039 %i2 = sext i1 %arg1 to i32 1040 %i3 = add i32 %i2, %i 1041 %i4 = icmp ugt i32 %i3, 0 1042 ret i1 %i4 1043} 1044 1045define i1 @test_sext_sext_cvt_2_ugt_icmp(i1 %arg, i1 %arg1) { 1046; CHECK-LABEL: @test_sext_sext_cvt_2_ugt_icmp( 1047; CHECK-NEXT: bb: 1048; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]] 1049; CHECK-NEXT: ret i1 [[I4]] 1050; 1051bb: 1052 %i = sext i1 %arg to i32 1053 %i2 = sext i1 %arg1 to i32 1054 %i3 = add i32 %i2, %i 1055 %i4 = icmp ugt i32 %i3, 2 1056 ret i1 %i4 1057} 1058 1059define i1 @test_zext_sext_cvt_neg_2_ugt_icmp(i1 %arg, i1 %arg1) { 1060; CHECK-LABEL: @test_zext_sext_cvt_neg_2_ugt_icmp( 1061; CHECK-NEXT: bb: 1062; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true 1063; CHECK-NEXT: [[I4:%.*]] = and i1 [[ARG1:%.*]], [[TMP0]] 1064; CHECK-NEXT: ret i1 [[I4]] 1065; 1066bb: 1067 %i = zext i1 %arg to i32 1068 %i2 = sext i1 %arg1 to i32 1069 %i3 = add i32 %i2, %i 1070 %i4 = icmp ugt i32 %i3, -2 1071 ret i1 %i4 1072} 1073 1074define i1 @test_zext_sext_cvt_neg_1_ugt_icmp(i1 %arg, i1 %arg1) { 1075; CHECK-LABEL: @test_zext_sext_cvt_neg_1_ugt_icmp( 1076; CHECK-NEXT: bb: 1077; CHECK-NEXT: ret i1 false 1078; 1079bb: 1080 %i = zext i1 %arg to i32 1081 %i2 = sext i1 %arg1 to i32 1082 %i3 = add i32 %i2, %i 1083 %i4 = icmp ugt i32 %i3, -1 1084 ret i1 %i4 1085} 1086 1087define i1 @test_zext_sext_cvt_0_ugt_icmp(i1 %arg, i1 %arg1) { 1088; CHECK-LABEL: @test_zext_sext_cvt_0_ugt_icmp( 1089; CHECK-NEXT: bb: 1090; CHECK-NEXT: [[I4:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]] 1091; CHECK-NEXT: ret i1 [[I4]] 1092; 1093bb: 1094 %i = zext i1 %arg to i32 1095 %i2 = sext i1 %arg1 to i32 1096 %i3 = add i32 %i2, %i 1097 %i4 = icmp ugt i32 %i3, 0 1098 ret i1 %i4 1099} 1100 1101define i1 @test_zext_sext_cvt_1_ugt_icmp(i1 %arg, i1 %arg1) { 1102; CHECK-LABEL: @test_zext_sext_cvt_1_ugt_icmp( 1103; CHECK-NEXT: bb: 1104; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true 1105; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[ARG1:%.*]], [[TMP0]] 1106; CHECK-NEXT: ret i1 [[TMP1]] 1107; 1108bb: 1109 %i = zext i1 %arg to i32 1110 %i2 = sext i1 %arg1 to i32 1111 %i3 = add i32 %i2, %i 1112 %i4 = icmp ugt i32 %i3, 1 1113 ret i1 %i4 1114} 1115 1116define i1 @test_zext_sext_cvt_2_ugt_icmp(i1 %arg, i1 %arg1) { 1117; CHECK-LABEL: @test_zext_sext_cvt_2_ugt_icmp( 1118; CHECK-NEXT: bb: 1119; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true 1120; CHECK-NEXT: [[I4:%.*]] = and i1 [[ARG1:%.*]], [[TMP0]] 1121; CHECK-NEXT: ret i1 [[I4]] 1122; 1123bb: 1124 %i = zext i1 %arg to i32 1125 %i2 = sext i1 %arg1 to i32 1126 %i3 = add i32 %i2, %i 1127 %i4 = icmp ugt i32 %i3, 2 1128 ret i1 %i4 1129} 1130 1131define i1 @test_cvt_icmp5(i1 %arg, i1 %arg1) { 1132; CHECK-LABEL: @test_cvt_icmp5( 1133; CHECK-NEXT: bb: 1134; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]] 1135; CHECK-NEXT: ret i1 [[I4]] 1136; 1137bb: 1138 %i = zext i1 %arg to i32 1139 %i2 = zext i1 %arg1 to i32 1140 %i3 = add i32 %i2, %i 1141 %i4 = icmp uge i32 %i3, 1 1142 ret i1 %i4 1143} 1144 1145define i1 @test_cvt_icmp6(i1 %arg, i1 %arg1) { 1146; CHECK-LABEL: @test_cvt_icmp6( 1147; CHECK-NEXT: bb: 1148; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]] 1149; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true 1150; CHECK-NEXT: ret i1 [[I4]] 1151; 1152bb: 1153 %i = zext i1 %arg to i32 1154 %i2 = zext i1 %arg1 to i32 1155 %i3 = add i32 %i2, %i 1156 %i4 = icmp ule i32 %i3, 1 1157 ret i1 %i4 1158} 1159 1160; tests for sgt 1161define i1 @test_cvt_icmp7(i1 %arg, i1 %arg1) { 1162; CHECK-LABEL: @test_cvt_icmp7( 1163; CHECK-NEXT: bb: 1164; CHECK-NEXT: [[I4:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]] 1165; CHECK-NEXT: ret i1 [[I4]] 1166; 1167bb: 1168 %i = zext i1 %arg to i32 1169 %i2 = zext i1 %arg1 to i32 1170 %i3 = add i32 %i2, %i 1171 %i4 = icmp sgt i32 %i3, 1 1172 ret i1 %i4 1173} 1174 1175define i1 @test_zext_zext_cvt_neg_2_sgt_icmp(i1 %arg, i1 %arg1) { 1176; CHECK-LABEL: @test_zext_zext_cvt_neg_2_sgt_icmp( 1177; CHECK-NEXT: bb: 1178; CHECK-NEXT: ret i1 true 1179; 1180bb: 1181 %i = zext i1 %arg to i32 1182 %i2 = zext i1 %arg1 to i32 1183 %i3 = add i32 %i2, %i 1184 %i4 = icmp sgt i32 %i3, -2 1185 ret i1 %i4 1186} 1187 1188define i1 @test_zext_zext_cvt_neg_1_sgt_icmp(i1 %arg, i1 %arg1) { 1189; CHECK-LABEL: @test_zext_zext_cvt_neg_1_sgt_icmp( 1190; CHECK-NEXT: bb: 1191; CHECK-NEXT: ret i1 true 1192; 1193bb: 1194 %i = zext i1 %arg to i32 1195 %i2 = zext i1 %arg1 to i32 1196 %i3 = add i32 %i2, %i 1197 %i4 = icmp sgt i32 %i3, -1 1198 ret i1 %i4 1199} 1200 1201define i1 @test_zext_zext_cvt_2_sgt_icmp(i1 %arg, i1 %arg1) { 1202; CHECK-LABEL: @test_zext_zext_cvt_2_sgt_icmp( 1203; CHECK-NEXT: bb: 1204; CHECK-NEXT: ret i1 false 1205; 1206bb: 1207 %i = zext i1 %arg to i32 1208 %i2 = zext i1 %arg1 to i32 1209 %i3 = add i32 %i2, %i 1210 %i4 = icmp sgt i32 %i3, 2 1211 ret i1 %i4 1212} 1213 1214define i1 @test_sext_sext_cvt_neg_2_sgt_icmp(i1 %arg, i1 %arg1) { 1215; CHECK-LABEL: @test_sext_sext_cvt_neg_2_sgt_icmp( 1216; CHECK-NEXT: bb: 1217; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]] 1218; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true 1219; CHECK-NEXT: ret i1 [[I4]] 1220; 1221bb: 1222 %i = sext i1 %arg to i32 1223 %i2 = sext i1 %arg1 to i32 1224 %i3 = add i32 %i2, %i 1225 %i4 = icmp sgt i32 %i3, -2 1226 ret i1 %i4 1227} 1228 1229define i1 @test_sext_sext_cvt_0_sgt_icmp(i1 %arg, i1 %arg1) { 1230; CHECK-LABEL: @test_sext_sext_cvt_0_sgt_icmp( 1231; CHECK-NEXT: bb: 1232; CHECK-NEXT: ret i1 false 1233; 1234bb: 1235 %i = sext i1 %arg to i32 1236 %i2 = sext i1 %arg1 to i32 1237 %i3 = add i32 %i2, %i 1238 %i4 = icmp sgt i32 %i3, 0 1239 ret i1 %i4 1240} 1241 1242define i1 @test_sext_sext_cvt_2_sgt_icmp(i1 %arg, i1 %arg1) { 1243; CHECK-LABEL: @test_sext_sext_cvt_2_sgt_icmp( 1244; CHECK-NEXT: bb: 1245; CHECK-NEXT: ret i1 false 1246; 1247bb: 1248 %i = sext i1 %arg to i32 1249 %i2 = sext i1 %arg1 to i32 1250 %i3 = add i32 %i2, %i 1251 %i4 = icmp sgt i32 %i3, 2 1252 ret i1 %i4 1253} 1254 1255define i1 @test_zext_sext_cvt_neg_2_sgt_icmp(i1 %arg, i1 %arg1) { 1256; CHECK-LABEL: @test_zext_sext_cvt_neg_2_sgt_icmp( 1257; CHECK-NEXT: bb: 1258; CHECK-NEXT: ret i1 true 1259; 1260bb: 1261 %i = zext i1 %arg to i32 1262 %i2 = sext i1 %arg1 to i32 1263 %i3 = add i32 %i2, %i 1264 %i4 = icmp sgt i32 %i3, -2 1265 ret i1 %i4 1266} 1267 1268define i1 @test_zext_sext_cvt_neg_1_sgt_icmp(i1 %arg, i1 %arg1) { 1269; CHECK-LABEL: @test_zext_sext_cvt_neg_1_sgt_icmp( 1270; CHECK-NEXT: bb: 1271; CHECK-NEXT: [[ARG1_NOT:%.*]] = xor i1 [[ARG1:%.*]], true 1272; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG:%.*]], [[ARG1_NOT]] 1273; CHECK-NEXT: ret i1 [[I4]] 1274; 1275bb: 1276 %i = zext i1 %arg to i32 1277 %i2 = sext i1 %arg1 to i32 1278 %i3 = add i32 %i2, %i 1279 %i4 = icmp sgt i32 %i3, -1 1280 ret i1 %i4 1281} 1282 1283define i1 @test_zext_sext_cvt_0_sgt_icmp(i1 %arg, i1 %arg1) { 1284; CHECK-LABEL: @test_zext_sext_cvt_0_sgt_icmp( 1285; CHECK-NEXT: bb: 1286; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true 1287; CHECK-NEXT: [[I4:%.*]] = and i1 [[ARG:%.*]], [[TMP0]] 1288; CHECK-NEXT: ret i1 [[I4]] 1289; 1290bb: 1291 %i = zext i1 %arg to i32 1292 %i2 = sext i1 %arg1 to i32 1293 %i3 = add i32 %i2, %i 1294 %i4 = icmp sgt i32 %i3, 0 1295 ret i1 %i4 1296} 1297 1298define i1 @test_zext_sext_cvt_1_sgt_icmp(i1 %arg, i1 %arg1) { 1299; CHECK-LABEL: @test_zext_sext_cvt_1_sgt_icmp( 1300; CHECK-NEXT: bb: 1301; CHECK-NEXT: ret i1 false 1302; 1303bb: 1304 %i = zext i1 %arg to i32 1305 %i2 = sext i1 %arg1 to i32 1306 %i3 = add i32 %i2, %i 1307 %i4 = icmp sgt i32 %i3, 1 1308 ret i1 %i4 1309} 1310 1311define i1 @test_zext_sext_cvt_2_sgt_icmp(i1 %arg, i1 %arg1) { 1312; CHECK-LABEL: @test_zext_sext_cvt_2_sgt_icmp( 1313; CHECK-NEXT: bb: 1314; CHECK-NEXT: ret i1 false 1315; 1316bb: 1317 %i = zext i1 %arg to i32 1318 %i2 = sext i1 %arg1 to i32 1319 %i3 = add i32 %i2, %i 1320 %i4 = icmp sgt i32 %i3, 2 1321 ret i1 %i4 1322} 1323 1324; tests for slt 1325define i1 @test_zext_zext_cvt_neg_2_slt_icmp(i1 %arg, i1 %arg1) { 1326; CHECK-LABEL: @test_zext_zext_cvt_neg_2_slt_icmp( 1327; CHECK-NEXT: bb: 1328; CHECK-NEXT: ret i1 false 1329; 1330bb: 1331 %i = zext i1 %arg to i32 1332 %i2 = zext i1 %arg1 to i32 1333 %i3 = add i32 %i2, %i 1334 %i4 = icmp slt i32 %i3, -2 1335 ret i1 %i4 1336} 1337 1338define i1 @test_zext_zext_cvt_neg_1_slt_icmp(i1 %arg, i1 %arg1) { 1339; CHECK-LABEL: @test_zext_zext_cvt_neg_1_slt_icmp( 1340; CHECK-NEXT: bb: 1341; CHECK-NEXT: ret i1 false 1342; 1343bb: 1344 %i = zext i1 %arg to i32 1345 %i2 = zext i1 %arg1 to i32 1346 %i3 = add i32 %i2, %i 1347 %i4 = icmp slt i32 %i3, -1 1348 ret i1 %i4 1349} 1350 1351define i1 @test_zext_zext_cvt_2_slt_icmp(i1 %arg, i1 %arg1) { 1352; CHECK-LABEL: @test_zext_zext_cvt_2_slt_icmp( 1353; CHECK-NEXT: bb: 1354; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]] 1355; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true 1356; CHECK-NEXT: ret i1 [[I4]] 1357; 1358bb: 1359 %i = zext i1 %arg to i32 1360 %i2 = zext i1 %arg1 to i32 1361 %i3 = add i32 %i2, %i 1362 %i4 = icmp slt i32 %i3, 2 1363 ret i1 %i4 1364} 1365 1366define i1 @test_sext_sext_cvt_neg_2_slt_icmp(i1 %arg, i1 %arg1) { 1367; CHECK-LABEL: @test_sext_sext_cvt_neg_2_slt_icmp( 1368; CHECK-NEXT: bb: 1369; CHECK-NEXT: ret i1 false 1370; 1371bb: 1372 %i = sext i1 %arg to i32 1373 %i2 = sext i1 %arg1 to i32 1374 %i3 = add i32 %i2, %i 1375 %i4 = icmp slt i32 %i3, -2 1376 ret i1 %i4 1377} 1378 1379define i1 @test_sext_sext_cvt_0_slt_icmp(i1 %arg, i1 %arg1) { 1380; CHECK-LABEL: @test_sext_sext_cvt_0_slt_icmp( 1381; CHECK-NEXT: bb: 1382; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]] 1383; CHECK-NEXT: ret i1 [[TMP0]] 1384; 1385bb: 1386 %i = sext i1 %arg to i32 1387 %i2 = sext i1 %arg1 to i32 1388 %i3 = add i32 %i2, %i 1389 %i4 = icmp slt i32 %i3, 0 1390 ret i1 %i4 1391} 1392 1393define i1 @test_sext_sext_cvt_2_slt_icmp(i1 %arg, i1 %arg1) { 1394; CHECK-LABEL: @test_sext_sext_cvt_2_slt_icmp( 1395; CHECK-NEXT: bb: 1396; CHECK-NEXT: ret i1 true 1397; 1398bb: 1399 %i = sext i1 %arg to i32 1400 %i2 = sext i1 %arg1 to i32 1401 %i3 = add i32 %i2, %i 1402 %i4 = icmp slt i32 %i3, 2 1403 ret i1 %i4 1404} 1405 1406define i1 @test_zext_sext_cvt_neg_2_slt_icmp(i1 %arg, i1 %arg1) { 1407; CHECK-LABEL: @test_zext_sext_cvt_neg_2_slt_icmp( 1408; CHECK-NEXT: bb: 1409; CHECK-NEXT: ret i1 false 1410; 1411bb: 1412 %i = zext i1 %arg to i32 1413 %i2 = sext i1 %arg1 to i32 1414 %i3 = add i32 %i2, %i 1415 %i4 = icmp slt i32 %i3, -2 1416 ret i1 %i4 1417} 1418 1419define i1 @test_zext_sext_cvt_neg_1_slt_icmp(i1 %arg, i1 %arg1) { 1420; CHECK-LABEL: @test_zext_sext_cvt_neg_1_slt_icmp( 1421; CHECK-NEXT: bb: 1422; CHECK-NEXT: ret i1 false 1423; 1424bb: 1425 %i = zext i1 %arg to i32 1426 %i2 = sext i1 %arg1 to i32 1427 %i3 = add i32 %i2, %i 1428 %i4 = icmp slt i32 %i3, -1 1429 ret i1 %i4 1430} 1431 1432define i1 @test_zext_sext_cvt_0_slt_icmp(i1 %arg, i1 %arg1) { 1433; CHECK-LABEL: @test_zext_sext_cvt_0_slt_icmp( 1434; CHECK-NEXT: bb: 1435; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true 1436; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[ARG1:%.*]], [[TMP0]] 1437; CHECK-NEXT: ret i1 [[TMP1]] 1438; 1439bb: 1440 %i = zext i1 %arg to i32 1441 %i2 = sext i1 %arg1 to i32 1442 %i3 = add i32 %i2, %i 1443 %i4 = icmp slt i32 %i3, 0 1444 ret i1 %i4 1445} 1446 1447define i1 @test_zext_sext_cvt_1_slt_icmp(i1 %arg, i1 %arg1) { 1448; CHECK-LABEL: @test_zext_sext_cvt_1_slt_icmp( 1449; CHECK-NEXT: bb: 1450; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true 1451; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[TMP0]] 1452; CHECK-NEXT: ret i1 [[I4]] 1453; 1454bb: 1455 %i = zext i1 %arg to i32 1456 %i2 = sext i1 %arg1 to i32 1457 %i3 = add i32 %i2, %i 1458 %i4 = icmp slt i32 %i3, 1 1459 ret i1 %i4 1460} 1461 1462define i1 @test_zext_sext_cvt_2_slt_icmp(i1 %arg, i1 %arg1) { 1463; CHECK-LABEL: @test_zext_sext_cvt_2_slt_icmp( 1464; CHECK-NEXT: bb: 1465; CHECK-NEXT: ret i1 true 1466; 1467bb: 1468 %i = zext i1 %arg to i32 1469 %i2 = sext i1 %arg1 to i32 1470 %i3 = add i32 %i2, %i 1471 %i4 = icmp slt i32 %i3, 2 1472 ret i1 %i4 1473} 1474 1475define i1 @test_cvt_icmp8(i1 %arg, i1 %arg1) { 1476; CHECK-LABEL: @test_cvt_icmp8( 1477; CHECK-NEXT: bb: 1478; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]] 1479; CHECK-NEXT: ret i1 [[I4]] 1480; 1481bb: 1482 %i = zext i1 %arg to i32 1483 %i2 = zext i1 %arg1 to i32 1484 %i3 = add i32 %i2, %i 1485 %i4 = icmp sge i32 %i3, 1 1486 ret i1 %i4 1487} 1488 1489define i1 @test_cvt_icmp9(i1 %arg, i1 %arg1) { 1490; CHECK-LABEL: @test_cvt_icmp9( 1491; CHECK-NEXT: bb: 1492; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]] 1493; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true 1494; CHECK-NEXT: ret i1 [[I4]] 1495; 1496bb: 1497 %i = zext i1 %arg to i32 1498 %i2 = zext i1 %arg1 to i32 1499 %i3 = add i32 %i2, %i 1500 %i4 = icmp slt i32 %i3, 1 1501 ret i1 %i4 1502} 1503 1504define i1 @test_cvt_icmp10(i1 %arg, i1 %arg1) { 1505; CHECK-LABEL: @test_cvt_icmp10( 1506; CHECK-NEXT: bb: 1507; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]] 1508; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true 1509; CHECK-NEXT: ret i1 [[I4]] 1510; 1511bb: 1512 %i = zext i1 %arg to i32 1513 %i2 = zext i1 %arg1 to i32 1514 %i3 = add i32 %i2, %i 1515 %i4 = icmp sle i32 %i3, 1 1516 ret i1 %i4 1517} 1518 1519define i1 @test_cvt_icmp11(i1 %arg, i1 %arg1) { 1520; CHECK-LABEL: @test_cvt_icmp11( 1521; CHECK-NEXT: bb: 1522; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]] 1523; CHECK-NEXT: ret i1 [[I4]] 1524; 1525bb: 1526 %i = sext i1 %arg to i32 1527 %i2 = sext i1 %arg1 to i32 1528 %i3 = add i32 %i2, %i 1529 %i4 = icmp ugt i32 %i3, 2 1530 ret i1 %i4 1531} 1532 1533define i1 @test_cvt_icmp12(i1 %arg, i1 %arg1) { 1534; CHECK-LABEL: @test_cvt_icmp12( 1535; CHECK-NEXT: bb: 1536; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]] 1537; CHECK-NEXT: ret i1 [[I4]] 1538; 1539bb: 1540 %i = sext i1 %arg to i32 1541 %i2 = sext i1 %arg1 to i32 1542 %i3 = add i32 %i2, %i 1543 %i4 = icmp uge i32 %i3, 1 1544 ret i1 %i4 1545} 1546 1547define i1 @test_cvt_icmp13(i1 %arg, i1 %arg1) { 1548; CHECK-LABEL: @test_cvt_icmp13( 1549; CHECK-NEXT: bb: 1550; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]] 1551; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true 1552; CHECK-NEXT: ret i1 [[I4]] 1553; 1554bb: 1555 %i = sext i1 %arg to i32 1556 %i2 = sext i1 %arg1 to i32 1557 %i3 = add i32 %i2, %i 1558 %i4 = icmp ult i32 %i3, 1 1559 ret i1 %i4 1560} 1561 1562define i1 @test_cvt_icmp14(i1 %arg, i1 %arg1) { 1563; CHECK-LABEL: @test_cvt_icmp14( 1564; CHECK-NEXT: bb: 1565; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]] 1566; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true 1567; CHECK-NEXT: ret i1 [[I4]] 1568; 1569bb: 1570 %i = sext i1 %arg to i32 1571 %i2 = sext i1 %arg1 to i32 1572 %i3 = add i32 %i2, %i 1573 %i4 = icmp ule i32 %i3, 2 1574 ret i1 %i4 1575} 1576 1577define i1 @test_cvt_icmp15(i1 %arg, i1 %arg1) { 1578; CHECK-LABEL: @test_cvt_icmp15( 1579; CHECK-NEXT: bb: 1580; CHECK-NEXT: ret i1 false 1581; 1582bb: 1583 %i = sext i1 %arg to i32 1584 %i2 = sext i1 %arg1 to i32 1585 %i3 = add i32 %i2, %i 1586 %i4 = icmp sgt i32 %i3, 2 1587 ret i1 %i4 1588} 1589 1590define i1 @test_cvt_icmp16(i1 %arg, i1 %arg1) { 1591; CHECK-LABEL: @test_cvt_icmp16( 1592; CHECK-NEXT: bb: 1593; CHECK-NEXT: ret i1 false 1594; 1595bb: 1596 %i = sext i1 %arg to i32 1597 %i2 = sext i1 %arg1 to i32 1598 %i3 = add i32 %i2, %i 1599 %i4 = icmp sge i32 %i3, 2 1600 ret i1 %i4 1601} 1602 1603define i1 @test_cvt_icmp17(i1 %arg, i1 %arg1) { 1604; CHECK-LABEL: @test_cvt_icmp17( 1605; CHECK-NEXT: bb: 1606; CHECK-NEXT: ret i1 true 1607; 1608bb: 1609 %i = sext i1 %arg to i32 1610 %i2 = sext i1 %arg1 to i32 1611 %i3 = add i32 %i2, %i 1612 %i4 = icmp slt i32 %i3, 2 1613 ret i1 %i4 1614} 1615 1616define i1 @test_cvt_icmp18(i1 %arg, i1 %arg1) { 1617; CHECK-LABEL: @test_cvt_icmp18( 1618; CHECK-NEXT: bb: 1619; CHECK-NEXT: ret i1 true 1620; 1621bb: 1622 %i = sext i1 %arg to i32 1623 %i2 = sext i1 %arg1 to i32 1624 %i3 = add i32 %i2, %i 1625 %i4 = icmp sle i32 %i3, 2 1626 ret i1 %i4 1627} 1628 1629define i1 @test_cvt_icmp19(i1 %arg, i1 %arg1) { 1630; CHECK-LABEL: @test_cvt_icmp19( 1631; CHECK-NEXT: bb: 1632; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true 1633; CHECK-NEXT: [[I4:%.*]] = and i1 [[ARG:%.*]], [[TMP0]] 1634; CHECK-NEXT: ret i1 [[I4]] 1635; 1636bb: 1637 %i = sext i1 %arg to i32 1638 %i2 = zext i1 %arg1 to i32 1639 %i3 = add i32 %i2, %i 1640 %i4 = icmp ugt i32 %i3, 2 1641 ret i1 %i4 1642} 1643 1644define i1 @test_cvt_icmp20(i1 %arg, i1 %arg1) { 1645; CHECK-LABEL: @test_cvt_icmp20( 1646; CHECK-NEXT: bb: 1647; CHECK-NEXT: [[I4:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]] 1648; CHECK-NEXT: ret i1 [[I4]] 1649; 1650bb: 1651 %i = sext i1 %arg to i32 1652 %i2 = zext i1 %arg1 to i32 1653 %i3 = add i32 %i2, %i 1654 %i4 = icmp uge i32 %i3, 1 1655 ret i1 %i4 1656} 1657 1658define i1 @test_cvt_icmp21(i1 %arg, i1 %arg1) { 1659; CHECK-LABEL: @test_cvt_icmp21( 1660; CHECK-NEXT: bb: 1661; CHECK-NEXT: [[ARG_NOT:%.*]] = xor i1 [[ARG:%.*]], true 1662; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG_NOT]] 1663; CHECK-NEXT: ret i1 [[I4]] 1664; 1665bb: 1666 %i = sext i1 %arg to i32 1667 %i2 = zext i1 %arg1 to i32 1668 %i3 = add i32 %i2, %i 1669 %i4 = icmp ult i32 %i3, 2 1670 ret i1 %i4 1671} 1672 1673define i1 @test_cvt_icmp22(i1 %arg, i1 %arg1) { 1674; CHECK-LABEL: @test_cvt_icmp22( 1675; CHECK-NEXT: bb: 1676; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true 1677; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[TMP0]] 1678; CHECK-NEXT: ret i1 [[I4]] 1679; 1680bb: 1681 %i = sext i1 %arg to i32 1682 %i2 = zext i1 %arg1 to i32 1683 %i3 = add i32 %i2, %i 1684 %i4 = icmp ule i32 %i3, 2 1685 ret i1 %i4 1686} 1687 1688define i1 @test_cvt_icmp23(i1 %arg, i1 %arg1) { 1689; CHECK-LABEL: @test_cvt_icmp23( 1690; CHECK-NEXT: bb: 1691; CHECK-NEXT: ret i1 false 1692; 1693bb: 1694 %i = sext i1 %arg to i32 1695 %i2 = zext i1 %arg1 to i32 1696 %i3 = add i32 %i2, %i 1697 %i4 = icmp sgt i32 %i3, 2 1698 ret i1 %i4 1699} 1700 1701define i1 @test_cvt_icmp24(i1 %arg, i1 %arg1) { 1702; CHECK-LABEL: @test_cvt_icmp24( 1703; CHECK-NEXT: bb: 1704; CHECK-NEXT: [[ARG_NOT:%.*]] = xor i1 [[ARG:%.*]], true 1705; CHECK-NEXT: [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG_NOT]] 1706; CHECK-NEXT: ret i1 [[I4]] 1707; 1708bb: 1709 %i = sext i1 %arg to i32 1710 %i2 = zext i1 %arg1 to i32 1711 %i3 = add i32 %i2, %i 1712 %i4 = icmp sge i32 %i3, 0 1713 ret i1 %i4 1714} 1715 1716define i1 @test_cvt_icmp25(i1 %arg, i1 %arg1) { 1717; CHECK-LABEL: @test_cvt_icmp25( 1718; CHECK-NEXT: bb: 1719; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true 1720; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[ARG:%.*]], [[TMP0]] 1721; CHECK-NEXT: ret i1 [[TMP1]] 1722; 1723bb: 1724 %i = sext i1 %arg to i32 1725 %i2 = zext i1 %arg1 to i32 1726 %i3 = add i32 %i2, %i 1727 %i4 = icmp slt i32 %i3, 0 1728 ret i1 %i4 1729} 1730 1731define i1 @test_cvt_icmp26(i1 %arg, i1 %arg1) { 1732; CHECK-LABEL: @test_cvt_icmp26( 1733; CHECK-NEXT: bb: 1734; CHECK-NEXT: ret i1 true 1735; 1736bb: 1737 %i = sext i1 %arg to i32 1738 %i2 = zext i1 %arg1 to i32 1739 %i3 = add i32 %i2, %i 1740 %i4 = icmp sle i32 %i3, 1 1741 ret i1 %i4 1742} 1743 1744define i1 @test1(i32 %a) { 1745; CHECK-LABEL: @test1( 1746; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[A:%.*]], -5 1747; CHECK-NEXT: ret i1 [[C]] 1748; 1749 %b = add i32 %a, 4 1750 %c = icmp ult i32 %b, 4 1751 ret i1 %c 1752} 1753 1754define <2 x i1> @test1vec(<2 x i32> %a) { 1755; CHECK-LABEL: @test1vec( 1756; CHECK-NEXT: [[C:%.*]] = icmp ugt <2 x i32> [[A:%.*]], splat (i32 -5) 1757; CHECK-NEXT: ret <2 x i1> [[C]] 1758; 1759 %b = add <2 x i32> %a, <i32 4, i32 4> 1760 %c = icmp ult <2 x i32> %b, <i32 4, i32 4> 1761 ret <2 x i1> %c 1762} 1763 1764define i1 @test2(i32 %a) { 1765; CHECK-LABEL: @test2( 1766; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[A:%.*]], 4 1767; CHECK-NEXT: ret i1 [[C]] 1768; 1769 %b = sub i32 %a, 4 1770 %c = icmp ugt i32 %b, -5 1771 ret i1 %c 1772} 1773 1774define <2 x i1> @test2vec(<2 x i32> %a) { 1775; CHECK-LABEL: @test2vec( 1776; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i32> [[A:%.*]], splat (i32 4) 1777; CHECK-NEXT: ret <2 x i1> [[C]] 1778; 1779 %b = sub <2 x i32> %a, <i32 4, i32 4> 1780 %c = icmp ugt <2 x i32> %b, <i32 -5, i32 -5> 1781 ret <2 x i1> %c 1782} 1783 1784define i1 @test3(i32 %a) { 1785; CHECK-LABEL: @test3( 1786; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[A:%.*]], 2147483643 1787; CHECK-NEXT: ret i1 [[C]] 1788; 1789 %b = add i32 %a, 4 1790 %c = icmp slt i32 %b, 2147483652 1791 ret i1 %c 1792} 1793 1794define <2 x i1> @test3vec(<2 x i32> %a) { 1795; CHECK-LABEL: @test3vec( 1796; CHECK-NEXT: [[C:%.*]] = icmp sgt <2 x i32> [[A:%.*]], splat (i32 2147483643) 1797; CHECK-NEXT: ret <2 x i1> [[C]] 1798; 1799 %b = add <2 x i32> %a, <i32 4, i32 4> 1800 %c = icmp slt <2 x i32> %b, <i32 2147483652, i32 2147483652> 1801 ret <2 x i1> %c 1802} 1803 1804define i1 @test4(i32 %a) { 1805; CHECK-LABEL: @test4( 1806; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[A:%.*]], -4 1807; CHECK-NEXT: ret i1 [[C]] 1808; 1809 %b = add i32 %a, 2147483652 1810 %c = icmp sge i32 %b, 4 1811 ret i1 %c 1812} 1813 1814define { i32, i1 } @test4multiuse(i32 %a) { 1815; CHECK-LABEL: @test4multiuse( 1816; CHECK-NEXT: [[B:%.*]] = add nsw i32 [[A:%.*]], -2147483644 1817; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[A]], 2147483640 1818; CHECK-NEXT: [[TMP:%.*]] = insertvalue { i32, i1 } undef, i32 [[B]], 0 1819; CHECK-NEXT: [[RES:%.*]] = insertvalue { i32, i1 } [[TMP]], i1 [[C]], 1 1820; CHECK-NEXT: ret { i32, i1 } [[RES]] 1821; 1822 1823 %b = add nsw i32 %a, -2147483644 1824 %c = icmp slt i32 %b, -4 1825 1826 %tmp = insertvalue { i32, i1 } undef, i32 %b, 0 1827 %res = insertvalue { i32, i1 } %tmp, i1 %c, 1 1828 1829 ret { i32, i1 } %res 1830} 1831 1832define <2 x i1> @test4vec(<2 x i32> %a) { 1833; CHECK-LABEL: @test4vec( 1834; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i32> [[A:%.*]], splat (i32 -4) 1835; CHECK-NEXT: ret <2 x i1> [[C]] 1836; 1837 %b = add <2 x i32> %a, <i32 2147483652, i32 2147483652> 1838 %c = icmp sge <2 x i32> %b, <i32 4, i32 4> 1839 ret <2 x i1> %c 1840} 1841 1842; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow. 1843; This becomes equality because it's at the limit. 1844 1845define i1 @nsw_slt1(i8 %a) { 1846; CHECK-LABEL: @nsw_slt1( 1847; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A:%.*]], -128 1848; CHECK-NEXT: ret i1 [[C]] 1849; 1850 %b = add nsw i8 %a, 100 1851 %c = icmp slt i8 %b, -27 1852 ret i1 %c 1853} 1854 1855define <2 x i1> @nsw_slt1_splat_vec(<2 x i8> %a) { 1856; CHECK-LABEL: @nsw_slt1_splat_vec( 1857; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[A:%.*]], splat (i8 -128) 1858; CHECK-NEXT: ret <2 x i1> [[C]] 1859; 1860 %b = add nsw <2 x i8> %a, <i8 100, i8 100> 1861 %c = icmp slt <2 x i8> %b, <i8 -27, i8 -27> 1862 ret <2 x i1> %c 1863} 1864 1865; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow. 1866; This becomes equality because it's at the limit. 1867 1868define i1 @nsw_slt2(i8 %a) { 1869; CHECK-LABEL: @nsw_slt2( 1870; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A:%.*]], 127 1871; CHECK-NEXT: ret i1 [[C]] 1872; 1873 %b = add nsw i8 %a, -100 1874 %c = icmp slt i8 %b, 27 1875 ret i1 %c 1876} 1877 1878define <2 x i1> @nsw_slt2_splat_vec(<2 x i8> %a) { 1879; CHECK-LABEL: @nsw_slt2_splat_vec( 1880; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[A:%.*]], splat (i8 127) 1881; CHECK-NEXT: ret <2 x i1> [[C]] 1882; 1883 %b = add nsw <2 x i8> %a, <i8 -100, i8 -100> 1884 %c = icmp slt <2 x i8> %b, <i8 27, i8 27> 1885 ret <2 x i1> %c 1886} 1887 1888; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow. 1889; Less than the limit, so the predicate doesn't change. 1890 1891define i1 @nsw_slt3(i8 %a) { 1892; CHECK-LABEL: @nsw_slt3( 1893; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[A:%.*]], -126 1894; CHECK-NEXT: ret i1 [[C]] 1895; 1896 %b = add nsw i8 %a, 100 1897 %c = icmp slt i8 %b, -26 1898 ret i1 %c 1899} 1900 1901; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow. 1902; Less than the limit, so the predicate doesn't change. 1903 1904define i1 @nsw_slt4(i8 %a) { 1905; CHECK-LABEL: @nsw_slt4( 1906; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[A:%.*]], 126 1907; CHECK-NEXT: ret i1 [[C]] 1908; 1909 %b = add nsw i8 %a, -100 1910 %c = icmp slt i8 %b, 26 1911 ret i1 %c 1912} 1913 1914; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow. 1915; Try sgt to make sure that works too. 1916 1917define i1 @nsw_sgt1(i8 %a) { 1918; CHECK-LABEL: @nsw_sgt1( 1919; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A:%.*]], 127 1920; CHECK-NEXT: ret i1 [[C]] 1921; 1922 %b = add nsw i8 %a, -100 1923 %c = icmp sgt i8 %b, 26 1924 ret i1 %c 1925} 1926 1927define <2 x i1> @nsw_sgt1_splat_vec(<2 x i8> %a) { 1928; CHECK-LABEL: @nsw_sgt1_splat_vec( 1929; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[A:%.*]], splat (i8 127) 1930; CHECK-NEXT: ret <2 x i1> [[C]] 1931; 1932 %b = add nsw <2 x i8> %a, <i8 -100, i8 -100> 1933 %c = icmp sgt <2 x i8> %b, <i8 26, i8 26> 1934 ret <2 x i1> %c 1935} 1936 1937define i1 @nsw_sgt2(i8 %a) { 1938; CHECK-LABEL: @nsw_sgt2( 1939; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[A:%.*]], -126 1940; CHECK-NEXT: ret i1 [[C]] 1941; 1942 %b = add nsw i8 %a, 100 1943 %c = icmp sgt i8 %b, -26 1944 ret i1 %c 1945} 1946 1947define <2 x i1> @nsw_sgt2_splat_vec(<2 x i8> %a) { 1948; CHECK-LABEL: @nsw_sgt2_splat_vec( 1949; CHECK-NEXT: [[C:%.*]] = icmp sgt <2 x i8> [[A:%.*]], splat (i8 -126) 1950; CHECK-NEXT: ret <2 x i1> [[C]] 1951; 1952 %b = add nsw <2 x i8> %a, <i8 100, i8 100> 1953 %c = icmp sgt <2 x i8> %b, <i8 -26, i8 -26> 1954 ret <2 x i1> %c 1955} 1956 1957; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow. 1958; Comparison with 0 doesn't need special-casing. 1959 1960define i1 @slt_zero_add_nsw(i32 %a) { 1961; CHECK-LABEL: @slt_zero_add_nsw( 1962; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], -1 1963; CHECK-NEXT: ret i1 [[CMP]] 1964; 1965 %add = add nsw i32 %a, 1 1966 %cmp = icmp slt i32 %add, 0 1967 ret i1 %cmp 1968} 1969 1970; The same fold should work with vectors. 1971 1972define <2 x i1> @slt_zero_add_nsw_splat_vec(<2 x i8> %a) { 1973; CHECK-LABEL: @slt_zero_add_nsw_splat_vec( 1974; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], splat (i8 -1) 1975; CHECK-NEXT: ret <2 x i1> [[CMP]] 1976; 1977 %add = add nsw <2 x i8> %a, <i8 1, i8 1> 1978 %cmp = icmp slt <2 x i8> %add, zeroinitializer 1979 ret <2 x i1> %cmp 1980} 1981 1982; Test the edges - instcombine should not interfere with simplification to constants. 1983; Constant subtraction does not overflow, but this is false. 1984 1985define i1 @nsw_slt3_ov_no(i8 %a) { 1986; CHECK-LABEL: @nsw_slt3_ov_no( 1987; CHECK-NEXT: ret i1 false 1988; 1989 %b = add nsw i8 %a, 100 1990 %c = icmp slt i8 %b, -28 1991 ret i1 %c 1992} 1993 1994; Test the edges - instcombine should not interfere with simplification to constants. 1995; Constant subtraction overflows. This is false. 1996 1997define i1 @nsw_slt4_ov(i8 %a) { 1998; CHECK-LABEL: @nsw_slt4_ov( 1999; CHECK-NEXT: ret i1 false 2000; 2001 %b = add nsw i8 %a, 100 2002 %c = icmp slt i8 %b, -29 2003 ret i1 %c 2004} 2005 2006; Test the edges - instcombine should not interfere with simplification to constants. 2007; Constant subtraction overflows. This is true. 2008 2009define i1 @nsw_slt5_ov(i8 %a) { 2010; CHECK-LABEL: @nsw_slt5_ov( 2011; CHECK-NEXT: ret i1 true 2012; 2013 %b = add nsw i8 %a, -100 2014 %c = icmp slt i8 %b, 28 2015 ret i1 %c 2016} 2017 2018; InstCombine should not thwart this opportunity to simplify completely. 2019 2020define i1 @slt_zero_add_nsw_signbit(i8 %x) { 2021; CHECK-LABEL: @slt_zero_add_nsw_signbit( 2022; CHECK-NEXT: ret i1 true 2023; 2024 %y = add nsw i8 %x, -128 2025 %z = icmp slt i8 %y, 0 2026 ret i1 %z 2027} 2028 2029; InstCombine should not thwart this opportunity to simplify completely. 2030 2031define i1 @slt_zero_add_nuw_signbit(i8 %x) { 2032; CHECK-LABEL: @slt_zero_add_nuw_signbit( 2033; CHECK-NEXT: ret i1 true 2034; 2035 %y = add nuw i8 %x, 128 2036 %z = icmp slt i8 %y, 0 2037 ret i1 %z 2038} 2039 2040define i1 @reduce_add_ult(i32 %in) { 2041; CHECK-LABEL: @reduce_add_ult( 2042; CHECK-NEXT: [[A18:%.*]] = icmp ult i32 [[IN:%.*]], 9 2043; CHECK-NEXT: ret i1 [[A18]] 2044; 2045 %a6 = add nuw i32 %in, 3 2046 %a18 = icmp ult i32 %a6, 12 2047 ret i1 %a18 2048} 2049 2050define i1 @reduce_add_ugt(i32 %in) { 2051; CHECK-LABEL: @reduce_add_ugt( 2052; CHECK-NEXT: [[A18:%.*]] = icmp ugt i32 [[IN:%.*]], 9 2053; CHECK-NEXT: ret i1 [[A18]] 2054; 2055 %a6 = add nuw i32 %in, 3 2056 %a18 = icmp ugt i32 %a6, 12 2057 ret i1 %a18 2058} 2059 2060define i1 @reduce_add_ule(i32 %in) { 2061; CHECK-LABEL: @reduce_add_ule( 2062; CHECK-NEXT: [[A18:%.*]] = icmp ult i32 [[IN:%.*]], 10 2063; CHECK-NEXT: ret i1 [[A18]] 2064; 2065 %a6 = add nuw i32 %in, 3 2066 %a18 = icmp ule i32 %a6, 12 2067 ret i1 %a18 2068} 2069 2070define i1 @reduce_add_uge(i32 %in) { 2071; CHECK-LABEL: @reduce_add_uge( 2072; CHECK-NEXT: [[A18:%.*]] = icmp ugt i32 [[IN:%.*]], 8 2073; CHECK-NEXT: ret i1 [[A18]] 2074; 2075 %a6 = add nuw i32 %in, 3 2076 %a18 = icmp uge i32 %a6, 12 2077 ret i1 %a18 2078} 2079 2080define i1 @ult_add_ssubov(i32 %in) { 2081; CHECK-LABEL: @ult_add_ssubov( 2082; CHECK-NEXT: ret i1 false 2083; 2084 %a6 = add nuw i32 %in, 71 2085 %a18 = icmp ult i32 %a6, 3 2086 ret i1 %a18 2087} 2088 2089define i1 @ult_add_nonuw(i8 %in) { 2090; CHECK-LABEL: @ult_add_nonuw( 2091; CHECK-NEXT: [[A6:%.*]] = add i8 [[IN:%.*]], 71 2092; CHECK-NEXT: [[A18:%.*]] = icmp ult i8 [[A6]], 12 2093; CHECK-NEXT: ret i1 [[A18]] 2094; 2095 %a6 = add i8 %in, 71 2096 %a18 = icmp ult i8 %a6, 12 2097 ret i1 %a18 2098} 2099 2100define i1 @uge_add_nonuw(i32 %in) { 2101; CHECK-LABEL: @uge_add_nonuw( 2102; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[IN:%.*]], -9 2103; CHECK-NEXT: [[A18:%.*]] = icmp ult i32 [[TMP1]], -12 2104; CHECK-NEXT: ret i1 [[A18]] 2105; 2106 %a6 = add i32 %in, 3 2107 %a18 = icmp uge i32 %a6, 12 2108 ret i1 %a18 2109} 2110 2111; Test unsigned add overflow patterns. The div ops are only here to 2112; thwart complexity based canonicalization of the operand order. 2113 2114define i1 @op_ugt_sum_commute1(i8 %p1, i8 %p2) { 2115; CHECK-LABEL: @op_ugt_sum_commute1( 2116; CHECK-NEXT: [[X:%.*]] = sdiv i8 42, [[P1:%.*]] 2117; CHECK-NEXT: [[Y:%.*]] = sdiv i8 42, [[P2:%.*]] 2118; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], -1 2119; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 [[Y]], [[TMP1]] 2120; CHECK-NEXT: ret i1 [[C]] 2121; 2122 %x = sdiv i8 42, %p1 2123 %y = sdiv i8 42, %p2 2124 %a = add i8 %x, %y 2125 %c = icmp ugt i8 %x, %a 2126 ret i1 %c 2127} 2128 2129define <2 x i1> @op_ugt_sum_vec_commute2(<2 x i8> %p1, <2 x i8> %p2) { 2130; CHECK-LABEL: @op_ugt_sum_vec_commute2( 2131; CHECK-NEXT: [[X:%.*]] = sdiv <2 x i8> <i8 42, i8 -42>, [[P1:%.*]] 2132; CHECK-NEXT: [[Y:%.*]] = sdiv <2 x i8> <i8 42, i8 -42>, [[P2:%.*]] 2133; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i8> [[X]], splat (i8 -1) 2134; CHECK-NEXT: [[C:%.*]] = icmp ugt <2 x i8> [[Y]], [[TMP1]] 2135; CHECK-NEXT: ret <2 x i1> [[C]] 2136; 2137 %x = sdiv <2 x i8> <i8 42, i8 -42>, %p1 2138 %y = sdiv <2 x i8> <i8 42, i8 -42>, %p2 2139 %a = add <2 x i8> %y, %x 2140 %c = icmp ugt <2 x i8> %x, %a 2141 ret <2 x i1> %c 2142} 2143 2144define i1 @sum_ugt_op_uses(i8 %p1, i8 %p2, ptr %p3) { 2145; CHECK-LABEL: @sum_ugt_op_uses( 2146; CHECK-NEXT: [[X:%.*]] = sdiv i8 42, [[P1:%.*]] 2147; CHECK-NEXT: [[Y:%.*]] = sdiv i8 42, [[P2:%.*]] 2148; CHECK-NEXT: [[A:%.*]] = add nsw i8 [[X]], [[Y]] 2149; CHECK-NEXT: store i8 [[A]], ptr [[P3:%.*]], align 1 2150; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 [[X]], [[A]] 2151; CHECK-NEXT: ret i1 [[C]] 2152; 2153 %x = sdiv i8 42, %p1 2154 %y = sdiv i8 42, %p2 2155 %a = add i8 %x, %y 2156 store i8 %a, ptr %p3 2157 %c = icmp ugt i8 %x, %a 2158 ret i1 %c 2159} 2160 2161define <2 x i1> @sum_ult_op_vec_commute1(<2 x i8> %p1, <2 x i8> %p2) { 2162; CHECK-LABEL: @sum_ult_op_vec_commute1( 2163; CHECK-NEXT: [[X:%.*]] = sdiv <2 x i8> <i8 42, i8 -42>, [[P1:%.*]] 2164; CHECK-NEXT: [[Y:%.*]] = sdiv <2 x i8> <i8 -42, i8 42>, [[P2:%.*]] 2165; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i8> [[X]], splat (i8 -1) 2166; CHECK-NEXT: [[C:%.*]] = icmp ugt <2 x i8> [[Y]], [[TMP1]] 2167; CHECK-NEXT: ret <2 x i1> [[C]] 2168; 2169 %x = sdiv <2 x i8> <i8 42, i8 -42>, %p1 2170 %y = sdiv <2 x i8> <i8 -42, i8 42>, %p2 2171 %a = add <2 x i8> %x, %y 2172 %c = icmp ult <2 x i8> %a, %x 2173 ret <2 x i1> %c 2174} 2175 2176define i1 @sum_ult_op_commute2(i8 %p1, i8 %p2) { 2177; CHECK-LABEL: @sum_ult_op_commute2( 2178; CHECK-NEXT: [[X:%.*]] = sdiv i8 42, [[P1:%.*]] 2179; CHECK-NEXT: [[Y:%.*]] = sdiv i8 42, [[P2:%.*]] 2180; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], -1 2181; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 [[Y]], [[TMP1]] 2182; CHECK-NEXT: ret i1 [[C]] 2183; 2184 %x = sdiv i8 42, %p1 2185 %y = sdiv i8 42, %p2 2186 %a = add i8 %y, %x 2187 %c = icmp ult i8 %a, %x 2188 ret i1 %c 2189} 2190 2191define i1 @sum_ult_op_uses(i8 %x, i8 %y, ptr %p) { 2192; CHECK-LABEL: @sum_ult_op_uses( 2193; CHECK-NEXT: [[A:%.*]] = add i8 [[Y:%.*]], [[X:%.*]] 2194; CHECK-NEXT: store i8 [[A]], ptr [[P:%.*]], align 1 2195; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[A]], [[X]] 2196; CHECK-NEXT: ret i1 [[C]] 2197; 2198 %a = add i8 %y, %x 2199 store i8 %a, ptr %p 2200 %c = icmp ult i8 %a, %x 2201 ret i1 %c 2202} 2203 2204; X + Z >s Y + Z -> X > Y if there is no overflow. 2205define i1 @common_op_nsw(i32 %x, i32 %y, i32 %z) { 2206; CHECK-LABEL: @common_op_nsw( 2207; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]] 2208; CHECK-NEXT: ret i1 [[C]] 2209; 2210 %lhs = add nsw i32 %x, %z 2211 %rhs = add nsw i32 %y, %z 2212 %c = icmp sgt i32 %lhs, %rhs 2213 ret i1 %c 2214} 2215 2216define i1 @common_op_nsw_extra_uses(i32 %x, i32 %y, i32 %z) { 2217; CHECK-LABEL: @common_op_nsw_extra_uses( 2218; CHECK-NEXT: [[LHS:%.*]] = add nsw i32 [[X:%.*]], [[Z:%.*]] 2219; CHECK-NEXT: call void @use(i32 [[LHS]]) 2220; CHECK-NEXT: [[RHS:%.*]] = add nsw i32 [[Y:%.*]], [[Z]] 2221; CHECK-NEXT: call void @use(i32 [[RHS]]) 2222; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X]], [[Y]] 2223; CHECK-NEXT: ret i1 [[C]] 2224; 2225 %lhs = add nsw i32 %x, %z 2226 call void @use(i32 %lhs) 2227 %rhs = add nsw i32 %y, %z 2228 call void @use(i32 %rhs) 2229 %c = icmp sgt i32 %lhs, %rhs 2230 ret i1 %c 2231} 2232 2233; X + Z >u Z + Y -> X > Y if there is no overflow. 2234define i1 @common_op_nuw(i32 %x, i32 %y, i32 %z) { 2235; CHECK-LABEL: @common_op_nuw( 2236; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]] 2237; CHECK-NEXT: ret i1 [[C]] 2238; 2239 %lhs = add nuw i32 %x, %z 2240 %rhs = add nuw i32 %z, %y 2241 %c = icmp ugt i32 %lhs, %rhs 2242 ret i1 %c 2243} 2244 2245define i1 @common_op_nuw_extra_uses(i32 %x, i32 %y, i32 %z) { 2246; CHECK-LABEL: @common_op_nuw_extra_uses( 2247; CHECK-NEXT: [[LHS:%.*]] = add nuw i32 [[X:%.*]], [[Z:%.*]] 2248; CHECK-NEXT: call void @use(i32 [[LHS]]) 2249; CHECK-NEXT: [[RHS:%.*]] = add nuw i32 [[Z]], [[Y:%.*]] 2250; CHECK-NEXT: call void @use(i32 [[RHS]]) 2251; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X]], [[Y]] 2252; CHECK-NEXT: ret i1 [[C]] 2253; 2254 %lhs = add nuw i32 %x, %z 2255 call void @use(i32 %lhs) 2256 %rhs = add nuw i32 %z, %y 2257 call void @use(i32 %rhs) 2258 %c = icmp ugt i32 %lhs, %rhs 2259 ret i1 %c 2260} 2261 2262define i1 @common_op_nsw_commute(i32 %x, i32 %y, i32 %z) { 2263; CHECK-LABEL: @common_op_nsw_commute( 2264; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]] 2265; CHECK-NEXT: ret i1 [[C]] 2266; 2267 %lhs = add nsw i32 %z, %x 2268 %rhs = add nsw i32 %y, %z 2269 %c = icmp slt i32 %lhs, %rhs 2270 ret i1 %c 2271} 2272 2273define i1 @common_op_nuw_commute(i32 %x, i32 %y, i32 %z) { 2274; CHECK-LABEL: @common_op_nuw_commute( 2275; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 2276; CHECK-NEXT: ret i1 [[C]] 2277; 2278 %lhs = add nuw i32 %z, %x 2279 %rhs = add nuw i32 %z, %y 2280 %c = icmp ult i32 %lhs, %rhs 2281 ret i1 %c 2282} 2283 2284; X + Y > X -> Y > 0 if there is no overflow. 2285define i1 @common_op_test29(i32 %x, i32 %y) { 2286; CHECK-LABEL: @common_op_test29( 2287; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Y:%.*]], 0 2288; CHECK-NEXT: ret i1 [[C]] 2289; 2290 %lhs = add nsw i32 %x, %y 2291 %c = icmp sgt i32 %lhs, %x 2292 ret i1 %c 2293} 2294 2295; X + Y > X -> Y > 0 if there is no overflow. 2296define i1 @sum_nuw(i32 %x, i32 %y) { 2297; CHECK-LABEL: @sum_nuw( 2298; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[Y:%.*]], 0 2299; CHECK-NEXT: ret i1 [[C]] 2300; 2301 %lhs = add nuw i32 %x, %y 2302 %c = icmp ugt i32 %lhs, %x 2303 ret i1 %c 2304} 2305 2306; X > X + Y -> 0 > Y if there is no overflow. 2307define i1 @sum_nsw_commute(i32 %x, i32 %y) { 2308; CHECK-LABEL: @sum_nsw_commute( 2309; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[Y:%.*]], 0 2310; CHECK-NEXT: ret i1 [[C]] 2311; 2312 %rhs = add nsw i32 %x, %y 2313 %c = icmp sgt i32 %x, %rhs 2314 ret i1 %c 2315} 2316 2317; X > X + Y -> 0 > Y if there is no overflow. 2318define i1 @sum_nuw_commute(i32 %x, i32 %y) { 2319; CHECK-LABEL: @sum_nuw_commute( 2320; CHECK-NEXT: ret i1 false 2321; 2322 %rhs = add nuw i32 %x, %y 2323 %c = icmp ugt i32 %x, %rhs 2324 ret i1 %c 2325} 2326 2327; PR2698 - https://bugs.llvm.org/show_bug.cgi?id=2698 2328 2329declare void @use1(i1) 2330declare void @use8(i8) 2331 2332define void @bzip1(i8 %a, i8 %b, i8 %x) { 2333; CHECK-LABEL: @bzip1( 2334; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A:%.*]], [[B:%.*]] 2335; CHECK-NEXT: call void @use1(i1 [[CMP]]) 2336; CHECK-NEXT: ret void 2337; 2338 %add1 = add i8 %a, %x 2339 %add2 = add i8 %b, %x 2340 %cmp = icmp eq i8 %add1, %add2 2341 call void @use1(i1 %cmp) 2342 ret void 2343} 2344 2345define void @bzip2(i8 %a, i8 %b, i8 %x) { 2346; CHECK-LABEL: @bzip2( 2347; CHECK-NEXT: [[ADD1:%.*]] = add i8 [[A:%.*]], [[X:%.*]] 2348; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], [[B:%.*]] 2349; CHECK-NEXT: call void @use1(i1 [[CMP]]) 2350; CHECK-NEXT: call void @use8(i8 [[ADD1]]) 2351; CHECK-NEXT: ret void 2352; 2353 %add1 = add i8 %a, %x 2354 %add2 = add i8 %b, %x 2355 %cmp = icmp eq i8 %add1, %add2 2356 call void @use1(i1 %cmp) 2357 call void @use8(i8 %add1) 2358 ret void 2359} 2360 2361define <2 x i1> @icmp_eq_add_undef(<2 x i32> %a) { 2362; CHECK-LABEL: @icmp_eq_add_undef( 2363; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 5, i32 undef> 2364; CHECK-NEXT: ret <2 x i1> [[CMP]] 2365; 2366 %add = add <2 x i32> %a, <i32 5, i32 undef> 2367 %cmp = icmp eq <2 x i32> %add, <i32 10, i32 10> 2368 ret <2 x i1> %cmp 2369} 2370 2371define <2 x i1> @icmp_eq_add_non_splat(<2 x i32> %a) { 2372; CHECK-LABEL: @icmp_eq_add_non_splat( 2373; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 5, i32 4> 2374; CHECK-NEXT: ret <2 x i1> [[CMP]] 2375; 2376 %add = add <2 x i32> %a, <i32 5, i32 6> 2377 %cmp = icmp eq <2 x i32> %add, <i32 10, i32 10> 2378 ret <2 x i1> %cmp 2379} 2380 2381define <2 x i1> @icmp_eq_add_undef2(<2 x i32> %a) { 2382; CHECK-LABEL: @icmp_eq_add_undef2( 2383; CHECK-NEXT: [[ADD:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 5) 2384; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[ADD]], <i32 10, i32 undef> 2385; CHECK-NEXT: ret <2 x i1> [[CMP]] 2386; 2387 %add = add <2 x i32> %a, <i32 5, i32 5> 2388 %cmp = icmp eq <2 x i32> %add, <i32 10, i32 undef> 2389 ret <2 x i1> %cmp 2390} 2391 2392define <2 x i1> @icmp_eq_add_non_splat2(<2 x i32> %a) { 2393; CHECK-LABEL: @icmp_eq_add_non_splat2( 2394; CHECK-NEXT: [[ADD:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 5) 2395; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[ADD]], <i32 10, i32 11> 2396; CHECK-NEXT: ret <2 x i1> [[CMP]] 2397; 2398 %add = add <2 x i32> %a, <i32 5, i32 5> 2399 %cmp = icmp eq <2 x i32> %add, <i32 10, i32 11> 2400 ret <2 x i1> %cmp 2401} 2402 2403define i1 @without_nsw_nuw(i8 %x, i8 %y) { 2404; CHECK-LABEL: @without_nsw_nuw( 2405; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], 2 2406; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8 [[Y:%.*]], [[TMP1]] 2407; CHECK-NEXT: ret i1 [[TOBOOL]] 2408; 2409 %t1 = add i8 %x, 37 2410 %t2 = add i8 %y, 35 2411 %tobool = icmp eq i8 %t2, %t1 2412 ret i1 %tobool 2413} 2414 2415define i1 @with_nsw_nuw(i8 %x, i8 %y) { 2416; CHECK-LABEL: @with_nsw_nuw( 2417; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i8 [[X:%.*]], 2 2418; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8 [[Y:%.*]], [[TMP1]] 2419; CHECK-NEXT: ret i1 [[TOBOOL]] 2420; 2421 %t1 = add nsw nuw i8 %x, 37 2422 %t2 = add i8 %y, 35 2423 %tobool = icmp eq i8 %t2, %t1 2424 ret i1 %tobool 2425} 2426 2427define i1 @with_nsw_large(i8 %x, i8 %y) { 2428; CHECK-LABEL: @with_nsw_large( 2429; CHECK-NEXT: [[TMP1:%.*]] = add nsw i8 [[X:%.*]], 2 2430; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8 [[Y:%.*]], [[TMP1]] 2431; CHECK-NEXT: ret i1 [[TOBOOL]] 2432; 2433 %t1 = add nsw i8 %x, 37 2434 %t2 = add i8 %y, 35 2435 %tobool = icmp eq i8 %t2, %t1 2436 ret i1 %tobool 2437} 2438 2439define i1 @with_nsw_small(i8 %x, i8 %y) { 2440; CHECK-LABEL: @with_nsw_small( 2441; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], 2 2442; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8 [[TMP1]], [[X:%.*]] 2443; CHECK-NEXT: ret i1 [[TOBOOL]] 2444; 2445 %t1 = add nsw i8 %x, 35 2446 %t2 = add i8 %y, 37 2447 %tobool = icmp eq i8 %t2, %t1 2448 ret i1 %tobool 2449} 2450 2451define i1 @with_nuw_large(i8 %x, i8 %y) { 2452; CHECK-LABEL: @with_nuw_large( 2453; CHECK-NEXT: [[TMP1:%.*]] = add nuw i8 [[X:%.*]], 2 2454; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8 [[Y:%.*]], [[TMP1]] 2455; CHECK-NEXT: ret i1 [[TOBOOL]] 2456; 2457 %t1 = add nuw i8 %x, 37 2458 %t2 = add i8 %y, 35 2459 %tobool = icmp eq i8 %t2, %t1 2460 ret i1 %tobool 2461} 2462 2463define i1 @with_nuw_small(i8 %x, i8 %y) { 2464; CHECK-LABEL: @with_nuw_small( 2465; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], 2 2466; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8 [[TMP1]], [[X:%.*]] 2467; CHECK-NEXT: ret i1 [[TOBOOL]] 2468; 2469 %t1 = add nuw i8 %x, 35 2470 %t2 = add i8 %y, 37 2471 %tobool = icmp eq i8 %t2, %t1 2472 ret i1 %tobool 2473} 2474 2475define i1 @with_nuw_large_negative(i8 %x, i8 %y) { 2476; CHECK-LABEL: @with_nuw_large_negative( 2477; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -2 2478; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8 [[Y:%.*]], [[TMP1]] 2479; CHECK-NEXT: ret i1 [[TOBOOL]] 2480; 2481 %t1 = add nuw i8 %x, -37 2482 %t2 = add i8 %y, -35 2483 %tobool = icmp eq i8 %t2, %t1 2484 ret i1 %tobool 2485} 2486 2487define i1 @ugt_offset(i8 %a) { 2488; CHECK-LABEL: @ugt_offset( 2489; CHECK-NEXT: [[OV:%.*]] = icmp slt i8 [[A:%.*]], -124 2490; CHECK-NEXT: ret i1 [[OV]] 2491; 2492 %t = add i8 %a, 124 2493 %ov = icmp ugt i8 %t, 251 2494 ret i1 %ov 2495} 2496 2497define i1 @ugt_offset_use(i32 %a) { 2498; CHECK-LABEL: @ugt_offset_use( 2499; CHECK-NEXT: [[T:%.*]] = add i32 [[A:%.*]], 42 2500; CHECK-NEXT: call void @use(i32 [[T]]) 2501; CHECK-NEXT: [[OV:%.*]] = icmp slt i32 [[A]], -42 2502; CHECK-NEXT: ret i1 [[OV]] 2503; 2504 %t = add i32 %a, 42 2505 call void @use(i32 %t) 2506 %ov = icmp ugt i32 %t, 2147483689 2507 ret i1 %ov 2508} 2509 2510define <2 x i1> @ugt_offset_splat(<2 x i5> %a) { 2511; CHECK-LABEL: @ugt_offset_splat( 2512; CHECK-NEXT: [[OV:%.*]] = icmp slt <2 x i5> [[A:%.*]], splat (i5 -9) 2513; CHECK-NEXT: ret <2 x i1> [[OV]] 2514; 2515 %t = add <2 x i5> %a, <i5 9, i5 9> 2516 %ov = icmp ugt <2 x i5> %t, <i5 24, i5 24> 2517 ret <2 x i1> %ov 2518} 2519 2520; negative test - constants must differ by SMAX 2521 2522define i1 @ugt_wrong_offset(i8 %a) { 2523; CHECK-LABEL: @ugt_wrong_offset( 2524; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[A:%.*]], 127 2525; CHECK-NEXT: [[OV:%.*]] = icmp ult i8 [[TMP1]], 4 2526; CHECK-NEXT: ret i1 [[OV]] 2527; 2528 %t = add i8 %a, 123 2529 %ov = icmp ugt i8 %t, 251 2530 ret i1 %ov 2531} 2532 2533define i1 @ugt_offset_nuw(i8 %a) { 2534; CHECK-LABEL: @ugt_offset_nuw( 2535; CHECK-NEXT: [[OV:%.*]] = icmp slt i8 [[A:%.*]], 0 2536; CHECK-NEXT: ret i1 [[OV]] 2537; 2538 %t = add nuw i8 %a, 124 2539 %ov = icmp ugt i8 %t, 251 2540 ret i1 %ov 2541} 2542 2543define i1 @ult_offset(i8 %a) { 2544; CHECK-LABEL: @ult_offset( 2545; CHECK-NEXT: [[OV:%.*]] = icmp sgt i8 [[A:%.*]], 5 2546; CHECK-NEXT: ret i1 [[OV]] 2547; 2548 %t = add i8 %a, 250 2549 %ov = icmp ult i8 %t, 122 2550 ret i1 %ov 2551} 2552 2553define i1 @ult_offset_use(i32 %a) { 2554; CHECK-LABEL: @ult_offset_use( 2555; CHECK-NEXT: [[T:%.*]] = add i32 [[A:%.*]], 42 2556; CHECK-NEXT: call void @use(i32 [[T]]) 2557; CHECK-NEXT: [[OV:%.*]] = icmp sgt i32 [[A]], -43 2558; CHECK-NEXT: ret i1 [[OV]] 2559; 2560 %t = add i32 %a, 42 2561 call void @use(i32 %t) 2562 %ov = icmp ult i32 %t, 2147483690 2563 ret i1 %ov 2564} 2565 2566define <2 x i1> @ult_offset_splat(<2 x i5> %a) { 2567; CHECK-LABEL: @ult_offset_splat( 2568; CHECK-NEXT: [[OV:%.*]] = icmp sgt <2 x i5> [[A:%.*]], splat (i5 -10) 2569; CHECK-NEXT: ret <2 x i1> [[OV]] 2570; 2571 %t = add <2 x i5> %a, <i5 9, i5 9> 2572 %ov = icmp ult <2 x i5> %t, <i5 25, i5 25> 2573 ret <2 x i1> %ov 2574} 2575 2576; negative test - constants must differ by SMIN 2577 2578define i1 @ult_wrong_offset(i8 %a) { 2579; CHECK-LABEL: @ult_wrong_offset( 2580; CHECK-NEXT: [[T:%.*]] = add i8 [[A:%.*]], -6 2581; CHECK-NEXT: [[OV:%.*]] = icmp ult i8 [[T]], 123 2582; CHECK-NEXT: ret i1 [[OV]] 2583; 2584 %t = add i8 %a, 250 2585 %ov = icmp ult i8 %t, 123 2586 ret i1 %ov 2587} 2588 2589define i1 @ult_offset_nuw(i8 %a) { 2590; CHECK-LABEL: @ult_offset_nuw( 2591; CHECK-NEXT: [[OV:%.*]] = icmp sgt i8 [[A:%.*]], -1 2592; CHECK-NEXT: ret i1 [[OV]] 2593; 2594 %t = add nuw i8 %a, 42 2595 %ov = icmp ult i8 %t, 170 2596 ret i1 %ov 2597} 2598 2599define i1 @sgt_offset(i8 %a) { 2600; CHECK-LABEL: @sgt_offset( 2601; CHECK-NEXT: [[OV:%.*]] = icmp ult i8 [[A:%.*]], -122 2602; CHECK-NEXT: ret i1 [[OV]] 2603; 2604 %t = add i8 %a, -6 2605 %ov = icmp sgt i8 %t, -7 2606 ret i1 %ov 2607} 2608 2609define i1 @sgt_offset_use(i32 %a) { 2610; CHECK-LABEL: @sgt_offset_use( 2611; CHECK-NEXT: [[T:%.*]] = add i32 [[A:%.*]], 42 2612; CHECK-NEXT: call void @use(i32 [[T]]) 2613; CHECK-NEXT: [[OV:%.*]] = icmp ult i32 [[A]], 2147483606 2614; CHECK-NEXT: ret i1 [[OV]] 2615; 2616 %t = add i32 %a, 42 2617 call void @use(i32 %t) 2618 %ov = icmp sgt i32 %t, 41 2619 ret i1 %ov 2620} 2621 2622define <2 x i1> @sgt_offset_splat(<2 x i5> %a) { 2623; CHECK-LABEL: @sgt_offset_splat( 2624; CHECK-NEXT: [[OV:%.*]] = icmp ult <2 x i5> [[A:%.*]], splat (i5 7) 2625; CHECK-NEXT: ret <2 x i1> [[OV]] 2626; 2627 %t = add <2 x i5> %a, <i5 9, i5 9> 2628 %ov = icmp sgt <2 x i5> %t, <i5 8, i5 8> 2629 ret <2 x i1> %ov 2630} 2631 2632; negative test - constants must differ by 1 2633 2634define i1 @sgt_wrong_offset(i8 %a) { 2635; CHECK-LABEL: @sgt_wrong_offset( 2636; CHECK-NEXT: [[T:%.*]] = add i8 [[A:%.*]], -7 2637; CHECK-NEXT: [[OV:%.*]] = icmp sgt i8 [[T]], -7 2638; CHECK-NEXT: ret i1 [[OV]] 2639; 2640 %t = add i8 %a, -7 2641 %ov = icmp sgt i8 %t, -7 2642 ret i1 %ov 2643} 2644 2645define i1 @sgt_offset_nsw(i8 %a, i8 %c) { 2646; CHECK-LABEL: @sgt_offset_nsw( 2647; CHECK-NEXT: [[OV:%.*]] = icmp sgt i8 [[A:%.*]], -1 2648; CHECK-NEXT: ret i1 [[OV]] 2649; 2650 %t = add nsw i8 %a, 42 2651 %ov = icmp sgt i8 %t, 41 2652 ret i1 %ov 2653} 2654 2655define i1 @slt_offset(i8 %a) { 2656; CHECK-LABEL: @slt_offset( 2657; CHECK-NEXT: [[OV:%.*]] = icmp ugt i8 [[A:%.*]], -123 2658; CHECK-NEXT: ret i1 [[OV]] 2659; 2660 %t = add i8 %a, -6 2661 %ov = icmp slt i8 %t, -6 2662 ret i1 %ov 2663} 2664 2665define i1 @slt_offset_use(i32 %a) { 2666; CHECK-LABEL: @slt_offset_use( 2667; CHECK-NEXT: [[T:%.*]] = add i32 [[A:%.*]], 42 2668; CHECK-NEXT: call void @use(i32 [[T]]) 2669; CHECK-NEXT: [[OV:%.*]] = icmp ugt i32 [[A]], 2147483605 2670; CHECK-NEXT: ret i1 [[OV]] 2671; 2672 %t = add i32 %a, 42 2673 call void @use(i32 %t) 2674 %ov = icmp slt i32 %t, 42 2675 ret i1 %ov 2676} 2677 2678define <2 x i1> @slt_offset_splat(<2 x i5> %a) { 2679; CHECK-LABEL: @slt_offset_splat( 2680; CHECK-NEXT: [[OV:%.*]] = icmp ugt <2 x i5> [[A:%.*]], splat (i5 6) 2681; CHECK-NEXT: ret <2 x i1> [[OV]] 2682; 2683 %t = add <2 x i5> %a, <i5 9, i5 9> 2684 %ov = icmp slt <2 x i5> %t, <i5 9, i5 9> 2685 ret <2 x i1> %ov 2686} 2687 2688; negative test - constants must be equal 2689 2690define i1 @slt_wrong_offset(i8 %a) { 2691; CHECK-LABEL: @slt_wrong_offset( 2692; CHECK-NEXT: [[T:%.*]] = add i8 [[A:%.*]], -6 2693; CHECK-NEXT: [[OV:%.*]] = icmp slt i8 [[T]], -7 2694; CHECK-NEXT: ret i1 [[OV]] 2695; 2696 %t = add i8 %a, -6 2697 %ov = icmp slt i8 %t, -7 2698 ret i1 %ov 2699} 2700 2701define i1 @slt_offset_nsw(i8 %a, i8 %c) { 2702; CHECK-LABEL: @slt_offset_nsw( 2703; CHECK-NEXT: [[OV:%.*]] = icmp slt i8 [[A:%.*]], 0 2704; CHECK-NEXT: ret i1 [[OV]] 2705; 2706 %t = add nsw i8 %a, 42 2707 %ov = icmp slt i8 %t, 42 2708 ret i1 %ov 2709} 2710 2711; In the following 4 tests, we could push the inc/dec 2712; through the min/max, but we should not break up the 2713; min/max idiom by using different icmp and select 2714; operands. 2715 2716define i32 @increment_max(i32 %x) { 2717; CHECK-LABEL: @increment_max( 2718; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -1) 2719; CHECK-NEXT: [[S:%.*]] = add nsw i32 [[TMP1]], 1 2720; CHECK-NEXT: ret i32 [[S]] 2721; 2722 %a = add nsw i32 %x, 1 2723 %c = icmp sgt i32 %a, 0 2724 %s = select i1 %c, i32 %a, i32 0 2725 ret i32 %s 2726} 2727 2728define i32 @decrement_max(i32 %x) { 2729; CHECK-LABEL: @decrement_max( 2730; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 1) 2731; CHECK-NEXT: [[S:%.*]] = add nsw i32 [[TMP1]], -1 2732; CHECK-NEXT: ret i32 [[S]] 2733; 2734 %a = add nsw i32 %x, -1 2735 %c = icmp sgt i32 %a, 0 2736 %s = select i1 %c, i32 %a, i32 0 2737 ret i32 %s 2738} 2739 2740define i32 @increment_min(i32 %x) { 2741; CHECK-LABEL: @increment_min( 2742; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 -1) 2743; CHECK-NEXT: [[S:%.*]] = add nsw i32 [[TMP1]], 1 2744; CHECK-NEXT: ret i32 [[S]] 2745; 2746 %a = add nsw i32 %x, 1 2747 %c = icmp slt i32 %a, 0 2748 %s = select i1 %c, i32 %a, i32 0 2749 ret i32 %s 2750} 2751 2752define i32 @decrement_min(i32 %x) { 2753; CHECK-LABEL: @decrement_min( 2754; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 1) 2755; CHECK-NEXT: [[S:%.*]] = add nsw i32 [[TMP1]], -1 2756; CHECK-NEXT: ret i32 [[S]] 2757; 2758 %a = add nsw i32 %x, -1 2759 %c = icmp slt i32 %a, 0 2760 %s = select i1 %c, i32 %a, i32 0 2761 ret i32 %s 2762} 2763 2764define i1 @icmp_add_add_C(i32 %a, i32 %b) { 2765; CHECK-LABEL: @icmp_add_add_C( 2766; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[B:%.*]] 2767; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], [[TMP1]] 2768; CHECK-NEXT: ret i1 [[CMP]] 2769; 2770 %add1 = add i32 %a, %b 2771 %add2 = add i32 %add1, -1 2772 %cmp = icmp ult i32 %add2, %a 2773 ret i1 %cmp 2774} 2775 2776define i1 @icmp_add_add_C_pred(i32 %a, i32 %b) { 2777; CHECK-LABEL: @icmp_add_add_C_pred( 2778; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[B:%.*]] 2779; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[A:%.*]], [[TMP1]] 2780; CHECK-NEXT: ret i1 [[CMP]] 2781; 2782 %add1 = add i32 %a, %b 2783 %add2 = add i32 %add1, -1 2784 %cmp = icmp uge i32 %add2, %a 2785 ret i1 %cmp 2786} 2787 2788define i1 @icmp_add_add_C_wrong_pred(i32 %a, i32 %b) { 2789; CHECK-LABEL: @icmp_add_add_C_wrong_pred( 2790; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 2791; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], -1 2792; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[ADD2]], [[A]] 2793; CHECK-NEXT: ret i1 [[CMP]] 2794; 2795 %add1 = add i32 %a, %b 2796 %add2 = add i32 %add1, -1 2797 %cmp = icmp ule i32 %add2, %a 2798 ret i1 %cmp 2799} 2800 2801define i1 @icmp_add_add_C_wrong_operand(i32 %a, i32 %b, i32 %c) { 2802; CHECK-LABEL: @icmp_add_add_C_wrong_operand( 2803; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 2804; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], -1 2805; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD2]], [[C:%.*]] 2806; CHECK-NEXT: ret i1 [[CMP]] 2807; 2808 %add1 = add i32 %a, %b 2809 %add2 = add i32 %add1, -1 2810 %cmp = icmp ult i32 %add2, %c 2811 ret i1 %cmp 2812} 2813 2814define i1 @icmp_add_add_C_different_const(i32 %a, i32 %b) { 2815; CHECK-LABEL: @icmp_add_add_C_different_const( 2816; CHECK-NEXT: [[TMP1:%.*]] = sub i32 -43, [[B:%.*]] 2817; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP1]], [[A:%.*]] 2818; CHECK-NEXT: ret i1 [[CMP]] 2819; 2820 %add1 = add i32 %a, %b 2821 %add2 = add i32 %add1, 42 2822 %cmp = icmp ult i32 %add2, %a 2823 ret i1 %cmp 2824} 2825 2826define <2 x i1> @icmp_add_add_C_vector(<2 x i8> %a, <2 x i8> %b) { 2827; CHECK-LABEL: @icmp_add_add_C_vector( 2828; CHECK-NEXT: [[TMP1:%.*]] = sub <2 x i8> <i8 -11, i8 -21>, [[B:%.*]] 2829; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[TMP1]], [[A:%.*]] 2830; CHECK-NEXT: ret <2 x i1> [[CMP]] 2831; 2832 %add1 = add <2 x i8> %a, %b 2833 %add2 = add <2 x i8> %add1, <i8 10, i8 20> 2834 %cmp = icmp ult <2 x i8> %add2, %a 2835 ret <2 x i1> %cmp 2836} 2837 2838define <2 x i1> @icmp_add_add_C_vector_undef(<2 x i8> %a, <2 x i8> %b) { 2839; CHECK-LABEL: @icmp_add_add_C_vector_undef( 2840; CHECK-NEXT: [[TMP1:%.*]] = sub <2 x i8> <i8 -11, i8 undef>, [[B:%.*]] 2841; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[TMP1]], [[A:%.*]] 2842; CHECK-NEXT: ret <2 x i1> [[CMP]] 2843; 2844 %add1 = add <2 x i8> %a, %b 2845 %add2 = add <2 x i8> %add1, <i8 10, i8 undef> 2846 %cmp = icmp ult <2 x i8> %add2, %a 2847 ret <2 x i1> %cmp 2848} 2849 2850define i1 @icmp_add_add_C_comm1(i32 %a, i32 %b) { 2851; CHECK-LABEL: @icmp_add_add_C_comm1( 2852; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[B:%.*]] 2853; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], [[TMP1]] 2854; CHECK-NEXT: ret i1 [[CMP]] 2855; 2856 %add1 = add i32 %b, %a 2857 %add2 = add i32 %add1, -1 2858 %cmp = icmp ult i32 %add2, %a 2859 ret i1 %cmp 2860} 2861 2862define i1 @icmp_add_add_C_comm2(i32 %X, i32 %b) { 2863; CHECK-LABEL: @icmp_add_add_C_comm2( 2864; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[X:%.*]] 2865; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[B:%.*]] 2866; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A]], [[TMP1]] 2867; CHECK-NEXT: ret i1 [[CMP]] 2868; 2869 %a = udiv i32 42, %X ; thwart complexity-based canonicalization 2870 %add1 = add i32 %a, %b 2871 %add2 = add i32 %add1, -1 2872 %cmp = icmp ugt i32 %a, %add2 2873 ret i1 %cmp 2874} 2875 2876define i1 @icmp_add_add_C_comm2_pred(i32 %X, i32 %b) { 2877; CHECK-LABEL: @icmp_add_add_C_comm2_pred( 2878; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[X:%.*]] 2879; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[B:%.*]] 2880; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[A]], [[TMP1]] 2881; CHECK-NEXT: ret i1 [[CMP]] 2882; 2883 %a = udiv i32 42, %X ; thwart complexity-based canonicalization 2884 %add1 = add i32 %a, %b 2885 %add2 = add i32 %add1, -1 2886 %cmp = icmp ule i32 %a, %add2 2887 ret i1 %cmp 2888} 2889 2890define i1 @icmp_add_add_C_comm2_wrong_pred(i32 %X, i32 %b) { 2891; CHECK-LABEL: @icmp_add_add_C_comm2_wrong_pred( 2892; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[X:%.*]] 2893; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[A]], [[B:%.*]] 2894; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], -1 2895; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], [[ADD2]] 2896; CHECK-NEXT: ret i1 [[CMP]] 2897; 2898 %a = udiv i32 42, %X ; thwart complexity-based canonicalization 2899 %add1 = add i32 %a, %b 2900 %add2 = add i32 %add1, -1 2901 %cmp = icmp ult i32 %a, %add2 2902 ret i1 %cmp 2903} 2904 2905define i1 @icmp_add_add_C_comm3(i32 %X, i32 %b) { 2906; CHECK-LABEL: @icmp_add_add_C_comm3( 2907; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[X:%.*]] 2908; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[B:%.*]] 2909; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A]], [[TMP1]] 2910; CHECK-NEXT: ret i1 [[CMP]] 2911; 2912 %a = udiv i32 42, %X ; thwart complexity-based canonicalization 2913 %add1 = add i32 %b, %a 2914 %add2 = add i32 %add1, -1 2915 %cmp = icmp ugt i32 %a, %add2 2916 ret i1 %cmp 2917} 2918 2919define i1 @icmp_add_add_C_extra_use1(i32 %a, i32 %b) { 2920; CHECK-LABEL: @icmp_add_add_C_extra_use1( 2921; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 2922; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], -1 2923; CHECK-NEXT: call void @use(i32 [[ADD2]]) 2924; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD2]], [[A]] 2925; CHECK-NEXT: ret i1 [[CMP]] 2926; 2927 %add1 = add i32 %a, %b 2928 %add2 = add i32 %add1, -1 2929 call void @use(i32 %add2) 2930 %cmp = icmp ult i32 %add2, %a 2931 ret i1 %cmp 2932} 2933 2934define i1 @icmp_add_add_C_extra_use2(i32 %a, i32 %b) { 2935; CHECK-LABEL: @icmp_add_add_C_extra_use2( 2936; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 2937; CHECK-NEXT: call void @use(i32 [[ADD1]]) 2938; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[B]] 2939; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A]], [[TMP1]] 2940; CHECK-NEXT: ret i1 [[CMP]] 2941; 2942 %add1 = add i32 %a, %b 2943 call void @use(i32 %add1) 2944 %add2 = add i32 %add1, -1 2945 %cmp = icmp ult i32 %add2, %a 2946 ret i1 %cmp 2947} 2948 2949; PR57635 - fold ULT->ULE pre-decrement of a non-zero inputs 2950 2951define i1 @icmp_dec_assume_nonzero(i8 %x) { 2952; CHECK-LABEL: @icmp_dec_assume_nonzero( 2953; CHECK-NEXT: [[Z:%.*]] = icmp ne i8 [[X:%.*]], 0 2954; CHECK-NEXT: call void @llvm.assume(i1 [[Z]]) 2955; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[X]], 8 2956; CHECK-NEXT: ret i1 [[C]] 2957; 2958 %z = icmp ne i8 %x, 0 2959 call void @llvm.assume(i1 %z) 2960 %i = add i8 %x, -1 2961 %c = icmp ult i8 %i, 7 2962 ret i1 %c 2963} 2964 2965define i1 @icmp_dec_sub_assume_nonzero(i8 %x) { 2966; CHECK-LABEL: @icmp_dec_sub_assume_nonzero( 2967; CHECK-NEXT: [[Z:%.*]] = icmp ne i8 [[X:%.*]], 0 2968; CHECK-NEXT: call void @llvm.assume(i1 [[Z]]) 2969; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[X]], 12 2970; CHECK-NEXT: ret i1 [[C]] 2971; 2972 %z = icmp ne i8 %x, 0 2973 call void @llvm.assume(i1 %z) 2974 %i = sub i8 %x, 1 2975 %c = icmp ult i8 %i, 11 2976 ret i1 %c 2977} 2978 2979define i1 @icmp_dec_nonzero(i16 %x) { 2980; CHECK-LABEL: @icmp_dec_nonzero( 2981; CHECK-NEXT: [[C:%.*]] = icmp ult i16 [[X:%.*]], 8 2982; CHECK-NEXT: ret i1 [[C]] 2983; 2984 %o = or i16 %x, 4 2985 %i = add i16 %o, -1 2986 %c = icmp ult i16 %i, 7 2987 ret i1 %c 2988} 2989 2990define <2 x i1> @icmp_dec_nonzero_vec(<2 x i32> %x) { 2991; CHECK-LABEL: @icmp_dec_nonzero_vec( 2992; CHECK-NEXT: [[O:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 8) 2993; CHECK-NEXT: [[I:%.*]] = add nsw <2 x i32> [[O]], splat (i32 -1) 2994; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i32> [[I]], <i32 15, i32 17> 2995; CHECK-NEXT: ret <2 x i1> [[C]] 2996; 2997 %o = or <2 x i32> %x, <i32 8, i32 8> 2998 %i = add <2 x i32> %o, <i32 -1, i32 -1> 2999 %c = icmp ult <2 x i32> %i, <i32 15, i32 17> 3000 ret <2 x i1> %c 3001} 3002 3003; Negative test 3004define i1 @icmp_dec_notnonzero(i8 %x) { 3005; CHECK-LABEL: @icmp_dec_notnonzero( 3006; CHECK-NEXT: [[I:%.*]] = add i8 [[X:%.*]], -1 3007; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[I]], 11 3008; CHECK-NEXT: ret i1 [[C]] 3009; 3010 %i = add i8 %x, -1 3011 %c = icmp ult i8 %i, 11 3012 ret i1 %c 3013} 3014 3015define i1 @icmp_addnuw_nonzero(i8 %x, i8 %y) { 3016; CHECK-LABEL: @icmp_addnuw_nonzero( 3017; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X:%.*]], [[Y:%.*]] 3018; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[TMP1]], 0 3019; CHECK-NEXT: ret i1 [[C]] 3020; 3021 %i = add nuw i8 %x, %y 3022 %c = icmp eq i8 %i, 0 3023 ret i1 %c 3024} 3025 3026define i1 @icmp_addnuw_nonzero_fail_multiuse(i32 %x, i32 %y) { 3027; CHECK-LABEL: @icmp_addnuw_nonzero_fail_multiuse( 3028; CHECK-NEXT: [[I:%.*]] = add nuw i32 [[X:%.*]], [[Y:%.*]] 3029; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[I]], 0 3030; CHECK-NEXT: call void @use(i32 [[I]]) 3031; CHECK-NEXT: ret i1 [[C]] 3032; 3033 %i = add nuw i32 %x, %y 3034 %c = icmp eq i32 %i, 0 3035 call void @use(i32 %i) 3036 ret i1 %c 3037} 3038 3039define i1 @ult_add_C2_pow2_C_neg(i8 %x) { 3040; CHECK-LABEL: @ult_add_C2_pow2_C_neg( 3041; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -32 3042; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[TMP1]], -64 3043; CHECK-NEXT: ret i1 [[C]] 3044; 3045 %i = add i8 %x, 32 3046 %c = icmp ult i8 %i, -32 3047 ret i1 %c 3048} 3049 3050define i1 @ult_add_nsw_C2_pow2_C_neg(i8 %x) { 3051; CHECK-LABEL: @ult_add_nsw_C2_pow2_C_neg( 3052; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -32 3053; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[TMP1]], -64 3054; CHECK-NEXT: ret i1 [[C]] 3055; 3056 %i = add nsw i8 %x, 32 3057 %c = icmp ult i8 %i, -32 3058 ret i1 %c 3059} 3060 3061define i1 @ult_add_nuw_nsw_C2_pow2_C_neg(i8 %x) { 3062; CHECK-LABEL: @ult_add_nuw_nsw_C2_pow2_C_neg( 3063; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[X:%.*]], -64 3064; CHECK-NEXT: ret i1 [[C]] 3065; 3066 %i = add nuw nsw i8 %x, 32 3067 %c = icmp ult i8 %i, -32 3068 ret i1 %c 3069} 3070 3071define i1 @ult_add_C2_neg_C_pow2(i8 %x) { 3072; CHECK-LABEL: @ult_add_C2_neg_C_pow2( 3073; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -32 3074; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[TMP1]], 32 3075; CHECK-NEXT: ret i1 [[C]] 3076; 3077 %i = add i8 %x, -32 3078 %c = icmp ult i8 %i, 32 3079 ret i1 %c 3080} 3081 3082define <2 x i1> @ult_add_C2_pow2_C_neg_vec(<2 x i8> %x) { 3083; CHECK-LABEL: @ult_add_C2_pow2_C_neg_vec( 3084; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 -32) 3085; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[TMP1]], splat (i8 -64) 3086; CHECK-NEXT: ret <2 x i1> [[C]] 3087; 3088 %i = add <2 x i8> %x, <i8 32, i8 32> 3089 %c = icmp ult <2 x i8> %i, <i8 -32, i8 -32> 3090 ret <2 x i1> %c 3091} 3092 3093define i1 @ult_add_C2_pow2_C_neg_multiuse(i8 %x) { 3094; CHECK-LABEL: @ult_add_C2_pow2_C_neg_multiuse( 3095; CHECK-NEXT: [[I:%.*]] = add i8 [[X:%.*]], 32 3096; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[I]], -32 3097; CHECK-NEXT: call void @use(i8 [[I]]) 3098; CHECK-NEXT: ret i1 [[C]] 3099; 3100 %i = add i8 %x, 32 3101 %c = icmp ult i8 %i, -32 3102 call void @use(i8 %i) 3103 ret i1 %c 3104} 3105 3106define i1 @uge_add_C2_pow2_C_neg(i8 %x) { 3107; CHECK-LABEL: @uge_add_C2_pow2_C_neg( 3108; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -32 3109; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[TMP1]], -64 3110; CHECK-NEXT: ret i1 [[C]] 3111; 3112 %i = add i8 %x, 32 3113 %c = icmp uge i8 %i, -32 3114 ret i1 %c 3115} 3116 3117declare void @llvm.assume(i1) 3118 3119; Change an unsigned predicate to signed in icmp (add x, C1), C2 3120define i1 @icmp_add_constant_with_constant_ult_to_slt(i32 range(i32 -4, 10) %x) { 3121; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt( 3122; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 8 3123; CHECK-NEXT: ret i1 [[CMP]] 3124; 3125 %add = add nsw i32 %x, 5 3126 %cmp = icmp ult i32 %add, 13 3127 ret i1 %cmp 3128} 3129 3130define i1 @icmp_add_constant_with_constant_ugt_to_sgt(i32 range(i32 -4, 10) %x) { 3131; CHECK-LABEL: @icmp_add_constant_with_constant_ugt_to_sgt( 3132; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 2 3133; CHECK-NEXT: ret i1 [[CMP]] 3134; 3135 %add = add nsw i32 %x, 10 3136 %cmp = icmp ugt i32 %add, 12 3137 ret i1 %cmp 3138} 3139 3140; Negative test: x + C1 may be negative 3141define i1 @icmp_add_constant_with_constant_ult_to_slt_neg1(i32 range(i32 -5, 10) %x) { 3142; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt_neg1( 3143; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], 4 3144; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 20 3145; CHECK-NEXT: ret i1 [[CMP]] 3146; 3147 %add = add nsw i32 %x, 4 3148 %cmp = icmp ult i32 %add, 20 3149 ret i1 %cmp 3150} 3151 3152; Negative test: missing nsw flag 3153define i1 @icmp_add_constant_with_constant_ult_to_slt_neg2(i8 range(i8 -4, 120) %x) { 3154; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt_neg2( 3155; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X:%.*]], 15 3156; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[ADD]], 20 3157; CHECK-NEXT: ret i1 [[CMP]] 3158; 3159 %add = add i8 %x, 15 3160 %cmp = icmp ult i8 %add, 20 3161 ret i1 %cmp 3162} 3163 3164; Negative test: C2 is negative 3165define i1 @icmp_add_constant_with_constant_ult_to_slt_neg3(i32 range(i32 -4, 10) %x) { 3166; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt_neg3( 3167; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], 4 3168; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], -6 3169; CHECK-NEXT: ret i1 [[CMP]] 3170; 3171 %add = add nsw i32 %x, 4 3172 %cmp = icmp ult i32 %add, -6 3173 ret i1 %cmp 3174} 3175 3176; Negative test: C2 - C1 is negative 3177define i1 @icmp_add_constant_with_constant_ult_to_slt_neg4(i32 range(i32 -4, 10) %x) { 3178; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt_neg4( 3179; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], 5 3180; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 2 3181; CHECK-NEXT: ret i1 [[CMP]] 3182; 3183 %add = add nsw i32 %x, 5 3184 %cmp = icmp ult i32 %add, 2 3185 ret i1 %cmp 3186} 3187 3188; Same as before, but infer the range of ucmp 3189define i1 @icmp_of_ucmp_plus_const_with_const(i32 %x, i32 %y) { 3190; CHECK-LABEL: @icmp_of_ucmp_plus_const_with_const( 3191; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X:%.*]], [[Y:%.*]] 3192; CHECK-NEXT: ret i1 [[CMP2]] 3193; 3194 %cmp1 = call i8 @llvm.ucmp(i32 %x, i32 %y) 3195 %add = add i8 %cmp1, 1 3196 %cmp2 = icmp ult i8 %add, 2 3197 ret i1 %cmp2 3198} 3199 3200define i1 @zext_range_check_ult(i8 %x) { 3201; CHECK-LABEL: @zext_range_check_ult( 3202; CHECK-NEXT: entry: 3203; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[X:%.*]], -4 3204; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[TMP0]], 3 3205; CHECK-NEXT: ret i1 [[CMP]] 3206; 3207entry: 3208 %conv = zext i8 %x to i32 3209 %add = add i32 %conv, -4 3210 %cmp = icmp ult i32 %add, 3 3211 ret i1 %cmp 3212} 3213 3214; TODO: should be canonicalized to (x - 4) u> 2 3215define i1 @zext_range_check_ugt(i8 %x) { 3216; CHECK-LABEL: @zext_range_check_ugt( 3217; CHECK-NEXT: entry: 3218; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32 3219; CHECK-NEXT: [[TMP0:%.*]] = add nsw i32 [[CONV]], -7 3220; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP0]], -3 3221; CHECK-NEXT: ret i1 [[CMP]] 3222; 3223entry: 3224 %conv = zext i8 %x to i32 3225 %add = add i32 %conv, -4 3226 %cmp = icmp ugt i32 %add, 2 3227 ret i1 %cmp 3228} 3229 3230; TODO: should be canonicalized to (x - 4) u> 2 3231define i1 @zext_range_check_ult_alter(i8 %x) { 3232; CHECK-LABEL: @zext_range_check_ult_alter( 3233; CHECK-NEXT: entry: 3234; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32 3235; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], -7 3236; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], -3 3237; CHECK-NEXT: ret i1 [[CMP]] 3238; 3239entry: 3240 %conv = zext i8 %x to i32 3241 %add = add i32 %conv, -7 3242 %cmp = icmp ult i32 %add, -3 3243 ret i1 %cmp 3244} 3245 3246define i1 @zext_range_check_mergable(i8 %x) { 3247; CHECK-LABEL: @zext_range_check_mergable( 3248; CHECK-NEXT: [[COND:%.*]] = icmp slt i8 [[X:%.*]], 7 3249; CHECK-NEXT: ret i1 [[COND]] 3250; 3251 %conv = zext i8 %x to i32 3252 %add = add nsw i32 %conv, -4 3253 %cmp1 = icmp ult i32 %add, 3 3254 %cmp2 = icmp slt i8 %x, 4 3255 %cond = select i1 %cmp2, i1 true, i1 %cmp1 3256 ret i1 %cond 3257} 3258 3259; Negative tests 3260 3261define i1 @sext_range_check_ult(i8 %x) { 3262; CHECK-LABEL: @sext_range_check_ult( 3263; CHECK-NEXT: entry: 3264; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[X:%.*]] to i32 3265; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], -4 3266; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 3 3267; CHECK-NEXT: ret i1 [[CMP]] 3268; 3269entry: 3270 %conv = sext i8 %x to i32 3271 %add = add i32 %conv, -4 3272 %cmp = icmp ult i32 %add, 3 3273 ret i1 %cmp 3274} 3275 3276define i1 @zext_range_check_ult_illegal_type(i7 %x) { 3277; CHECK-LABEL: @zext_range_check_ult_illegal_type( 3278; CHECK-NEXT: entry: 3279; CHECK-NEXT: [[CONV:%.*]] = zext i7 [[X:%.*]] to i32 3280; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], -4 3281; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 3 3282; CHECK-NEXT: ret i1 [[CMP]] 3283; 3284entry: 3285 %conv = zext i7 %x to i32 3286 %add = add i32 %conv, -4 3287 %cmp = icmp ult i32 %add, 3 3288 ret i1 %cmp 3289} 3290 3291define i1 @zext_range_check_ult_range_check_failure(i8 %x) { 3292; CHECK-LABEL: @zext_range_check_ult_range_check_failure( 3293; CHECK-NEXT: entry: 3294; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32 3295; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], -4 3296; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 253 3297; CHECK-NEXT: ret i1 [[CMP]] 3298; 3299entry: 3300 %conv = zext i8 %x to i32 3301 %add = add i32 %conv, -4 3302 %cmp = icmp ult i32 %add, 253 3303 ret i1 %cmp 3304} 3305