1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s --check-prefixes=CHECK,CONSTVEC 3; RUN: opt < %s -passes=instcombine -S -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=CHECK,CONSTSPLAT 4 5target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n32:64" 6declare void @use(i32) 7 8; Should be eliminated 9define i32 @test12(i32 %A) { 10; CHECK-LABEL: @test12( 11; CHECK-NEXT: [[C:%.*]] = and i32 [[A:%.*]], 8 12; CHECK-NEXT: ret i32 [[C]] 13; 14 %B = or i32 %A, 4 15 %C = and i32 %B, 8 16 ret i32 %C 17} 18 19define i32 @test13(i32 %A) { 20; CHECK-LABEL: @test13( 21; CHECK-NEXT: ret i32 8 22; 23 %B = or i32 %A, 12 24 ; Always equal to 8 25 %C = and i32 %B, 8 26 ret i32 %C 27} 28 29define i1 @test14(i32 %A, i32 %B) { 30; CHECK-LABEL: @test14( 31; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]] 32; CHECK-NEXT: ret i1 [[D]] 33; 34 %C1 = icmp ult i32 %A, %B 35 %C2 = icmp ugt i32 %A, %B 36 ; (A < B) | (A > B) === A != B 37 %D = or i1 %C1, %C2 38 ret i1 %D 39} 40 41define i1 @test14_commuted(i32 %A, i32 %B) { 42; CHECK-LABEL: @test14_commuted( 43; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[B:%.*]], [[A:%.*]] 44; CHECK-NEXT: ret i1 [[D]] 45; 46 %C1 = icmp ult i32 %A, %B 47 %C2 = icmp ult i32 %B, %A 48 ; (A < B) | (A > B) === A != B 49 %D = or i1 %C1, %C2 50 ret i1 %D 51} 52 53define i1 @test14_logical(i32 %A, i32 %B) { 54; CHECK-LABEL: @test14_logical( 55; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]] 56; CHECK-NEXT: ret i1 [[D]] 57; 58 %C1 = icmp ult i32 %A, %B 59 %C2 = icmp ugt i32 %A, %B 60 ; (A < B) | (A > B) === A != B 61 %D = select i1 %C1, i1 true, i1 %C2 62 ret i1 %D 63} 64 65define i1 @test15(i32 %A, i32 %B) { 66; CHECK-LABEL: @test15( 67; CHECK-NEXT: [[D:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]] 68; CHECK-NEXT: ret i1 [[D]] 69; 70 %C1 = icmp ult i32 %A, %B 71 %C2 = icmp eq i32 %A, %B 72 ; (A < B) | (A == B) === A <= B 73 %D = or i1 %C1, %C2 74 ret i1 %D 75} 76 77define i1 @test15_logical(i32 %A, i32 %B) { 78; CHECK-LABEL: @test15_logical( 79; CHECK-NEXT: [[D:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]] 80; CHECK-NEXT: ret i1 [[D]] 81; 82 %C1 = icmp ult i32 %A, %B 83 %C2 = icmp eq i32 %A, %B 84 ; (A < B) | (A == B) === A <= B 85 %D = select i1 %C1, i1 true, i1 %C2 86 ret i1 %D 87} 88 89define i32 @test16(i32 %A) { 90; CHECK-LABEL: @test16( 91; CHECK-NEXT: ret i32 [[A:%.*]] 92; 93 %B = and i32 %A, 1 94 ; -2 = ~1 95 %C = and i32 %A, -2 96 ; %D = and int %B, -1 == %B 97 %D = or i32 %B, %C 98 ret i32 %D 99} 100 101define i32 @test17(i32 %A) { 102; CHECK-LABEL: @test17( 103; CHECK-NEXT: [[D:%.*]] = and i32 [[A:%.*]], 5 104; CHECK-NEXT: ret i32 [[D]] 105; 106 %B = and i32 %A, 1 107 %C = and i32 %A, 4 108 ; %D = and int %B, 5 109 %D = or i32 %B, %C 110 ret i32 %D 111} 112 113define i1 @test18(i32 %A) { 114; CHECK-LABEL: @test18( 115; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], -100 116; CHECK-NEXT: [[D:%.*]] = icmp ult i32 [[TMP1]], -50 117; CHECK-NEXT: ret i1 [[D]] 118; 119 %B = icmp sge i32 %A, 100 120 %C = icmp slt i32 %A, 50 121 %D = or i1 %B, %C 122 ret i1 %D 123} 124 125define i1 @test18_logical(i32 %A) { 126; CHECK-LABEL: @test18_logical( 127; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], -100 128; CHECK-NEXT: [[D:%.*]] = icmp ult i32 [[TMP1]], -50 129; CHECK-NEXT: ret i1 [[D]] 130; 131 %B = icmp sge i32 %A, 100 132 %C = icmp slt i32 %A, 50 133 %D = select i1 %B, i1 true, i1 %C 134 ret i1 %D 135} 136 137define <2 x i1> @test18vec(<2 x i32> %A) { 138; CHECK-LABEL: @test18vec( 139; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 -100) 140; CHECK-NEXT: [[D:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 -50) 141; CHECK-NEXT: ret <2 x i1> [[D]] 142; 143 %B = icmp sge <2 x i32> %A, <i32 100, i32 100> 144 %C = icmp slt <2 x i32> %A, <i32 50, i32 50> 145 %D = or <2 x i1> %B, %C 146 ret <2 x i1> %D 147} 148 149define i32 @test20(i32 %x) { 150; CHECK-LABEL: @test20( 151; CHECK-NEXT: ret i32 [[X:%.*]] 152; 153 %y = and i32 %x, 123 154 %z = or i32 %y, %x 155 ret i32 %z 156} 157 158; TODO: This should combine to t1 + 2. 159define i32 @test21(i32 %t1) { 160; CHECK-LABEL: @test21( 161; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[T1:%.*]], -2 162; CHECK-NEXT: [[T3:%.*]] = add i32 [[TMP1]], 2 163; CHECK-NEXT: [[T5:%.*]] = and i32 [[T1]], 1 164; CHECK-NEXT: [[T6:%.*]] = or disjoint i32 [[T5]], [[T3]] 165; CHECK-NEXT: ret i32 [[T6]] 166; 167 %t1.mask1 = add i32 %t1, 2 168 %t3 = and i32 %t1.mask1, -2 169 %t5 = and i32 %t1, 1 170 ;; add tmp.1, 2 171 %t6 = or i32 %t5, %t3 172 ret i32 %t6 173} 174 175define i32 @test22(i32 %B) { 176; CHECK-LABEL: @test22( 177; CHECK-NEXT: ret i32 [[B:%.*]] 178; 179 %ELIM41 = and i32 %B, 1 180 %ELIM7 = and i32 %B, -2 181 %ELIM5 = or i32 %ELIM41, %ELIM7 182 ret i32 %ELIM5 183} 184 185define i16 @test23(i16 %A) { 186; CHECK-LABEL: @test23( 187; CHECK-NEXT: [[B:%.*]] = lshr i16 [[A:%.*]], 1 188; CHECK-NEXT: [[D:%.*]] = xor i16 [[B]], -24575 189; CHECK-NEXT: ret i16 [[D]] 190; 191 %B = lshr i16 %A, 1 192 ;; fold or into xor 193 %C = or i16 %B, -32768 194 %D = xor i16 %C, 8193 195 ret i16 %D 196} 197 198define <2 x i16> @test23vec(<2 x i16> %A) { 199; CHECK-LABEL: @test23vec( 200; CHECK-NEXT: [[B:%.*]] = lshr <2 x i16> [[A:%.*]], splat (i16 1) 201; CHECK-NEXT: [[D:%.*]] = xor <2 x i16> [[B]], splat (i16 -24575) 202; CHECK-NEXT: ret <2 x i16> [[D]] 203; 204 %B = lshr <2 x i16> %A, <i16 1, i16 1> 205 ;; fold or into xor 206 %C = or <2 x i16> %B, <i16 -32768, i16 -32768> 207 %D = xor <2 x i16> %C, <i16 8193, i16 8193> 208 ret <2 x i16> %D 209} 210 211; PR3266 & PR5276 212define i1 @test25(i32 %A, i32 %B) { 213; CHECK-LABEL: @test25( 214; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A:%.*]], 0 215; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[B:%.*]], 57 216; CHECK-NEXT: [[E_NOT:%.*]] = and i1 [[C]], [[D]] 217; CHECK-NEXT: ret i1 [[E_NOT]] 218; 219 %C = icmp eq i32 %A, 0 220 %D = icmp eq i32 %B, 57 221 %E = or i1 %C, %D 222 %F = xor i1 %E, -1 223 ret i1 %F 224} 225 226define i1 @test25_logical(i32 %A, i32 %B) { 227; CHECK-LABEL: @test25_logical( 228; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A:%.*]], 0 229; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[B:%.*]], 57 230; CHECK-NEXT: [[E_NOT:%.*]] = select i1 [[C]], i1 [[D]], i1 false 231; CHECK-NEXT: ret i1 [[E_NOT]] 232; 233 %C = icmp eq i32 %A, 0 234 %D = icmp eq i32 %B, 57 235 %E = select i1 %C, i1 true, i1 %D 236 %F = xor i1 %E, -1 237 ret i1 %F 238} 239 240; PR5634 241define i1 @and_icmp_eq_0(i32 %A, i32 %B) { 242; CHECK-LABEL: @and_icmp_eq_0( 243; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 244; CHECK-NEXT: [[D:%.*]] = icmp eq i32 [[TMP1]], 0 245; CHECK-NEXT: ret i1 [[D]] 246; 247 %C1 = icmp eq i32 %A, 0 248 %C2 = icmp eq i32 %B, 0 249 ; (A == 0) & (A == 0) --> (A|B) == 0 250 %D = and i1 %C1, %C2 251 ret i1 %D 252} 253 254define <2 x i1> @and_icmp_eq_0_vector(<2 x i32> %A, <2 x i32> %B) { 255; CHECK-LABEL: @and_icmp_eq_0_vector( 256; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]] 257; CHECK-NEXT: [[D:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer 258; CHECK-NEXT: ret <2 x i1> [[D]] 259; 260 %C1 = icmp eq <2 x i32> %A, zeroinitializer 261 %C2 = icmp eq <2 x i32> %B, zeroinitializer 262 %D = and <2 x i1> %C1, %C2 263 ret <2 x i1> %D 264} 265 266define <2 x i1> @and_icmp_eq_0_vector_poison1(<2 x i32> %A, <2 x i32> %B) { 267; CHECK-LABEL: @and_icmp_eq_0_vector_poison1( 268; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]] 269; CHECK-NEXT: [[D:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer 270; CHECK-NEXT: ret <2 x i1> [[D]] 271; 272 %C1 = icmp eq <2 x i32> %A, <i32 0, i32 poison> 273 %C2 = icmp eq <2 x i32> %B, <i32 0, i32 poison> 274 %D = and <2 x i1> %C1, %C2 275 ret <2 x i1> %D 276} 277 278define <2 x i1> @and_icmp_eq_0_vector_poison2(<2 x i32> %A, <2 x i32> %B) { 279; CHECK-LABEL: @and_icmp_eq_0_vector_poison2( 280; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]] 281; CHECK-NEXT: [[D:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer 282; CHECK-NEXT: ret <2 x i1> [[D]] 283; 284 %C1 = icmp eq <2 x i32> %A, <i32 0, i32 poison> 285 %C2 = icmp eq <2 x i32> %B, <i32 poison, i32 0> 286 %D = and <2 x i1> %C1, %C2 287 ret <2 x i1> %D 288} 289 290define i1 @and_icmp_eq_0_logical(i32 %A, i32 %B) { 291; CHECK-LABEL: @and_icmp_eq_0_logical( 292; CHECK-NEXT: [[C1:%.*]] = icmp eq i32 [[A:%.*]], 0 293; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[B:%.*]], 0 294; CHECK-NEXT: [[D:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false 295; CHECK-NEXT: ret i1 [[D]] 296; 297 %C1 = icmp eq i32 %A, 0 298 %C2 = icmp eq i32 %B, 0 299 ; (A == 0) & (A == 0) --> (A|B) == 0 300 %D = select i1 %C1, i1 %C2, i1 false 301 ret i1 %D 302} 303 304define i1 @test27(ptr %A, ptr %B) { 305; CHECK-LABEL: @test27( 306; CHECK-NEXT: [[TMP1:%.*]] = icmp eq ptr [[A:%.*]], null 307; CHECK-NEXT: [[TMP2:%.*]] = icmp eq ptr [[B:%.*]], null 308; CHECK-NEXT: [[E:%.*]] = and i1 [[TMP1]], [[TMP2]] 309; CHECK-NEXT: ret i1 [[E]] 310; 311 %C1 = ptrtoint ptr %A to i32 312 %C2 = ptrtoint ptr %B to i32 313 %D = or i32 %C1, %C2 314 %E = icmp eq i32 %D, 0 315 ret i1 %E 316} 317 318define <2 x i1> @test27vec(<2 x ptr> %A, <2 x ptr> %B) { 319; CHECK-LABEL: @test27vec( 320; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x ptr> [[A:%.*]], zeroinitializer 321; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x ptr> [[B:%.*]], zeroinitializer 322; CHECK-NEXT: [[E:%.*]] = and <2 x i1> [[TMP1]], [[TMP2]] 323; CHECK-NEXT: ret <2 x i1> [[E]] 324; 325 %C1 = ptrtoint <2 x ptr> %A to <2 x i32> 326 %C2 = ptrtoint <2 x ptr> %B to <2 x i32> 327 %D = or <2 x i32> %C1, %C2 328 %E = icmp eq <2 x i32> %D, zeroinitializer 329 ret <2 x i1> %E 330} 331 332; PR5634 333define i1 @test28(i32 %A, i32 %B) { 334; CHECK-LABEL: @test28( 335; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 336; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[TMP1]], 0 337; CHECK-NEXT: ret i1 [[D]] 338; 339 %C1 = icmp ne i32 %A, 0 340 %C2 = icmp ne i32 %B, 0 341 ; (A != 0) | (A != 0) --> (A|B) != 0 342 %D = or i1 %C1, %C2 343 ret i1 %D 344} 345 346define i1 @test28_logical(i32 %A, i32 %B) { 347; CHECK-LABEL: @test28_logical( 348; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[A:%.*]], 0 349; CHECK-NEXT: [[C2:%.*]] = icmp ne i32 [[B:%.*]], 0 350; CHECK-NEXT: [[D:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]] 351; CHECK-NEXT: ret i1 [[D]] 352; 353 %C1 = icmp ne i32 %A, 0 354 %C2 = icmp ne i32 %B, 0 355 ; (A != 0) | (A != 0) --> (A|B) != 0 356 %D = select i1 %C1, i1 true, i1 %C2 357 ret i1 %D 358} 359 360define i1 @test29(ptr %A, ptr %B) { 361; CHECK-LABEL: @test29( 362; CHECK-NEXT: [[TMP1:%.*]] = icmp ne ptr [[A:%.*]], null 363; CHECK-NEXT: [[TMP2:%.*]] = icmp ne ptr [[B:%.*]], null 364; CHECK-NEXT: [[E:%.*]] = or i1 [[TMP1]], [[TMP2]] 365; CHECK-NEXT: ret i1 [[E]] 366; 367 %C1 = ptrtoint ptr %A to i32 368 %C2 = ptrtoint ptr %B to i32 369 %D = or i32 %C1, %C2 370 %E = icmp ne i32 %D, 0 371 ret i1 %E 372} 373 374define <2 x i1> @test29vec(<2 x ptr> %A, <2 x ptr> %B) { 375; CHECK-LABEL: @test29vec( 376; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x ptr> [[A:%.*]], zeroinitializer 377; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x ptr> [[B:%.*]], zeroinitializer 378; CHECK-NEXT: [[E:%.*]] = or <2 x i1> [[TMP1]], [[TMP2]] 379; CHECK-NEXT: ret <2 x i1> [[E]] 380; 381 %C1 = ptrtoint <2 x ptr> %A to <2 x i32> 382 %C2 = ptrtoint <2 x ptr> %B to <2 x i32> 383 %D = or <2 x i32> %C1, %C2 384 %E = icmp ne <2 x i32> %D, zeroinitializer 385 ret <2 x i1> %E 386} 387 388; PR4216 389define i32 @test30(i32 %A) { 390; CHECK-LABEL: @test30( 391; CHECK-NEXT: [[D:%.*]] = and i32 [[A:%.*]], -58312 392; CHECK-NEXT: [[E:%.*]] = or disjoint i32 [[D]], 32962 393; CHECK-NEXT: ret i32 [[E]] 394; 395 %B = or i32 %A, 32962 ; 0b1000_0000_1100_0010 396 %C = and i32 %A, -65536 ; 0xffff0000 397 %D = and i32 %B, 40186 ; 0b1001_1100_1111_1010 398 %E = or i32 %D, %C 399 ret i32 %E 400} 401 402define <2 x i32> @test30vec(<2 x i32> %A) { 403; CONSTVEC-LABEL: @test30vec( 404; CONSTVEC-NEXT: [[TMP1:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 -58312) 405; CONSTVEC-NEXT: [[E:%.*]] = or disjoint <2 x i32> [[TMP1]], splat (i32 32962) 406; CONSTVEC-NEXT: ret <2 x i32> [[E]] 407; 408; CONSTSPLAT-LABEL: @test30vec( 409; CONSTSPLAT-NEXT: [[D:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 -58312) 410; CONSTSPLAT-NEXT: [[E:%.*]] = or disjoint <2 x i32> [[D]], splat (i32 32962) 411; CONSTSPLAT-NEXT: ret <2 x i32> [[E]] 412; 413 %B = or <2 x i32> %A, <i32 32962, i32 32962> 414 %C = and <2 x i32> %A, <i32 -65536, i32 -65536> 415 %D = and <2 x i32> %B, <i32 40186, i32 40186> 416 %E = or <2 x i32> %D, %C 417 ret <2 x i32> %E 418} 419 420; PR4216 421define i64 @test31(i64 %A) { 422; CHECK-LABEL: @test31( 423; CHECK-NEXT: [[E:%.*]] = and i64 [[A:%.*]], 4294908984 424; CHECK-NEXT: [[F:%.*]] = or disjoint i64 [[E]], 32962 425; CHECK-NEXT: ret i64 [[F]] 426; 427 %B = or i64 %A, 194 428 %D = and i64 %B, 250 429 430 %C = or i64 %A, 32768 431 %E = and i64 %C, 4294941696 432 433 %F = or i64 %D, %E 434 ret i64 %F 435} 436 437define <2 x i64> @test31vec(<2 x i64> %A) { 438; CHECK-LABEL: @test31vec( 439; CHECK-NEXT: [[E:%.*]] = and <2 x i64> [[A:%.*]], splat (i64 4294908984) 440; CHECK-NEXT: [[F:%.*]] = or disjoint <2 x i64> [[E]], splat (i64 32962) 441; CHECK-NEXT: ret <2 x i64> [[F]] 442; 443 %B = or <2 x i64> %A, <i64 194, i64 194> 444 %D = and <2 x i64> %B, <i64 250, i64 250> 445 446 %C = or <2 x i64> %A, <i64 32768, i64 32768> 447 %E = and <2 x i64> %C, <i64 4294941696, i64 4294941696> 448 449 %F = or <2 x i64> %D, %E 450 ret <2 x i64> %F 451} 452 453; codegen is mature enough to handle vector selects. 454define <4 x i32> @test32(<4 x i1> %and.i1352, <4 x i32> %vecinit6.i176, <4 x i32> %vecinit6.i191) { 455; CHECK-LABEL: @test32( 456; CHECK-NEXT: [[OR_I:%.*]] = select <4 x i1> [[AND_I1352:%.*]], <4 x i32> [[VECINIT6_I176:%.*]], <4 x i32> [[VECINIT6_I191:%.*]] 457; CHECK-NEXT: ret <4 x i32> [[OR_I]] 458; 459 %and.i135 = sext <4 x i1> %and.i1352 to <4 x i32> 460 %and.i129 = and <4 x i32> %vecinit6.i176, %and.i135 461 %neg.i = xor <4 x i32> %and.i135, <i32 -1, i32 -1, i32 -1, i32 -1> 462 %and.i = and <4 x i32> %vecinit6.i191, %neg.i 463 %or.i = or <4 x i32> %and.i, %and.i129 464 ret <4 x i32> %or.i 465} 466 467define i1 @test33(i1 %X, i1 %Y) { 468; CHECK-LABEL: @test33( 469; CHECK-NEXT: [[A:%.*]] = or i1 [[X:%.*]], [[Y:%.*]] 470; CHECK-NEXT: ret i1 [[A]] 471; 472 %a = or i1 %X, %Y 473 %b = or i1 %a, %X 474 ret i1 %b 475} 476 477define i1 @test33_logical(i1 %X, i1 %Y) { 478; CHECK-LABEL: @test33_logical( 479; CHECK-NEXT: [[A:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]] 480; CHECK-NEXT: ret i1 [[A]] 481; 482 %a = select i1 %X, i1 true, i1 %Y 483 %b = select i1 %a, i1 true, i1 %X 484 ret i1 %b 485} 486 487define i32 @test34(i32 %X, i32 %Y) { 488; CHECK-LABEL: @test34( 489; CHECK-NEXT: [[A:%.*]] = or i32 [[X:%.*]], [[Y:%.*]] 490; CHECK-NEXT: ret i32 [[A]] 491; 492 %a = or i32 %X, %Y 493 %b = or i32 %Y, %a 494 ret i32 %b 495} 496 497define i32 @test35(i32 %a, i32 %b) { 498; CHECK-LABEL: @test35( 499; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 500; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 1135 501; CHECK-NEXT: ret i32 [[TMP2]] 502; 503 %1 = or i32 %a, 1135 504 %2 = or i32 %1, %b 505 ret i32 %2 506} 507 508define i1 @test36(i32 %x) { 509; CHECK-LABEL: @test36( 510; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -23 511; CHECK-NEXT: [[RET2:%.*]] = icmp ult i32 [[TMP1]], 3 512; CHECK-NEXT: ret i1 [[RET2]] 513; 514 %cmp1 = icmp eq i32 %x, 23 515 %cmp2 = icmp eq i32 %x, 24 516 %ret1 = or i1 %cmp1, %cmp2 517 %cmp3 = icmp eq i32 %x, 25 518 %ret2 = or i1 %ret1, %cmp3 519 ret i1 %ret2 520} 521 522define i1 @test36_logical(i32 %x) { 523; CHECK-LABEL: @test36_logical( 524; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -23 525; CHECK-NEXT: [[RET2:%.*]] = icmp ult i32 [[TMP1]], 3 526; CHECK-NEXT: ret i1 [[RET2]] 527; 528 %cmp1 = icmp eq i32 %x, 23 529 %cmp2 = icmp eq i32 %x, 24 530 %ret1 = select i1 %cmp1, i1 true, i1 %cmp2 531 %cmp3 = icmp eq i32 %x, 25 532 %ret2 = select i1 %ret1, i1 true, i1 %cmp3 533 ret i1 %ret2 534} 535 536define i1 @test37(i32 %x) { 537; CHECK-LABEL: @test37( 538; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7 539; CHECK-NEXT: [[RET1:%.*]] = icmp ult i32 [[TMP1]], 31 540; CHECK-NEXT: ret i1 [[RET1]] 541; 542 %add1 = add i32 %x, 7 543 %cmp1 = icmp ult i32 %add1, 30 544 %cmp2 = icmp eq i32 %x, 23 545 %ret1 = or i1 %cmp1, %cmp2 546 ret i1 %ret1 547} 548 549define i1 @test37_logical(i32 %x) { 550; CHECK-LABEL: @test37_logical( 551; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7 552; CHECK-NEXT: [[RET1:%.*]] = icmp ult i32 [[TMP1]], 31 553; CHECK-NEXT: ret i1 [[RET1]] 554; 555 %add1 = add i32 %x, 7 556 %cmp1 = icmp ult i32 %add1, 30 557 %cmp2 = icmp eq i32 %x, 23 558 %ret1 = select i1 %cmp1, i1 true, i1 %cmp2 559 ret i1 %ret1 560} 561 562define <2 x i1> @test37_uniform(<2 x i32> %x) { 563; CHECK-LABEL: @test37_uniform( 564; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], splat (i32 7) 565; CHECK-NEXT: [[RET1:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 31) 566; CHECK-NEXT: ret <2 x i1> [[RET1]] 567; 568 %add1 = add <2 x i32> %x, <i32 7, i32 7> 569 %cmp1 = icmp ult <2 x i32> %add1, <i32 30, i32 30> 570 %cmp2 = icmp eq <2 x i32> %x, <i32 23, i32 23> 571 %ret1 = or <2 x i1> %cmp1, %cmp2 572 ret <2 x i1> %ret1 573} 574 575define <2 x i1> @test37_poison(<2 x i32> %x) { 576; CHECK-LABEL: @test37_poison( 577; CHECK-NEXT: [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 poison> 578; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 poison> 579; CHECK-NEXT: [[CMP2:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 poison> 580; CHECK-NEXT: [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]] 581; CHECK-NEXT: ret <2 x i1> [[RET1]] 582; 583 %add1 = add <2 x i32> %x, <i32 7, i32 poison> 584 %cmp1 = icmp ult <2 x i32> %add1, <i32 30, i32 poison> 585 %cmp2 = icmp eq <2 x i32> %x, <i32 23, i32 poison> 586 %ret1 = or <2 x i1> %cmp1, %cmp2 587 ret <2 x i1> %ret1 588} 589 590define i1 @test38(i32 %x) { 591; CHECK-LABEL: @test38( 592; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7 593; CHECK-NEXT: [[RET1:%.*]] = icmp ult i32 [[TMP1]], 31 594; CHECK-NEXT: ret i1 [[RET1]] 595; 596 %add1 = add i32 %x, 7 597 %cmp1 = icmp eq i32 %x, 23 598 %cmp2 = icmp ult i32 %add1, 30 599 %ret1 = or i1 %cmp1, %cmp2 600 ret i1 %ret1 601} 602 603define i1 @test38_logical(i32 %x) { 604; CHECK-LABEL: @test38_logical( 605; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 7 606; CHECK-NEXT: [[RET1:%.*]] = icmp ult i32 [[TMP1]], 31 607; CHECK-NEXT: ret i1 [[RET1]] 608; 609 %add1 = add i32 %x, 7 610 %cmp1 = icmp eq i32 %x, 23 611 %cmp2 = icmp ult i32 %add1, 30 612 %ret1 = select i1 %cmp1, i1 true, i1 %cmp2 613 ret i1 %ret1 614} 615 616define <2 x i1> @test38_nonuniform(<2 x i32> %x) { 617; CHECK-LABEL: @test38_nonuniform( 618; CHECK-NEXT: [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 24> 619; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 8> 620; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 32> 621; CHECK-NEXT: [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]] 622; CHECK-NEXT: ret <2 x i1> [[RET1]] 623; 624 %add1 = add <2 x i32> %x, <i32 7, i32 24> 625 %cmp1 = icmp eq <2 x i32> %x, <i32 23, i32 8> 626 %cmp2 = icmp ult <2 x i32> %add1, <i32 30, i32 32> 627 %ret1 = or <2 x i1> %cmp1, %cmp2 628 ret <2 x i1> %ret1 629} 630 631; (~A & B) | A --> A | B 632 633define i32 @test39a(i32 %a, float %b) { 634; CHECK-LABEL: @test39a( 635; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42 636; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32 637; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]] 638; CHECK-NEXT: ret i32 [[OR]] 639; 640 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering 641 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering 642 %nota = xor i32 %a1, -1 643 %and = and i32 %nota, %b1 644 %or = or i32 %and, %a1 645 ret i32 %or 646} 647 648; Commute 'and' operands: 649; (B & ~A) | A --> A | B 650 651define i32 @test39b(i32 %a, float %b) { 652; CHECK-LABEL: @test39b( 653; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42 654; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32 655; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]] 656; CHECK-NEXT: ret i32 [[OR]] 657; 658 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering 659 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering 660 %nota = xor i32 %a1, -1 661 %and = and i32 %b1, %nota 662 %or = or i32 %and, %a1 663 ret i32 %or 664} 665 666; Commute 'or' operands: 667; A | (~A & B) --> A | B 668 669define i32 @test39c(i32 %a, float %b) { 670; CHECK-LABEL: @test39c( 671; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42 672; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32 673; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]] 674; CHECK-NEXT: ret i32 [[OR]] 675; 676 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering 677 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering 678 %nota = xor i32 %a1, -1 679 %and = and i32 %nota, %b1 680 %or = or i32 %a1, %and 681 ret i32 %or 682} 683 684; Commute 'and' operands: 685; A | (B & ~A) --> A | B 686 687define i32 @test39d(i32 %a, float %b) { 688; CHECK-LABEL: @test39d( 689; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42 690; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32 691; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]] 692; CHECK-NEXT: ret i32 [[OR]] 693; 694 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering 695 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering 696 %nota = xor i32 %a1, -1 697 %and = and i32 %b1, %nota 698 %or = or i32 %a1, %and 699 ret i32 %or 700} 701 702define i32 @test40(i32 %a, i32 %b) { 703; CHECK-LABEL: @test40( 704; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1 705; CHECK-NEXT: [[OR:%.*]] = or i32 [[B:%.*]], [[XOR]] 706; CHECK-NEXT: ret i32 [[OR]] 707; 708 %and = and i32 %a, %b 709 %xor = xor i32 %a, -1 710 %or = or i32 %and, %xor 711 ret i32 %or 712} 713 714define i32 @test40b(i32 %a, i32 %b) { 715; CHECK-LABEL: @test40b( 716; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1 717; CHECK-NEXT: [[OR:%.*]] = or i32 [[B:%.*]], [[XOR]] 718; CHECK-NEXT: ret i32 [[OR]] 719; 720 %and = and i32 %b, %a 721 %xor = xor i32 %a, -1 722 %or = or i32 %and, %xor 723 ret i32 %or 724} 725 726define i32 @test40c(i32 %a, i32 %b) { 727; CHECK-LABEL: @test40c( 728; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1 729; CHECK-NEXT: [[OR:%.*]] = or i32 [[B:%.*]], [[XOR]] 730; CHECK-NEXT: ret i32 [[OR]] 731; 732 %and = and i32 %b, %a 733 %xor = xor i32 %a, -1 734 %or = or i32 %xor, %and 735 ret i32 %or 736} 737 738define i32 @test40d(i32 %a, i32 %b) { 739; CHECK-LABEL: @test40d( 740; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1 741; CHECK-NEXT: [[OR:%.*]] = or i32 [[B:%.*]], [[XOR]] 742; CHECK-NEXT: ret i32 [[OR]] 743; 744 %and = and i32 %a, %b 745 %xor = xor i32 %a, -1 746 %or = or i32 %xor, %and 747 ret i32 %or 748} 749 750define i32 @test45(i32 %x, i32 %y, i32 %z) { 751; CHECK-LABEL: @test45( 752; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z:%.*]] 753; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[Y:%.*]] 754; CHECK-NEXT: ret i32 [[OR1]] 755; 756 %or = or i32 %y, %z 757 %and = and i32 %x, %or 758 %or1 = or i32 %and, %y 759 ret i32 %or1 760} 761 762define i32 @test45_uses1(i32 %x, i32 %y, i32 %z) { 763; CHECK-LABEL: @test45_uses1( 764; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[Z:%.*]] 765; CHECK-NEXT: call void @use(i32 [[OR]]) 766; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z]] 767; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[Y]] 768; CHECK-NEXT: ret i32 [[OR1]] 769; 770 %or = or i32 %y, %z 771 call void @use(i32 %or) 772 %and = and i32 %x, %or 773 %or1 = or i32 %and, %y 774 ret i32 %or1 775} 776 777define i32 @test45_uses2(i32 %x, i32 %y, i32 %z) { 778; CHECK-LABEL: @test45_uses2( 779; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[Z:%.*]] 780; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[OR]] 781; CHECK-NEXT: call void @use(i32 [[AND]]) 782; CHECK-NEXT: [[OR1:%.*]] = or i32 [[AND]], [[Y]] 783; CHECK-NEXT: ret i32 [[OR1]] 784; 785 %or = or i32 %y, %z 786 %and = and i32 %x, %or 787 call void @use(i32 %and) 788 %or1 = or i32 %and, %y 789 ret i32 %or1 790} 791 792define i32 @test45_commuted1(i32 %x, i32 %y, i32 %z) { 793; CHECK-LABEL: @test45_commuted1( 794; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]] 795; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Z:%.*]], [[X:%.*]] 796; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[TMP1]] 797; CHECK-NEXT: ret i32 [[OR1]] 798; 799 %yy = mul i32 %y, %y ; thwart complexity-based ordering 800 %or = or i32 %yy, %z 801 %and = and i32 %or, %x 802 %or1 = or i32 %yy, %and 803 ret i32 %or1 804} 805 806define i32 @test45_commuted2(i32 %x, i32 %y, i32 %z) { 807; CHECK-LABEL: @test45_commuted2( 808; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]] 809; CHECK-NEXT: [[XX:%.*]] = mul i32 [[X:%.*]], [[X]] 810; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[XX]], [[Z:%.*]] 811; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[YY]] 812; CHECK-NEXT: ret i32 [[OR1]] 813; 814 %yy = mul i32 %y, %y ; thwart complexity-based ordering 815 %xx = mul i32 %x, %x ; thwart complexity-based ordering 816 %or = or i32 %yy, %z 817 %and = and i32 %xx, %or 818 %or1 = or i32 %and, %yy 819 ret i32 %or1 820} 821 822define i32 @test45_commuted3(i32 %x, i32 %y, i32 %z) { 823; CHECK-LABEL: @test45_commuted3( 824; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]] 825; CHECK-NEXT: [[ZZ:%.*]] = mul i32 [[Z:%.*]], [[Z]] 826; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ZZ]], [[X:%.*]] 827; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[YY]] 828; CHECK-NEXT: ret i32 [[OR1]] 829; 830 %yy = mul i32 %y, %y ; thwart complexity-based ordering 831 %zz = mul i32 %z, %z ; thwart complexity-based ordering 832 %or = or i32 %zz, %yy 833 %and = and i32 %or, %x 834 %or1 = or i32 %and, %yy 835 ret i32 %or1 836} 837 838define i1 @test46(i8 signext %c) { 839; CHECK-LABEL: @test46( 840; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33 841; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65 842; CHECK-NEXT: [[OR:%.*]] = icmp ult i8 [[TMP2]], 26 843; CHECK-NEXT: ret i1 [[OR]] 844; 845 %c.off = add i8 %c, -97 846 %cmp1 = icmp ult i8 %c.off, 26 847 %c.off17 = add i8 %c, -65 848 %cmp2 = icmp ult i8 %c.off17, 26 849 %or = or i1 %cmp1, %cmp2 850 ret i1 %or 851} 852 853define i1 @test46_logical(i8 signext %c) { 854; CHECK-LABEL: @test46_logical( 855; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33 856; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65 857; CHECK-NEXT: [[OR:%.*]] = icmp ult i8 [[TMP2]], 26 858; CHECK-NEXT: ret i1 [[OR]] 859; 860 %c.off = add i8 %c, -97 861 %cmp1 = icmp ult i8 %c.off, 26 862 %c.off17 = add i8 %c, -65 863 %cmp2 = icmp ult i8 %c.off17, 26 864 %or = select i1 %cmp1, i1 true, i1 %cmp2 865 ret i1 %or 866} 867 868define <2 x i1> @test46_uniform(<2 x i8> %c) { 869; CHECK-LABEL: @test46_uniform( 870; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[C:%.*]], splat (i8 -33) 871; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i8> [[TMP1]], splat (i8 -65) 872; CHECK-NEXT: [[OR:%.*]] = icmp ult <2 x i8> [[TMP2]], splat (i8 26) 873; CHECK-NEXT: ret <2 x i1> [[OR]] 874; 875 %c.off = add <2 x i8> %c, <i8 -97, i8 -97> 876 %cmp1 = icmp ult <2 x i8> %c.off, <i8 26, i8 26> 877 %c.off17 = add <2 x i8> %c, <i8 -65, i8 -65> 878 %cmp2 = icmp ult <2 x i8> %c.off17, <i8 26, i8 26> 879 %or = or <2 x i1> %cmp1, %cmp2 880 ret <2 x i1> %or 881} 882 883define <2 x i1> @test46_poison(<2 x i8> %c) { 884; CHECK-LABEL: @test46_poison( 885; CHECK-NEXT: [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -97, i8 poison> 886; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], <i8 26, i8 poison> 887; CHECK-NEXT: [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -65, i8 poison> 888; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], <i8 26, i8 poison> 889; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]] 890; CHECK-NEXT: ret <2 x i1> [[OR]] 891; 892 %c.off = add <2 x i8> %c, <i8 -97, i8 poison> 893 %cmp1 = icmp ult <2 x i8> %c.off, <i8 26, i8 poison> 894 %c.off17 = add <2 x i8> %c, <i8 -65, i8 poison> 895 %cmp2 = icmp ult <2 x i8> %c.off17, <i8 26, i8 poison> 896 %or = or <2 x i1> %cmp1, %cmp2 897 ret <2 x i1> %or 898} 899 900; This is the variant of the above pattern where one of the ranges is 901; represented with an add. 902define i1 @two_ranges_to_mask_and_range_degenerate(i16 %x) { 903; CHECK-LABEL: @two_ranges_to_mask_and_range_degenerate( 904; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[X:%.*]], -20 905; CHECK-NEXT: [[OR:%.*]] = icmp ult i16 [[TMP1]], 12 906; CHECK-NEXT: ret i1 [[OR]] 907; 908 %cmp1 = icmp ult i16 %x, 12 909 %cmp2 = icmp uge i16 %x, 16 910 %cmp3 = icmp ult i16 %x, 28 911 %and = and i1 %cmp2, %cmp3 912 %or = or i1 %cmp1, %and 913 ret i1 %or 914} 915 916define i1 @test47(i8 signext %c) { 917; CHECK-LABEL: @test47( 918; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33 919; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65 920; CHECK-NEXT: [[OR:%.*]] = icmp ult i8 [[TMP2]], 27 921; CHECK-NEXT: ret i1 [[OR]] 922; 923 %c.off = add i8 %c, -65 924 %cmp1 = icmp ule i8 %c.off, 26 925 %c.off17 = add i8 %c, -97 926 %cmp2 = icmp ule i8 %c.off17, 26 927 %or = or i1 %cmp1, %cmp2 928 ret i1 %or 929} 930 931define i1 @test47_logical(i8 signext %c) { 932; CHECK-LABEL: @test47_logical( 933; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33 934; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65 935; CHECK-NEXT: [[OR:%.*]] = icmp ult i8 [[TMP2]], 27 936; CHECK-NEXT: ret i1 [[OR]] 937; 938 %c.off = add i8 %c, -65 939 %cmp1 = icmp ule i8 %c.off, 26 940 %c.off17 = add i8 %c, -97 941 %cmp2 = icmp ule i8 %c.off17, 26 942 %or = select i1 %cmp1, i1 true, i1 %cmp2 943 ret i1 %or 944} 945 946define <2 x i1> @test47_nonuniform(<2 x i8> %c) { 947; CHECK-LABEL: @test47_nonuniform( 948; CHECK-NEXT: [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -65, i8 -97> 949; CHECK-NEXT: [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], splat (i8 27) 950; CHECK-NEXT: [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -97, i8 -65> 951; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], splat (i8 27) 952; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]] 953; CHECK-NEXT: ret <2 x i1> [[OR]] 954; 955 %c.off = add <2 x i8> %c, <i8 -65, i8 -97> 956 %cmp1 = icmp ule <2 x i8> %c.off, <i8 26, i8 26> 957 %c.off17 = add <2 x i8> %c, <i8 -97, i8 -65> 958 %cmp2 = icmp ule <2 x i8> %c.off17, <i8 26, i8 26> 959 %or = or <2 x i1> %cmp1, %cmp2 960 ret <2 x i1> %or 961} 962 963define i32 @test49(i1 %C) { 964; CHECK-LABEL: @test49( 965; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1019, i32 123 966; CHECK-NEXT: ret i32 [[V]] 967; 968 %A = select i1 %C, i32 1000, i32 10 969 %V = or i32 %A, 123 970 ret i32 %V 971} 972 973define <2 x i32> @test49vec(i1 %C) { 974; CHECK-LABEL: @test49vec( 975; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> splat (i32 1019), <2 x i32> splat (i32 123) 976; CHECK-NEXT: ret <2 x i32> [[V]] 977; 978 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10> 979 %V = or <2 x i32> %A, <i32 123, i32 123> 980 ret <2 x i32> %V 981} 982 983define <2 x i32> @test49vec2(i1 %C) { 984; CHECK-LABEL: @test49vec2( 985; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1019, i32 2509>, <2 x i32> <i32 123, i32 351> 986; CHECK-NEXT: ret <2 x i32> [[V]] 987; 988 %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30> 989 %V = or <2 x i32> %A, <i32 123, i32 333> 990 ret <2 x i32> %V 991} 992 993define i32 @test50(i1 %which) { 994; CHECK-LABEL: @test50( 995; CHECK-NEXT: entry: 996; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 997; CHECK: delay: 998; CHECK-NEXT: br label [[FINAL]] 999; CHECK: final: 1000; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1019, [[ENTRY:%.*]] ], [ 123, [[DELAY]] ] 1001; CHECK-NEXT: ret i32 [[A]] 1002; 1003entry: 1004 br i1 %which, label %final, label %delay 1005 1006delay: 1007 br label %final 1008 1009final: 1010 %A = phi i32 [ 1000, %entry ], [ 10, %delay ] 1011 %value = or i32 %A, 123 1012 ret i32 %value 1013} 1014 1015define <2 x i32> @test50vec(i1 %which) { 1016; CHECK-LABEL: @test50vec( 1017; CHECK-NEXT: entry: 1018; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 1019; CHECK: delay: 1020; CHECK-NEXT: br label [[FINAL]] 1021; CHECK: final: 1022; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ splat (i32 1019), [[ENTRY:%.*]] ], [ splat (i32 123), [[DELAY]] ] 1023; CHECK-NEXT: ret <2 x i32> [[A]] 1024; 1025entry: 1026 br i1 %which, label %final, label %delay 1027 1028delay: 1029 br label %final 1030 1031final: 1032 %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ] 1033 %value = or <2 x i32> %A, <i32 123, i32 123> 1034 ret <2 x i32> %value 1035} 1036 1037define <2 x i32> @test50vec2(i1 %which) { 1038; CHECK-LABEL: @test50vec2( 1039; CHECK-NEXT: entry: 1040; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 1041; CHECK: delay: 1042; CHECK-NEXT: br label [[FINAL]] 1043; CHECK: final: 1044; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1019, i32 2509>, [[ENTRY:%.*]] ], [ <i32 123, i32 351>, [[DELAY]] ] 1045; CHECK-NEXT: ret <2 x i32> [[A]] 1046; 1047entry: 1048 br i1 %which, label %final, label %delay 1049 1050delay: 1051 br label %final 1052 1053final: 1054 %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ] 1055 %value = or <2 x i32> %A, <i32 123, i32 333> 1056 ret <2 x i32> %value 1057} 1058 1059; In the next 4 tests, vary the types and predicates for extra coverage. 1060; (X | (Y & ~X)) -> (X | Y), where 'not' is an inverted cmp 1061 1062define i1 @or_andn_cmp_1(i32 %a, i32 %b, i32 %c) { 1063; CHECK-LABEL: @or_andn_cmp_1( 1064; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]] 1065; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42 1066; CHECK-NEXT: [[OR:%.*]] = or i1 [[X]], [[Y]] 1067; CHECK-NEXT: ret i1 [[OR]] 1068; 1069 %x = icmp sgt i32 %a, %b 1070 %x_inv = icmp sle i32 %a, %b 1071 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering 1072 %and = and i1 %y, %x_inv 1073 %or = or i1 %x, %and 1074 ret i1 %or 1075} 1076 1077define i1 @or_andn_cmp_1_logical(i32 %a, i32 %b, i32 %c) { 1078; CHECK-LABEL: @or_andn_cmp_1_logical( 1079; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]] 1080; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42 1081; CHECK-NEXT: [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]] 1082; CHECK-NEXT: ret i1 [[OR]] 1083; 1084 %x = icmp sgt i32 %a, %b 1085 %x_inv = icmp sle i32 %a, %b 1086 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering 1087 %and = select i1 %y, i1 %x_inv, i1 false 1088 %or = select i1 %x, i1 true, i1 %and 1089 ret i1 %or 1090} 1091 1092; Commute the 'or': 1093; ((Y & ~X) | X) -> (X | Y), where 'not' is an inverted cmp 1094 1095define <2 x i1> @or_andn_cmp_2(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) { 1096; CHECK-LABEL: @or_andn_cmp_2( 1097; CHECK-NEXT: [[X:%.*]] = icmp sge <2 x i32> [[A:%.*]], [[B:%.*]] 1098; CHECK-NEXT: [[Y:%.*]] = icmp ugt <2 x i32> [[C:%.*]], <i32 42, i32 47> 1099; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[Y]], [[X]] 1100; CHECK-NEXT: ret <2 x i1> [[OR]] 1101; 1102 %x = icmp sge <2 x i32> %a, %b 1103 %x_inv = icmp slt <2 x i32> %a, %b 1104 %y = icmp ugt <2 x i32> %c, <i32 42, i32 47> ; thwart complexity-based ordering 1105 %and = and <2 x i1> %y, %x_inv 1106 %or = or <2 x i1> %and, %x 1107 ret <2 x i1> %or 1108} 1109 1110; Commute the 'and': 1111; (X | (~X & Y)) -> (X | Y), where 'not' is an inverted cmp 1112 1113define i1 @or_andn_cmp_3(i72 %a, i72 %b, i72 %c) { 1114; CHECK-LABEL: @or_andn_cmp_3( 1115; CHECK-NEXT: [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]] 1116; CHECK-NEXT: [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42 1117; CHECK-NEXT: [[OR:%.*]] = or i1 [[X]], [[Y]] 1118; CHECK-NEXT: ret i1 [[OR]] 1119; 1120 %x = icmp ugt i72 %a, %b 1121 %x_inv = icmp ule i72 %a, %b 1122 %y = icmp ugt i72 %c, 42 ; thwart complexity-based ordering 1123 %and = and i1 %x_inv, %y 1124 %or = or i1 %x, %and 1125 ret i1 %or 1126} 1127 1128define i1 @or_andn_cmp_3_logical(i72 %a, i72 %b, i72 %c) { 1129; CHECK-LABEL: @or_andn_cmp_3_logical( 1130; CHECK-NEXT: [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]] 1131; CHECK-NEXT: [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42 1132; CHECK-NEXT: [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]] 1133; CHECK-NEXT: ret i1 [[OR]] 1134; 1135 %x = icmp ugt i72 %a, %b 1136 %x_inv = icmp ule i72 %a, %b 1137 %y = icmp ugt i72 %c, 42 ; thwart complexity-based ordering 1138 %and = select i1 %x_inv, i1 %y, i1 false 1139 %or = select i1 %x, i1 true, i1 %and 1140 ret i1 %or 1141} 1142 1143; Commute the 'or': 1144; ((~X & Y) | X) -> (X | Y), where 'not' is an inverted cmp 1145 1146define <3 x i1> @or_andn_cmp_4(<3 x i32> %a, <3 x i32> %b, <3 x i32> %c) { 1147; CHECK-LABEL: @or_andn_cmp_4( 1148; CHECK-NEXT: [[X:%.*]] = icmp eq <3 x i32> [[A:%.*]], [[B:%.*]] 1149; CHECK-NEXT: [[Y:%.*]] = icmp ugt <3 x i32> [[C:%.*]], <i32 42, i32 43, i32 -1> 1150; CHECK-NEXT: [[OR:%.*]] = or <3 x i1> [[Y]], [[X]] 1151; CHECK-NEXT: ret <3 x i1> [[OR]] 1152; 1153 %x = icmp eq <3 x i32> %a, %b 1154 %x_inv = icmp ne <3 x i32> %a, %b 1155 %y = icmp ugt <3 x i32> %c, <i32 42, i32 43, i32 -1> ; thwart complexity-based ordering 1156 %and = and <3 x i1> %x_inv, %y 1157 %or = or <3 x i1> %and, %x 1158 ret <3 x i1> %or 1159} 1160 1161; In the next 4 tests, vary the types and predicates for extra coverage. 1162; (~X | (Y & X)) -> (~X | Y), where 'not' is an inverted cmp 1163 1164define i1 @orn_and_cmp_1(i37 %a, i37 %b, i37 %c) { 1165; CHECK-LABEL: @orn_and_cmp_1( 1166; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]] 1167; CHECK-NEXT: [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42 1168; CHECK-NEXT: [[OR:%.*]] = or i1 [[X_INV]], [[Y]] 1169; CHECK-NEXT: ret i1 [[OR]] 1170; 1171 %x = icmp sgt i37 %a, %b 1172 %x_inv = icmp sle i37 %a, %b 1173 %y = icmp ugt i37 %c, 42 ; thwart complexity-based ordering 1174 %and = and i1 %y, %x 1175 %or = or i1 %x_inv, %and 1176 ret i1 %or 1177} 1178 1179define i1 @orn_and_cmp_1_logical(i37 %a, i37 %b, i37 %c) { 1180; CHECK-LABEL: @orn_and_cmp_1_logical( 1181; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]] 1182; CHECK-NEXT: [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42 1183; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]] 1184; CHECK-NEXT: ret i1 [[OR]] 1185; 1186 %x = icmp sgt i37 %a, %b 1187 %x_inv = icmp sle i37 %a, %b 1188 %y = icmp ugt i37 %c, 42 ; thwart complexity-based ordering 1189 %and = select i1 %y, i1 %x, i1 false 1190 %or = select i1 %x_inv, i1 true, i1 %and 1191 ret i1 %or 1192} 1193 1194; Commute the 'or': 1195; ((Y & X) | ~X) -> (~X | Y), where 'not' is an inverted cmp 1196 1197define i1 @orn_and_cmp_2(i16 %a, i16 %b, i16 %c) { 1198; CHECK-LABEL: @orn_and_cmp_2( 1199; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]] 1200; CHECK-NEXT: [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42 1201; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y]], [[X_INV]] 1202; CHECK-NEXT: ret i1 [[OR]] 1203; 1204 %x = icmp sge i16 %a, %b 1205 %x_inv = icmp slt i16 %a, %b 1206 %y = icmp ugt i16 %c, 42 ; thwart complexity-based ordering 1207 %and = and i1 %y, %x 1208 %or = or i1 %and, %x_inv 1209 ret i1 %or 1210} 1211 1212define i1 @orn_and_cmp_2_logical(i16 %a, i16 %b, i16 %c) { 1213; CHECK-LABEL: @orn_and_cmp_2_logical( 1214; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]] 1215; CHECK-NEXT: [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42 1216; CHECK-NEXT: [[OR:%.*]] = select i1 [[Y]], i1 true, i1 [[X_INV]] 1217; CHECK-NEXT: ret i1 [[OR]] 1218; 1219 %x = icmp sge i16 %a, %b 1220 %x_inv = icmp slt i16 %a, %b 1221 %y = icmp ugt i16 %c, 42 ; thwart complexity-based ordering 1222 %and = select i1 %y, i1 %x, i1 false 1223 %or = select i1 %and, i1 true, i1 %x_inv 1224 ret i1 %or 1225} 1226 1227; Commute the 'and': 1228; (~X | (X & Y)) -> (~X | Y), where 'not' is an inverted cmp 1229 1230define <4 x i1> @orn_and_cmp_3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 1231; CHECK-LABEL: @orn_and_cmp_3( 1232; CHECK-NEXT: [[X_INV:%.*]] = icmp ule <4 x i32> [[A:%.*]], [[B:%.*]] 1233; CHECK-NEXT: [[Y:%.*]] = icmp ugt <4 x i32> [[C:%.*]], <i32 42, i32 0, i32 1, i32 -1> 1234; CHECK-NEXT: [[OR:%.*]] = or <4 x i1> [[X_INV]], [[Y]] 1235; CHECK-NEXT: ret <4 x i1> [[OR]] 1236; 1237 %x = icmp ugt <4 x i32> %a, %b 1238 %x_inv = icmp ule <4 x i32> %a, %b 1239 %y = icmp ugt <4 x i32> %c, <i32 42, i32 0, i32 1, i32 -1> ; thwart complexity-based ordering 1240 %and = and <4 x i1> %x, %y 1241 %or = or <4 x i1> %x_inv, %and 1242 ret <4 x i1> %or 1243} 1244 1245; Commute the 'or': 1246; ((X & Y) | ~X) -> (~X | Y), where 'not' is an inverted cmp 1247 1248define i1 @orn_and_cmp_4(i32 %a, i32 %b, i32 %c) { 1249; CHECK-LABEL: @orn_and_cmp_4( 1250; CHECK-NEXT: [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]] 1251; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42 1252; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y]], [[X_INV]] 1253; CHECK-NEXT: ret i1 [[OR]] 1254; 1255 %x = icmp eq i32 %a, %b 1256 %x_inv = icmp ne i32 %a, %b 1257 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering 1258 %and = and i1 %x, %y 1259 %or = or i1 %and, %x_inv 1260 ret i1 %or 1261} 1262 1263define i1 @orn_and_cmp_4_logical(i32 %a, i32 %b, i32 %c) { 1264; CHECK-LABEL: @orn_and_cmp_4_logical( 1265; CHECK-NEXT: [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]] 1266; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42 1267; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]] 1268; CHECK-NEXT: ret i1 [[OR]] 1269; 1270 %x = icmp eq i32 %a, %b 1271 %x_inv = icmp ne i32 %a, %b 1272 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering 1273 %and = select i1 %x, i1 %y, i1 false 1274 %or = select i1 %and, i1 true, i1 %x_inv 1275 ret i1 %or 1276} 1277 1278; The constant vectors are inverses. Make sure we can turn this into a select without crashing trying to truncate the constant to 16xi1. 1279define <16 x i1> @test51(<16 x i1> %arg, <16 x i1> %arg1) { 1280; CHECK-LABEL: @test51( 1281; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <16 x i1> [[ARG:%.*]], <16 x i1> [[ARG1:%.*]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 20, i32 5, i32 6, i32 23, i32 24, i32 9, i32 10, i32 27, i32 28, i32 29, i32 30, i32 31> 1282; CHECK-NEXT: ret <16 x i1> [[TMP3]] 1283; 1284 %tmp = and <16 x i1> %arg, <i1 true, i1 true, i1 true, i1 true, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false> 1285 %tmp2 = and <16 x i1> %arg1, <i1 false, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 true, i1 true, i1 true> 1286 %tmp3 = or <16 x i1> %tmp, %tmp2 1287 ret <16 x i1> %tmp3 1288} 1289 1290; This would infinite loop because it reaches a transform 1291; that was not expecting a constant-foldable value. 1292 1293define i32 @PR46712(i1 %x, i1 %y, i1 %b, i64 %z) { 1294; CHECK-LABEL: @PR46712( 1295; CHECK-NEXT: entry: 1296; CHECK-NEXT: br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]] 1297; CHECK: true: 1298; CHECK-NEXT: [[BOOL5_NOT:%.*]] = icmp eq i64 [[Z:%.*]], 0 1299; CHECK-NEXT: [[TMP0:%.*]] = zext i1 [[BOOL5_NOT]] to i32 1300; CHECK-NEXT: br label [[END]] 1301; CHECK: end: 1302; CHECK-NEXT: [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP0]], [[TRUE]] ] 1303; CHECK-NEXT: ret i32 [[T5]] 1304; 1305entry: 1306 %t2 = or i1 %x, %y 1307 %conv = sext i1 %t2 to i32 1308 %cmp = icmp sge i32 %conv, 1 1309 %conv2 = zext i1 %cmp to i64 1310 br i1 %b, label %true, label %end 1311 1312true: 1313 %bool4 = icmp eq i64 %conv2, 0 1314 %bool5 = icmp ne i64 %z, 0 1315 %and = and i1 %bool4, %bool5 1316 %sel = select i1 %and, i1 false, i1 true 1317 br label %end 1318 1319end: 1320 %t5 = phi i1 [ 0, %entry ], [ %sel, %true ] 1321 %conv8 = zext i1 %t5 to i32 1322 ret i32 %conv8 1323} 1324 1325define i32 @PR46712_logical(i1 %x, i1 %y, i1 %b, i64 %z) { 1326; CHECK-LABEL: @PR46712_logical( 1327; CHECK-NEXT: entry: 1328; CHECK-NEXT: br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]] 1329; CHECK: true: 1330; CHECK-NEXT: [[BOOL5_NOT:%.*]] = icmp eq i64 [[Z:%.*]], 0 1331; CHECK-NEXT: [[TMP0:%.*]] = zext i1 [[BOOL5_NOT]] to i32 1332; CHECK-NEXT: br label [[END]] 1333; CHECK: end: 1334; CHECK-NEXT: [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP0]], [[TRUE]] ] 1335; CHECK-NEXT: ret i32 [[T5]] 1336; 1337entry: 1338 %t2 = select i1 %x, i1 true, i1 %y 1339 %conv = sext i1 %t2 to i32 1340 %cmp = icmp sge i32 %conv, 1 1341 %conv2 = zext i1 %cmp to i64 1342 br i1 %b, label %true, label %end 1343 1344true: 1345 %bool4 = icmp eq i64 %conv2, 0 1346 %bool5 = icmp ne i64 %z, 0 1347 %and = select i1 %bool4, i1 %bool5, i1 false 1348 %sel = select i1 %and, i1 false, i1 true 1349 br label %end 1350 1351end: 1352 %t5 = phi i1 [ 0, %entry ], [ %sel, %true ] 1353 %conv8 = zext i1 %t5 to i32 1354 ret i32 %conv8 1355} 1356 1357; (~x & y) | ~(x | y) --> ~x 1358define i32 @PR38929(i32 %0, i32 %1) { 1359; CHECK-LABEL: @PR38929( 1360; CHECK-NEXT: [[TMP3:%.*]] = xor i32 [[TMP0:%.*]], -1 1361; CHECK-NEXT: ret i32 [[TMP3]] 1362; 1363 %3 = xor i32 %0, -1 1364 %4 = and i32 %3, %1 1365 %5 = or i32 %1, %0 1366 %6 = xor i32 %5, -1 1367 %7 = or i32 %4, %6 1368 ret i32 %7 1369} 1370 1371define i32 @test1(i32 %x, i32 %y) { 1372; CHECK-LABEL: @test1( 1373; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 1374; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1 1375; CHECK-NEXT: ret i32 [[OR1]] 1376; 1377 %xor = xor i32 %y, %x 1378 %or = or i32 %y, %x 1379 %neg = xor i32 %or, -1 1380 %or1 = or i32 %xor, %neg 1381 ret i32 %or1 1382} 1383 1384define i32 @test2(i32 %x, i32 %y) { 1385; CHECK-LABEL: @test2( 1386; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 1387; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1 1388; CHECK-NEXT: ret i32 [[OR1]] 1389; 1390 %or = or i32 %x, %y 1391 %neg = xor i32 %or, -1 1392 %xor = xor i32 %y, %x 1393 %or1 = or i32 %xor, %neg 1394 ret i32 %or1 1395} 1396 1397define i32 @test3(i32 %x, i32 %y) { 1398; CHECK-LABEL: @test3( 1399; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 1400; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1 1401; CHECK-NEXT: ret i32 [[OR1]] 1402; 1403 %or = or i32 %y, %x 1404 %neg = xor i32 %or, -1 1405 %xor = xor i32 %x, %y 1406 %or1 = or i32 %xor, %neg 1407 ret i32 %or1 1408} 1409 1410define <2 x i32> @test4_vec(<2 x i32> %x, <2 x i32> %y) { 1411; CHECK-LABEL: @test4_vec( 1412; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[Y:%.*]], [[X:%.*]] 1413; CHECK-NEXT: [[OR1:%.*]] = xor <2 x i32> [[TMP1]], splat (i32 -1) 1414; CHECK-NEXT: ret <2 x i32> [[OR1]] 1415; 1416 %or = or <2 x i32> %y, %x 1417 %neg = xor <2 x i32> %or, <i32 -1, i32 -1> 1418 %xor = xor <2 x i32> %y, %x 1419 %or1 = or <2 x i32> %xor, %neg 1420 ret <2 x i32> %or1 1421} 1422 1423define i32 @test5_use(i32 %x, i32 %y) { 1424; CHECK-LABEL: @test5_use( 1425; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] 1426; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[OR]], -1 1427; CHECK-NEXT: call void @use(i32 [[NEG]]) 1428; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y]], [[X]] 1429; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1 1430; CHECK-NEXT: ret i32 [[OR1]] 1431; 1432 %or = or i32 %y, %x 1433 %neg = xor i32 %or, -1 1434 %xor = xor i32 %y, %x 1435 call void @use(i32 %neg) 1436 %or1 = or i32 %xor, %neg 1437 ret i32 %or1 1438} 1439 1440define i32 @test5_use2(i32 %x, i32 %y) { 1441; CHECK-LABEL: @test5_use2( 1442; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]] 1443; CHECK-NEXT: call void @use(i32 [[XOR]]) 1444; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y]], [[X]] 1445; CHECK-NEXT: [[OR1:%.*]] = xor i32 [[TMP1]], -1 1446; CHECK-NEXT: ret i32 [[OR1]] 1447; 1448 %or = or i32 %y, %x 1449 %neg = xor i32 %or, -1 1450 %xor = xor i32 %y, %x 1451 call void @use(i32 %xor) 1452 %or1 = or i32 %xor, %neg 1453 ret i32 %or1 1454} 1455define i32 @test5_use3(i32 %x, i32 %y) { 1456; CHECK-LABEL: @test5_use3( 1457; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] 1458; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[OR]], -1 1459; CHECK-NEXT: call void @use(i32 [[NEG]]) 1460; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]] 1461; CHECK-NEXT: call void @use(i32 [[XOR]]) 1462; CHECK-NEXT: [[OR1:%.*]] = or i32 [[XOR]], [[NEG]] 1463; CHECK-NEXT: ret i32 [[OR1]] 1464; 1465 %or = or i32 %y, %x 1466 %neg = xor i32 %or, -1 1467 call void @use(i32 %neg) 1468 %xor = xor i32 %y, %x 1469 call void @use(i32 %xor) 1470 %or1 = or i32 %xor, %neg 1471 ret i32 %or1 1472} 1473 1474define i8 @ashr_bitwidth_mask(i8 %x, i8 %y) { 1475; CHECK-LABEL: @ashr_bitwidth_mask( 1476; CHECK-NEXT: [[SIGN:%.*]] = ashr i8 [[X:%.*]], 7 1477; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]] 1478; CHECK-NEXT: ret i8 [[R]] 1479; 1480 %sign = ashr i8 %x, 7 1481 %r = or i8 %sign, %y 1482 ret i8 %r 1483} 1484 1485define <2 x i8> @ashr_bitwidth_mask_vec_commute(<2 x i8> %x, <2 x i8> %py) { 1486; CHECK-LABEL: @ashr_bitwidth_mask_vec_commute( 1487; CHECK-NEXT: [[Y:%.*]] = mul <2 x i8> [[PY:%.*]], <i8 42, i8 2> 1488; CHECK-NEXT: [[SIGN:%.*]] = ashr <2 x i8> [[X:%.*]], splat (i8 7) 1489; CHECK-NEXT: [[R:%.*]] = or <2 x i8> [[Y]], [[SIGN]] 1490; CHECK-NEXT: ret <2 x i8> [[R]] 1491; 1492 %y = mul <2 x i8> %py, <i8 42, i8 2> ; thwart complexity-based ordering 1493 %sign = ashr <2 x i8> %x, <i8 7, i8 7> 1494 %r = or <2 x i8> %y, %sign 1495 ret <2 x i8> %r 1496} 1497 1498define i32 @ashr_bitwidth_mask_use(i32 %x, i32 %y) { 1499; CHECK-LABEL: @ashr_bitwidth_mask_use( 1500; CHECK-NEXT: [[SIGN:%.*]] = ashr i32 [[X:%.*]], 7 1501; CHECK-NEXT: call void @use(i32 [[SIGN]]) 1502; CHECK-NEXT: [[R:%.*]] = or i32 [[SIGN]], [[Y:%.*]] 1503; CHECK-NEXT: ret i32 [[R]] 1504; 1505 %sign = ashr i32 %x, 7 1506 call void @use(i32 %sign) 1507 %r = or i32 %sign, %y 1508 ret i32 %r 1509} 1510 1511define i8 @ashr_not_bitwidth_mask(i8 %x, i8 %y) { 1512; CHECK-LABEL: @ashr_not_bitwidth_mask( 1513; CHECK-NEXT: [[SIGN:%.*]] = ashr i8 [[X:%.*]], 6 1514; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]] 1515; CHECK-NEXT: ret i8 [[R]] 1516; 1517 %sign = ashr i8 %x, 6 1518 %r = or i8 %sign, %y 1519 ret i8 %r 1520} 1521 1522define i8 @lshr_bitwidth_mask(i8 %x, i8 %y) { 1523; CHECK-LABEL: @lshr_bitwidth_mask( 1524; CHECK-NEXT: [[SIGN:%.*]] = lshr i8 [[X:%.*]], 7 1525; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]] 1526; CHECK-NEXT: ret i8 [[R]] 1527; 1528 %sign = lshr i8 %x, 7 1529 %r = or i8 %sign, %y 1530 ret i8 %r 1531} 1532 1533define i1 @cmp_overlap(i32 %x) { 1534; CHECK-LABEL: @cmp_overlap( 1535; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[X:%.*]], 1 1536; CHECK-NEXT: ret i1 [[R]] 1537; 1538 %isneg = icmp slt i32 %x, 0 1539 %negx = sub i32 0, %x 1540 %isnotneg = icmp sgt i32 %negx, -1 1541 %r = or i1 %isneg, %isnotneg 1542 ret i1 %r 1543} 1544 1545define <2 x i1> @cmp_overlap_splat(<2 x i5> %x) { 1546; CHECK-LABEL: @cmp_overlap_splat( 1547; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i5> [[X:%.*]], splat (i5 1) 1548; CHECK-NEXT: ret <2 x i1> [[R]] 1549; 1550 %isneg = icmp slt <2 x i5> %x, zeroinitializer 1551 %negx = sub <2 x i5> zeroinitializer, %x 1552 %isnotneg = icmp sgt <2 x i5> %negx, <i5 -1, i5 -1> 1553 %r = or <2 x i1> %isneg, %isnotneg 1554 ret <2 x i1> %r 1555} 1556 1557define i32 @mul_no_common_bits(i32 %p1, i32 %p2) { 1558; CHECK-LABEL: @mul_no_common_bits( 1559; CHECK-NEXT: [[X:%.*]] = and i32 [[P1:%.*]], 7 1560; CHECK-NEXT: [[Y:%.*]] = shl i32 [[P2:%.*]], 3 1561; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i32 [[Y]], 1 1562; CHECK-NEXT: [[R:%.*]] = mul i32 [[X]], [[TMP1]] 1563; CHECK-NEXT: ret i32 [[R]] 1564; 1565 %x = and i32 %p1, 7 1566 %y = shl i32 %p2, 3 1567 %m = mul i32 %x, %y 1568 %r = or i32 %m, %x 1569 ret i32 %r 1570} 1571 1572define i32 @mul_no_common_bits_const_op(i32 %p) { 1573; CHECK-LABEL: @mul_no_common_bits_const_op( 1574; CHECK-NEXT: [[X:%.*]] = and i32 [[P:%.*]], 7 1575; CHECK-NEXT: [[R:%.*]] = mul nuw nsw i32 [[X]], 25 1576; CHECK-NEXT: ret i32 [[R]] 1577; 1578 %x = and i32 %p, 7 1579 %m = mul i32 %x, 24 1580 %r = or i32 %m, %x 1581 ret i32 %r 1582} 1583 1584define <2 x i12> @mul_no_common_bits_commute(<2 x i12> %p) { 1585; CHECK-LABEL: @mul_no_common_bits_commute( 1586; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i12> [[P:%.*]] to <2 x i1> 1587; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[TMP1]], <2 x i12> <i12 15, i12 17>, <2 x i12> zeroinitializer 1588; CHECK-NEXT: ret <2 x i12> [[R]] 1589; 1590 %x = and <2 x i12> %p, <i12 1, i12 1> 1591 %m = mul <2 x i12> %x, <i12 14, i12 16> 1592 %r = or <2 x i12> %x, %m 1593 ret <2 x i12> %r 1594} 1595 1596define i32 @mul_no_common_bits_commute2(i32 %p1, i32 %p2) { 1597; CHECK-LABEL: @mul_no_common_bits_commute2( 1598; CHECK-NEXT: [[X:%.*]] = and i32 [[P1:%.*]], 7 1599; CHECK-NEXT: [[Y:%.*]] = shl i32 [[P2:%.*]], 3 1600; CHECK-NEXT: [[M:%.*]] = mul i32 [[Y]], [[X]] 1601; CHECK-NEXT: [[R:%.*]] = or disjoint i32 [[M]], [[X]] 1602; CHECK-NEXT: ret i32 [[R]] 1603; 1604 %x = and i32 %p1, 7 1605 %y = shl i32 %p2, 3 1606 %m = mul i32 %y, %x 1607 %r = or i32 %m, %x 1608 ret i32 %r 1609} 1610 1611define i32 @mul_no_common_bits_disjoint(i32 %x, i32 %y) { 1612; CHECK-LABEL: @mul_no_common_bits_disjoint( 1613; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[Y:%.*]], 1 1614; CHECK-NEXT: [[R:%.*]] = mul i32 [[X:%.*]], [[TMP1]] 1615; CHECK-NEXT: ret i32 [[R]] 1616; 1617 %m = mul i32 %x, %y 1618 %r = or disjoint i32 %m, %x 1619 ret i32 %r 1620} 1621 1622define i32 @mul_no_common_bits_const_op_disjoint(i32 %x, i32 %y) { 1623; CHECK-LABEL: @mul_no_common_bits_const_op_disjoint( 1624; CHECK-NEXT: [[R:%.*]] = mul i32 [[X:%.*]], 25 1625; CHECK-NEXT: ret i32 [[R]] 1626; 1627 %m = mul i32 %x, 24 1628 %r = or disjoint i32 %m, %x 1629 ret i32 %r 1630} 1631 1632; negative test - extra use requires extra instructions 1633 1634define i32 @mul_no_common_bits_uses(i32 %p1, i32 %p2) { 1635; CHECK-LABEL: @mul_no_common_bits_uses( 1636; CHECK-NEXT: [[X:%.*]] = and i32 [[P1:%.*]], 7 1637; CHECK-NEXT: [[Y:%.*]] = shl i32 [[P2:%.*]], 3 1638; CHECK-NEXT: [[M:%.*]] = mul i32 [[X]], [[Y]] 1639; CHECK-NEXT: call void @use(i32 [[M]]) 1640; CHECK-NEXT: [[R:%.*]] = or disjoint i32 [[M]], [[X]] 1641; CHECK-NEXT: ret i32 [[R]] 1642; 1643 %x = and i32 %p1, 7 1644 %y = shl i32 %p2, 3 1645 %m = mul i32 %x, %y 1646 call void @use(i32 %m) 1647 %r = or i32 %m, %x 1648 ret i32 %r 1649} 1650 1651; negative test - probably not good to create an extra mul 1652 1653define i32 @mul_no_common_bits_const_op_uses(i32 %p) { 1654; CHECK-LABEL: @mul_no_common_bits_const_op_uses( 1655; CHECK-NEXT: [[X:%.*]] = and i32 [[P:%.*]], 7 1656; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[X]], 24 1657; CHECK-NEXT: call void @use(i32 [[M]]) 1658; CHECK-NEXT: [[R:%.*]] = or disjoint i32 [[M]], [[X]] 1659; CHECK-NEXT: ret i32 [[R]] 1660; 1661 %x = and i32 %p, 7 1662 %m = mul i32 %x, 24 1663 call void @use(i32 %m) 1664 %r = or i32 %m, %x 1665 ret i32 %r 1666} 1667 1668; negative test - %x and %m may have set 3rd bit 1669 1670define i32 @mul_common_bits(i32 %p) { 1671; CHECK-LABEL: @mul_common_bits( 1672; CHECK-NEXT: [[X:%.*]] = and i32 [[P:%.*]], 7 1673; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[X]], 12 1674; CHECK-NEXT: [[R:%.*]] = or i32 [[M]], [[X]] 1675; CHECK-NEXT: ret i32 [[R]] 1676; 1677 %x = and i32 %p, 7 1678 %m = mul i32 %x, 12 1679 %r = or i32 %m, %x 1680 ret i32 %r 1681} 1682 1683define <4 x i1> @and_or_not_or_logical_vec(<4 x i32> %ap, <4 x i32> %bp) { 1684; CHECK-LABEL: @and_or_not_or_logical_vec( 1685; CHECK-NEXT: [[A:%.*]] = icmp ne <4 x i32> [[AP:%.*]], zeroinitializer 1686; CHECK-NEXT: ret <4 x i1> [[A]] 1687; 1688 %A = icmp eq <4 x i32> %ap, zeroinitializer 1689 %B = icmp eq <4 x i32> %bp, zeroinitializer 1690 %V = xor <4 x i1> %A, <i1 true, i1 true, i1 true, i1 true> 1691 %X = select <4 x i1> %B, <4 x i1> %V, <4 x i1> zeroinitializer 1692 %W = or <4 x i1> %B, %A 1693 %Y = xor <4 x i1> %W, <i1 true, i1 true, i1 true, i1 true> 1694 %Z = or <4 x i1> %X, %Y 1695 ret <4 x i1> %Z 1696} 1697 1698; Make sure SimplifyDemandedBits drops the disjoint flag. 1699define i8 @drop_disjoint(i8 %x) { 1700; CHECK-LABEL: @drop_disjoint( 1701; CHECK-NEXT: [[B:%.*]] = or i8 [[X:%.*]], 1 1702; CHECK-NEXT: ret i8 [[B]] 1703; 1704 %a = and i8 %x, -2 1705 %b = or disjoint i8 %a, 1 1706 ret i8 %b 1707} 1708 1709; Make sure we drop disjoint when combining the Ors. 1710define i32 @assoc_cast_assoc_disjoint(i16 %x) { 1711; CHECK-LABEL: @assoc_cast_assoc_disjoint( 1712; CHECK-NEXT: [[B:%.*]] = zext i16 [[X:%.*]] to i32 1713; CHECK-NEXT: [[C:%.*]] = or i32 [[B]], 65537 1714; CHECK-NEXT: ret i32 [[C]] 1715; 1716 %a = or i16 %x, 1 1717 %b = zext i16 %a to i32 1718 %c = or disjoint i32 %b, 65536 1719 ret i32 %c 1720} 1721 1722; (X & C1) | C2 -> X & (C1 | C2) iff (X & C2) == C2 1723define i32 @test_or_and_disjoint(i32 %a) { 1724; CHECK-LABEL: @test_or_and_disjoint( 1725; CHECK-NEXT: [[A0:%.*]] = and i32 [[A:%.*]], 24 1726; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A0]], 8 1727; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1728; CHECK: if.then: 1729; CHECK-NEXT: [[A2:%.*]] = and i32 [[A]], 15 1730; CHECK-NEXT: ret i32 [[A2]] 1731; CHECK: if.else: 1732; CHECK-NEXT: ret i32 0 1733; 1734 %a0 = and i32 %a, 24 1735 %cmp = icmp eq i32 %a0, 8 1736 br i1 %cmp, label %if.then, label %if.else 1737if.then: 1738 %a1 = and i32 %a, 7 1739 %a2 = or i32 %a1, 8 1740 ret i32 %a2 1741if.else: 1742 ret i32 0 1743} 1744 1745define i32 @test_or_and_mixed(i32 %a) { 1746; CHECK-LABEL: @test_or_and_mixed( 1747; CHECK-NEXT: [[A0:%.*]] = and i32 [[A:%.*]], 27 1748; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A0]], 11 1749; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1750; CHECK: if.then: 1751; CHECK-NEXT: [[A2:%.*]] = and i32 [[A]], 15 1752; CHECK-NEXT: ret i32 [[A2]] 1753; CHECK: if.else: 1754; CHECK-NEXT: ret i32 0 1755; 1756 %a0 = and i32 %a, 27 1757 %cmp = icmp eq i32 %a0, 11 1758 br i1 %cmp, label %if.then, label %if.else 1759if.then: 1760 %a1 = and i32 %a, 7 1761 %a2 = or i32 %a1, 11 1762 ret i32 %a2 1763if.else: 1764 ret i32 0 1765} 1766 1767; Negative tests 1768 1769define i32 @test_or_and_disjoint_fail(i32 %a) { 1770; CHECK-LABEL: @test_or_and_disjoint_fail( 1771; CHECK-NEXT: [[A0:%.*]] = and i32 [[A:%.*]], 24 1772; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A0]], 16 1773; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1774; CHECK: if.then: 1775; CHECK-NEXT: [[A1:%.*]] = and i32 [[A]], 7 1776; CHECK-NEXT: [[A2:%.*]] = or disjoint i32 [[A1]], 8 1777; CHECK-NEXT: ret i32 [[A2]] 1778; CHECK: if.else: 1779; CHECK-NEXT: ret i32 0 1780; 1781 %a0 = and i32 %a, 24 1782 %cmp = icmp eq i32 %a0, 16 1783 br i1 %cmp, label %if.then, label %if.else 1784if.then: 1785 %a1 = and i32 %a, 7 1786 %a2 = or i32 %a1, 8 1787 ret i32 %a2 1788if.else: 1789 ret i32 0 1790} 1791 1792define i32 @test_or_and_disjoint_multiuse(i32 %a) { 1793; CHECK-LABEL: @test_or_and_disjoint_multiuse( 1794; CHECK-NEXT: [[A0:%.*]] = and i32 [[A:%.*]], 24 1795; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A0]], 8 1796; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1797; CHECK: if.then: 1798; CHECK-NEXT: [[A1:%.*]] = and i32 [[A]], 7 1799; CHECK-NEXT: call void @use(i32 [[A1]]) 1800; CHECK-NEXT: [[A2:%.*]] = or disjoint i32 [[A1]], 8 1801; CHECK-NEXT: ret i32 [[A2]] 1802; CHECK: if.else: 1803; CHECK-NEXT: ret i32 0 1804; 1805 %a0 = and i32 %a, 24 1806 %cmp = icmp eq i32 %a0, 8 1807 br i1 %cmp, label %if.then, label %if.else 1808if.then: 1809 %a1 = and i32 %a, 7 1810 call void @use(i32 %a1) 1811 %a2 = or i32 %a1, 8 1812 ret i32 %a2 1813if.else: 1814 ret i32 0 1815} 1816 1817; Tests from PR76554 1818define i32 @test_or_and_xor_constant(i32 %x, i32 %y) { 1819; CHECK-LABEL: @test_or_and_xor_constant( 1820; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] 1821; CHECK-NEXT: [[D:%.*]] = and i32 [[TMP1]], -2147483648 1822; CHECK-NEXT: ret i32 [[D]] 1823; 1824 %a = and i32 %x, -2147483648 1825 %b = xor i32 %a, -2147483648 1826 %c = and i32 %b, %y 1827 %d = or i32 %c, %a 1828 ret i32 %d 1829} 1830 1831define i32 @test_or_and_xor(i32 %a, i32 %b, i32 %c) { 1832; CHECK-LABEL: @test_or_and_xor( 1833; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B:%.*]], [[C:%.*]] 1834; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], [[A:%.*]] 1835; CHECK-NEXT: ret i32 [[OR]] 1836; 1837 %xor = xor i32 %a, %b 1838 %and = and i32 %xor, %c 1839 %or = or i32 %and, %a 1840 ret i32 %or 1841} 1842 1843define i32 @test_or_and_xor_commuted1(i32 %a, i32 %b, i32 %c) { 1844; CHECK-LABEL: @test_or_and_xor_commuted1( 1845; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B:%.*]], [[C:%.*]] 1846; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], [[A:%.*]] 1847; CHECK-NEXT: ret i32 [[OR]] 1848; 1849 %xor = xor i32 %b, %a 1850 %and = and i32 %xor, %c 1851 %or = or i32 %and, %a 1852 ret i32 %or 1853} 1854 1855define i32 @test_or_and_xor_commuted2(i32 %a, i32 %b, i32 %c) { 1856; CHECK-LABEL: @test_or_and_xor_commuted2( 1857; CHECK-NEXT: [[CC:%.*]] = mul i32 [[C:%.*]], [[C]] 1858; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[CC]], [[B:%.*]] 1859; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], [[A:%.*]] 1860; CHECK-NEXT: ret i32 [[OR]] 1861; 1862 %cc = mul i32 %c, %c 1863 %xor = xor i32 %a, %b 1864 %and = and i32 %cc, %xor 1865 %or = or i32 %and, %a 1866 ret i32 %or 1867} 1868 1869define i32 @test_or_and_xor_commuted3(i32 %a, i32 %b, i32 %c) { 1870; CHECK-LABEL: @test_or_and_xor_commuted3( 1871; CHECK-NEXT: [[AA:%.*]] = mul i32 [[A:%.*]], [[A]] 1872; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B:%.*]], [[C:%.*]] 1873; CHECK-NEXT: [[OR:%.*]] = or i32 [[AA]], [[TMP1]] 1874; CHECK-NEXT: ret i32 [[OR]] 1875; 1876 %aa = mul i32 %a, %a 1877 %xor = xor i32 %aa, %b 1878 %and = and i32 %xor, %c 1879 %or = or i32 %aa, %and 1880 ret i32 %or 1881} 1882 1883define i32 @test_or_and_xor_multiuse1(i32 %a, i32 %b, i32 %c) { 1884; CHECK-LABEL: @test_or_and_xor_multiuse1( 1885; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 1886; CHECK-NEXT: call void @use(i32 [[XOR]]) 1887; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B]], [[C:%.*]] 1888; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], [[A]] 1889; CHECK-NEXT: ret i32 [[OR]] 1890; 1891 %xor = xor i32 %a, %b 1892 call void @use(i32 %xor) 1893 %and = and i32 %xor, %c 1894 %or = or i32 %and, %a 1895 ret i32 %or 1896} 1897 1898; Negative tests 1899 1900define i32 @test_or_and_xor_mismatched_op(i32 %a, i32 %b, i32 %c, i32 %d) { 1901; CHECK-LABEL: @test_or_and_xor_mismatched_op( 1902; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 1903; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR]], [[C:%.*]] 1904; CHECK-NEXT: [[OR:%.*]] = or i32 [[AND]], [[D:%.*]] 1905; CHECK-NEXT: ret i32 [[OR]] 1906; 1907 %xor = xor i32 %a, %b 1908 %and = and i32 %xor, %c 1909 %or = or i32 %and, %d 1910 ret i32 %or 1911} 1912 1913define i32 @test_or_and_xor_multiuse2(i32 %a, i32 %b, i32 %c) { 1914; CHECK-LABEL: @test_or_and_xor_multiuse2( 1915; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 1916; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR]], [[C:%.*]] 1917; CHECK-NEXT: call void @use(i32 [[AND]]) 1918; CHECK-NEXT: [[OR:%.*]] = or i32 [[AND]], [[A]] 1919; CHECK-NEXT: ret i32 [[OR]] 1920; 1921 %xor = xor i32 %a, %b 1922 %and = and i32 %xor, %c 1923 call void @use(i32 %and) 1924 %or = or i32 %and, %a 1925 ret i32 %or 1926} 1927 1928define i32 @test_or_add_xor(i32 %a, i32 %b, i32 %c) { 1929; CHECK-LABEL: @test_or_add_xor( 1930; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 1931; CHECK-NEXT: [[ADD:%.*]] = add i32 [[XOR]], [[C:%.*]] 1932; CHECK-NEXT: [[OR:%.*]] = or i32 [[ADD]], [[A]] 1933; CHECK-NEXT: ret i32 [[OR]] 1934; 1935 %xor = xor i32 %a, %b 1936 %add = add i32 %xor, %c 1937 %or = or i32 %add, %a 1938 ret i32 %or 1939} 1940 1941define i32 @test_or_and_and_multiuse(i32 %a, i32 %b, i32 %c) { 1942; CHECK-LABEL: @test_or_and_and_multiuse( 1943; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A:%.*]], [[B:%.*]] 1944; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C:%.*]] 1945; CHECK-NEXT: call void @use(i32 [[AND1]]) 1946; CHECK-NEXT: call void @use(i32 [[AND2]]) 1947; CHECK-NEXT: ret i32 [[A]] 1948; 1949 %and1 = and i32 %a, %b 1950 %and2 = and i32 %and1, %c 1951 call void @use(i32 %and1) 1952 call void @use(i32 %and2) 1953 %or = or i32 %and2, %a 1954 ret i32 %or 1955} 1956 1957define i32 @or_xor_and(i32 %x, i32 %y, i32 %z) { 1958; CHECK-LABEL: @or_xor_and( 1959; CHECK-NEXT: [[OR1:%.*]] = or i32 [[X:%.*]], [[Y:%.*]] 1960; CHECK-NEXT: ret i32 [[OR1]] 1961; 1962 %and = and i32 %y, %z 1963 %xor = xor i32 %x, %and 1964 %or1 = or i32 %xor, %y 1965 ret i32 %or1 1966} 1967 1968define i32 @or_xor_and_uses1(i32 %x, i32 %y, i32 %z) { 1969; CHECK-LABEL: @or_xor_and_uses1( 1970; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[Z:%.*]] 1971; CHECK-NEXT: call void @use(i32 [[AND]]) 1972; CHECK-NEXT: [[OR1:%.*]] = or i32 [[X:%.*]], [[Y]] 1973; CHECK-NEXT: ret i32 [[OR1]] 1974; 1975 %and = and i32 %y, %z 1976 call void @use(i32 %and) 1977 %xor = xor i32 %x, %and 1978 %or1 = or i32 %xor, %y 1979 ret i32 %or1 1980} 1981 1982define i32 @or_xor_and_uses2(i32 %x, i32 %y, i32 %z) { 1983; CHECK-LABEL: @or_xor_and_uses2( 1984; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[Z:%.*]] 1985; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[AND]] 1986; CHECK-NEXT: call void @use(i32 [[XOR]]) 1987; CHECK-NEXT: [[OR1:%.*]] = or i32 [[X]], [[Y]] 1988; CHECK-NEXT: ret i32 [[OR1]] 1989; 1990 %and = and i32 %y, %z 1991 %xor = xor i32 %x, %and 1992 call void @use(i32 %xor) 1993 %or1 = or i32 %xor, %y 1994 ret i32 %or1 1995} 1996 1997define i32 @or_xor_and_commuted1(i32 %x, i32 %y, i32 %z) { 1998; CHECK-LABEL: @or_xor_and_commuted1( 1999; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]] 2000; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[X:%.*]] 2001; CHECK-NEXT: ret i32 [[OR1]] 2002; 2003 %yy = mul i32 %y, %y ; thwart complexity-based ordering 2004 %and = and i32 %yy, %z 2005 %xor = xor i32 %and, %x 2006 %or1 = or i32 %yy, %xor 2007 ret i32 %or1 2008} 2009 2010define i32 @or_xor_and_commuted2(i32 %x, i32 %y, i32 %z) { 2011; CHECK-LABEL: @or_xor_and_commuted2( 2012; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]] 2013; CHECK-NEXT: [[XX:%.*]] = mul i32 [[X:%.*]], [[X]] 2014; CHECK-NEXT: [[OR1:%.*]] = or i32 [[XX]], [[YY]] 2015; CHECK-NEXT: ret i32 [[OR1]] 2016; 2017 %yy = mul i32 %y, %y ; thwart complexity-based ordering 2018 %xx = mul i32 %x, %x ; thwart complexity-based ordering 2019 %and = and i32 %yy, %z 2020 %xor = xor i32 %xx, %and 2021 %or1 = or i32 %xor, %yy 2022 ret i32 %or1 2023} 2024 2025define i32 @or_xor_and_commuted3(i32 %x, i32 %y, i32 %z) { 2026; CHECK-LABEL: @or_xor_and_commuted3( 2027; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]] 2028; CHECK-NEXT: [[OR1:%.*]] = or i32 [[X:%.*]], [[YY]] 2029; CHECK-NEXT: ret i32 [[OR1]] 2030; 2031 %yy = mul i32 %y, %y ; thwart complexity-based ordering 2032 %zz = mul i32 %z, %z ; thwart complexity-based ordering 2033 %and = and i32 %zz, %yy 2034 %xor = xor i32 %and, %x 2035 %or1 = or i32 %xor, %yy 2036 ret i32 %or1 2037} 2038