1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s 3 4define i32 @test1(i32 %A) { 5; CHECK-LABEL: @test1( 6; CHECK-NEXT: ret i32 [[A:%.*]] 7; 8 %B = or i32 %A, 0 9 ret i32 %B 10} 11 12define i32 @all_ones(i32 %A) { 13; CHECK-LABEL: @all_ones( 14; CHECK-NEXT: ret i32 -1 15; 16 %B = or i32 %A, -1 17 ret i32 %B 18} 19 20define <3 x i8> @all_ones_vec_with_poison_elt(<3 x i8> %A) { 21; CHECK-LABEL: @all_ones_vec_with_poison_elt( 22; CHECK-NEXT: ret <3 x i8> splat (i8 -1) 23; 24 %B = or <3 x i8> %A, <i8 -1, i8 poison, i8 -1> 25 ret <3 x i8> %B 26} 27 28define i1 @test3(i1 %A) { 29; CHECK-LABEL: @test3( 30; CHECK-NEXT: ret i1 [[A:%.*]] 31; 32 %B = or i1 %A, false 33 ret i1 %B 34} 35 36define i1 @test4(i1 %A) { 37; CHECK-LABEL: @test4( 38; CHECK-NEXT: ret i1 true 39; 40 %B = or i1 %A, true 41 ret i1 %B 42} 43 44define i1 @test5(i1 %A) { 45; CHECK-LABEL: @test5( 46; CHECK-NEXT: ret i1 [[A:%.*]] 47; 48 %B = or i1 %A, %A 49 ret i1 %B 50} 51 52define i32 @test6(i32 %A) { 53; CHECK-LABEL: @test6( 54; CHECK-NEXT: ret i32 [[A:%.*]] 55; 56 %B = or i32 %A, %A 57 ret i32 %B 58} 59 60; A | ~A == -1 61 62define i32 @or_not(i32 %A) { 63; CHECK-LABEL: @or_not( 64; CHECK-NEXT: ret i32 -1 65; 66 %NotA = xor i32 %A, -1 67 %B = or i32 %A, %NotA 68 ret i32 %B 69} 70 71define <2 x i4> @or_not_commute_vec_poison(<2 x i4> %A) { 72; CHECK-LABEL: @or_not_commute_vec_poison( 73; CHECK-NEXT: ret <2 x i4> splat (i4 -1) 74; 75 %NotA = xor <2 x i4> %A, <i4 -1, i4 poison> 76 %B = or <2 x i4> %NotA, %A 77 ret <2 x i4> %B 78} 79 80define i8 @test8(i8 %A) { 81; CHECK-LABEL: @test8( 82; CHECK-NEXT: ret i8 -1 83; 84 %B = or i8 %A, -2 85 %C = or i8 %B, 1 86 ret i8 %C 87} 88 89; Test that (A|c1)|(B|c2) == (A|B)|(c1|c2) 90define i8 @test9(i8 %A, i8 %B) { 91; CHECK-LABEL: @test9( 92; CHECK-NEXT: ret i8 -1 93; 94 %C = or i8 %A, 1 95 %D = or i8 %B, -2 96 %E = or i8 %C, %D 97 ret i8 %E 98} 99 100; (X & C1) | C2 --> (X | C2) & (C1|C2) 101define i8 @test10(i8 %A) { 102; CHECK-LABEL: @test10( 103; CHECK-NEXT: ret i8 -2 104; 105 %B = or i8 %A, 1 106 %C = and i8 %B, -2 107 %D = or i8 %C, -2 108 ret i8 %D 109} 110 111; The following two cases only get folded by InstCombine, 112; see InstCombine/or-xor.ll. 113 114; (X ^ C1) | C2 --> (X | C2) ^ (C1&~C2) 115define i8 @test11(i8 %A) { 116; CHECK-LABEL: @test11( 117; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], -2 118; CHECK-NEXT: [[C:%.*]] = xor i8 [[B]], 13 119; CHECK-NEXT: [[D:%.*]] = or i8 [[C]], 1 120; CHECK-NEXT: [[E:%.*]] = xor i8 [[D]], 12 121; CHECK-NEXT: ret i8 [[E]] 122; 123 %B = or i8 %A, -2 124 %C = xor i8 %B, 13 125 %D = or i8 %C, 1 126 %E = xor i8 %D, 12 127 ret i8 %E 128} 129 130define i8 @test11v(<2 x i8> %A) { 131; CHECK-LABEL: @test11v( 132; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A:%.*]], <i8 -2, i8 0> 133; CHECK-NEXT: [[CV:%.*]] = xor <2 x i8> [[B]], splat (i8 13) 134; CHECK-NEXT: [[C:%.*]] = extractelement <2 x i8> [[CV]], i32 0 135; CHECK-NEXT: [[D:%.*]] = or i8 [[C]], 1 136; CHECK-NEXT: [[E:%.*]] = xor i8 [[D]], 12 137; CHECK-NEXT: ret i8 [[E]] 138; 139 %B = or <2 x i8> %A, <i8 -2, i8 0> 140 %CV = xor <2 x i8> %B, <i8 13, i8 13> 141 %C = extractelement <2 x i8> %CV, i32 0 142 %D = or i8 %C, 1 143 %E = xor i8 %D, 12 144 ret i8 %E 145} 146 147; Test the case where integer BitWidth <= 64 && BitWidth % 2 != 0. 148; If we have: ((V + N) & C1) | (V & C2) 149; .. and C2 = ~C1 and C2 is 0+1+ and (N & C2) == 0 150; replace with V+N. 151define i39 @test1_apint(i39 %V, i39 %M) { 152; CHECK-LABEL: @test1_apint( 153; CHECK-NEXT: [[N:%.*]] = and i39 [[M:%.*]], -274877906944 154; CHECK-NEXT: [[A:%.*]] = add i39 [[V:%.*]], [[N]] 155; CHECK-NEXT: ret i39 [[A]] 156; 157 %C1 = xor i39 274877906943, -1 ;; C2 = 274877906943 158 %N = and i39 %M, 274877906944 159 %A = add i39 %V, %N 160 %B = and i39 %A, %C1 161 %D = and i39 %V, 274877906943 162 %R = or i39 %B, %D 163 ret i39 %R 164} 165 166define i7 @test2_apint(i7 %X) { 167; CHECK-LABEL: @test2_apint( 168; CHECK-NEXT: ret i7 [[X:%.*]] 169; 170 %Y = or i7 %X, 0 171 ret i7 %Y 172} 173 174define i17 @test3_apint(i17 %X) { 175; CHECK-LABEL: @test3_apint( 176; CHECK-NEXT: ret i17 -1 177; 178 %Y = or i17 %X, -1 179 ret i17 %Y 180} 181 182; Test the case where Integer BitWidth > 64 && BitWidth <= 1024. 183; If we have: ((V + N) & C1) | (V & C2) 184; .. and C2 = ~C1 and C2 is 0+1+ and (N & C2) == 0 185; replace with V+N. 186define i399 @test4_apint(i399 %V, i399 %M) { 187; CHECK-LABEL: @test4_apint( 188; CHECK-NEXT: [[N:%.*]] = and i399 [[M:%.*]], 18446742974197923840 189; CHECK-NEXT: [[A:%.*]] = add i399 [[V:%.*]], [[N]] 190; CHECK-NEXT: ret i399 [[A]] 191; 192 %C1 = xor i399 274877906943, -1 ;; C2 = 274877906943 193 %N = and i399 %M, 18446742974197923840 194 %A = add i399 %V, %N 195 %B = and i399 %A, %C1 196 %D = and i399 %V, 274877906943 197 %R = or i399 %D, %B 198 ret i399 %R 199} 200 201define i777 @test5_apint(i777 %X) { 202; CHECK-LABEL: @test5_apint( 203; CHECK-NEXT: ret i777 [[X:%.*]] 204; 205 %Y = or i777 %X, 0 206 ret i777 %Y 207} 208 209define i117 @test6_apint(i117 %X) { 210; CHECK-LABEL: @test6_apint( 211; CHECK-NEXT: ret i117 -1 212; 213 %Y = or i117 %X, -1 214 ret i117 %Y 215} 216 217; Test the case where integer BitWidth <= 64 && BitWidth % 2 != 0. 218; Vector version of test1_apint with the add commuted 219; If we have: ((V + N) & C1) | (V & C2) 220; .. and C2 = ~C1 and C2 is 0+1+ and (N & C2) == 0 221; replace with V+N. 222define <2 x i39> @test7_apint(<2 x i39> %V, <2 x i39> %M) { 223; CHECK-LABEL: @test7_apint( 224; CHECK-NEXT: [[N:%.*]] = and <2 x i39> [[M:%.*]], splat (i39 -274877906944) 225; CHECK-NEXT: [[A:%.*]] = add <2 x i39> [[N]], [[V:%.*]] 226; CHECK-NEXT: ret <2 x i39> [[A]] 227; 228 %C1 = xor <2 x i39> <i39 274877906943, i39 274877906943>, <i39 -1, i39 -1> ;; C2 = 274877906943 229 %N = and <2 x i39> %M, <i39 274877906944, i39 274877906944> 230 %A = add <2 x i39> %N, %V 231 %B = and <2 x i39> %A, %C1 232 %D = and <2 x i39> %V, <i39 274877906943, i39 274877906943> 233 %R = or <2 x i39> %B, %D 234 ret <2 x i39> %R 235} 236 237; Test the case where Integer BitWidth > 64 && BitWidth <= 1024. 238; Vector version of test4_apint with the add and the or commuted 239; If we have: ((V + N) & C1) | (V & C2) 240; .. and C2 = ~C1 and C2 is 0+1+ and (N & C2) == 0 241; replace with V+N. 242define <2 x i399> @test8_apint(<2 x i399> %V, <2 x i399> %M) { 243; CHECK-LABEL: @test8_apint( 244; CHECK-NEXT: [[N:%.*]] = and <2 x i399> [[M:%.*]], splat (i399 18446742974197923840) 245; CHECK-NEXT: [[A:%.*]] = add <2 x i399> [[N]], [[V:%.*]] 246; CHECK-NEXT: ret <2 x i399> [[A]] 247; 248 %C1 = xor <2 x i399> <i399 274877906943, i399 274877906943>, <i399 -1, i399 -1> ;; C2 = 274877906943 249 %N = and <2 x i399> %M, <i399 18446742974197923840, i399 18446742974197923840> 250 %A = add <2 x i399> %N, %V 251 %B = and <2 x i399> %A, %C1 252 %D = and <2 x i399> %V, <i399 274877906943, i399 274877906943> 253 %R = or <2 x i399> %D, %B 254 ret <2 x i399> %R 255} 256 257; (A & B) | A = A 258 259define i8 @or_and_common_op_commute0(i8 %a, i8 %b) { 260; CHECK-LABEL: @or_and_common_op_commute0( 261; CHECK-NEXT: ret i8 [[A:%.*]] 262; 263 %and = and i8 %a, %b 264 %or = or i8 %and, %a 265 ret i8 %or 266} 267 268define <2 x i8> @or_and_common_op_commute1(<2 x i8> %a, <2 x i8> %b) { 269; CHECK-LABEL: @or_and_common_op_commute1( 270; CHECK-NEXT: ret <2 x i8> [[A:%.*]] 271; 272 %and = and <2 x i8> %b, %a 273 %or = or <2 x i8> %and, %a 274 ret <2 x i8> %or 275} 276 277define i8 @or_and_common_op_commute2(i8 %a, i8 %b) { 278; CHECK-LABEL: @or_and_common_op_commute2( 279; CHECK-NEXT: ret i8 [[A:%.*]] 280; 281 %and = and i8 %a, %b 282 %or = or i8 %a, %and 283 ret i8 %or 284} 285 286define <2 x i8> @or_and_common_op_commute3(<2 x i8> %a, <2 x i8> %b) { 287; CHECK-LABEL: @or_and_common_op_commute3( 288; CHECK-NEXT: ret <2 x i8> [[A:%.*]] 289; 290 %and = and <2 x i8> %b, %a 291 %or = or <2 x i8> %a, %and 292 ret <2 x i8> %or 293} 294 295; A | ~(A & B) = -1 296 297define i1 @or_with_not_op_commute1(i1 %a, i1 %b) { 298; CHECK-LABEL: @or_with_not_op_commute1( 299; CHECK-NEXT: ret i1 true 300; 301 %ab = and i1 %a, %b 302 %not = xor i1 %ab, -1 303 %r = or i1 %a, %not 304 ret i1 %r 305} 306 307; A | ~(B & A) = -1 308 309define i8 @or_with_not_op_commute2(i8 %a, i8 %b) { 310; CHECK-LABEL: @or_with_not_op_commute2( 311; CHECK-NEXT: ret i8 -1 312; 313 %ab = and i8 %b, %a 314 %not = xor i8 %ab, -1 315 %r = or i8 %a, %not 316 ret i8 %r 317} 318 319; ~(A & B) | A = -1 320 321define <3 x i17> @or_with_not_op_commute3(<3 x i17> %a, <3 x i17> %b) { 322; CHECK-LABEL: @or_with_not_op_commute3( 323; CHECK-NEXT: ret <3 x i17> splat (i17 -1) 324; 325 %ab = and <3 x i17> %a, %b 326 %not = xor <3 x i17> %ab, <i17 -1, i17 -1, i17 -1> 327 %r = or <3 x i17> %not, %a 328 ret <3 x i17> %r 329} 330 331; ~(B & A) | A = -1 332 333define <2 x i1> @or_with_not_op_commute4(<2 x i1> %a, <2 x i1> %b) { 334; CHECK-LABEL: @or_with_not_op_commute4( 335; CHECK-NEXT: ret <2 x i1> splat (i1 true) 336; 337 %ab = and <2 x i1> %b, %a 338 %not = xor <2 x i1> %ab, <i1 -1, i1 poison> 339 %r = or <2 x i1> %not, %a 340 ret <2 x i1> %r 341} 342 343define i32 @poison(i32 %x) { 344; CHECK-LABEL: @poison( 345; CHECK-NEXT: ret i32 poison 346; 347 %v = or i32 %x, poison 348 ret i32 %v 349} 350 351; (~A & B) | ~(A | B) --> ~A 352 353define i4 @and_or_not_or_commute0(i4 %A, i4 %B) { 354; CHECK-LABEL: @and_or_not_or_commute0( 355; CHECK-NEXT: [[NOTA:%.*]] = xor i4 [[A:%.*]], -1 356; CHECK-NEXT: ret i4 [[NOTA]] 357; 358 %nota = xor i4 %A, -1 359 %and = and i4 %nota, %B 360 %or = or i4 %A, %B 361 %notab = xor i4 %or, -1 362 %r = or i4 %and, %notab 363 ret i4 %r 364} 365 366define i41 @and_or_not_or_commute1(i41 %A, i41 %B) { 367; CHECK-LABEL: @and_or_not_or_commute1( 368; CHECK-NEXT: [[NOTA:%.*]] = xor i41 [[A:%.*]], -1 369; CHECK-NEXT: ret i41 [[NOTA]] 370; 371 %nota = xor i41 %A, -1 372 %and = and i41 %B, %nota 373 %or = or i41 %A, %B 374 %notab = xor i41 %or, -1 375 %r = or i41 %and, %notab 376 ret i41 %r 377} 378 379define i8 @and_or_not_or_commute2(i8 %A, i8 %B) { 380; CHECK-LABEL: @and_or_not_or_commute2( 381; CHECK-NEXT: [[NOTA:%.*]] = xor i8 [[A:%.*]], -1 382; CHECK-NEXT: ret i8 [[NOTA]] 383; 384 %nota = xor i8 %A, -1 385 %and = and i8 %nota, %B 386 %or = or i8 %B, %A 387 %notab = xor i8 %or, -1 388 %r = or i8 %and, %notab 389 ret i8 %r 390} 391 392define <2 x i4> @and_or_not_or_commute3(<2 x i4> %A, <2 x i4> %B) { 393; CHECK-LABEL: @and_or_not_or_commute3( 394; CHECK-NEXT: [[NOTA:%.*]] = xor <2 x i4> [[A:%.*]], splat (i4 -1) 395; CHECK-NEXT: ret <2 x i4> [[NOTA]] 396; 397 %nota = xor <2 x i4> %A, <i4 -1, i4 -1> 398 %and = and <2 x i4> %B, %nota 399 %or = or <2 x i4> %B, %A 400 %notab = xor <2 x i4> %or, <i4 -1, i4 -1> 401 %r = or <2 x i4> %and, %notab 402 ret <2 x i4> %r 403} 404 405define i4 @and_or_not_or_commute4(i4 %A, i4 %B) { 406; CHECK-LABEL: @and_or_not_or_commute4( 407; CHECK-NEXT: [[NOTA:%.*]] = xor i4 [[A:%.*]], -1 408; CHECK-NEXT: ret i4 [[NOTA]] 409; 410 %nota = xor i4 %A, -1 411 %and = and i4 %nota, %B 412 %or = or i4 %A, %B 413 %notab = xor i4 %or, -1 414 %r = or i4 %notab, %and 415 ret i4 %r 416} 417 418define i41 @and_or_not_or_commute5(i41 %A, i41 %B) { 419; CHECK-LABEL: @and_or_not_or_commute5( 420; CHECK-NEXT: [[NOTA:%.*]] = xor i41 [[A:%.*]], -1 421; CHECK-NEXT: ret i41 [[NOTA]] 422; 423 %nota = xor i41 %A, -1 424 %and = and i41 %B, %nota 425 %or = or i41 %A, %B 426 %notab = xor i41 %or, -1 427 %r = or i41 %notab, %and 428 ret i41 %r 429} 430 431define i8 @and_or_not_or_commute6(i8 %A, i8 %B) { 432; CHECK-LABEL: @and_or_not_or_commute6( 433; CHECK-NEXT: [[NOTA:%.*]] = xor i8 [[A:%.*]], -1 434; CHECK-NEXT: ret i8 [[NOTA]] 435; 436 %nota = xor i8 %A, -1 437 %and = and i8 %nota, %B 438 %or = or i8 %B, %A 439 %notab = xor i8 %or, -1 440 %r = or i8 %notab, %and 441 ret i8 %r 442} 443 444define <2 x i4> @and_or_not_or_commute7(<2 x i4> %A, <2 x i4> %B) { 445; CHECK-LABEL: @and_or_not_or_commute7( 446; CHECK-NEXT: [[NOTA:%.*]] = xor <2 x i4> [[A:%.*]], splat (i4 -1) 447; CHECK-NEXT: ret <2 x i4> [[NOTA]] 448; 449 %nota = xor <2 x i4> %A, <i4 -1, i4 -1> 450 %and = and <2 x i4> %B, %nota 451 %or = or <2 x i4> %B, %A 452 %notab = xor <2 x i4> %or, <i4 -1, i4 -1> 453 %r = or <2 x i4> %notab, %and 454 ret <2 x i4> %r 455} 456 457; (~A & B) | ~(A | B) --> ~A with logical and 458define i1 @and_or_not_or_logical(i1 %A, i1 %B) { 459; CHECK-LABEL: @and_or_not_or_logical( 460; CHECK-NEXT: [[V:%.*]] = xor i1 [[A:%.*]], true 461; CHECK-NEXT: ret i1 [[V]] 462; 463 %V = xor i1 %A, true 464 %X = select i1 %V, i1 %B, i1 false 465 %W = or i1 %B, %A 466 %Y = xor i1 %W, true 467 %Z = or i1 %X, %Y 468 ret i1 %Z 469} 470 471; (~B & A) | ~(A | B) --> ~A with logical and 472define i1 @and_or_not_or_logical_rev(i1 %A, i1 %B) { 473; CHECK-LABEL: @and_or_not_or_logical_rev( 474; CHECK-NEXT: [[V:%.*]] = xor i1 [[A:%.*]], true 475; CHECK-NEXT: ret i1 [[V]] 476; 477 %V = xor i1 %A, true 478 %X = select i1 %B, i1 %V, i1 false 479 %W = or i1 %B, %A 480 %Y = xor i1 %W, true 481 %Z = or i1 %X, %Y 482 ret i1 %Z 483} 484 485; (~A & B) | ~(A | B) --> ~A with logical And and logical Or 486define i1 @and_or_not_logical_or_logical_rev(i1 %A, i1 %B) { 487; CHECK-LABEL: @and_or_not_logical_or_logical_rev( 488; CHECK-NEXT: [[V:%.*]] = xor i1 [[A:%.*]], true 489; CHECK-NEXT: ret i1 [[V]] 490; 491 %V = xor i1 %A, true 492 %X = select i1 %B, i1 %V, i1 false 493 %W = select i1 %B, i1 true, i1 %A 494 %Y = xor i1 %W, true 495 %Z = or i1 %X, %Y 496 ret i1 %Z 497} 498 499; negative test - It is not safe to propagate an undef element from the 'not' op. 500 501define <2 x i4> @and_or_not_or_commute7_undef_elt(<2 x i4> %A, <2 x i4> %B) { 502; CHECK-LABEL: @and_or_not_or_commute7_undef_elt( 503; CHECK-NEXT: [[NOTA:%.*]] = xor <2 x i4> [[A:%.*]], <i4 undef, i4 -1> 504; CHECK-NEXT: [[AND:%.*]] = and <2 x i4> [[B:%.*]], [[NOTA]] 505; CHECK-NEXT: [[OR:%.*]] = or <2 x i4> [[B]], [[A]] 506; CHECK-NEXT: [[NOTAB:%.*]] = xor <2 x i4> [[OR]], splat (i4 -1) 507; CHECK-NEXT: [[R:%.*]] = or <2 x i4> [[NOTAB]], [[AND]] 508; CHECK-NEXT: ret <2 x i4> [[R]] 509; 510 %nota = xor <2 x i4> %A, <i4 undef, i4 -1> 511 %and = and <2 x i4> %B, %nota 512 %or = or <2 x i4> %B, %A 513 %notab = xor <2 x i4> %or, <i4 -1, i4 -1> 514 %r = or <2 x i4> %notab, %and 515 ret <2 x i4> %r 516} 517 518; doing the same with poison is safe. 519 520define <2 x i4> @and_or_not_or_commute7_poison_elt(<2 x i4> %A, <2 x i4> %B) { 521; CHECK-LABEL: @and_or_not_or_commute7_poison_elt( 522; CHECK-NEXT: [[NOTA:%.*]] = xor <2 x i4> [[A:%.*]], <i4 poison, i4 -1> 523; CHECK-NEXT: ret <2 x i4> [[NOTA]] 524; 525 %nota = xor <2 x i4> %A, <i4 poison, i4 -1> 526 %and = and <2 x i4> %B, %nota 527 %or = or <2 x i4> %B, %A 528 %notab = xor <2 x i4> %or, <i4 -1, i4 -1> 529 %r = or <2 x i4> %notab, %and 530 ret <2 x i4> %r 531} 532 533; (A | B) | (A ^ B) --> A | B 534 535define i69 @or_or_xor(i69 %A, i69 %B) { 536; CHECK-LABEL: @or_or_xor( 537; CHECK-NEXT: [[I1:%.*]] = or i69 [[A:%.*]], [[B:%.*]] 538; CHECK-NEXT: ret i69 [[I1]] 539; 540 %i1 = or i69 %A, %B 541 %i2 = xor i69 %A, %B 542 %i3 = or i69 %i1, %i2 543 ret i69 %i3 544} 545 546; (B | A) | (A ^ B) --> B | A 547 548define i8 @or_or_xor_inner_or_commuted(i8 %A, i8 %B) { 549; CHECK-LABEL: @or_or_xor_inner_or_commuted( 550; CHECK-NEXT: [[I1:%.*]] = or i8 [[B:%.*]], [[A:%.*]] 551; CHECK-NEXT: ret i8 [[I1]] 552; 553 %i1 = or i8 %B, %A 554 %i2 = xor i8 %A, %B 555 %i3 = or i8 %i1, %i2 556 ret i8 %i3 557} 558 559; (A ^ B) | (A | B) --> A | B 560 561define <4 x i4> @or_or_xor_commuted(<4 x i4> %A, <4 x i4> %B) { 562; CHECK-LABEL: @or_or_xor_commuted( 563; CHECK-NEXT: [[I1:%.*]] = or <4 x i4> [[A:%.*]], [[B:%.*]] 564; CHECK-NEXT: ret <4 x i4> [[I1]] 565; 566 %i1 = or <4 x i4> %A, %B 567 %i2 = xor <4 x i4> %A, %B 568 %i3 = or <4 x i4> %i2, %i1 569 ret <4 x i4> %i3 570} 571 572; (A ^ B) | (B | A) --> B | A 573 574define i4 @or_or_xor_inner_or_outer_or_commuted(i4 %A, i4 %B) { 575; CHECK-LABEL: @or_or_xor_inner_or_outer_or_commuted( 576; CHECK-NEXT: [[I1:%.*]] = or i4 [[B:%.*]], [[A:%.*]] 577; CHECK-NEXT: ret i4 [[I1]] 578; 579 %i1 = or i4 %B, %A 580 %i2 = xor i4 %A, %B 581 %i3 = or i4 %i2, %i1 582 ret i4 %i3 583} 584 585define i32 @shifted_all_ones(i32 %shamt) { 586; CHECK-LABEL: @shifted_all_ones( 587; CHECK-NEXT: ret i32 -1 588; 589 %r = lshr i32 -1, %shamt 590 %s = sub i32 32, %shamt 591 %l = shl i32 -1, %s 592 %o = or i32 %r, %l 593 ret i32 %o 594} 595 596; Sub from less than bitwidth is ok (overlapping ones). 597 598define i32 @shifted_all_ones_commute(i32 %shamt) { 599; CHECK-LABEL: @shifted_all_ones_commute( 600; CHECK-NEXT: ret i32 -1 601; 602 %r = lshr i32 -1, %shamt 603 %s = sub i32 31, %shamt 604 %l = shl i32 -1, %s 605 %o = or i32 %l, %r 606 ret i32 %o 607} 608 609define <2 x i9> @shifted_all_ones_sub_on_lshr(<2 x i9> %shamt) { 610; CHECK-LABEL: @shifted_all_ones_sub_on_lshr( 611; CHECK-NEXT: ret <2 x i9> splat (i9 -1) 612; 613 %l = shl <2 x i9> <i9 -1, i9 -1>, %shamt 614 %s = sub <2 x i9> <i9 5, i9 5>, %shamt 615 %r = lshr <2 x i9> <i9 -1, i9 -1>, %s 616 %o = or <2 x i9> %l, %r 617 ret <2 x i9> %o 618} 619 620define i8 @shifted_all_ones_sub_on_lshr_commute(i8 %shamt) { 621; CHECK-LABEL: @shifted_all_ones_sub_on_lshr_commute( 622; CHECK-NEXT: ret i8 -1 623; 624 %l = shl i8 -1, %shamt 625 %s = sub i8 8, %shamt 626 %r = lshr i8 -1, %s 627 %o = or i8 %r, %l 628 ret i8 %o 629} 630 631; negative test - need -1 in general case 632 633define i32 @shifted_not_all_ones(i32 %shamt) { 634; CHECK-LABEL: @shifted_not_all_ones( 635; CHECK-NEXT: [[R:%.*]] = lshr i32 -2, [[SHAMT:%.*]] 636; CHECK-NEXT: [[S:%.*]] = sub i32 31, [[SHAMT]] 637; CHECK-NEXT: [[L:%.*]] = shl i32 -1, [[S]] 638; CHECK-NEXT: [[O:%.*]] = or i32 [[R]], [[L]] 639; CHECK-NEXT: ret i32 [[O]] 640; 641 %r = lshr i32 -2, %shamt 642 %s = sub i32 31, %shamt 643 %l = shl i32 -1, %s 644 %o = or i32 %r, %l 645 ret i32 %o 646} 647 648; negative test - opposite shift amount may be too big 649 650define i32 @shifted_all_ones_greater_than_bitwidth(i32 %shamt) { 651; CHECK-LABEL: @shifted_all_ones_greater_than_bitwidth( 652; CHECK-NEXT: [[R:%.*]] = lshr i32 -1, [[SHAMT:%.*]] 653; CHECK-NEXT: [[S:%.*]] = sub i32 33, [[SHAMT]] 654; CHECK-NEXT: [[L:%.*]] = shl i32 -1, [[S]] 655; CHECK-NEXT: [[O:%.*]] = or i32 [[R]], [[L]] 656; CHECK-NEXT: ret i32 [[O]] 657; 658 %r = lshr i32 -1, %shamt 659 %s = sub i32 33, %shamt 660 %l = shl i32 -1, %s 661 %o = or i32 %r, %l 662 ret i32 %o 663} 664 665; negative test - shift amount must be derived from same base 666 667define i32 @shifted_all_ones_not_same_amt(i32 %shamt, i32 %other) { 668; CHECK-LABEL: @shifted_all_ones_not_same_amt( 669; CHECK-NEXT: [[R:%.*]] = lshr i32 -1, [[SHAMT:%.*]] 670; CHECK-NEXT: [[S:%.*]] = sub i32 32, [[OTHER:%.*]] 671; CHECK-NEXT: [[L:%.*]] = shl i32 -1, [[S]] 672; CHECK-NEXT: [[O:%.*]] = or i32 [[R]], [[L]] 673; CHECK-NEXT: ret i32 [[O]] 674; 675 %r = lshr i32 -1, %shamt 676 %s = sub i32 32, %other 677 %l = shl i32 -1, %s 678 %o = or i32 %r, %l 679 ret i32 %o 680} 681 682; (A & B) | ~(A ^ B) --> ~(A ^ B) 683 684define i4 @or_nxor_and_commute0(i4 %a, i4 %b) { 685; CHECK-LABEL: @or_nxor_and_commute0( 686; CHECK-NEXT: [[XOR:%.*]] = xor i4 [[A:%.*]], [[B:%.*]] 687; CHECK-NEXT: [[NOT:%.*]] = xor i4 [[XOR]], -1 688; CHECK-NEXT: ret i4 [[NOT]] 689; 690 %and = and i4 %a, %b 691 %xor = xor i4 %a, %b 692 %not = xor i4 %xor, -1 693 %r = or i4 %and, %not 694 ret i4 %r 695} 696 697define <2 x i4> @or_nxor_and_commute1(<2 x i4> %a, <2 x i4> %b) { 698; CHECK-LABEL: @or_nxor_and_commute1( 699; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i4> [[A:%.*]], [[B:%.*]] 700; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i4> [[XOR]], splat (i4 -1) 701; CHECK-NEXT: ret <2 x i4> [[NOT]] 702; 703 %and = and <2 x i4> %a, %b 704 %xor = xor <2 x i4> %a, %b 705 %not = xor <2 x i4> %xor, <i4 -1, i4 -1> 706 %r = or <2 x i4> %not, %and 707 ret <2 x i4> %r 708} 709 710define i74 @or_nxor_and_commute2(i74 %a, i74 %b) { 711; CHECK-LABEL: @or_nxor_and_commute2( 712; CHECK-NEXT: [[XOR:%.*]] = xor i74 [[A:%.*]], [[B:%.*]] 713; CHECK-NEXT: [[NOT:%.*]] = xor i74 [[XOR]], -1 714; CHECK-NEXT: ret i74 [[NOT]] 715; 716 %and = and i74 %b, %a 717 %xor = xor i74 %a, %b 718 %not = xor i74 %xor, -1 719 %r = or i74 %and, %not 720 ret i74 %r 721} 722 723define <2 x i4> @or_nxor_and_commute3(<2 x i4> %a, <2 x i4> %b) { 724; CHECK-LABEL: @or_nxor_and_commute3( 725; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i4> [[A:%.*]], [[B:%.*]] 726; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i4> [[XOR]], splat (i4 -1) 727; CHECK-NEXT: ret <2 x i4> [[NOT]] 728; 729 %and = and <2 x i4> %b, %a 730 %xor = xor <2 x i4> %a, %b 731 %not = xor <2 x i4> %xor, <i4 -1, i4 -1> 732 %r = or <2 x i4> %not, %and 733 ret <2 x i4> %r 734} 735 736; negative test - must have common operands 737 738define i4 @or_nxor_and_wrong_val1(i4 %a, i4 %b, i4 %c) { 739; CHECK-LABEL: @or_nxor_and_wrong_val1( 740; CHECK-NEXT: [[AND:%.*]] = and i4 [[A:%.*]], [[C:%.*]] 741; CHECK-NEXT: [[XOR:%.*]] = xor i4 [[A]], [[B:%.*]] 742; CHECK-NEXT: [[NOT:%.*]] = xor i4 [[XOR]], -1 743; CHECK-NEXT: [[R:%.*]] = or i4 [[AND]], [[NOT]] 744; CHECK-NEXT: ret i4 [[R]] 745; 746 %and = and i4 %a, %c 747 %xor = xor i4 %a, %b 748 %not = xor i4 %xor, -1 749 %r = or i4 %and, %not 750 ret i4 %r 751} 752 753; negative test - must have common operands 754 755define i4 @or_nxor_and_wrong_val2(i4 %a, i4 %b, i4 %c) { 756; CHECK-LABEL: @or_nxor_and_wrong_val2( 757; CHECK-NEXT: [[AND:%.*]] = and i4 [[C:%.*]], [[B:%.*]] 758; CHECK-NEXT: [[XOR:%.*]] = xor i4 [[A:%.*]], [[B]] 759; CHECK-NEXT: [[NOT:%.*]] = xor i4 [[XOR]], -1 760; CHECK-NEXT: [[R:%.*]] = or i4 [[AND]], [[NOT]] 761; CHECK-NEXT: ret i4 [[R]] 762; 763 %and = and i4 %c, %b 764 %xor = xor i4 %a, %b 765 %not = xor i4 %xor, -1 766 %r = or i4 %and, %not 767 ret i4 %r 768} 769 770; negative test - undef in 'not' is allowed 771 772define <2 x i4> @or_nxor_and_undef_elt(<2 x i4> %a, <2 x i4> %b) { 773; CHECK-LABEL: @or_nxor_and_undef_elt( 774; CHECK-NEXT: [[AND:%.*]] = and <2 x i4> [[B:%.*]], [[A:%.*]] 775; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i4> [[A]], [[B]] 776; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i4> [[XOR]], <i4 -1, i4 undef> 777; CHECK-NEXT: [[R:%.*]] = or <2 x i4> [[NOT]], [[AND]] 778; CHECK-NEXT: ret <2 x i4> [[R]] 779; 780 %and = and <2 x i4> %b, %a 781 %xor = xor <2 x i4> %a, %b 782 %not = xor <2 x i4> %xor, <i4 -1, i4 undef> 783 %r = or <2 x i4> %not, %and 784 ret <2 x i4> %r 785} 786 787; Same with poison is safe. 788 789define <2 x i4> @or_nxor_and_poison_elt(<2 x i4> %a, <2 x i4> %b) { 790; CHECK-LABEL: @or_nxor_and_poison_elt( 791; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i4> [[A:%.*]], [[B:%.*]] 792; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i4> [[XOR]], <i4 -1, i4 poison> 793; CHECK-NEXT: ret <2 x i4> [[NOT]] 794; 795 %and = and <2 x i4> %b, %a 796 %xor = xor <2 x i4> %a, %b 797 %not = xor <2 x i4> %xor, <i4 -1, i4 poison> 798 %r = or <2 x i4> %not, %and 799 ret <2 x i4> %r 800} 801 802; ~(A ^ B) | (A | B) --> -1 803 804define i4 @or_nxor_or_commute0(i4 %a, i4 %b) { 805; CHECK-LABEL: @or_nxor_or_commute0( 806; CHECK-NEXT: ret i4 -1 807; 808 %or = or i4 %a, %b 809 %xor = xor i4 %a, %b 810 %not = xor i4 %xor, -1 811 %r = or i4 %not, %or 812 ret i4 %r 813} 814 815define <2 x i4> @or_nxor_or_commute1(<2 x i4> %a, <2 x i4> %b) { 816; CHECK-LABEL: @or_nxor_or_commute1( 817; CHECK-NEXT: ret <2 x i4> splat (i4 -1) 818; 819 %or = or <2 x i4> %a, %b 820 %xor = xor <2 x i4> %a, %b 821 %not = xor <2 x i4> %xor, <i4 -1, i4 -1> 822 %r = or <2 x i4> %or, %not 823 ret <2 x i4> %r 824} 825 826define i74 @or_nxor_or_commute2(i74 %a, i74 %b) { 827; CHECK-LABEL: @or_nxor_or_commute2( 828; CHECK-NEXT: ret i74 -1 829; 830 %or = or i74 %b, %a 831 %xor = xor i74 %a, %b 832 %not = xor i74 %xor, -1 833 %r = or i74 %not, %or 834 ret i74 %r 835} 836 837define <2 x i4> @or_nxor_or_commute3(<2 x i4> %a, <2 x i4> %b) { 838; CHECK-LABEL: @or_nxor_or_commute3( 839; CHECK-NEXT: ret <2 x i4> splat (i4 -1) 840; 841 %or = or <2 x i4> %b, %a 842 %xor = xor <2 x i4> %a, %b 843 %not = xor <2 x i4> %xor, <i4 -1, i4 -1> 844 %r = or <2 x i4> %or, %not 845 ret <2 x i4> %r 846} 847 848; negative test - must have common operands 849 850define i4 @or_nxor_or_wrong_val1(i4 %a, i4 %b, i4 %c) { 851; CHECK-LABEL: @or_nxor_or_wrong_val1( 852; CHECK-NEXT: [[OR:%.*]] = or i4 [[A:%.*]], [[C:%.*]] 853; CHECK-NEXT: [[XOR:%.*]] = xor i4 [[A]], [[B:%.*]] 854; CHECK-NEXT: [[NOT:%.*]] = xor i4 [[XOR]], -1 855; CHECK-NEXT: [[R:%.*]] = or i4 [[NOT]], [[OR]] 856; CHECK-NEXT: ret i4 [[R]] 857; 858 %or = or i4 %a, %c 859 %xor = xor i4 %a, %b 860 %not = xor i4 %xor, -1 861 %r = or i4 %not, %or 862 ret i4 %r 863} 864 865; negative test - must have common operands 866 867define i4 @or_nxor_or_wrong_val2(i4 %a, i4 %b, i4 %c) { 868; CHECK-LABEL: @or_nxor_or_wrong_val2( 869; CHECK-NEXT: [[OR:%.*]] = or i4 [[C:%.*]], [[B:%.*]] 870; CHECK-NEXT: [[XOR:%.*]] = xor i4 [[A:%.*]], [[B]] 871; CHECK-NEXT: [[NOT:%.*]] = xor i4 [[XOR]], -1 872; CHECK-NEXT: [[R:%.*]] = or i4 [[NOT]], [[OR]] 873; CHECK-NEXT: ret i4 [[R]] 874; 875 %or = or i4 %c, %b 876 %xor = xor i4 %a, %b 877 %not = xor i4 %xor, -1 878 %r = or i4 %not, %or 879 ret i4 %r 880} 881 882; negative test - poison in 'not' is allowed 883 884define <2 x i4> @or_nxor_or_poison_elt(<2 x i4> %a, <2 x i4> %b) { 885; CHECK-LABEL: @or_nxor_or_poison_elt( 886; CHECK-NEXT: ret <2 x i4> splat (i4 -1) 887; 888 %or = or <2 x i4> %b, %a 889 %xor = xor <2 x i4> %a, %b 890 %not = xor <2 x i4> %xor, <i4 -1, i4 poison> 891 %r = or <2 x i4> %or, %not 892 ret <2 x i4> %r 893} 894 895; (A ^ B) | (~A | B) --> -1 896 897define i4 @or_xor_not_op_or(i4 %a, i4 %b){ 898; CHECK-LABEL: @or_xor_not_op_or( 899; CHECK-NEXT: ret i4 -1 900; 901 %xor = xor i4 %a, %b 902 %nota = xor i4 %a, -1 903 %or = or i4 %nota, %b 904 %r = or i4 %xor, %or 905 ret i4 %r 906} 907 908; (A ^ B) | (B | ~A) --> -1 909 910define i71 @or_xor_not_op_or_commute1(i71 %a, i71 %b){ 911; CHECK-LABEL: @or_xor_not_op_or_commute1( 912; CHECK-NEXT: ret i71 -1 913; 914 %xor = xor i71 %a, %b 915 %nota = xor i71 %a, -1 916 %or = or i71 %b, %nota 917 %r = or i71 %xor, %or 918 ret i71 %r 919} 920 921; (B ^ A) | (~A | B) --> -1 922 923define i32 @or_xor_not_op_or_commute2(i32 %a, i32 %b){ 924; CHECK-LABEL: @or_xor_not_op_or_commute2( 925; CHECK-NEXT: ret i32 -1 926; 927 %xor = xor i32 %b, %a 928 %nota = xor i32 %a, -1 929 %or = or i32 %nota, %b 930 %r = or i32 %xor, %or 931 ret i32 %r 932} 933 934; (B ^ A) | (B | ~A) --> -1 935 936define i32 @or_xor_not_op_or_commute3(i32 %a, i32 %b){ 937; CHECK-LABEL: @or_xor_not_op_or_commute3( 938; CHECK-NEXT: ret i32 -1 939; 940 %xor = xor i32 %b, %a 941 %nota = xor i32 %a, -1 942 %or = or i32 %b, %nota 943 %r = or i32 %xor, %or 944 ret i32 %r 945} 946 947; (~A | B) | (A ^ B) --> -1 948 949define i32 @or_xor_not_op_or_commute4(i32 %a, i32 %b){ 950; CHECK-LABEL: @or_xor_not_op_or_commute4( 951; CHECK-NEXT: ret i32 -1 952; 953 %xor = xor i32 %a, %b 954 %nota = xor i32 %a, -1 955 %or = or i32 %nota, %b 956 %r = or i32 %or, %xor 957 ret i32 %r 958} 959 960; (B | ~A) | (A ^ B) --> -1 961 962define i32 @or_xor_not_op_or_commute5(i32 %a, i32 %b){ 963; CHECK-LABEL: @or_xor_not_op_or_commute5( 964; CHECK-NEXT: ret i32 -1 965; 966 %xor = xor i32 %a, %b 967 %nota = xor i32 %a, -1 968 %or = or i32 %b, %nota 969 %r = or i32 %or, %xor 970 ret i32 %r 971} 972 973; (~A | B) | (B ^ A) --> -1 974 975define i32 @or_xor_not_op_or_commute6(i32 %a, i32 %b){ 976; CHECK-LABEL: @or_xor_not_op_or_commute6( 977; CHECK-NEXT: ret i32 -1 978; 979 %xor = xor i32 %b, %a 980 %nota = xor i32 %a, -1 981 %or = or i32 %nota, %b 982 %r = or i32 %or, %xor 983 ret i32 %r 984} 985 986; (B | ~A) | (B ^ A) --> -1 987 988define i32 @or_xor_not_op_or_commute7(i32 %a, i32 %b){ 989; CHECK-LABEL: @or_xor_not_op_or_commute7( 990; CHECK-NEXT: ret i32 -1 991; 992 %xor = xor i32 %b, %a 993 %nota = xor i32 %a, -1 994 %or = or i32 %b, %nota 995 %r = or i32 %or, %xor 996 ret i32 %r 997} 998 999define <2 x i4> @or_xor_not_op_or_poison_elt(<2 x i4> %a, <2 x i4> %b) { 1000; CHECK-LABEL: @or_xor_not_op_or_poison_elt( 1001; CHECK-NEXT: ret <2 x i4> splat (i4 -1) 1002; 1003 %xor = xor <2 x i4> %a, %b 1004 %nota = xor <2 x i4> %a, <i4 -1, i4 poison> 1005 %or = or <2 x i4> %nota, %b 1006 %r = or <2 x i4> %xor, %or 1007 ret <2 x i4> %r 1008} 1009 1010; negative test 1011 1012define i16 @or_xor_not_op_or_wrong_val(i16 %a, i16 %b, i16 %c) { 1013; CHECK-LABEL: @or_xor_not_op_or_wrong_val( 1014; CHECK-NEXT: [[XOR:%.*]] = xor i16 [[A:%.*]], [[C:%.*]] 1015; CHECK-NEXT: [[NOTA:%.*]] = xor i16 [[A]], -1 1016; CHECK-NEXT: [[OR:%.*]] = or i16 [[NOTA]], [[B:%.*]] 1017; CHECK-NEXT: [[R:%.*]] = or i16 [[XOR]], [[OR]] 1018; CHECK-NEXT: ret i16 [[R]] 1019; 1020 %xor = xor i16 %a, %c 1021 %nota = xor i16 %a, -1 1022 %or = or i16 %nota, %b 1023 %r = or i16 %xor, %or 1024 ret i16 %r 1025} 1026 1027; ~(x & y) | (x ^ y) --> ~(x & y) 1028 1029define i4 @or_nand_xor(i4 %x, i4 %y) { 1030; CHECK-LABEL: @or_nand_xor( 1031; CHECK-NEXT: [[AND:%.*]] = and i4 [[X:%.*]], [[Y:%.*]] 1032; CHECK-NEXT: [[NAND:%.*]] = xor i4 [[AND]], -1 1033; CHECK-NEXT: ret i4 [[NAND]] 1034; 1035 %and = and i4 %x, %y 1036 %xor = xor i4 %x, %y 1037 %nand = xor i4 %and, -1 1038 %or = or i4 %xor, %nand 1039 ret i4 %or 1040} 1041 1042define <2 x i4> @or_nand_xor_commute1(<2 x i4> %x, <2 x i4> %y) { 1043; CHECK-LABEL: @or_nand_xor_commute1( 1044; CHECK-NEXT: [[AND:%.*]] = and <2 x i4> [[Y:%.*]], [[X:%.*]] 1045; CHECK-NEXT: [[NAND:%.*]] = xor <2 x i4> [[AND]], splat (i4 -1) 1046; CHECK-NEXT: ret <2 x i4> [[NAND]] 1047; 1048 %and = and <2 x i4> %y, %x 1049 %xor = xor <2 x i4> %x, %y 1050 %nand = xor <2 x i4> %and, <i4 -1, i4 -1> 1051 %or = or <2 x i4> %xor, %nand 1052 ret <2 x i4> %or 1053} 1054 1055define i71 @or_nand_xor_commute2(i71 %x, i71 %y) { 1056; CHECK-LABEL: @or_nand_xor_commute2( 1057; CHECK-NEXT: [[AND:%.*]] = and i71 [[X:%.*]], [[Y:%.*]] 1058; CHECK-NEXT: [[NAND:%.*]] = xor i71 [[AND]], -1 1059; CHECK-NEXT: ret i71 [[NAND]] 1060; 1061 %and = and i71 %x, %y 1062 %xor = xor i71 %x, %y 1063 %nand = xor i71 %and, -1 1064 %or = or i71 %nand, %xor 1065 ret i71 %or 1066} 1067 1068define i4 @or_nand_xor_commute3(i4 %x, i4 %y) { 1069; CHECK-LABEL: @or_nand_xor_commute3( 1070; CHECK-NEXT: [[AND:%.*]] = and i4 [[Y:%.*]], [[X:%.*]] 1071; CHECK-NEXT: [[NAND:%.*]] = xor i4 [[AND]], -1 1072; CHECK-NEXT: ret i4 [[NAND]] 1073; 1074 %and = and i4 %y, %x 1075 %xor = xor i4 %x, %y 1076 %nand = xor i4 %and, -1 1077 %or = or i4 %nand, %xor 1078 ret i4 %or 1079} 1080 1081; negative test wrong operand 1082 1083define i4 @or_nand_xor_wrong_val(i4 %x, i4 %y, i4 %z) { 1084; CHECK-LABEL: @or_nand_xor_wrong_val( 1085; CHECK-NEXT: [[AND:%.*]] = and i4 [[X:%.*]], [[Y:%.*]] 1086; CHECK-NEXT: [[XOR:%.*]] = xor i4 [[X]], [[Z:%.*]] 1087; CHECK-NEXT: [[NAND:%.*]] = xor i4 [[AND]], -1 1088; CHECK-NEXT: [[OR:%.*]] = or i4 [[XOR]], [[NAND]] 1089; CHECK-NEXT: ret i4 [[OR]] 1090; 1091 %and = and i4 %x, %y 1092 %xor = xor i4 %x, %z 1093 %nand = xor i4 %and, -1 1094 %or = or i4 %xor, %nand 1095 ret i4 %or 1096} 1097 1098; negative test - undef element in 'not' is not allowed 1099 1100define <2 x i4> @or_nand_xor_undef_elt(<2 x i4> %x, <2 x i4> %y) { 1101; CHECK-LABEL: @or_nand_xor_undef_elt( 1102; CHECK-NEXT: [[AND:%.*]] = and <2 x i4> [[Y:%.*]], [[X:%.*]] 1103; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i4> [[X]], [[Y]] 1104; CHECK-NEXT: [[NAND:%.*]] = xor <2 x i4> [[AND]], <i4 undef, i4 -1> 1105; CHECK-NEXT: [[OR:%.*]] = or <2 x i4> [[XOR]], [[NAND]] 1106; CHECK-NEXT: ret <2 x i4> [[OR]] 1107; 1108 %and = and <2 x i4> %y, %x 1109 %xor = xor <2 x i4> %x, %y 1110 %nand = xor <2 x i4> %and, <i4 undef, i4 -1> 1111 %or = or <2 x i4> %xor, %nand 1112 ret <2 x i4> %or 1113} 1114 1115; Same with poison is safe. 1116 1117define <2 x i4> @or_nand_xor_poison_elt(<2 x i4> %x, <2 x i4> %y) { 1118; CHECK-LABEL: @or_nand_xor_poison_elt( 1119; CHECK-NEXT: [[AND:%.*]] = and <2 x i4> [[Y:%.*]], [[X:%.*]] 1120; CHECK-NEXT: [[NAND:%.*]] = xor <2 x i4> [[AND]], <i4 poison, i4 -1> 1121; CHECK-NEXT: ret <2 x i4> [[NAND]] 1122; 1123 %and = and <2 x i4> %y, %x 1124 %xor = xor <2 x i4> %x, %y 1125 %nand = xor <2 x i4> %and, <i4 poison, i4 -1> 1126 %or = or <2 x i4> %xor, %nand 1127 ret <2 x i4> %or 1128} 1129 1130declare i32 @llvm.fshl.i32 (i32, i32, i32) 1131declare i32 @llvm.fshr.i32 (i32, i32, i32) 1132 1133define i32 @or_shl_fshl(i32 %x, i32 %y, i32 %s) { 1134; CHECK-LABEL: @or_shl_fshl( 1135; CHECK-NEXT: [[FUN:%.*]] = call i32 @llvm.fshl.i32(i32 [[Y:%.*]], i32 [[X:%.*]], i32 [[S:%.*]]) 1136; CHECK-NEXT: ret i32 [[FUN]] 1137; 1138 %shy = shl i32 %y, %s 1139 %fun = call i32 @llvm.fshl.i32(i32 %y, i32 %x, i32 %s) 1140 %or = or i32 %fun, %shy 1141 ret i32 %or 1142} 1143 1144define i32 @or_shl_fshl_commute(i32 %x, i32 %y, i32 %s) { 1145; CHECK-LABEL: @or_shl_fshl_commute( 1146; CHECK-NEXT: [[FUN:%.*]] = call i32 @llvm.fshl.i32(i32 [[Y:%.*]], i32 [[X:%.*]], i32 [[S:%.*]]) 1147; CHECK-NEXT: ret i32 [[FUN]] 1148; 1149 %shy = shl i32 %y, %s 1150 %fun = call i32 @llvm.fshl.i32(i32 %y, i32 %x, i32 %s) 1151 %or = or i32 %shy, %fun 1152 ret i32 %or 1153} 1154 1155; negative test - fshl operands are not commutative 1156 1157define i32 @or_shl_fshl_wrong_order(i32 %x, i32 %y, i32 %s) { 1158; CHECK-LABEL: @or_shl_fshl_wrong_order( 1159; CHECK-NEXT: [[SHY:%.*]] = shl i32 [[Y:%.*]], [[S:%.*]] 1160; CHECK-NEXT: [[FUN:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y]], i32 [[S]]) 1161; CHECK-NEXT: [[OR:%.*]] = or i32 [[FUN]], [[SHY]] 1162; CHECK-NEXT: ret i32 [[OR]] 1163; 1164 %shy = shl i32 %y, %s 1165 %fun = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %s) 1166 %or = or i32 %fun, %shy 1167 ret i32 %or 1168} 1169 1170define i32 @or_lshr_fshr(i32 %x, i32 %y, i32 %s) { 1171; CHECK-LABEL: @or_lshr_fshr( 1172; CHECK-NEXT: [[FUN:%.*]] = call i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[S:%.*]]) 1173; CHECK-NEXT: ret i32 [[FUN]] 1174; 1175 %shy = lshr i32 %y, %s 1176 %fun = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %s) 1177 %or = or i32 %fun, %shy 1178 ret i32 %or 1179} 1180 1181define i32 @or_lshr_fshr_commute(i32 %x, i32 %y, i32 %s) { 1182; CHECK-LABEL: @or_lshr_fshr_commute( 1183; CHECK-NEXT: [[FUN:%.*]] = call i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[S:%.*]]) 1184; CHECK-NEXT: ret i32 [[FUN]] 1185; 1186 %shy = lshr i32 %y, %s 1187 %fun = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %s) 1188 %or = or i32 %shy, %fun 1189 ret i32 %or 1190} 1191 1192; negative test - fshr operands are not commutative 1193 1194define i32 @or_lshr_fshr_wrong_order(i32 %x, i32 %y, i32 %s) { 1195; CHECK-LABEL: @or_lshr_fshr_wrong_order( 1196; CHECK-NEXT: [[SHY:%.*]] = lshr i32 [[Y:%.*]], [[S:%.*]] 1197; CHECK-NEXT: [[FUN:%.*]] = call i32 @llvm.fshr.i32(i32 [[Y]], i32 [[X:%.*]], i32 [[S]]) 1198; CHECK-NEXT: [[OR:%.*]] = or i32 [[FUN]], [[SHY]] 1199; CHECK-NEXT: ret i32 [[OR]] 1200; 1201 %shy = lshr i32 %y, %s 1202 %fun = call i32 @llvm.fshr.i32(i32 %y, i32 %x, i32 %s) 1203 %or = or i32 %fun, %shy 1204 ret i32 %or 1205} 1206