1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4; PR1253 5define i1 @test0(i32 %A) { 6; CHECK-LABEL: @test0( 7; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[A:%.*]], 0 8; CHECK-NEXT: ret i1 [[C]] 9; 10 %B = xor i32 %A, -2147483648 11 %C = icmp sgt i32 %B, -1 12 ret i1 %C 13} 14 15define <2 x i1> @test0vec(<2 x i32> %A) { 16; CHECK-LABEL: @test0vec( 17; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i32> [[A:%.*]], zeroinitializer 18; CHECK-NEXT: ret <2 x i1> [[C]] 19; 20 %B = xor <2 x i32> %A, <i32 -2147483648, i32 -2147483648> 21 %C = icmp sgt <2 x i32> %B, <i32 -1, i32 -1> 22 ret <2 x i1> %C 23} 24 25define i1 @test1(i32 %A) { 26; CHECK-LABEL: @test1( 27; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[A:%.*]], 0 28; CHECK-NEXT: ret i1 [[C]] 29; 30 %B = xor i32 %A, 12345 31 %C = icmp slt i32 %B, 0 32 ret i1 %C 33} 34 35; PR1014 36define i32 @test2(i32 %t1) { 37; CHECK-LABEL: @test2( 38; CHECK-NEXT: [[OVM:%.*]] = and i32 [[T1:%.*]], 32 39; CHECK-NEXT: [[OV110:%.*]] = or disjoint i32 [[OVM]], 8 40; CHECK-NEXT: ret i32 [[OV110]] 41; 42 %ovm = and i32 %t1, 32 43 %ov3 = add i32 %ovm, 145 44 %ov110 = xor i32 %ov3, 153 45 ret i32 %ov110 46} 47 48define i32 @test3(i32 %t1) { 49; CHECK-LABEL: @test3( 50; CHECK-NEXT: [[OVM:%.*]] = and i32 [[T1:%.*]], 32 51; CHECK-NEXT: [[OV110:%.*]] = or disjoint i32 [[OVM]], 8 52; CHECK-NEXT: ret i32 [[OV110]] 53; 54 %ovm = or i32 %t1, 145 55 %ov31 = and i32 %ovm, 177 56 %ov110 = xor i32 %ov31, 153 57 ret i32 %ov110 58} 59 60; defect-2 in rdar://12329730 61; (X^C1) >> C2) ^ C3 -> (X>>C2) ^ ((C1>>C2)^C3) 62; where the "X" has more than one use 63define i32 @test5(i32 %val1) { 64; CHECK-LABEL: @test5( 65; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[VAL1:%.*]], 1234 66; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[VAL1]], 8 67; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[SHR]], 5 68; CHECK-NEXT: [[ADD:%.*]] = add i32 [[XOR1]], [[XOR]] 69; CHECK-NEXT: ret i32 [[ADD]] 70; 71 %xor = xor i32 %val1, 1234 72 %shr = lshr i32 %xor, 8 73 %xor1 = xor i32 %shr, 1 74 %add = add i32 %xor1, %xor 75 ret i32 %add 76} 77 78; defect-1 in rdar://12329730 79; Simplify (X^Y) -> X or Y in the user's context if we know that 80; only bits from X or Y are demanded. 81; e.g. the "x ^ 1234" can be optimized into x in the context of "t >> 16". 82; Put in other word, t >> 16 -> x >> 16. 83; unsigned foo(unsigned x) { unsigned t = x ^ 1234; ; return (t >> 16) + t;} 84define i32 @test6(i32 %x) { 85; CHECK-LABEL: @test6( 86; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], 1234 87; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X]], 16 88; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SHR]], [[XOR]] 89; CHECK-NEXT: ret i32 [[ADD]] 90; 91 %xor = xor i32 %x, 1234 92 %shr = lshr i32 %xor, 16 93 %add = add i32 %shr, %xor 94 ret i32 %add 95} 96 97 98; (A | B) ^ (~A) -> (A | ~B) 99define i32 @test7(i32 %a, i32 %b) { 100; CHECK-LABEL: @test7( 101; CHECK-NEXT: [[B_NOT:%.*]] = xor i32 [[B:%.*]], -1 102; CHECK-NEXT: [[XOR:%.*]] = or i32 [[A:%.*]], [[B_NOT]] 103; CHECK-NEXT: ret i32 [[XOR]] 104; 105 %or = or i32 %a, %b 106 %neg = xor i32 %a, -1 107 %xor = xor i32 %or, %neg 108 ret i32 %xor 109} 110 111; (~A) ^ (A | B) -> (A | ~B) 112define i32 @test8(i32 %a, i32 %b) { 113; CHECK-LABEL: @test8( 114; CHECK-NEXT: [[B_NOT:%.*]] = xor i32 [[B:%.*]], -1 115; CHECK-NEXT: [[XOR:%.*]] = or i32 [[A:%.*]], [[B_NOT]] 116; CHECK-NEXT: ret i32 [[XOR]] 117; 118 %neg = xor i32 %a, -1 119 %or = or i32 %a, %b 120 %xor = xor i32 %neg, %or 121 ret i32 %xor 122} 123 124; (A & B) ^ (A ^ B) -> (A | B) 125define i32 @test9(i32 %b, i32 %c) { 126; CHECK-LABEL: @test9( 127; CHECK-NEXT: [[XOR2:%.*]] = or i32 [[B:%.*]], [[C:%.*]] 128; CHECK-NEXT: ret i32 [[XOR2]] 129; 130 %and = and i32 %b, %c 131 %xor = xor i32 %b, %c 132 %xor2 = xor i32 %and, %xor 133 ret i32 %xor2 134} 135 136; (A & B) ^ (B ^ A) -> (A | B) 137define i32 @test9b(i32 %b, i32 %c) { 138; CHECK-LABEL: @test9b( 139; CHECK-NEXT: [[XOR2:%.*]] = or i32 [[B:%.*]], [[C:%.*]] 140; CHECK-NEXT: ret i32 [[XOR2]] 141; 142 %and = and i32 %b, %c 143 %xor = xor i32 %c, %b 144 %xor2 = xor i32 %and, %xor 145 ret i32 %xor2 146} 147 148; (A ^ B) ^ (A & B) -> (A | B) 149define i32 @test10(i32 %b, i32 %c) { 150; CHECK-LABEL: @test10( 151; CHECK-NEXT: [[XOR2:%.*]] = or i32 [[B:%.*]], [[C:%.*]] 152; CHECK-NEXT: ret i32 [[XOR2]] 153; 154 %xor = xor i32 %b, %c 155 %and = and i32 %b, %c 156 %xor2 = xor i32 %xor, %and 157 ret i32 %xor2 158} 159 160; (A ^ B) ^ (A & B) -> (A | B) 161define i32 @test10b(i32 %b, i32 %c) { 162; CHECK-LABEL: @test10b( 163; CHECK-NEXT: [[XOR2:%.*]] = or i32 [[B:%.*]], [[C:%.*]] 164; CHECK-NEXT: ret i32 [[XOR2]] 165; 166 %xor = xor i32 %b, %c 167 %and = and i32 %c, %b 168 %xor2 = xor i32 %xor, %and 169 ret i32 %xor2 170} 171 172define i32 @test11(i32 %A, i32 %B) { 173; CHECK-LABEL: @test11( 174; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]] 175; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[B]] 176; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[TMP1]], -1 177; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]] 178; CHECK-NEXT: ret i32 [[AND]] 179; 180 %xor1 = xor i32 %B, %A 181 %not = xor i32 %A, -1 182 %xor2 = xor i32 %not, %B 183 %and = and i32 %xor1, %xor2 184 ret i32 %and 185} 186 187define i32 @test11b(i32 %A, i32 %B) { 188; CHECK-LABEL: @test11b( 189; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]] 190; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[B]] 191; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[TMP1]], -1 192; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]] 193; CHECK-NEXT: ret i32 [[AND]] 194; 195 %xor1 = xor i32 %B, %A 196 %not = xor i32 %A, -1 197 %xor2 = xor i32 %not, %B 198 %and = and i32 %xor2, %xor1 199 ret i32 %and 200} 201 202define i32 @test11c(i32 %A, i32 %B) { 203; CHECK-LABEL: @test11c( 204; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 205; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[B]] 206; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[TMP1]], -1 207; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]] 208; CHECK-NEXT: ret i32 [[AND]] 209; 210 %xor1 = xor i32 %A, %B 211 %not = xor i32 %A, -1 212 %xor2 = xor i32 %not, %B 213 %and = and i32 %xor1, %xor2 214 ret i32 %and 215} 216 217define i32 @test11d(i32 %A, i32 %B) { 218; CHECK-LABEL: @test11d( 219; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 220; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[B]] 221; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[TMP1]], -1 222; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]] 223; CHECK-NEXT: ret i32 [[AND]] 224; 225 %xor1 = xor i32 %A, %B 226 %not = xor i32 %A, -1 227 %xor2 = xor i32 %not, %B 228 %and = and i32 %xor2, %xor1 229 ret i32 %and 230} 231 232define i32 @test11e(i32 %A, i32 %B, i32 %C) { 233; CHECK-LABEL: @test11e( 234; CHECK-NEXT: [[FORCE:%.*]] = mul i32 [[B:%.*]], [[C:%.*]] 235; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[FORCE]], [[A:%.*]] 236; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[FORCE]] 237; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[TMP1]], -1 238; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]] 239; CHECK-NEXT: ret i32 [[AND]] 240; 241 %force = mul i32 %B, %C 242 %xor1 = xor i32 %force, %A 243 %not = xor i32 %A, -1 244 %xor2 = xor i32 %force, %not 245 %and = and i32 %xor1, %xor2 246 ret i32 %and 247} 248 249define i32 @test11f(i32 %A, i32 %B, i32 %C) { 250; CHECK-LABEL: @test11f( 251; CHECK-NEXT: [[FORCE:%.*]] = mul i32 [[B:%.*]], [[C:%.*]] 252; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[FORCE]], [[A:%.*]] 253; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[FORCE]] 254; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[TMP1]], -1 255; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]] 256; CHECK-NEXT: ret i32 [[AND]] 257; 258 %force = mul i32 %B, %C 259 %xor1 = xor i32 %force, %A 260 %not = xor i32 %A, -1 261 %xor2 = xor i32 %force, %not 262 %and = and i32 %xor2, %xor1 263 ret i32 %and 264} 265 266define i32 @test12(i32 %a, i32 %b) { 267; CHECK-LABEL: @test12( 268; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]] 269; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1 270; CHECK-NEXT: ret i32 [[XOR]] 271; 272 %negb = xor i32 %b, -1 273 %and = and i32 %a, %negb 274 %nega = xor i32 %a, -1 275 %xor = xor i32 %and, %nega 276 ret i32 %xor 277} 278 279define i32 @test12commuted(i32 %a, i32 %b) { 280; CHECK-LABEL: @test12commuted( 281; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]] 282; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1 283; CHECK-NEXT: ret i32 [[XOR]] 284; 285 %negb = xor i32 %b, -1 286 %and = and i32 %negb, %a 287 %nega = xor i32 %a, -1 288 %xor = xor i32 %and, %nega 289 ret i32 %xor 290} 291 292; This is a test of canonicalization via operand complexity. 293; The final xor has a binary operator and a (fake) unary operator, 294; so binary (more complex) should come first. 295 296define i32 @test13(i32 %a, i32 %b) { 297; CHECK-LABEL: @test13( 298; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]] 299; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1 300; CHECK-NEXT: ret i32 [[XOR]] 301; 302 %nega = xor i32 %a, -1 303 %negb = xor i32 %b, -1 304 %and = and i32 %a, %negb 305 %xor = xor i32 %nega, %and 306 ret i32 %xor 307} 308 309define i32 @test13commuted(i32 %a, i32 %b) { 310; CHECK-LABEL: @test13commuted( 311; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]] 312; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1 313; CHECK-NEXT: ret i32 [[XOR]] 314; 315 %nega = xor i32 %a, -1 316 %negb = xor i32 %b, -1 317 %and = and i32 %negb, %a 318 %xor = xor i32 %nega, %and 319 ret i32 %xor 320} 321 322; (A ^ C) ^ (A | B) -> ((~A) & B) ^ C 323 324define i32 @xor_or_xor_common_op_commute1(i32 %a, i32 %b, i32 %c) { 325; CHECK-LABEL: @xor_or_xor_common_op_commute1( 326; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1 327; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]] 328; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]] 329; CHECK-NEXT: ret i32 [[R]] 330; 331 %ac = xor i32 %a, %c 332 %ab = or i32 %a, %b 333 %r = xor i32 %ac, %ab 334 ret i32 %r 335} 336 337; (C ^ A) ^ (A | B) -> ((~A) & B) ^ C 338 339define i32 @xor_or_xor_common_op_commute2(i32 %a, i32 %b, i32 %c) { 340; CHECK-LABEL: @xor_or_xor_common_op_commute2( 341; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1 342; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]] 343; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]] 344; CHECK-NEXT: ret i32 [[R]] 345; 346 %ac = xor i32 %c, %a 347 %ab = or i32 %a, %b 348 %r = xor i32 %ac, %ab 349 ret i32 %r 350} 351 352; (A ^ C) ^ (B | A) -> ((~A) & B) ^ C 353 354define i32 @xor_or_xor_common_op_commute3(i32 %a, i32 %b, i32 %c) { 355; CHECK-LABEL: @xor_or_xor_common_op_commute3( 356; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1 357; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]] 358; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]] 359; CHECK-NEXT: ret i32 [[R]] 360; 361 %ac = xor i32 %a, %c 362 %ab = or i32 %b, %a 363 %r = xor i32 %ac, %ab 364 ret i32 %r 365} 366 367; (C ^ A) ^ (B | A) -> ((~A) & B) ^ C 368 369define i32 @xor_or_xor_common_op_commute4(i32 %a, i32 %b, i32 %c) { 370; CHECK-LABEL: @xor_or_xor_common_op_commute4( 371; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1 372; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]] 373; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]] 374; CHECK-NEXT: ret i32 [[R]] 375; 376 %ac = xor i32 %c, %a 377 %ab = or i32 %b, %a 378 %r = xor i32 %ac, %ab 379 ret i32 %r 380} 381 382; (A | B) ^ (A ^ C) -> ((~A) & B) ^ C 383 384define i32 @xor_or_xor_common_op_commute5(i32 %a, i32 %b, i32 %c) { 385; CHECK-LABEL: @xor_or_xor_common_op_commute5( 386; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1 387; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]] 388; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]] 389; CHECK-NEXT: ret i32 [[R]] 390; 391 %ac = xor i32 %a, %c 392 %ab = or i32 %a, %b 393 %r = xor i32 %ab, %ac 394 ret i32 %r 395} 396 397; (A | B) ^ (C ^ A) -> ((~A) & B) ^ C 398 399define i32 @xor_or_xor_common_op_commute6(i32 %a, i32 %b, i32 %c) { 400; CHECK-LABEL: @xor_or_xor_common_op_commute6( 401; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1 402; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]] 403; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]] 404; CHECK-NEXT: ret i32 [[R]] 405; 406 %ac = xor i32 %c, %a 407 %ab = or i32 %a, %b 408 %r = xor i32 %ab, %ac 409 ret i32 %r 410} 411 412; (B | A) ^ (A ^ C) -> ((~A) & B) ^ C 413 414define i32 @xor_or_xor_common_op_commute7(i32 %a, i32 %b, i32 %c) { 415; CHECK-LABEL: @xor_or_xor_common_op_commute7( 416; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1 417; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]] 418; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]] 419; CHECK-NEXT: ret i32 [[R]] 420; 421 %ac = xor i32 %a, %c 422 %ab = or i32 %b, %a 423 %r = xor i32 %ab, %ac 424 ret i32 %r 425} 426 427; (B | A) ^ (C ^ A) -> ((~A) & B) ^ C 428 429define i32 @xor_or_xor_common_op_commute8(i32 %a, i32 %b, i32 %c) { 430; CHECK-LABEL: @xor_or_xor_common_op_commute8( 431; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1 432; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]] 433; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]] 434; CHECK-NEXT: ret i32 [[R]] 435; 436 %ac = xor i32 %c, %a 437 %ab = or i32 %b, %a 438 %r = xor i32 %ab, %ac 439 ret i32 %r 440} 441 442define i32 @xor_or_xor_common_op_extra_use1(i32 %a, i32 %b, i32 %c, ptr %p) { 443; CHECK-LABEL: @xor_or_xor_common_op_extra_use1( 444; CHECK-NEXT: [[AC:%.*]] = xor i32 [[A:%.*]], [[C:%.*]] 445; CHECK-NEXT: store i32 [[AC]], ptr [[P:%.*]], align 4 446; CHECK-NEXT: [[AB:%.*]] = or i32 [[A]], [[B:%.*]] 447; CHECK-NEXT: [[R:%.*]] = xor i32 [[AC]], [[AB]] 448; CHECK-NEXT: ret i32 [[R]] 449; 450 %ac = xor i32 %a, %c 451 store i32 %ac, ptr %p 452 %ab = or i32 %a, %b 453 %r = xor i32 %ac, %ab 454 ret i32 %r 455} 456 457define i32 @xor_or_xor_common_op_extra_use2(i32 %a, i32 %b, i32 %c, ptr %p) { 458; CHECK-LABEL: @xor_or_xor_common_op_extra_use2( 459; CHECK-NEXT: [[AC:%.*]] = xor i32 [[A:%.*]], [[C:%.*]] 460; CHECK-NEXT: [[AB:%.*]] = or i32 [[A]], [[B:%.*]] 461; CHECK-NEXT: store i32 [[AB]], ptr [[P:%.*]], align 4 462; CHECK-NEXT: [[R:%.*]] = xor i32 [[AC]], [[AB]] 463; CHECK-NEXT: ret i32 [[R]] 464; 465 %ac = xor i32 %a, %c 466 %ab = or i32 %a, %b 467 store i32 %ab, ptr %p 468 %r = xor i32 %ac, %ab 469 ret i32 %r 470} 471 472define i32 @xor_or_xor_common_op_extra_use3(i32 %a, i32 %b, i32 %c, ptr %p1, ptr %p2) { 473; CHECK-LABEL: @xor_or_xor_common_op_extra_use3( 474; CHECK-NEXT: [[AC:%.*]] = xor i32 [[A:%.*]], [[C:%.*]] 475; CHECK-NEXT: store i32 [[AC]], ptr [[P1:%.*]], align 4 476; CHECK-NEXT: [[AB:%.*]] = or i32 [[A]], [[B:%.*]] 477; CHECK-NEXT: store i32 [[AB]], ptr [[P2:%.*]], align 4 478; CHECK-NEXT: [[R:%.*]] = xor i32 [[AC]], [[AB]] 479; CHECK-NEXT: ret i32 [[R]] 480; 481 %ac = xor i32 %a, %c 482 store i32 %ac, ptr %p1 483 %ab = or i32 %a, %b 484 store i32 %ab, ptr %p2 485 %r = xor i32 %ac, %ab 486 ret i32 %r 487} 488 489define i8 @test15(i8 %A, i8 %B) { 490; CHECK-LABEL: @test15( 491; CHECK-NEXT: [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]] 492; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[A]], [[B]] 493; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[TMP1]], 33 494; CHECK-NEXT: [[AND:%.*]] = and i8 [[XOR1]], [[XOR2]] 495; CHECK-NEXT: [[RES:%.*]] = mul i8 [[AND]], [[XOR2]] 496; CHECK-NEXT: ret i8 [[RES]] 497; 498 %xor1 = xor i8 %B, %A 499 %not = xor i8 %A, 33 500 %xor2 = xor i8 %not, %B 501 %and = and i8 %xor1, %xor2 502 %res = mul i8 %and, %xor2 ; to increase the use count for the xor 503 ret i8 %res 504} 505 506define i8 @test16(i8 %A, i8 %B) { 507; CHECK-LABEL: @test16( 508; CHECK-NEXT: [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]] 509; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[A]], [[B]] 510; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[TMP1]], 33 511; CHECK-NEXT: [[AND:%.*]] = and i8 [[XOR2]], [[XOR1]] 512; CHECK-NEXT: [[RES:%.*]] = mul i8 [[AND]], [[XOR2]] 513; CHECK-NEXT: ret i8 [[RES]] 514; 515 %xor1 = xor i8 %B, %A 516 %not = xor i8 %A, 33 517 %xor2 = xor i8 %not, %B 518 %and = and i8 %xor2, %xor1 519 %res = mul i8 %and, %xor2 ; to increase the use count for the xor 520 ret i8 %res 521} 522 523; Canonicalize ~((A & B) ^ (A | ?)) -> (A & B) | ~(A | ?) 524 525define i3 @not_xor_to_or_not1(i3 %a, i3 %b, i3 %c) { 526; CHECK-LABEL: @not_xor_to_or_not1( 527; CHECK-NEXT: [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]] 528; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[C]] 529; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[OR]], -1 530; CHECK-NEXT: [[NOT:%.*]] = or i3 [[AND]], [[TMP1]] 531; CHECK-NEXT: ret i3 [[NOT]] 532; 533 %or = or i3 %b, %c 534 %and = and i3 %a, %c 535 %xor = xor i3 %and, %or 536 %not = xor i3 %xor, -1 537 ret i3 %not 538} 539 540define i3 @not_xor_to_or_not2(i3 %a, i3 %b, i3 %c) { 541; CHECK-LABEL: @not_xor_to_or_not2( 542; CHECK-NEXT: [[OR:%.*]] = or i3 [[C:%.*]], [[B:%.*]] 543; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[C]] 544; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[OR]], -1 545; CHECK-NEXT: [[NOT:%.*]] = or i3 [[AND]], [[TMP1]] 546; CHECK-NEXT: ret i3 [[NOT]] 547; 548 %or = or i3 %c, %b 549 %and = and i3 %a, %c 550 %xor = xor i3 %and, %or 551 %not = xor i3 %xor, -1 552 ret i3 %not 553} 554 555define i3 @not_xor_to_or_not3(i3 %a, i3 %b, i3 %c) { 556; CHECK-LABEL: @not_xor_to_or_not3( 557; CHECK-NEXT: [[OR:%.*]] = or i3 [[C:%.*]], [[B:%.*]] 558; CHECK-NEXT: [[AND:%.*]] = and i3 [[C]], [[A:%.*]] 559; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[OR]], -1 560; CHECK-NEXT: [[NOT:%.*]] = or i3 [[AND]], [[TMP1]] 561; CHECK-NEXT: ret i3 [[NOT]] 562; 563 %or = or i3 %c, %b 564 %and = and i3 %c, %a 565 %xor = xor i3 %and, %or 566 %not = xor i3 %xor, -1 567 ret i3 %not 568} 569 570define i3 @not_xor_to_or_not4(i3 %a, i3 %b, i3 %c) { 571; CHECK-LABEL: @not_xor_to_or_not4( 572; CHECK-NEXT: [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]] 573; CHECK-NEXT: [[AND:%.*]] = and i3 [[C]], [[A:%.*]] 574; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[OR]], -1 575; CHECK-NEXT: [[NOT:%.*]] = or i3 [[AND]], [[TMP1]] 576; CHECK-NEXT: ret i3 [[NOT]] 577; 578 %or = or i3 %b, %c 579 %and = and i3 %c, %a 580 %xor = xor i3 %and, %or 581 %not = xor i3 %xor, -1 582 ret i3 %not 583} 584 585define <3 x i5> @not_xor_to_or_not_vector(<3 x i5> %a, <3 x i5> %b, <3 x i5> %c) { 586; CHECK-LABEL: @not_xor_to_or_not_vector( 587; CHECK-NEXT: [[OR:%.*]] = or <3 x i5> [[B:%.*]], [[C:%.*]] 588; CHECK-NEXT: [[AND:%.*]] = and <3 x i5> [[A:%.*]], [[C]] 589; CHECK-NEXT: [[TMP1:%.*]] = xor <3 x i5> [[OR]], splat (i5 -1) 590; CHECK-NEXT: [[NOT:%.*]] = or <3 x i5> [[AND]], [[TMP1]] 591; CHECK-NEXT: ret <3 x i5> [[NOT]] 592; 593 %or = or <3 x i5> %b, %c 594 %and = and <3 x i5> %a, %c 595 %xor = xor <3 x i5> %or, %and 596 %not = xor <3 x i5> %xor, <i5 -1, i5 -1, i5 -1> 597 ret <3 x i5> %not 598} 599 600define <3 x i5> @not_xor_to_or_not_vector_poison(<3 x i5> %a, <3 x i5> %b, <3 x i5> %c) { 601; CHECK-LABEL: @not_xor_to_or_not_vector_poison( 602; CHECK-NEXT: [[OR:%.*]] = or <3 x i5> [[B:%.*]], [[C:%.*]] 603; CHECK-NEXT: [[AND:%.*]] = and <3 x i5> [[A:%.*]], [[C]] 604; CHECK-NEXT: [[TMP1:%.*]] = xor <3 x i5> [[OR]], splat (i5 -1) 605; CHECK-NEXT: [[NOT:%.*]] = or <3 x i5> [[AND]], [[TMP1]] 606; CHECK-NEXT: ret <3 x i5> [[NOT]] 607; 608 %or = or <3 x i5> %b, %c 609 %and = and <3 x i5> %a, %c 610 %xor = xor <3 x i5> %or, %and 611 %not = xor <3 x i5> %xor, <i5 poison, i5 -1, i5 -1> 612 ret <3 x i5> %not 613} 614 615; negative test : not one use 616 617define i3 @not_xor_to_or_not_2use(i3 %a, i3 %b, i3 %c) { 618; CHECK-LABEL: @not_xor_to_or_not_2use( 619; CHECK-NEXT: [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]] 620; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[C]] 621; CHECK-NEXT: [[XOR:%.*]] = xor i3 [[AND]], [[OR]] 622; CHECK-NEXT: [[NOT:%.*]] = xor i3 [[XOR]], -1 623; CHECK-NEXT: call void @use3(i3 [[XOR]]) 624; CHECK-NEXT: ret i3 [[NOT]] 625; 626 %or = or i3 %b, %c 627 %and = and i3 %a, %c 628 %xor = xor i3 %and, %or 629 %not = xor i3 %xor, -1 630 call void @use3(i3 %xor) 631 ret i3 %not 632} 633 634; Canonicalize ~(A & B) ^ (A | ?) -> (A & B) | ~(A | ?) 635 636define i3 @xor_notand_to_or_not1(i3 %a, i3 %b, i3 %c) { 637; CHECK-LABEL: @xor_notand_to_or_not1( 638; CHECK-NEXT: [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]] 639; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[C]] 640; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[OR]], -1 641; CHECK-NEXT: [[XOR:%.*]] = or i3 [[AND]], [[TMP1]] 642; CHECK-NEXT: ret i3 [[XOR]] 643; 644 %or = or i3 %b, %c 645 %and = and i3 %a, %c 646 %not = xor i3 %and, -1 647 %xor = xor i3 %not, %or 648 ret i3 %xor 649} 650 651define i3 @xor_notand_to_or_not2(i3 %a, i3 %b, i3 %c) { 652; CHECK-LABEL: @xor_notand_to_or_not2( 653; CHECK-NEXT: [[OR:%.*]] = or i3 [[C:%.*]], [[B:%.*]] 654; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[C]] 655; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[OR]], -1 656; CHECK-NEXT: [[XOR:%.*]] = or i3 [[AND]], [[TMP1]] 657; CHECK-NEXT: ret i3 [[XOR]] 658; 659 %or = or i3 %c, %b 660 %and = and i3 %a, %c 661 %not = xor i3 %and, -1 662 %xor = xor i3 %not, %or 663 ret i3 %xor 664} 665 666define i3 @xor_notand_to_or_not3(i3 %a, i3 %b, i3 %c) { 667; CHECK-LABEL: @xor_notand_to_or_not3( 668; CHECK-NEXT: [[OR:%.*]] = or i3 [[C:%.*]], [[B:%.*]] 669; CHECK-NEXT: [[AND:%.*]] = and i3 [[C]], [[A:%.*]] 670; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[OR]], -1 671; CHECK-NEXT: [[XOR:%.*]] = or i3 [[AND]], [[TMP1]] 672; CHECK-NEXT: ret i3 [[XOR]] 673; 674 %or = or i3 %c, %b 675 %and = and i3 %c, %a 676 %not = xor i3 %and, -1 677 %xor = xor i3 %not, %or 678 ret i3 %xor 679} 680 681define i3 @xor_notand_to_or_not4(i3 %a, i3 %b, i3 %c) { 682; CHECK-LABEL: @xor_notand_to_or_not4( 683; CHECK-NEXT: [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]] 684; CHECK-NEXT: [[AND:%.*]] = and i3 [[C]], [[A:%.*]] 685; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[OR]], -1 686; CHECK-NEXT: [[XOR:%.*]] = or i3 [[AND]], [[TMP1]] 687; CHECK-NEXT: ret i3 [[XOR]] 688; 689 %or = or i3 %b, %c 690 %and = and i3 %c, %a 691 %not = xor i3 %and, -1 692 %xor = xor i3 %not, %or 693 ret i3 %xor 694} 695 696define <3 x i5> @xor_notand_to_or_not_vector(<3 x i5> %a, <3 x i5> %b, <3 x i5> %c) { 697; CHECK-LABEL: @xor_notand_to_or_not_vector( 698; CHECK-NEXT: [[OR:%.*]] = or <3 x i5> [[B:%.*]], [[C:%.*]] 699; CHECK-NEXT: [[AND:%.*]] = and <3 x i5> [[A:%.*]], [[C]] 700; CHECK-NEXT: [[TMP1:%.*]] = xor <3 x i5> [[OR]], splat (i5 -1) 701; CHECK-NEXT: [[XOR:%.*]] = or <3 x i5> [[AND]], [[TMP1]] 702; CHECK-NEXT: ret <3 x i5> [[XOR]] 703; 704 %or = or <3 x i5> %b, %c 705 %and = and <3 x i5> %a, %c 706 %not = xor <3 x i5> %and, <i5 -1, i5 -1, i5 -1> 707 %xor = xor <3 x i5> %not, %or 708 ret <3 x i5> %xor 709} 710 711define <3 x i5> @xor_notand_to_or_not_vector_poison(<3 x i5> %a, <3 x i5> %b, <3 x i5> %c) { 712; CHECK-LABEL: @xor_notand_to_or_not_vector_poison( 713; CHECK-NEXT: [[OR:%.*]] = or <3 x i5> [[B:%.*]], [[C:%.*]] 714; CHECK-NEXT: [[AND:%.*]] = and <3 x i5> [[A:%.*]], [[C]] 715; CHECK-NEXT: [[TMP1:%.*]] = xor <3 x i5> [[OR]], splat (i5 -1) 716; CHECK-NEXT: [[XOR:%.*]] = or <3 x i5> [[AND]], [[TMP1]] 717; CHECK-NEXT: ret <3 x i5> [[XOR]] 718; 719 %or = or <3 x i5> %b, %c 720 %and = and <3 x i5> %a, %c 721 %not = xor <3 x i5> %and, <i5 -1, i5 poison, i5 -1> 722 %xor = xor <3 x i5> %not, %or 723 ret <3 x i5> %xor 724} 725 726; negative test : not one use 727 728define i3 @xor_notand_to_or_not_2use(i3 %a, i3 %b, i3 %c) { 729; CHECK-LABEL: @xor_notand_to_or_not_2use( 730; CHECK-NEXT: [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]] 731; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[C]] 732; CHECK-NEXT: [[NOT:%.*]] = xor i3 [[AND]], -1 733; CHECK-NEXT: [[XOR:%.*]] = xor i3 [[OR]], [[NOT]] 734; CHECK-NEXT: call void @use3(i3 [[NOT]]) 735; CHECK-NEXT: ret i3 [[XOR]] 736; 737 %or = or i3 %b, %c 738 %and = and i3 %a, %c 739 %not = xor i3 %and, -1 740 %xor = xor i3 %not, %or 741 call void @use3(i3 %not) 742 ret i3 %xor 743} 744 745declare void @use3(i3) 746