1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3; These should be InstSimplify checks, but most of the code 4; is currently only in InstCombine. TODO: move supporting code 5 6declare void @use(i8) 7declare void @use_vec(<2 x i8>) 8 9; Definitely out of range 10define i1 @test_nonzero(ptr nocapture readonly %arg) { 11; CHECK-LABEL: @test_nonzero( 12; CHECK-NEXT: ret i1 true 13; 14 %val = load i32, ptr %arg, !range !0 15 %rval = icmp ne i32 %val, 0 16 ret i1 %rval 17} 18define i1 @test_nonzero2(ptr nocapture readonly %arg) { 19; CHECK-LABEL: @test_nonzero2( 20; CHECK-NEXT: ret i1 false 21; 22 %val = load i32, ptr %arg, !range !0 23 %rval = icmp eq i32 %val, 0 24 ret i1 %rval 25} 26 27; Potentially in range 28define i1 @test_nonzero3(ptr nocapture readonly %arg) { 29; CHECK-LABEL: @test_nonzero3( 30; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[ARG:%.*]], align 4, !range [[RNG0:![0-9]+]] 31; CHECK-NEXT: [[RVAL:%.*]] = icmp ne i32 [[VAL]], 0 32; CHECK-NEXT: ret i1 [[RVAL]] 33; 34; Check that this does not trigger - it wouldn't be legal 35 %val = load i32, ptr %arg, !range !1 36 %rval = icmp ne i32 %val, 0 37 ret i1 %rval 38} 39 40; Definitely in range 41define i1 @test_nonzero4(ptr nocapture readonly %arg) { 42; CHECK-LABEL: @test_nonzero4( 43; CHECK-NEXT: ret i1 false 44; 45 %val = load i8, ptr %arg, !range !2 46 %rval = icmp ne i8 %val, 0 47 ret i1 %rval 48} 49 50define i1 @test_nonzero5(ptr nocapture readonly %arg) { 51; CHECK-LABEL: @test_nonzero5( 52; CHECK-NEXT: ret i1 false 53; 54 %val = load i8, ptr %arg, !range !2 55 %rval = icmp ugt i8 %val, 0 56 ret i1 %rval 57} 58 59; Cheaper checks (most values in range meet requirements) 60define i1 @test_nonzero6(ptr %argw) { 61; CHECK-LABEL: @test_nonzero6( 62; CHECK-NEXT: [[VAL:%.*]] = load i8, ptr [[ARGW:%.*]], align 1, !range [[RNG1:![0-9]+]] 63; CHECK-NEXT: [[RVAL:%.*]] = icmp ne i8 [[VAL]], 0 64; CHECK-NEXT: ret i1 [[RVAL]] 65; 66 %val = load i8, ptr %argw, !range !3 67 %rval = icmp sgt i8 %val, 0 68 ret i1 %rval 69} 70 71; Constant not in range, should return true. 72define i1 @test_not_in_range(ptr nocapture readonly %arg) { 73; CHECK-LABEL: @test_not_in_range( 74; CHECK-NEXT: ret i1 true 75; 76 %val = load i32, ptr %arg, !range !0 77 %rval = icmp ne i32 %val, 6 78 ret i1 %rval 79} 80 81; Constant in range, can not fold. 82define i1 @test_in_range(ptr nocapture readonly %arg) { 83; CHECK-LABEL: @test_in_range( 84; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[ARG:%.*]], align 4, !range [[RNG2:![0-9]+]] 85; CHECK-NEXT: [[RVAL:%.*]] = icmp ne i32 [[VAL]], 3 86; CHECK-NEXT: ret i1 [[RVAL]] 87; 88 %val = load i32, ptr %arg, !range !0 89 %rval = icmp ne i32 %val, 3 90 ret i1 %rval 91} 92 93; Values in range greater than constant. 94define i1 @test_range_sgt_constant(ptr nocapture readonly %arg) { 95; CHECK-LABEL: @test_range_sgt_constant( 96; CHECK-NEXT: ret i1 true 97; 98 %val = load i32, ptr %arg, !range !0 99 %rval = icmp sgt i32 %val, 0 100 ret i1 %rval 101} 102 103; Values in range less than constant. 104define i1 @test_range_slt_constant(ptr nocapture readonly %arg) { 105; CHECK-LABEL: @test_range_slt_constant( 106; CHECK-NEXT: ret i1 false 107; 108 %val = load i32, ptr %arg, !range !0 109 %rval = icmp sgt i32 %val, 6 110 ret i1 %rval 111} 112 113; Values in union of multiple sub ranges not equal to constant. 114define i1 @test_multi_range1(ptr nocapture readonly %arg) { 115; CHECK-LABEL: @test_multi_range1( 116; CHECK-NEXT: ret i1 true 117; 118 %val = load i32, ptr %arg, !range !4 119 %rval = icmp ne i32 %val, 0 120 ret i1 %rval 121} 122 123; Values in multiple sub ranges not equal to constant, but in 124; union of sub ranges could possibly equal to constant. This 125; in theory could also be folded and might be implemented in 126; the future if shown profitable in practice. 127define i1 @test_multi_range2(ptr nocapture readonly %arg) { 128; CHECK-LABEL: @test_multi_range2( 129; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[ARG:%.*]], align 4, !range [[RNG3:![0-9]+]] 130; CHECK-NEXT: [[RVAL:%.*]] = icmp ne i32 [[VAL]], 7 131; CHECK-NEXT: ret i1 [[RVAL]] 132; 133 %val = load i32, ptr %arg, !range !4 134 %rval = icmp ne i32 %val, 7 135 ret i1 %rval 136} 137 138; Values' ranges overlap each other, so it can not be simplified. 139define i1 @test_two_ranges(ptr nocapture readonly %arg1, ptr nocapture readonly %arg2) { 140; CHECK-LABEL: @test_two_ranges( 141; CHECK-NEXT: [[VAL1:%.*]] = load i32, ptr [[ARG1:%.*]], align 4, !range [[RNG4:![0-9]+]] 142; CHECK-NEXT: [[VAL2:%.*]] = load i32, ptr [[ARG2:%.*]], align 4, !range [[RNG5:![0-9]+]] 143; CHECK-NEXT: [[RVAL:%.*]] = icmp samesign ult i32 [[VAL2]], [[VAL1]] 144; CHECK-NEXT: ret i1 [[RVAL]] 145; 146 %val1 = load i32, ptr %arg1, !range !5 147 %val2 = load i32, ptr %arg2, !range !6 148 %rval = icmp ult i32 %val2, %val1 149 ret i1 %rval 150} 151 152; Values' ranges overlap each other, so it can not be simplified. 153define i1 @test_two_attribute_ranges(i32 range(i32 5, 10) %arg1, i32 range(i32 8, 16) %arg2) { 154; CHECK-LABEL: @test_two_attribute_ranges( 155; CHECK-NEXT: [[RVAL:%.*]] = icmp samesign ult i32 [[ARG2:%.*]], [[ARG1:%.*]] 156; CHECK-NEXT: ret i1 [[RVAL]] 157; 158 %rval = icmp ult i32 %arg2, %arg1 159 ret i1 %rval 160} 161 162; Values' ranges do not overlap each other, so it can simplified to false. 163define i1 @test_two_ranges2(ptr nocapture readonly %arg1, ptr nocapture readonly %arg2) { 164; CHECK-LABEL: @test_two_ranges2( 165; CHECK-NEXT: ret i1 false 166; 167 %val1 = load i32, ptr %arg1, !range !0 168 %val2 = load i32, ptr %arg2, !range !6 169 %rval = icmp ult i32 %val2, %val1 170 ret i1 %rval 171} 172 173; Values' ranges do not overlap each other, so it can simplified to false. 174define i1 @test_two_argument_ranges(i32 range(i32 1, 6) %arg1, i32 range(i32 8, 16) %arg2) { 175; CHECK-LABEL: @test_two_argument_ranges( 176; CHECK-NEXT: ret i1 false 177; 178 %rval = icmp ult i32 %arg2, %arg1 179 ret i1 %rval 180} 181 182; Values' ranges do not overlap each other, so it can simplified to false. 183define i1 @test_one_range_and_one_argument_range(ptr nocapture readonly %arg1, i32 range(i32 8, 16) %arg2) { 184; CHECK-LABEL: @test_one_range_and_one_argument_range( 185; CHECK-NEXT: ret i1 false 186; 187 %val1 = load i32, ptr %arg1, !range !0 188 %rval = icmp ult i32 %arg2, %val1 189 ret i1 %rval 190} 191 192; Values' ranges do not overlap each other, so it can simplified to false. 193define i1 @test_one_argument_range_and_one_range(i32 range(i32 1, 6) %arg1, ptr nocapture readonly %arg2) { 194; CHECK-LABEL: @test_one_argument_range_and_one_range( 195; CHECK-NEXT: ret i1 false 196; 197 %val1 = load i32, ptr %arg2, !range !6 198 %rval = icmp ult i32 %val1, %arg1 199 ret i1 %rval 200} 201 202; Values' ranges do not overlap each other, so it can simplified to true. 203define i1 @test_two_ranges3(ptr nocapture readonly %arg1, ptr nocapture readonly %arg2) { 204; CHECK-LABEL: @test_two_ranges3( 205; CHECK-NEXT: ret i1 true 206; 207 %val1 = load i32, ptr %arg1, !range !0 208 %val2 = load i32, ptr %arg2, !range !6 209 %rval = icmp ugt i32 %val2, %val1 210 ret i1 %rval 211} 212 213; Values' ranges overlap each other, so it can not be simplified. 214define <2 x i1> @test_two_ranges_vec(ptr nocapture readonly %arg1, ptr nocapture readonly %arg2) { 215; CHECK-LABEL: @test_two_ranges_vec( 216; CHECK-NEXT: [[VAL1:%.*]] = load <2 x i32>, ptr [[ARG1:%.*]], align 8, !range [[RNG4]] 217; CHECK-NEXT: [[VAL2:%.*]] = load <2 x i32>, ptr [[ARG2:%.*]], align 8, !range [[RNG5]] 218; CHECK-NEXT: [[RVAL:%.*]] = icmp samesign ult <2 x i32> [[VAL2]], [[VAL1]] 219; CHECK-NEXT: ret <2 x i1> [[RVAL]] 220; 221 %val1 = load <2 x i32>, ptr %arg1, !range !5 222 %val2 = load <2 x i32>, ptr %arg2, !range !6 223 %rval = icmp ult <2 x i32> %val2, %val1 224 ret <2 x i1> %rval 225} 226 227; Values' ranges do not overlap each other, so it can simplified to false. 228define <2 x i1> @test_two_ranges_vec_false(ptr nocapture readonly %arg1, ptr nocapture readonly %arg2) { 229; CHECK-LABEL: @test_two_ranges_vec_false( 230; CHECK-NEXT: ret <2 x i1> zeroinitializer 231; 232 %val1 = load <2 x i32>, ptr %arg1, !range !0 233 %val2 = load <2 x i32>, ptr %arg2, !range !6 234 %rval = icmp ult <2 x i32> %val2, %val1 235 ret <2 x i1> %rval 236} 237 238; Values' ranges do not overlap each other, so it can simplified to true. 239define <2 x i1> @test_two_ranges_vec_true(ptr nocapture readonly %arg1, ptr nocapture readonly %arg2) { 240; CHECK-LABEL: @test_two_ranges_vec_true( 241; CHECK-NEXT: ret <2 x i1> splat (i1 true) 242; 243 %val1 = load <2 x i32>, ptr %arg1, !range !0 244 %val2 = load <2 x i32>, ptr %arg2, !range !6 245 %rval = icmp ugt <2 x i32> %val2, %val1 246 ret <2 x i1> %rval 247} 248 249; Values' ranges overlap each other, so it can not be simplified. 250define <2 x i1> @test_two_argument_ranges_vec(<2 x i32> range(i32 5, 10) %arg1, <2 x i32> range(i32 8, 16) %arg2) { 251; CHECK-LABEL: @test_two_argument_ranges_vec( 252; CHECK-NEXT: [[RVAL:%.*]] = icmp samesign ult <2 x i32> [[ARG2:%.*]], [[ARG1:%.*]] 253; CHECK-NEXT: ret <2 x i1> [[RVAL]] 254; 255 %rval = icmp ult <2 x i32> %arg2, %arg1 256 ret <2 x i1> %rval 257} 258 259; Values' ranges do not overlap each other, so it can simplified to false. 260define <2 x i1> @test_two_argument_ranges_vec_false(<2 x i32> range(i32 1, 6) %arg1, <2 x i32> range(i32 8, 16) %arg2) { 261; CHECK-LABEL: @test_two_argument_ranges_vec_false( 262; CHECK-NEXT: ret <2 x i1> zeroinitializer 263; 264 %rval = icmp ult <2 x i32> %arg2, %arg1 265 ret <2 x i1> %rval 266} 267 268; Values' ranges do not overlap each other, so it can simplified to true. 269define <2 x i1> @test_two_argument_ranges_vec_true(<2 x i32> range(i32 1, 6) %arg1, <2 x i32> range(i32 8, 16) %arg2) { 270; CHECK-LABEL: @test_two_argument_ranges_vec_true( 271; CHECK-NEXT: ret <2 x i1> splat (i1 true) 272; 273 %rval = icmp ugt <2 x i32> %arg2, %arg1 274 ret <2 x i1> %rval 275} 276 277declare i32 @create_range1() 278declare range(i32 8, 16) i32 @create_range2() 279declare range(i32 1, 6) i32 @create_range3() 280 281; Values' ranges overlap each other, so it can not be simplified. 282define i1 @test_two_return_attribute_ranges_not_simplified() { 283; CHECK-LABEL: @test_two_return_attribute_ranges_not_simplified( 284; CHECK-NEXT: [[VAL1:%.*]] = call range(i32 5, 10) i32 @create_range1() 285; CHECK-NEXT: [[VAL2:%.*]] = call i32 @create_range2() 286; CHECK-NEXT: [[RVAL:%.*]] = icmp samesign ult i32 [[VAL2]], [[VAL1]] 287; CHECK-NEXT: ret i1 [[RVAL]] 288; 289 %val1 = call range(i32 5, 10) i32 @create_range1() 290 %val2 = call i32 @create_range2() 291 %rval = icmp ult i32 %val2, %val1 292 ret i1 %rval 293} 294 295; Values' ranges do not overlap each other, so it can simplified to false. 296define i1 @test_two_return_attribute_ranges_one_in_call() { 297; CHECK-LABEL: @test_two_return_attribute_ranges_one_in_call( 298; CHECK-NEXT: [[VAL1:%.*]] = call range(i32 1, 6) i32 @create_range1() 299; CHECK-NEXT: [[VAL2:%.*]] = call i32 @create_range2() 300; CHECK-NEXT: ret i1 false 301; 302 %val1 = call range(i32 1, 6) i32 @create_range1() 303 %val2 = call i32 @create_range2() 304 %rval = icmp ult i32 %val2, %val1 305 ret i1 %rval 306} 307 308; Values' ranges do not overlap each other, so it can simplified to false. 309define i1 @test_two_return_attribute_ranges() { 310; CHECK-LABEL: @test_two_return_attribute_ranges( 311; CHECK-NEXT: [[VAL1:%.*]] = call i32 @create_range3() 312; CHECK-NEXT: [[VAL2:%.*]] = call i32 @create_range2() 313; CHECK-NEXT: ret i1 false 314; 315 %val1 = call i32 @create_range3() 316 %val2 = call i32 @create_range2() 317 %rval = icmp ult i32 %val2, %val1 318 ret i1 %rval 319} 320 321; Values' ranges do not overlap each other, so it can simplified to false. 322define i1 @test_one_return_argument_and_one_argument_range(i32 range(i32 8, 16) %arg1) { 323; CHECK-LABEL: @test_one_return_argument_and_one_argument_range( 324; CHECK-NEXT: [[VAL1:%.*]] = call i32 @create_range3() 325; CHECK-NEXT: ret i1 false 326; 327 %val1 = call i32 @create_range3() 328 %rval = icmp ult i32 %arg1, %val1 329 ret i1 %rval 330} 331 332; Values' ranges do not overlap each other, so it can simplified to false. 333define i1 @test_one_range_and_one_return_argument(ptr nocapture readonly %arg1) { 334; CHECK-LABEL: @test_one_range_and_one_return_argument( 335; CHECK-NEXT: [[VAL1:%.*]] = call i32 @create_range3() 336; CHECK-NEXT: ret i1 false 337; 338 %val1 = call i32 @create_range3() 339 %val2 = load i32, ptr %arg1, !range !6 340 %rval = icmp ult i32 %val2, %val1 341 ret i1 %rval 342} 343 344define i1 @ugt_zext(i1 %b, i8 %x) { 345; CHECK-LABEL: @ugt_zext( 346; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], 0 347; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[B:%.*]] 348; CHECK-NEXT: ret i1 [[R]] 349; 350 %z = zext i1 %b to i8 351 %r = icmp ugt i8 %z, %x 352 ret i1 %r 353} 354 355define <2 x i1> @ult_zext(<2 x i1> %b, <2 x i8> %p) { 356; CHECK-LABEL: @ult_zext( 357; CHECK-NEXT: [[X:%.*]] = mul <2 x i8> [[P:%.*]], [[P]] 358; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X]], zeroinitializer 359; CHECK-NEXT: [[R:%.*]] = and <2 x i1> [[TMP1]], [[B:%.*]] 360; CHECK-NEXT: ret <2 x i1> [[R]] 361; 362 %x = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization 363 %z = zext <2 x i1> %b to <2 x i8> 364 %r = icmp ult <2 x i8> %x, %z 365 ret <2 x i1> %r 366} 367 368; negative test - need ult/ugt 369 370define i1 @uge_zext(i1 %b, i8 %x) { 371; CHECK-LABEL: @uge_zext( 372; CHECK-NEXT: [[Z:%.*]] = zext i1 [[B:%.*]] to i8 373; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X:%.*]], [[Z]] 374; CHECK-NEXT: ret i1 [[R]] 375; 376 %z = zext i1 %b to i8 377 %r = icmp uge i8 %z, %x 378 ret i1 %r 379} 380 381; negative test - need ult/ugt 382 383define i1 @ule_zext(i1 %b, i8 %p) { 384; CHECK-LABEL: @ule_zext( 385; CHECK-NEXT: [[X:%.*]] = mul i8 [[P:%.*]], [[P]] 386; CHECK-NEXT: [[Z:%.*]] = zext i1 [[B:%.*]] to i8 387; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X]], [[Z]] 388; CHECK-NEXT: ret i1 [[R]] 389; 390 %x = mul i8 %p, %p ; thwart complexity-based canonicalization 391 %z = zext i1 %b to i8 392 %r = icmp ule i8 %x, %z 393 ret i1 %r 394} 395 396; negative test - extra use 397 398define i1 @ugt_zext_use(i1 %b, i8 %x) { 399; CHECK-LABEL: @ugt_zext_use( 400; CHECK-NEXT: [[Z:%.*]] = zext i1 [[B:%.*]] to i8 401; CHECK-NEXT: call void @use(i8 [[Z]]) 402; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[X:%.*]], [[Z]] 403; CHECK-NEXT: ret i1 [[R]] 404; 405 %z = zext i1 %b to i8 406 call void @use(i8 %z) 407 %r = icmp ugt i8 %z, %x 408 ret i1 %r 409} 410 411; negative test - must be zext of i1 412 413define i1 @ult_zext_not_i1(i2 %b, i8 %x) { 414; CHECK-LABEL: @ult_zext_not_i1( 415; CHECK-NEXT: [[Z:%.*]] = zext i2 [[B:%.*]] to i8 416; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[X:%.*]], [[Z]] 417; CHECK-NEXT: ret i1 [[R]] 418; 419 %z = zext i2 %b to i8 420 %r = icmp ult i8 %x, %z 421 ret i1 %r 422} 423 424; sub is eliminated 425 426define i1 @sub_ult_zext(i1 %b, i8 %x, i8 %y) { 427; CHECK-LABEL: @sub_ult_zext( 428; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]] 429; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[B:%.*]] 430; CHECK-NEXT: ret i1 [[R]] 431; 432 %z = zext i1 %b to i8 433 %s = sub i8 %x, %y 434 %r = icmp ult i8 %s, %z 435 ret i1 %r 436} 437 438define i1 @zext_ult_zext(i1 %b, i8 %p) { 439; CHECK-LABEL: @zext_ult_zext( 440; CHECK-NEXT: [[X:%.*]] = mul i8 [[P:%.*]], [[P]] 441; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X]], 0 442; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[B:%.*]] 443; CHECK-NEXT: ret i1 [[R]] 444; 445 %x = mul i8 %p, %p ; thwart complexity-based canonicalization 446 %z = zext i1 %b to i16 447 %zx = zext i8 %x to i16 448 %r = icmp ult i16 %zx, %z 449 ret i1 %r 450} 451 452; match and fold even if both sides are zexts (from different source types) 453 454define i1 @zext_ugt_zext(i1 %b, i4 %x) { 455; CHECK-LABEL: @zext_ugt_zext( 456; CHECK-NEXT: [[ZX:%.*]] = zext i4 [[X:%.*]] to i8 457; CHECK-NEXT: call void @use(i8 [[ZX]]) 458; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i4 [[X]], 0 459; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[B:%.*]] 460; CHECK-NEXT: ret i1 [[R]] 461; 462 %z = zext i1 %b to i8 463 %zx = zext i4 %x to i8 464 call void @use(i8 %zx) 465 %r = icmp ugt i8 %z, %zx 466 ret i1 %r 467} 468 469; negative test - must be zext of i1 470 471define i1 @sub_ult_zext_not_i1(i2 %b, i8 %x, i8 %y) { 472; CHECK-LABEL: @sub_ult_zext_not_i1( 473; CHECK-NEXT: [[Z:%.*]] = zext i2 [[B:%.*]] to i8 474; CHECK-NEXT: [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 475; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[S]], [[Z]] 476; CHECK-NEXT: ret i1 [[R]] 477; 478 %z = zext i2 %b to i8 479 %s = sub i8 %x, %y 480 %r = icmp ult i8 %s, %z 481 ret i1 %r 482} 483 484; negative test - extra use (but we could try harder to fold this) 485 486define i1 @sub_ult_zext_use1(i1 %b, i8 %x, i8 %y) { 487; CHECK-LABEL: @sub_ult_zext_use1( 488; CHECK-NEXT: [[Z:%.*]] = zext i1 [[B:%.*]] to i8 489; CHECK-NEXT: call void @use(i8 [[Z]]) 490; CHECK-NEXT: [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 491; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[S]], [[Z]] 492; CHECK-NEXT: ret i1 [[R]] 493; 494 %z = zext i1 %b to i8 495 call void @use(i8 %z) 496 %s = sub i8 %x, %y 497 %r = icmp ult i8 %s, %z 498 ret i1 %r 499} 500 501define <2 x i1> @zext_ugt_sub_use2(<2 x i1> %b, <2 x i8> %x, <2 x i8> %y) { 502; CHECK-LABEL: @zext_ugt_sub_use2( 503; CHECK-NEXT: [[S:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]] 504; CHECK-NEXT: call void @use_vec(<2 x i8> [[S]]) 505; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X]], [[Y]] 506; CHECK-NEXT: [[R:%.*]] = and <2 x i1> [[TMP1]], [[B:%.*]] 507; CHECK-NEXT: ret <2 x i1> [[R]] 508; 509 %z = zext <2 x i1> %b to <2 x i8> 510 %s = sub <2 x i8> %x, %y 511 call void @use_vec(<2 x i8> %s) 512 %r = icmp ugt <2 x i8> %z, %s 513 ret <2 x i1> %r 514} 515 516define i1 @sub_ult_zext_use3(i1 %b, i8 %x, i8 %y) { 517; CHECK-LABEL: @sub_ult_zext_use3( 518; CHECK-NEXT: [[Z:%.*]] = zext i1 [[B:%.*]] to i8 519; CHECK-NEXT: call void @use(i8 [[Z]]) 520; CHECK-NEXT: [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 521; CHECK-NEXT: call void @use(i8 [[S]]) 522; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[S]], [[Z]] 523; CHECK-NEXT: ret i1 [[R]] 524; 525 %z = zext i1 %b to i8 526 call void @use(i8 %z) 527 %s = sub i8 %x, %y 528 call void @use(i8 %s) 529 %r = icmp ult i8 %s, %z 530 ret i1 %r 531} 532 533define i1 @sub_ule_zext(i1 %b, i8 %x, i8 %y) { 534; CHECK-LABEL: @sub_ule_zext( 535; CHECK-NEXT: [[Z:%.*]] = zext i1 [[B:%.*]] to i8 536; CHECK-NEXT: [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 537; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[S]], [[Z]] 538; CHECK-NEXT: ret i1 [[R]] 539; 540 %z = zext i1 %b to i8 541 %s = sub i8 %x, %y 542 %r = icmp ule i8 %s, %z 543 ret i1 %r 544} 545 546define <2 x i1> @sub_ult_and(<2 x i8> %b, <2 x i8> %x, <2 x i8> %y) { 547; CHECK-LABEL: @sub_ult_and( 548; CHECK-NEXT: [[A:%.*]] = and <2 x i8> [[B:%.*]], splat (i8 1) 549; CHECK-NEXT: [[S:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]] 550; CHECK-NEXT: [[R:%.*]] = icmp ult <2 x i8> [[S]], [[A]] 551; CHECK-NEXT: ret <2 x i1> [[R]] 552; 553 %a = and <2 x i8> %b, <i8 1, i8 1> 554 %s = sub <2 x i8> %x, %y 555 %r = icmp ult <2 x i8> %s, %a 556 ret <2 x i1> %r 557} 558 559define i1 @and_ugt_sub(i8 %b, i8 %x, i8 %y) { 560; CHECK-LABEL: @and_ugt_sub( 561; CHECK-NEXT: [[A:%.*]] = and i8 [[B:%.*]], 1 562; CHECK-NEXT: [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 563; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[A]], [[S]] 564; CHECK-NEXT: ret i1 [[R]] 565; 566 %a = and i8 %b, 1 567 %s = sub i8 %x, %y 568 %r = icmp ugt i8 %a, %s 569 ret i1 %r 570} 571 572; Repeat the zext set of tests with a sext instead. 573 574define i1 @uge_sext(i1 %b, i8 %x) { 575; CHECK-LABEL: @uge_sext( 576; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], 0 577; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[B:%.*]] 578; CHECK-NEXT: ret i1 [[R]] 579; 580 %s = sext i1 %b to i8 581 %r = icmp uge i8 %s, %x 582 ret i1 %r 583} 584 585define <2 x i1> @ule_sext(<2 x i1> %b, <2 x i8> %p) { 586; CHECK-LABEL: @ule_sext( 587; CHECK-NEXT: [[X:%.*]] = mul <2 x i8> [[P:%.*]], [[P]] 588; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X]], zeroinitializer 589; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[TMP1]], [[B:%.*]] 590; CHECK-NEXT: ret <2 x i1> [[R]] 591; 592 %x = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization 593 %s = sext <2 x i1> %b to <2 x i8> 594 %r = icmp ule <2 x i8> %x, %s 595 ret <2 x i1> %r 596} 597 598; negative test - need ule/uge 599 600define i1 @ugt_sext(i1 %b, i8 %x) { 601; CHECK-LABEL: @ugt_sext( 602; CHECK-NEXT: [[S:%.*]] = sext i1 [[B:%.*]] to i8 603; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[X:%.*]], [[S]] 604; CHECK-NEXT: ret i1 [[R]] 605; 606 %s = sext i1 %b to i8 607 %r = icmp ugt i8 %s, %x 608 ret i1 %r 609} 610 611; negative test - need ule/uge 612 613define i1 @ult_sext(i1 %b, i8 %p) { 614; CHECK-LABEL: @ult_sext( 615; CHECK-NEXT: [[X:%.*]] = mul i8 [[P:%.*]], [[P]] 616; CHECK-NEXT: [[S:%.*]] = sext i1 [[B:%.*]] to i8 617; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[X]], [[S]] 618; CHECK-NEXT: ret i1 [[R]] 619; 620 %x = mul i8 %p, %p ; thwart complexity-based canonicalization 621 %s = sext i1 %b to i8 622 %r = icmp ult i8 %x, %s 623 ret i1 %r 624} 625 626; negative test - extra use 627 628define i1 @uge_sext_use(i1 %b, i8 %x) { 629; CHECK-LABEL: @uge_sext_use( 630; CHECK-NEXT: [[S:%.*]] = sext i1 [[B:%.*]] to i8 631; CHECK-NEXT: call void @use(i8 [[S]]) 632; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X:%.*]], [[S]] 633; CHECK-NEXT: ret i1 [[R]] 634; 635 %s = sext i1 %b to i8 636 call void @use(i8 %s) 637 %r = icmp uge i8 %s, %x 638 ret i1 %r 639} 640 641; negative test - must be sext of i1 642 643define i1 @ule_sext_not_i1(i2 %b, i8 %x) { 644; CHECK-LABEL: @ule_sext_not_i1( 645; CHECK-NEXT: [[S:%.*]] = sext i2 [[B:%.*]] to i8 646; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X:%.*]], [[S]] 647; CHECK-NEXT: ret i1 [[R]] 648; 649 %s = sext i2 %b to i8 650 %r = icmp ule i8 %x, %s 651 ret i1 %r 652} 653 654; sub is eliminated 655 656define i1 @sub_ule_sext(i1 %b, i8 %x, i8 %y) { 657; CHECK-LABEL: @sub_ule_sext( 658; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]] 659; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[B:%.*]] 660; CHECK-NEXT: ret i1 [[R]] 661; 662 %s = sext i1 %b to i8 663 %d = sub i8 %x, %y 664 %r = icmp ule i8 %d, %s 665 ret i1 %r 666} 667 668define i1 @sext_ule_sext(i1 %b, i8 %p) { 669; CHECK-LABEL: @sext_ule_sext( 670; CHECK-NEXT: [[X:%.*]] = mul i8 [[P:%.*]], [[P]] 671; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X]], 0 672; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[B:%.*]] 673; CHECK-NEXT: ret i1 [[R]] 674; 675 %x = mul i8 %p, %p ; thwart complexity-based canonicalization 676 %s = sext i1 %b to i16 677 %sx = sext i8 %x to i16 678 %r = icmp ule i16 %sx, %s 679 ret i1 %r 680} 681 682; match and fold even if both sides are sexts (from different source types) 683 684define i1 @sext_uge_sext(i1 %b, i4 %x) { 685; CHECK-LABEL: @sext_uge_sext( 686; CHECK-NEXT: [[SX:%.*]] = sext i4 [[X:%.*]] to i8 687; CHECK-NEXT: call void @use(i8 [[SX]]) 688; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i4 [[X]], 0 689; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[B:%.*]] 690; CHECK-NEXT: ret i1 [[R]] 691; 692 %s = sext i1 %b to i8 693 %sx = sext i4 %x to i8 694 call void @use(i8 %sx) 695 %r = icmp uge i8 %s, %sx 696 ret i1 %r 697} 698 699; negative test - must be sext of i1 700 701define i1 @sub_ule_sext_not_i1(i2 %b, i8 %x, i8 %y) { 702; CHECK-LABEL: @sub_ule_sext_not_i1( 703; CHECK-NEXT: [[S:%.*]] = sext i2 [[B:%.*]] to i8 704; CHECK-NEXT: [[D:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 705; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[D]], [[S]] 706; CHECK-NEXT: ret i1 [[R]] 707; 708 %s = sext i2 %b to i8 709 %d = sub i8 %x, %y 710 %r = icmp ule i8 %d, %s 711 ret i1 %r 712} 713 714; negative test - extra use (but we could try harder to fold this) 715 716define i1 @sub_ule_sext_use1(i1 %b, i8 %x, i8 %y) { 717; CHECK-LABEL: @sub_ule_sext_use1( 718; CHECK-NEXT: [[S:%.*]] = sext i1 [[B:%.*]] to i8 719; CHECK-NEXT: call void @use(i8 [[S]]) 720; CHECK-NEXT: [[D:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 721; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[D]], [[S]] 722; CHECK-NEXT: ret i1 [[R]] 723; 724 %s = sext i1 %b to i8 725 call void @use(i8 %s) 726 %d = sub i8 %x, %y 727 %r = icmp ule i8 %d, %s 728 ret i1 %r 729} 730 731define <2 x i1> @sext_uge_sub_use2(<2 x i1> %b, <2 x i8> %x, <2 x i8> %y) { 732; CHECK-LABEL: @sext_uge_sub_use2( 733; CHECK-NEXT: [[D:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]] 734; CHECK-NEXT: call void @use_vec(<2 x i8> [[D]]) 735; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[X]], [[Y]] 736; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[TMP1]], [[B:%.*]] 737; CHECK-NEXT: ret <2 x i1> [[R]] 738; 739 %s = sext <2 x i1> %b to <2 x i8> 740 %d = sub <2 x i8> %x, %y 741 call void @use_vec(<2 x i8> %d) 742 %r = icmp uge <2 x i8> %s, %d 743 ret <2 x i1> %r 744} 745 746define i1 @sub_ule_sext_use3(i1 %b, i8 %x, i8 %y) { 747; CHECK-LABEL: @sub_ule_sext_use3( 748; CHECK-NEXT: [[S:%.*]] = sext i1 [[B:%.*]] to i8 749; CHECK-NEXT: call void @use(i8 [[S]]) 750; CHECK-NEXT: [[D:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 751; CHECK-NEXT: call void @use(i8 [[D]]) 752; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[D]], [[S]] 753; CHECK-NEXT: ret i1 [[R]] 754; 755 %s = sext i1 %b to i8 756 call void @use(i8 %s) 757 %d = sub i8 %x, %y 758 call void @use(i8 %d) 759 %r = icmp ule i8 %d, %s 760 ret i1 %r 761} 762 763define i1 @sub_ult_sext(i1 %b, i8 %x, i8 %y) { 764; CHECK-LABEL: @sub_ult_sext( 765; CHECK-NEXT: [[S:%.*]] = sext i1 [[B:%.*]] to i8 766; CHECK-NEXT: [[D:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 767; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[D]], [[S]] 768; CHECK-NEXT: ret i1 [[R]] 769; 770 %s = sext i1 %b to i8 771 %d = sub i8 %x, %y 772 %r = icmp ult i8 %d, %s 773 ret i1 %r 774} 775 776define <2 x i1> @sub_ule_ashr(<2 x i8> %b, <2 x i8> %x, <2 x i8> %y) { 777; CHECK-LABEL: @sub_ule_ashr( 778; CHECK-NEXT: [[A:%.*]] = ashr <2 x i8> [[B:%.*]], splat (i8 7) 779; CHECK-NEXT: [[S:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]] 780; CHECK-NEXT: [[R:%.*]] = icmp ule <2 x i8> [[S]], [[A]] 781; CHECK-NEXT: ret <2 x i1> [[R]] 782; 783 %a = ashr <2 x i8> %b, <i8 7, i8 7> 784 %s = sub <2 x i8> %x, %y 785 %r = icmp ule <2 x i8> %s, %a 786 ret <2 x i1> %r 787} 788 789define i1 @ashr_uge_sub(i8 %b, i8 %x, i8 %y) { 790; CHECK-LABEL: @ashr_uge_sub( 791; CHECK-NEXT: [[A:%.*]] = ashr i8 [[B:%.*]], 7 792; CHECK-NEXT: [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 793; CHECK-NEXT: [[R:%.*]] = icmp uge i8 [[A]], [[S]] 794; CHECK-NEXT: ret i1 [[R]] 795; 796 %a = ashr i8 %b, 7 797 %s = sub i8 %x, %y 798 %r = icmp uge i8 %a, %s 799 ret i1 %r 800} 801 802; (zext i1 a) + (sext i1 b)) s< -1 --> false 803 804define i1 @zext_sext_add_icmp_slt_minus1(i1 %a, i1 %b) { 805; CHECK-LABEL: @zext_sext_add_icmp_slt_minus1( 806; CHECK-NEXT: ret i1 false 807; 808 %zext.a = zext i1 %a to i8 809 %sext.b = sext i1 %b to i8 810 %add = add i8 %zext.a, %sext.b 811 %r = icmp slt i8 %add, -1 812 ret i1 %r 813} 814 815; (zext i1 a) + (sext i1 b)) s> 1 --> false 816 817define i1 @zext_sext_add_icmp_sgt_1(i1 %a, i1 %b) { 818; CHECK-LABEL: @zext_sext_add_icmp_sgt_1( 819; CHECK-NEXT: ret i1 false 820; 821 %zext.a = zext i1 %a to i8 822 %sext.b = sext i1 %b to i8 823 %add = add i8 %zext.a, %sext.b 824 %r = icmp sgt i8 %add, 1 825 ret i1 %r 826} 827 828; (zext i1 a) + (sext i1 b)) s> -2 --> true 829 830define i1 @zext_sext_add_icmp_sgt_minus2(i1 %a, i1 %b) { 831; CHECK-LABEL: @zext_sext_add_icmp_sgt_minus2( 832; CHECK-NEXT: ret i1 true 833; 834 %zext.a = zext i1 %a to i8 835 %sext.b = sext i1 %b to i8 836 %add = add i8 %zext.a, %sext.b 837 %r = icmp sgt i8 %add, -2 838 ret i1 %r 839} 840 841; (zext i1 a) + (sext i1 b)) s< 2 --> true 842 843define i1 @zext_sext_add_icmp_slt_2(i1 %a, i1 %b) { 844; CHECK-LABEL: @zext_sext_add_icmp_slt_2( 845; CHECK-NEXT: ret i1 true 846; 847 %zext.a = zext i1 %a to i8 848 %sext.b = sext i1 %b to i8 849 %add = add i8 %zext.a, %sext.b 850 %r = icmp slt i8 %add, 2 851 ret i1 %r 852} 853 854; test case with i128 855 856define i1 @zext_sext_add_icmp_i128(i1 %a, i1 %b) { 857; CHECK-LABEL: @zext_sext_add_icmp_i128( 858; CHECK-NEXT: ret i1 false 859; 860 %zext.a = zext i1 %a to i128 861 %sext.b = sext i1 %b to i128 862 %add = add i128 %zext.a, %sext.b 863 %r = icmp sgt i128 %add, 9223372036854775808 864 ret i1 %r 865} 866 867; (zext i1 a) + (sext i1 b)) == -1 --> ~a & b 868 869define i1 @zext_sext_add_icmp_eq_minus1(i1 %a, i1 %b) { 870; CHECK-LABEL: @zext_sext_add_icmp_eq_minus1( 871; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[A:%.*]], true 872; CHECK-NEXT: [[R:%.*]] = and i1 [[B:%.*]], [[TMP1]] 873; CHECK-NEXT: ret i1 [[R]] 874; 875 %zext.a = zext i1 %a to i8 876 %sext.b = sext i1 %b to i8 877 %add = add i8 %zext.a, %sext.b 878 %r = icmp eq i8 %add, -1 879 ret i1 %r 880} 881 882 883; (zext i1 a) + (sext i1 b)) != -1 --> a | ~b 884 885define i1 @zext_sext_add_icmp_ne_minus1(i1 %a, i1 %b) { 886; CHECK-LABEL: @zext_sext_add_icmp_ne_minus1( 887; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[B:%.*]], true 888; CHECK-NEXT: [[R:%.*]] = or i1 [[A:%.*]], [[TMP1]] 889; CHECK-NEXT: ret i1 [[R]] 890; 891 %zext.a = zext i1 %a to i8 892 %sext.b = sext i1 %b to i8 893 %add = add i8 %zext.a, %sext.b 894 %r = icmp ne i8 %add, -1 895 ret i1 %r 896} 897 898; (zext i1 a) + (sext i1 b)) s> -1 --> a | ~b 899 900define i1 @zext_sext_add_icmp_sgt_minus1(i1 %a, i1 %b) { 901; CHECK-LABEL: @zext_sext_add_icmp_sgt_minus1( 902; CHECK-NEXT: [[B_NOT:%.*]] = xor i1 [[B:%.*]], true 903; CHECK-NEXT: [[R:%.*]] = or i1 [[A:%.*]], [[B_NOT]] 904; CHECK-NEXT: ret i1 [[R]] 905; 906 %zext.a = zext i1 %a to i8 907 %sext.b = sext i1 %b to i8 908 %add = add i8 %zext.a, %sext.b 909 %r = icmp sgt i8 %add, -1 910 ret i1 %r 911} 912 913; (zext i1 a) + (sext i1 b)) u< -1 --> a | ~b 914 915define i1 @zext_sext_add_icmp_ult_minus1(i1 %a, i1 %b) { 916; CHECK-LABEL: @zext_sext_add_icmp_ult_minus1( 917; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[B:%.*]], true 918; CHECK-NEXT: [[R:%.*]] = or i1 [[A:%.*]], [[TMP1]] 919; CHECK-NEXT: ret i1 [[R]] 920; 921 %zext.a = zext i1 %a to i8 922 %sext.b = sext i1 %b to i8 923 %add = add i8 %zext.a, %sext.b 924 %r = icmp ult i8 %add, -1 925 ret i1 %r 926} 927 928; (zext i1 a) + (sext i1 b)) s> 0 --> a & ~b 929 930define i1 @zext_sext_add_icmp_sgt_0(i1 %a, i1 %b) { 931; CHECK-LABEL: @zext_sext_add_icmp_sgt_0( 932; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[B:%.*]], true 933; CHECK-NEXT: [[R:%.*]] = and i1 [[A:%.*]], [[TMP1]] 934; CHECK-NEXT: ret i1 [[R]] 935; 936 %zext.a = zext i1 %a to i8 937 %sext.b = sext i1 %b to i8 938 %add = add i8 %zext.a, %sext.b 939 %r = icmp sgt i8 %add, 0 940 ret i1 %r 941} 942 943; (zext i1 a) + (sext i1 b)) s< 0 --> ~a & b 944 945define i1 @zext_sext_add_icmp_slt_0(i1 %a, i1 %b) { 946; CHECK-LABEL: @zext_sext_add_icmp_slt_0( 947; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[A:%.*]], true 948; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[B:%.*]], [[TMP1]] 949; CHECK-NEXT: ret i1 [[TMP2]] 950; 951 %zext.a = zext i1 %a to i8 952 %sext.b = sext i1 %b to i8 953 %add = add i8 %zext.a, %sext.b 954 %r = icmp slt i8 %add, 0 955 ret i1 %r 956} 957 958; (zext i1 a) + (sext i1 b)) == 1 --> a & ~b 959 960define i1 @zext_sext_add_icmp_eq_1(i1 %a, i1 %b) { 961; CHECK-LABEL: @zext_sext_add_icmp_eq_1( 962; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[B:%.*]], true 963; CHECK-NEXT: [[R:%.*]] = and i1 [[A:%.*]], [[TMP1]] 964; CHECK-NEXT: ret i1 [[R]] 965; 966 %zext.a = zext i1 %a to i8 967 %sext.b = sext i1 %b to i8 968 %add = add i8 %zext.a, %sext.b 969 %r = icmp eq i8 %add, 1 970 ret i1 %r 971} 972 973; (zext i1 a) + (sext i1 b)) != 1 --> ~a | b 974 975define i1 @zext_sext_add_icmp_ne_1(i1 %a, i1 %b) { 976; CHECK-LABEL: @zext_sext_add_icmp_ne_1( 977; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[A:%.*]], true 978; CHECK-NEXT: [[R:%.*]] = or i1 [[B:%.*]], [[TMP1]] 979; CHECK-NEXT: ret i1 [[R]] 980; 981 %zext.a = zext i1 %a to i8 982 %sext.b = sext i1 %b to i8 983 %add = add i8 %zext.a, %sext.b 984 %r = icmp ne i8 %add, 1 985 ret i1 %r 986} 987 988; (zext i1 a) + (sext i1 b)) s< 1 --> ~a | b 989 990define i1 @zext_sext_add_icmp_slt_1(i1 %a, i1 %b) { 991; CHECK-LABEL: @zext_sext_add_icmp_slt_1( 992; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[A:%.*]], true 993; CHECK-NEXT: [[R:%.*]] = or i1 [[B:%.*]], [[TMP1]] 994; CHECK-NEXT: ret i1 [[R]] 995; 996 %zext.a = zext i1 %a to i8 997 %sext.b = sext i1 %b to i8 998 %add = add i8 %zext.a, %sext.b 999 %r = icmp slt i8 %add, 1 1000 ret i1 %r 1001} 1002 1003; (zext i1 a) + (sext i1 b)) u> 1 --> ~a & b 1004 1005define i1 @zext_sext_add_icmp_ugt_1(i1 %a, i1 %b) { 1006; CHECK-LABEL: @zext_sext_add_icmp_ugt_1( 1007; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[A:%.*]], true 1008; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[B:%.*]], [[TMP1]] 1009; CHECK-NEXT: ret i1 [[TMP2]] 1010; 1011 %zext.a = zext i1 %a to i8 1012 %sext.b = sext i1 %b to i8 1013 %add = add i8 %zext.a, %sext.b 1014 %r = icmp ugt i8 %add, 1 1015 ret i1 %r 1016} 1017 1018define <2 x i1> @vector_zext_sext_add_icmp_slt_1(<2 x i1> %a, <2 x i1> %b) { 1019; CHECK-LABEL: @vector_zext_sext_add_icmp_slt_1( 1020; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i1> [[A:%.*]], splat (i1 true) 1021; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[B:%.*]], [[TMP1]] 1022; CHECK-NEXT: ret <2 x i1> [[R]] 1023; 1024 %zext.a = zext <2 x i1> %a to <2 x i8> 1025 %sext.b = sext <2 x i1> %b to <2 x i8> 1026 %add = add <2 x i8> %zext.a, %sext.b 1027 %r = icmp slt <2 x i8> %add, <i8 1, i8 1> 1028 ret <2 x i1> %r 1029} 1030 1031define <2 x i1> @vector_zext_sext_add_icmp_slt_1_poison(<2 x i1> %a, <2 x i1> %b) { 1032; CHECK-LABEL: @vector_zext_sext_add_icmp_slt_1_poison( 1033; CHECK-NEXT: [[ZEXT_A:%.*]] = zext <2 x i1> [[A:%.*]] to <2 x i8> 1034; CHECK-NEXT: [[SEXT_B:%.*]] = sext <2 x i1> [[B:%.*]] to <2 x i8> 1035; CHECK-NEXT: [[ADD:%.*]] = add nsw <2 x i8> [[ZEXT_A]], [[SEXT_B]] 1036; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i8> [[ADD]], <i8 1, i8 poison> 1037; CHECK-NEXT: ret <2 x i1> [[R]] 1038; 1039 %zext.a = zext <2 x i1> %a to <2 x i8> 1040 %sext.b = sext <2 x i1> %b to <2 x i8> 1041 %add = add <2 x i8> %zext.a, %sext.b 1042 %r = icmp slt <2 x i8> %add, <i8 1, i8 poison> 1043 ret <2 x i1> %r 1044} 1045 1046define i1 @zext_sext_add_icmp_slt_minus_1_no_oneuse(i1 %a, i1 %b) { 1047; CHECK-LABEL: @zext_sext_add_icmp_slt_minus_1_no_oneuse( 1048; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8 1049; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8 1050; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]] 1051; CHECK-NEXT: call void @use(i8 [[ADD]]) 1052; CHECK-NEXT: ret i1 false 1053; 1054 %zext.a = zext i1 %a to i8 1055 %sext.b = sext i1 %b to i8 1056 %add = add i8 %zext.a, %sext.b 1057 call void @use(i8 %add) 1058 %r = icmp slt i8 %add, -1 1059 ret i1 %r 1060} 1061 1062define i1 @zext_sext_add_icmp_sgt_1_no_oneuse(i1 %a, i1 %b) { 1063; CHECK-LABEL: @zext_sext_add_icmp_sgt_1_no_oneuse( 1064; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8 1065; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8 1066; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]] 1067; CHECK-NEXT: call void @use(i8 [[ADD]]) 1068; CHECK-NEXT: ret i1 false 1069; 1070 %zext.a = zext i1 %a to i8 1071 %sext.b = sext i1 %b to i8 1072 %add = add i8 %zext.a, %sext.b 1073 call void @use(i8 %add) 1074 %r = icmp sgt i8 %add, 1 1075 ret i1 %r 1076} 1077 1078define i1 @zext_sext_add_icmp_slt_2_no_oneuse(i1 %a, i1 %b) { 1079; CHECK-LABEL: @zext_sext_add_icmp_slt_2_no_oneuse( 1080; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8 1081; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8 1082; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]] 1083; CHECK-NEXT: call void @use(i8 [[ADD]]) 1084; CHECK-NEXT: ret i1 true 1085; 1086 %zext.a = zext i1 %a to i8 1087 %sext.b = sext i1 %b to i8 1088 %add = add i8 %zext.a, %sext.b 1089 call void @use(i8 %add) 1090 %r = icmp slt i8 %add, 2 1091 ret i1 %r 1092} 1093 1094define i1 @zext_sext_add_icmp_sgt_mins_2_no_oneuse(i1 %a, i1 %b) { 1095; CHECK-LABEL: @zext_sext_add_icmp_sgt_mins_2_no_oneuse( 1096; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8 1097; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8 1098; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]] 1099; CHECK-NEXT: call void @use(i8 [[ADD]]) 1100; CHECK-NEXT: ret i1 true 1101; 1102 %zext.a = zext i1 %a to i8 1103 %sext.b = sext i1 %b to i8 1104 %add = add i8 %zext.a, %sext.b 1105 call void @use(i8 %add) 1106 %r = icmp sgt i8 %add, -2 1107 ret i1 %r 1108} 1109 1110; Negative test, more than one use for icmp LHS 1111 1112define i1 @zext_sext_add_icmp_slt_1_no_oneuse(i1 %a, i1 %b) { 1113; CHECK-LABEL: @zext_sext_add_icmp_slt_1_no_oneuse( 1114; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8 1115; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8 1116; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]] 1117; CHECK-NEXT: call void @use(i8 [[ADD]]) 1118; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[ADD]], 1 1119; CHECK-NEXT: ret i1 [[R]] 1120; 1121 %zext.a = zext i1 %a to i8 1122 %sext.b = sext i1 %b to i8 1123 %add = add i8 %zext.a, %sext.b 1124 call void @use(i8 %add) 1125 %r = icmp slt i8 %add, 1 1126 ret i1 %r 1127} 1128 1129; Negative test, icmp RHS is not a constant 1130 1131define i1 @zext_sext_add_icmp_slt_1_rhs_not_const(i1 %a, i1 %b, i8 %c) { 1132; CHECK-LABEL: @zext_sext_add_icmp_slt_1_rhs_not_const( 1133; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8 1134; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8 1135; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]] 1136; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[ADD]], [[C:%.*]] 1137; CHECK-NEXT: ret i1 [[R]] 1138; 1139 %zext.a = zext i1 %a to i8 1140 %sext.b = sext i1 %b to i8 1141 %add = add i8 %zext.a, %sext.b 1142 %r = icmp slt i8 %add, %c 1143 ret i1 %r 1144} 1145 1146; Negative test, ext source is not i1 1147 1148define i1 @zext_sext_add_icmp_slt_1_type_not_i1(i2 %a, i1 %b) { 1149; CHECK-LABEL: @zext_sext_add_icmp_slt_1_type_not_i1( 1150; CHECK-NEXT: [[ZEXT_A:%.*]] = zext i2 [[A:%.*]] to i8 1151; CHECK-NEXT: [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8 1152; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]] 1153; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[ADD]], 1 1154; CHECK-NEXT: ret i1 [[R]] 1155; 1156 %zext.a = zext i2 %a to i8 1157 %sext.b = sext i1 %b to i8 1158 %add = add i8 %zext.a, %sext.b 1159 %r = icmp slt i8 %add, 1 1160 ret i1 %r 1161} 1162 1163define i1 @icmp_eq_bool_0(ptr %ptr) { 1164; CHECK-LABEL: @icmp_eq_bool_0( 1165; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[PTR:%.*]], align 8, !range [[RNG6:![0-9]+]] 1166; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[VAL]], 0 1167; CHECK-NEXT: ret i1 [[CMP]] 1168; 1169 %val = load i64, ptr %ptr, align 8, !range !{i64 0, i64 2} 1170 %cmp = icmp eq i64 %val, 0 1171 ret i1 %cmp 1172} 1173 1174define i1 @icmp_eq_bool_1(ptr %ptr) { 1175; CHECK-LABEL: @icmp_eq_bool_1( 1176; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[PTR:%.*]], align 8, !range [[RNG6]] 1177; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[VAL]], 0 1178; CHECK-NEXT: ret i1 [[CMP]] 1179; 1180 %val = load i64, ptr %ptr, align 8, !range !{i64 0, i64 2} 1181 %cmp = icmp eq i64 %val, 1 1182 ret i1 %cmp 1183} 1184 1185define i1 @icmp_ne_bool_0(ptr %ptr) { 1186; CHECK-LABEL: @icmp_ne_bool_0( 1187; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[PTR:%.*]], align 8, !range [[RNG6]] 1188; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[VAL]], 0 1189; CHECK-NEXT: ret i1 [[CMP]] 1190; 1191 %val = load i64, ptr %ptr, align 8, !range !{i64 0, i64 2} 1192 %cmp = icmp ne i64 %val, 0 1193 ret i1 %cmp 1194} 1195 1196define i1 @icmp_ne_bool_1(ptr %ptr) { 1197; CHECK-LABEL: @icmp_ne_bool_1( 1198; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[PTR:%.*]], align 8, !range [[RNG6]] 1199; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[VAL]], 0 1200; CHECK-NEXT: ret i1 [[CMP]] 1201; 1202 %val = load i64, ptr %ptr, align 8, !range !{i64 0, i64 2} 1203 %cmp = icmp ne i64 %val, 1 1204 ret i1 %cmp 1205} 1206 1207; Tests from PR65073 1208define i1 @icmp_ne_zext_eq_zero(i32 %a) { 1209; CHECK-LABEL: @icmp_ne_zext_eq_zero( 1210; CHECK-NEXT: ret i1 true 1211; 1212 %cmp = icmp eq i32 %a, 0 1213 %conv = zext i1 %cmp to i32 1214 %cmp1 = icmp ne i32 %conv, %a 1215 ret i1 %cmp1 1216} 1217 1218define i1 @icmp_ne_zext_ne_zero(i32 %a) { 1219; CHECK-LABEL: @icmp_ne_zext_ne_zero( 1220; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 1 1221; CHECK-NEXT: ret i1 [[CMP1]] 1222; 1223 %cmp = icmp ne i32 %a, 0 1224 %conv = zext i1 %cmp to i32 1225 %cmp1 = icmp ne i32 %conv, %a 1226 ret i1 %cmp1 1227} 1228 1229define i1 @icmp_eq_zext_eq_zero(i32 %a) { 1230; CHECK-LABEL: @icmp_eq_zext_eq_zero( 1231; CHECK-NEXT: ret i1 false 1232; 1233 %cmp = icmp eq i32 %a, 0 1234 %conv = zext i1 %cmp to i32 1235 %cmp1 = icmp eq i32 %conv, %a 1236 ret i1 %cmp1 1237} 1238 1239define i1 @icmp_eq_zext_ne_zero(i32 %a) { 1240; CHECK-LABEL: @icmp_eq_zext_ne_zero( 1241; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[A:%.*]], 2 1242; CHECK-NEXT: ret i1 [[CMP1]] 1243; 1244 %cmp = icmp ne i32 %a, 0 1245 %conv = zext i1 %cmp to i32 1246 %cmp1 = icmp eq i32 %conv, %a 1247 ret i1 %cmp1 1248} 1249 1250define i1 @icmp_ne_zext_eq_one(i32 %a) { 1251; CHECK-LABEL: @icmp_ne_zext_eq_one( 1252; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 1 1253; CHECK-NEXT: ret i1 [[CMP1]] 1254; 1255 %cmp = icmp eq i32 %a, 1 1256 %conv = zext i1 %cmp to i32 1257 %cmp1 = icmp ne i32 %conv, %a 1258 ret i1 %cmp1 1259} 1260 1261define i1 @icmp_ne_zext_ne_one(i32 %a) { 1262; CHECK-LABEL: @icmp_ne_zext_ne_one( 1263; CHECK-NEXT: ret i1 true 1264; 1265 %cmp = icmp ne i32 %a, 1 1266 %conv = zext i1 %cmp to i32 1267 %cmp1 = icmp ne i32 %conv, %a 1268 ret i1 %cmp1 1269} 1270 1271define i1 @icmp_eq_zext_eq_one(i32 %a) { 1272; CHECK-LABEL: @icmp_eq_zext_eq_one( 1273; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[A:%.*]], 2 1274; CHECK-NEXT: ret i1 [[CMP1]] 1275; 1276 %cmp = icmp eq i32 %a, 1 1277 %conv = zext i1 %cmp to i32 1278 %cmp1 = icmp eq i32 %conv, %a 1279 ret i1 %cmp1 1280} 1281 1282define i1 @icmp_eq_zext_ne_one(i32 %a) { 1283; CHECK-LABEL: @icmp_eq_zext_ne_one( 1284; CHECK-NEXT: ret i1 false 1285; 1286 %cmp = icmp ne i32 %a, 1 1287 %conv = zext i1 %cmp to i32 1288 %cmp1 = icmp eq i32 %conv, %a 1289 ret i1 %cmp1 1290} 1291 1292define i1 @icmp_ne_zext_eq_non_boolean(i32 %a) { 1293; CHECK-LABEL: @icmp_ne_zext_eq_non_boolean( 1294; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 0 1295; CHECK-NEXT: ret i1 [[CMP1]] 1296; 1297 %cmp = icmp eq i32 %a, 2 1298 %conv = zext i1 %cmp to i32 1299 %cmp1 = icmp ne i32 %conv, %a 1300 ret i1 %cmp1 1301} 1302 1303define i1 @icmp_ne_zext_ne_non_boolean(i32 %a) { 1304; CHECK-LABEL: @icmp_ne_zext_ne_non_boolean( 1305; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 1 1306; CHECK-NEXT: ret i1 [[CMP1]] 1307; 1308 %cmp = icmp ne i32 %a, 2 1309 %conv = zext i1 %cmp to i32 1310 %cmp1 = icmp ne i32 %conv, %a 1311 ret i1 %cmp1 1312} 1313 1314define i1 @icmp_eq_zext_eq_non_boolean(i32 %a) { 1315; CHECK-LABEL: @icmp_eq_zext_eq_non_boolean( 1316; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 0 1317; CHECK-NEXT: ret i1 [[CMP1]] 1318; 1319 %cmp = icmp eq i32 %a, 2 1320 %conv = zext i1 %cmp to i32 1321 %cmp1 = icmp eq i32 %conv, %a 1322 ret i1 %cmp1 1323} 1324 1325define i1 @icmp_eq_zext_ne_non_boolean(i32 %a) { 1326; CHECK-LABEL: @icmp_eq_zext_ne_non_boolean( 1327; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 1 1328; CHECK-NEXT: ret i1 [[CMP1]] 1329; 1330 %cmp = icmp ne i32 %a, 2 1331 %conv = zext i1 %cmp to i32 1332 %cmp1 = icmp eq i32 %conv, %a 1333 ret i1 %cmp1 1334} 1335 1336define <2 x i1> @icmp_ne_zext_eq_zero_vec(<2 x i32> %a) { 1337; CHECK-LABEL: @icmp_ne_zext_eq_zero_vec( 1338; CHECK-NEXT: ret <2 x i1> splat (i1 true) 1339; 1340 %cmp = icmp eq <2 x i32> %a, <i32 0, i32 0> 1341 %conv = zext <2 x i1> %cmp to <2 x i32> 1342 %cmp1 = icmp ne <2 x i32> %conv, %a 1343 ret <2 x i1> %cmp1 1344} 1345 1346define <2 x i1> @icmp_ne_zext_ne_zero_vec(<2 x i32> %a) { 1347; CHECK-LABEL: @icmp_ne_zext_ne_zero_vec( 1348; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt <2 x i32> [[A:%.*]], splat (i32 1) 1349; CHECK-NEXT: ret <2 x i1> [[CMP1]] 1350; 1351 %cmp = icmp ne <2 x i32> %a, <i32 0, i32 0> 1352 %conv = zext <2 x i1> %cmp to <2 x i32> 1353 %cmp1 = icmp ne <2 x i32> %conv, %a 1354 ret <2 x i1> %cmp1 1355} 1356 1357define <2 x i1> @icmp_ne_zext_eq_one_vec(<2 x i32> %a) { 1358; CHECK-LABEL: @icmp_ne_zext_eq_one_vec( 1359; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt <2 x i32> [[A:%.*]], splat (i32 1) 1360; CHECK-NEXT: ret <2 x i1> [[CMP1]] 1361; 1362 %cmp = icmp eq <2 x i32> %a, <i32 1, i32 1> 1363 %conv = zext <2 x i1> %cmp to <2 x i32> 1364 %cmp1 = icmp ne <2 x i32> %conv, %a 1365 ret <2 x i1> %cmp1 1366} 1367 1368define <2 x i1> @icmp_ne_zext_ne_one_vec(<2 x i32> %a) { 1369; CHECK-LABEL: @icmp_ne_zext_ne_one_vec( 1370; CHECK-NEXT: ret <2 x i1> splat (i1 true) 1371; 1372 %cmp = icmp ne <2 x i32> %a, <i32 1, i32 1> 1373 %conv = zext <2 x i1> %cmp to <2 x i32> 1374 %cmp1 = icmp ne <2 x i32> %conv, %a 1375 ret <2 x i1> %cmp1 1376} 1377 1378define <2 x i1> @icmp_ne_zext_eq_non_boolean_vec(<2 x i32> %a) { 1379; CHECK-LABEL: @icmp_ne_zext_eq_non_boolean_vec( 1380; CHECK-NEXT: [[CMP1:%.*]] = icmp ne <2 x i32> [[A:%.*]], zeroinitializer 1381; CHECK-NEXT: ret <2 x i1> [[CMP1]] 1382; 1383 %cmp = icmp eq <2 x i32> %a, <i32 2, i32 2> 1384 %conv = zext <2 x i1> %cmp to <2 x i32> 1385 %cmp1 = icmp ne <2 x i32> %conv, %a 1386 ret <2 x i1> %cmp1 1387} 1388 1389define i1 @icmp_ne_sext_eq_zero(i32 %a) { 1390; CHECK-LABEL: @icmp_ne_sext_eq_zero( 1391; CHECK-NEXT: ret i1 true 1392; 1393 %cmp = icmp eq i32 %a, 0 1394 %conv = sext i1 %cmp to i32 1395 %cmp1 = icmp ne i32 %conv, %a 1396 ret i1 %cmp1 1397} 1398 1399define i1 @icmp_ne_sext_ne_zero(i32 %a) { 1400; CHECK-LABEL: @icmp_ne_sext_ne_zero( 1401; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], -1 1402; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[TMP1]], -2 1403; CHECK-NEXT: ret i1 [[CMP1]] 1404; 1405 %cmp = icmp ne i32 %a, 0 1406 %conv = sext i1 %cmp to i32 1407 %cmp1 = icmp ne i32 %conv, %a 1408 ret i1 %cmp1 1409} 1410 1411define i1 @icmp_eq_sext_eq_zero(i32 %a) { 1412; CHECK-LABEL: @icmp_eq_sext_eq_zero( 1413; CHECK-NEXT: ret i1 false 1414; 1415 %cmp = icmp eq i32 %a, 0 1416 %conv = sext i1 %cmp to i32 1417 %cmp1 = icmp eq i32 %conv, %a 1418 ret i1 %cmp1 1419} 1420 1421define i1 @icmp_eq_sext_ne_zero(i32 %a) { 1422; CHECK-LABEL: @icmp_eq_sext_ne_zero( 1423; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], 1 1424; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[TMP1]], 2 1425; CHECK-NEXT: ret i1 [[CMP1]] 1426; 1427 %cmp = icmp ne i32 %a, 0 1428 %conv = sext i1 %cmp to i32 1429 %cmp1 = icmp eq i32 %conv, %a 1430 ret i1 %cmp1 1431} 1432 1433define i1 @icmp_ne_sext_eq_allones(i32 %a) { 1434; CHECK-LABEL: @icmp_ne_sext_eq_allones( 1435; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], -1 1436; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[TMP1]], -2 1437; CHECK-NEXT: ret i1 [[CMP1]] 1438; 1439 %cmp = icmp eq i32 %a, -1 1440 %conv = sext i1 %cmp to i32 1441 %cmp1 = icmp ne i32 %conv, %a 1442 ret i1 %cmp1 1443} 1444 1445define i1 @icmp_ne_sext_ne_allones(i32 %a) { 1446; CHECK-LABEL: @icmp_ne_sext_ne_allones( 1447; CHECK-NEXT: ret i1 true 1448; 1449 %cmp = icmp ne i32 %a, -1 1450 %conv = sext i1 %cmp to i32 1451 %cmp1 = icmp ne i32 %conv, %a 1452 ret i1 %cmp1 1453} 1454 1455define i1 @icmp_eq_sext_eq_allones(i32 %a) { 1456; CHECK-LABEL: @icmp_eq_sext_eq_allones( 1457; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], 1 1458; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[TMP1]], 2 1459; CHECK-NEXT: ret i1 [[CMP1]] 1460; 1461 %cmp = icmp eq i32 %a, -1 1462 %conv = sext i1 %cmp to i32 1463 %cmp1 = icmp eq i32 %conv, %a 1464 ret i1 %cmp1 1465} 1466 1467define i1 @icmp_eq_sext_ne_allones(i32 %a) { 1468; CHECK-LABEL: @icmp_eq_sext_ne_allones( 1469; CHECK-NEXT: ret i1 false 1470; 1471 %cmp = icmp ne i32 %a, -1 1472 %conv = sext i1 %cmp to i32 1473 %cmp1 = icmp eq i32 %conv, %a 1474 ret i1 %cmp1 1475} 1476 1477define i1 @icmp_ne_sext_eq_otherwise(i32 %a) { 1478; CHECK-LABEL: @icmp_ne_sext_eq_otherwise( 1479; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 0 1480; CHECK-NEXT: ret i1 [[CMP1]] 1481; 1482 %cmp = icmp eq i32 %a, 2 1483 %conv = sext i1 %cmp to i32 1484 %cmp1 = icmp ne i32 %conv, %a 1485 ret i1 %cmp1 1486} 1487 1488define i1 @icmp_ne_sext_ne_otherwise(i32 %a) { 1489; CHECK-LABEL: @icmp_ne_sext_ne_otherwise( 1490; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], -1 1491; CHECK-NEXT: ret i1 [[CMP1]] 1492; 1493 %cmp = icmp ne i32 %a, 2 1494 %conv = sext i1 %cmp to i32 1495 %cmp1 = icmp ne i32 %conv, %a 1496 ret i1 %cmp1 1497} 1498 1499define i1 @icmp_eq_sext_eq_otherwise(i32 %a) { 1500; CHECK-LABEL: @icmp_eq_sext_eq_otherwise( 1501; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 0 1502; CHECK-NEXT: ret i1 [[CMP1]] 1503; 1504 %cmp = icmp eq i32 %a, 2 1505 %conv = sext i1 %cmp to i32 1506 %cmp1 = icmp eq i32 %conv, %a 1507 ret i1 %cmp1 1508} 1509 1510define i1 @icmp_eq_sext_ne_otherwise(i32 %a) { 1511; CHECK-LABEL: @icmp_eq_sext_ne_otherwise( 1512; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], -1 1513; CHECK-NEXT: ret i1 [[CMP1]] 1514; 1515 %cmp = icmp ne i32 %a, 2 1516 %conv = sext i1 %cmp to i32 1517 %cmp1 = icmp eq i32 %conv, %a 1518 ret i1 %cmp1 1519} 1520 1521define <2 x i1> @icmp_ne_sext_eq_zero_vec(<2 x i32> %a) { 1522; CHECK-LABEL: @icmp_ne_sext_eq_zero_vec( 1523; CHECK-NEXT: ret <2 x i1> splat (i1 true) 1524; 1525 %cmp = icmp eq <2 x i32> %a, <i32 0, i32 0> 1526 %conv = sext <2 x i1> %cmp to <2 x i32> 1527 %cmp1 = icmp ne <2 x i32> %conv, %a 1528 ret <2 x i1> %cmp1 1529} 1530 1531define <2 x i1> @icmp_ne_sext_ne_zero_vec(<2 x i32> %a) { 1532; CHECK-LABEL: @icmp_ne_sext_ne_zero_vec( 1533; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 -1) 1534; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 -2) 1535; CHECK-NEXT: ret <2 x i1> [[CMP1]] 1536; 1537 %cmp = icmp ne <2 x i32> %a, <i32 0, i32 0> 1538 %conv = sext <2 x i1> %cmp to <2 x i32> 1539 %cmp1 = icmp ne <2 x i32> %conv, %a 1540 ret <2 x i1> %cmp1 1541} 1542 1543define <2 x i1> @icmp_ne_sext_eq_allones_vec(<2 x i32> %a) { 1544; CHECK-LABEL: @icmp_ne_sext_eq_allones_vec( 1545; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 -1) 1546; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 -2) 1547; CHECK-NEXT: ret <2 x i1> [[CMP1]] 1548; 1549 %cmp = icmp eq <2 x i32> %a, <i32 -1, i32 -1> 1550 %conv = sext <2 x i1> %cmp to <2 x i32> 1551 %cmp1 = icmp ne <2 x i32> %conv, %a 1552 ret <2 x i1> %cmp1 1553} 1554 1555define <2 x i1> @icmp_ne_sext_ne_allones_vec(<2 x i32> %a) { 1556; CHECK-LABEL: @icmp_ne_sext_ne_allones_vec( 1557; CHECK-NEXT: ret <2 x i1> splat (i1 true) 1558; 1559 %cmp = icmp ne <2 x i32> %a, <i32 -1, i32 -1> 1560 %conv = sext <2 x i1> %cmp to <2 x i32> 1561 %cmp1 = icmp ne <2 x i32> %conv, %a 1562 ret <2 x i1> %cmp1 1563} 1564 1565define <2 x i1> @icmp_ne_sext_eq_otherwise_vec(<2 x i32> %a) { 1566; CHECK-LABEL: @icmp_ne_sext_eq_otherwise_vec( 1567; CHECK-NEXT: [[CMP1:%.*]] = icmp ne <2 x i32> [[A:%.*]], zeroinitializer 1568; CHECK-NEXT: ret <2 x i1> [[CMP1]] 1569; 1570 %cmp = icmp eq <2 x i32> %a, <i32 2, i32 2> 1571 %conv = sext <2 x i1> %cmp to <2 x i32> 1572 %cmp1 = icmp ne <2 x i32> %conv, %a 1573 ret <2 x i1> %cmp1 1574} 1575 1576define i1 @icmp_ne_sext_ne_zero_i128(i128 %a) { 1577; CHECK-LABEL: @icmp_ne_sext_ne_zero_i128( 1578; CHECK-NEXT: [[TMP1:%.*]] = add i128 [[A:%.*]], -1 1579; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i128 [[TMP1]], -2 1580; CHECK-NEXT: ret i1 [[CMP1]] 1581; 1582 %cmp = icmp ne i128 %a, 0 1583 %conv = sext i1 %cmp to i128 1584 %cmp1 = icmp ne i128 %conv, %a 1585 ret i1 %cmp1 1586} 1587 1588define i1 @icmp_ne_sext_ne_otherwise_i128(i128 %a) { 1589; CHECK-LABEL: @icmp_ne_sext_ne_otherwise_i128( 1590; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i128 [[A:%.*]], -1 1591; CHECK-NEXT: ret i1 [[CMP1]] 1592; 1593 %cmp = icmp ne i128 %a, 2 1594 %conv = sext i1 %cmp to i128 1595 %cmp1 = icmp ne i128 %conv, %a 1596 ret i1 %cmp1 1597} 1598 1599; Negative tests with non-equality predicates 1600define i1 @icmp_ne_sext_sgt_zero_nofold(i32 %a) { 1601; CHECK-LABEL: @icmp_ne_sext_sgt_zero_nofold( 1602; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0 1603; CHECK-NEXT: [[CONV:%.*]] = sext i1 [[CMP]] to i32 1604; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A]], [[CONV]] 1605; CHECK-NEXT: ret i1 [[CMP1]] 1606; 1607 %cmp = icmp sgt i32 %a, 0 1608 %conv = sext i1 %cmp to i32 1609 %cmp1 = icmp ne i32 %conv, %a 1610 ret i1 %cmp1 1611} 1612 1613define i1 @icmp_slt_sext_ne_zero_nofold(i32 %a) { 1614; CHECK-LABEL: @icmp_slt_sext_ne_zero_nofold( 1615; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[A:%.*]], 0 1616; CHECK-NEXT: [[CONV:%.*]] = sext i1 [[CMP]] to i32 1617; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A]], [[CONV]] 1618; CHECK-NEXT: ret i1 [[CMP1]] 1619; 1620 %cmp = icmp ne i32 %a, 0 1621 %conv = sext i1 %cmp to i32 1622 %cmp1 = icmp slt i32 %conv, %a 1623 ret i1 %cmp1 1624} 1625 1626define i1 @icmp_ne_sext_slt_allones_nofold(i32 %a) { 1627; CHECK-LABEL: @icmp_ne_sext_slt_allones_nofold( 1628; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], -1 1629; CHECK-NEXT: [[CONV:%.*]] = sext i1 [[CMP]] to i32 1630; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A]], [[CONV]] 1631; CHECK-NEXT: ret i1 [[CMP1]] 1632; 1633 %cmp = icmp slt i32 %a, -1 1634 %conv = sext i1 %cmp to i32 1635 %cmp1 = icmp ne i32 %conv, %a 1636 ret i1 %cmp1 1637} 1638 1639define i1 @icmp_slt_sext_ne_allones_nofold(i32 %a) { 1640; CHECK-LABEL: @icmp_slt_sext_ne_allones_nofold( 1641; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[A:%.*]], -1 1642; CHECK-NEXT: [[CONV:%.*]] = sext i1 [[CMP]] to i32 1643; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A]], [[CONV]] 1644; CHECK-NEXT: ret i1 [[CMP1]] 1645; 1646 %cmp = icmp ne i32 %a, -1 1647 %conv = sext i1 %cmp to i32 1648 %cmp1 = icmp slt i32 %conv, %a 1649 ret i1 %cmp1 1650} 1651 1652define i1 @icmp_ne_sext_slt_otherwise_nofold(i32 %a) { 1653; CHECK-LABEL: @icmp_ne_sext_slt_otherwise_nofold( 1654; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 2 1655; CHECK-NEXT: [[CONV:%.*]] = sext i1 [[CMP]] to i32 1656; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A]], [[CONV]] 1657; CHECK-NEXT: ret i1 [[CMP1]] 1658; 1659 %cmp = icmp slt i32 %a, 2 1660 %conv = sext i1 %cmp to i32 1661 %cmp1 = icmp ne i32 %conv, %a 1662 ret i1 %cmp1 1663} 1664 1665define i1 @icmp_slt_sext_ne_otherwise_nofold(i32 %a) { 1666; CHECK-LABEL: @icmp_slt_sext_ne_otherwise_nofold( 1667; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[A:%.*]], 2 1668; CHECK-NEXT: [[CONV:%.*]] = sext i1 [[CMP]] to i32 1669; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A]], [[CONV]] 1670; CHECK-NEXT: ret i1 [[CMP1]] 1671; 1672 %cmp = icmp ne i32 %a, 2 1673 %conv = sext i1 %cmp to i32 1674 %cmp1 = icmp slt i32 %conv, %a 1675 ret i1 %cmp1 1676} 1677 1678; tests from PR59555 1679define i1 @isFloat(i64 %0) { 1680; CHECK-LABEL: @isFloat( 1681; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i64 [[TMP0:%.*]], 281474976710655 1682; CHECK-NEXT: [[TMP3:%.*]] = and i64 [[TMP0]], -281474976710656 1683; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i64 [[TMP3]], 281474976710656 1684; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP2]], [[TMP4]] 1685; CHECK-NEXT: ret i1 [[TMP5]] 1686; 1687 %2 = icmp ugt i64 %0, 281474976710655 1688 %3 = and i64 %0, -281474976710656 1689 %4 = icmp ne i64 %3, 281474976710656 1690 %5 = and i1 %2, %4 1691 ret i1 %5 1692} 1693 1694!0 = !{i32 1, i32 6} 1695!1 = !{i32 0, i32 6} 1696!2 = !{i8 0, i8 1} 1697!3 = !{i8 0, i8 6} 1698!4 = !{i32 1, i32 6, i32 8, i32 10} 1699!5 = !{i32 5, i32 10} 1700!6 = !{i32 8, i32 16} 1701