1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=instcombine < %s | FileCheck %s 3 4declare void @use(i8) 5 6; X | ~(X | Y) --> X | ~Y 7 8define i32 @test1(i32 %x, i32 %y) { 9; CHECK-LABEL: @test1( 10; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], -1 11; CHECK-NEXT: [[Z:%.*]] = or i32 [[X:%.*]], [[TMP1]] 12; CHECK-NEXT: ret i32 [[Z]] 13; 14 %or = or i32 %x, %y 15 %not = xor i32 %or, -1 16 %z = or i32 %x, %not 17 ret i32 %z 18} 19 20; Commute (rename) the inner 'or' operands: 21; Y | ~(X | Y) --> ~X | Y 22 23define i32 @test2(i32 %x, i32 %y) { 24; CHECK-LABEL: @test2( 25; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], -1 26; CHECK-NEXT: [[Z:%.*]] = or i32 [[Y:%.*]], [[TMP1]] 27; CHECK-NEXT: ret i32 [[Z]] 28; 29 %or = or i32 %x, %y 30 %not = xor i32 %or, -1 31 %z = or i32 %y, %not 32 ret i32 %z 33} 34 35; X | ~(X ^ Y) --> X | ~Y 36 37define i32 @test3(i32 %x, i32 %y) { 38; CHECK-LABEL: @test3( 39; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], -1 40; CHECK-NEXT: [[Z:%.*]] = or i32 [[X:%.*]], [[TMP1]] 41; CHECK-NEXT: ret i32 [[Z]] 42; 43 %xor = xor i32 %x, %y 44 %not = xor i32 %xor, -1 45 %z = or i32 %x, %not 46 ret i32 %z 47} 48 49; Commute (rename) the 'xor' operands: 50; Y | ~(X ^ Y) --> ~X | Y 51 52define i32 @test4(i32 %x, i32 %y) { 53; CHECK-LABEL: @test4( 54; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], -1 55; CHECK-NEXT: [[Z:%.*]] = or i32 [[Y:%.*]], [[TMP1]] 56; CHECK-NEXT: ret i32 [[Z]] 57; 58 %xor = xor i32 %x, %y 59 %not = xor i32 %xor, -1 60 %z = or i32 %y, %not 61 ret i32 %z 62} 63 64; (X ^ Y) | ~X --> ~(X & Y) 65 66define i32 @test5(i32 %x, i32 %y) { 67; CHECK-LABEL: @test5( 68; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 69; CHECK-NEXT: [[Z:%.*]] = xor i32 [[TMP1]], -1 70; CHECK-NEXT: ret i32 [[Z]] 71; 72 %xor = xor i32 %x, %y 73 %notx = xor i32 %x, -1 74 %z = or i32 %xor, %notx 75 ret i32 %z 76} 77 78; Commute the 'or' operands 79; ~X | (X ^ Y) --> ~(X & Y) 80 81define <2 x i4> @test5_commuted(<2 x i4> %x, <2 x i4> %y) { 82; CHECK-LABEL: @test5_commuted( 83; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], [[Y:%.*]] 84; CHECK-NEXT: [[Z:%.*]] = xor <2 x i4> [[TMP1]], splat (i4 -1) 85; CHECK-NEXT: ret <2 x i4> [[Z]] 86; 87 %xor = xor <2 x i4> %x, %y 88 %notx = xor <2 x i4> %x, <i4 -1, i4 -1> 89 %z = or <2 x i4> %notx, %xor 90 ret <2 x i4> %z 91} 92 93; Commute the inner 'xor' operands 94; (Y ^ X) | ~X --> ~(Y & X) 95 96define i64 @test5_commuted_x_y(i64 %x, i64 %y) { 97; CHECK-LABEL: @test5_commuted_x_y( 98; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[Y:%.*]], [[X:%.*]] 99; CHECK-NEXT: [[Z:%.*]] = xor i64 [[TMP1]], -1 100; CHECK-NEXT: ret i64 [[Z]] 101; 102 %xor = xor i64 %y, %x 103 %notx = xor i64 %x, -1 104 %z = or i64 %xor, %notx 105 ret i64 %z 106} 107 108 109define i8 @test5_extra_use_not(i8 %x, i8 %y, ptr %dst) { 110; CHECK-LABEL: @test5_extra_use_not( 111; CHECK-NEXT: [[NOTX:%.*]] = xor i8 [[X:%.*]], -1 112; CHECK-NEXT: store i8 [[NOTX]], ptr [[DST:%.*]], align 1 113; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], [[Y:%.*]] 114; CHECK-NEXT: [[Z:%.*]] = xor i8 [[TMP1]], -1 115; CHECK-NEXT: ret i8 [[Z]] 116; 117 %xor = xor i8 %x, %y 118 %notx = xor i8 %x, -1 119 store i8 %notx, ptr %dst 120 %z = or i8 %notx, %xor 121 ret i8 %z 122} 123 124 125define i65 @test5_extra_use_xor(i65 %x, i65 %y, ptr %dst) { 126; CHECK-LABEL: @test5_extra_use_xor( 127; CHECK-NEXT: [[XOR:%.*]] = xor i65 [[X:%.*]], [[Y:%.*]] 128; CHECK-NEXT: store i65 [[XOR]], ptr [[DST:%.*]], align 4 129; CHECK-NEXT: [[TMP1:%.*]] = and i65 [[X]], [[Y]] 130; CHECK-NEXT: [[Z:%.*]] = xor i65 [[TMP1]], -1 131; CHECK-NEXT: ret i65 [[Z]] 132; 133 %xor = xor i65 %x, %y 134 store i65 %xor, ptr %dst 135 %notx = xor i65 %x, -1 136 %z = or i65 %notx, %xor 137 ret i65 %z 138} 139 140define i16 @test5_extra_use_not_xor(i16 %x, i16 %y, ptr %dst_not, ptr %dst_xor) { 141; CHECK-LABEL: @test5_extra_use_not_xor( 142; CHECK-NEXT: [[XOR:%.*]] = xor i16 [[X:%.*]], [[Y:%.*]] 143; CHECK-NEXT: store i16 [[XOR]], ptr [[DST_XOR:%.*]], align 2 144; CHECK-NEXT: [[NOTX:%.*]] = xor i16 [[X]], -1 145; CHECK-NEXT: store i16 [[NOTX]], ptr [[DST_NOT:%.*]], align 2 146; CHECK-NEXT: [[Z:%.*]] = or i16 [[XOR]], [[NOTX]] 147; CHECK-NEXT: ret i16 [[Z]] 148; 149 %xor = xor i16 %x, %y 150 store i16 %xor, ptr %dst_xor 151 %notx = xor i16 %x, -1 152 store i16 %notx, ptr %dst_not 153 %z = or i16 %notx, %xor 154 ret i16 %z 155} 156 157define i8 @xor_common_op_commute0(i8 %x, i8 %y) { 158; CHECK-LABEL: @xor_common_op_commute0( 159; CHECK-NEXT: [[Z:%.*]] = or i8 [[Y:%.*]], [[X:%.*]] 160; CHECK-NEXT: ret i8 [[Z]] 161; 162 %xor = xor i8 %x, %y 163 %z = or i8 %xor, %x 164 ret i8 %z 165} 166 167define i8 @xor_common_op_commute1(i8 %x, i8 %y) { 168; CHECK-LABEL: @xor_common_op_commute1( 169; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]] 170; CHECK-NEXT: call void @use(i8 [[XOR]]) 171; CHECK-NEXT: [[Z:%.*]] = or i8 [[Y]], [[X]] 172; CHECK-NEXT: ret i8 [[Z]] 173; 174 %xor = xor i8 %y, %x 175 call void @use(i8 %xor) 176 %z = or i8 %xor, %x 177 ret i8 %z 178} 179 180define i8 @xor_common_op_commute2(i8 %p, i8 %y) { 181; CHECK-LABEL: @xor_common_op_commute2( 182; CHECK-NEXT: [[X:%.*]] = xor i8 [[P:%.*]], 5 183; CHECK-NEXT: [[Z:%.*]] = or i8 [[X]], [[Y:%.*]] 184; CHECK-NEXT: ret i8 [[Z]] 185; 186 %x = xor i8 %p, 5 ; thwart complexity-based canonicalization 187 %xor = xor i8 %x, %y 188 %z = or i8 %x, %xor 189 ret i8 %z 190} 191 192define i8 @xor_common_op_commute3(i8 %p, i8 %q) { 193; CHECK-LABEL: @xor_common_op_commute3( 194; CHECK-NEXT: [[X:%.*]] = xor i8 [[P:%.*]], 5 195; CHECK-NEXT: [[Y:%.*]] = mul i8 [[Q:%.*]], [[Q]] 196; CHECK-NEXT: [[Z:%.*]] = or i8 [[X]], [[Y]] 197; CHECK-NEXT: ret i8 [[Z]] 198; 199 %x = xor i8 %p, 5 ; thwart complexity-based canonicalization 200 %y = mul i8 %q, %q ; thwart complexity-based canonicalization 201 %xor = xor i8 %y, %x 202 %z = or i8 %x, %xor 203 ret i8 %z 204} 205 206define i32 @test8(i32 %x, i32 %y) { 207; CHECK-LABEL: @test8( 208; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], -1 209; CHECK-NEXT: [[Z:%.*]] = or i32 [[Y:%.*]], [[TMP1]] 210; CHECK-NEXT: ret i32 [[Z]] 211; 212 %not = xor i32 %y, -1 213 %xor = xor i32 %x, %not 214 %z = or i32 %y, %xor 215 ret i32 %z 216} 217 218define i32 @test9(i32 %x, i32 %y) { 219; CHECK-LABEL: @test9( 220; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], -1 221; CHECK-NEXT: [[Z:%.*]] = or i32 [[X:%.*]], [[TMP1]] 222; CHECK-NEXT: ret i32 [[Z]] 223; 224 %not = xor i32 %x, -1 225 %xor = xor i32 %not, %y 226 %z = or i32 %x, %xor 227 ret i32 %z 228} 229 230; (A ^ B) | (~A ^ B) --> -1 231 232define i32 @test10(i32 %A, i32 %B) { 233; CHECK-LABEL: @test10( 234; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]] 235; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[B]] 236; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[TMP1]], -1 237; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[XOR2]] 238; CHECK-NEXT: ret i32 [[OR]] 239; 240 %xor1 = xor i32 %B, %A 241 %not = xor i32 %A, -1 242 %xor2 = xor i32 %not, %B 243 %or = or i32 %xor1, %xor2 244 ret i32 %or 245} 246 247define i32 @test10_commuted(i32 %A, i32 %B) { 248; CHECK-LABEL: @test10_commuted( 249; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]] 250; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[B]] 251; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[TMP1]], -1 252; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[XOR2]] 253; CHECK-NEXT: ret i32 [[OR]] 254; 255 %xor1 = xor i32 %B, %A 256 %not = xor i32 %A, -1 257 %xor2 = xor i32 %not, %B 258 %or = or i32 %xor2, %xor1 259 ret i32 %or 260} 261 262define i32 @test10_extrause(i32 %A, i32 %B, ptr %dst) { 263; CHECK-LABEL: @test10_extrause( 264; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1 265; CHECK-NEXT: store i32 [[NOT]], ptr [[DST:%.*]], align 4 266; CHECK-NEXT: ret i32 -1 267; 268 %xor1 = xor i32 %B, %A 269 %not = xor i32 %A, -1 270 store i32 %not, ptr %dst 271 %xor2 = xor i32 %not, %B 272 %or = or i32 %xor1, %xor2 273 ret i32 %or 274} 275 276define i32 @test10_commuted_extrause(i32 %A, i32 %B, ptr %dst) { 277; CHECK-LABEL: @test10_commuted_extrause( 278; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1 279; CHECK-NEXT: store i32 [[NOT]], ptr [[DST:%.*]], align 4 280; CHECK-NEXT: ret i32 -1 281; 282 %xor1 = xor i32 %B, %A 283 %not = xor i32 %A, -1 284 store i32 %not, ptr %dst 285 %xor2 = xor i32 %not, %B 286 %or = or i32 %xor2, %xor1 287 ret i32 %or 288} 289 290; (A ^ B) | ~(A ^ B) --> -1 291define i32 @test10_canonical(i32 %A, i32 %B) { 292; CHECK-LABEL: @test10_canonical( 293; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]] 294; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[A]], [[B]] 295; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[XOR2]], -1 296; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[NOT]] 297; CHECK-NEXT: ret i32 [[OR]] 298; 299 %xor1 = xor i32 %B, %A 300 %xor2 = xor i32 %A, %B 301 %not = xor i32 %xor2, -1 302 %or = or i32 %xor1, %not 303 ret i32 %or 304} 305 306; (x | y) & ((~x) ^ y) -> (x & y) 307define i32 @test11(i32 %x, i32 %y) { 308; CHECK-LABEL: @test11( 309; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 310; CHECK-NEXT: ret i32 [[AND]] 311; 312 %or = or i32 %x, %y 313 %neg = xor i32 %x, -1 314 %xor = xor i32 %neg, %y 315 %and = and i32 %or, %xor 316 ret i32 %and 317} 318 319; ((~x) ^ y) & (x | y) -> (x & y) 320define i32 @test12(i32 %x, i32 %y) { 321; CHECK-LABEL: @test12( 322; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 323; CHECK-NEXT: ret i32 [[AND]] 324; 325 %neg = xor i32 %x, -1 326 %xor = xor i32 %neg, %y 327 %or = or i32 %x, %y 328 %and = and i32 %xor, %or 329 ret i32 %and 330} 331 332define i32 @test12_commuted(i32 %x, i32 %y) { 333; CHECK-LABEL: @test12_commuted( 334; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 335; CHECK-NEXT: ret i32 [[AND]] 336; 337 %neg = xor i32 %x, -1 338 %xor = xor i32 %neg, %y 339 %or = or i32 %y, %x 340 %and = and i32 %xor, %or 341 ret i32 %and 342} 343 344; ((x | y) ^ (x ^ y)) -> (x & y) 345define i32 @test13(i32 %x, i32 %y) { 346; CHECK-LABEL: @test13( 347; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 348; CHECK-NEXT: ret i32 [[TMP1]] 349; 350 %1 = xor i32 %y, %x 351 %2 = or i32 %y, %x 352 %3 = xor i32 %2, %1 353 ret i32 %3 354} 355 356; ((x | ~y) ^ (~x | y)) -> x ^ y 357define i32 @test14(i32 %x, i32 %y) { 358; CHECK-LABEL: @test14( 359; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 360; CHECK-NEXT: ret i32 [[XOR]] 361; 362 %noty = xor i32 %y, -1 363 %notx = xor i32 %x, -1 364 %or1 = or i32 %x, %noty 365 %or2 = or i32 %notx, %y 366 %xor = xor i32 %or1, %or2 367 ret i32 %xor 368} 369 370define i32 @test14_commuted(i32 %x, i32 %y) { 371; CHECK-LABEL: @test14_commuted( 372; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 373; CHECK-NEXT: ret i32 [[XOR]] 374; 375 %noty = xor i32 %y, -1 376 %notx = xor i32 %x, -1 377 %or1 = or i32 %noty, %x 378 %or2 = or i32 %notx, %y 379 %xor = xor i32 %or1, %or2 380 ret i32 %xor 381} 382 383; ((x & ~y) ^ (~x & y)) -> x ^ y 384define i32 @test15(i32 %x, i32 %y) { 385; CHECK-LABEL: @test15( 386; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 387; CHECK-NEXT: ret i32 [[XOR]] 388; 389 %noty = xor i32 %y, -1 390 %notx = xor i32 %x, -1 391 %and1 = and i32 %x, %noty 392 %and2 = and i32 %notx, %y 393 %xor = xor i32 %and1, %and2 394 ret i32 %xor 395} 396 397define i32 @test15_commuted(i32 %x, i32 %y) { 398; CHECK-LABEL: @test15_commuted( 399; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 400; CHECK-NEXT: ret i32 [[XOR]] 401; 402 %noty = xor i32 %y, -1 403 %notx = xor i32 %x, -1 404 %and1 = and i32 %noty, %x 405 %and2 = and i32 %notx, %y 406 %xor = xor i32 %and1, %and2 407 ret i32 %xor 408} 409 410; ((a ^ b) & C1) | (b & C2) -> (a & C1) ^ b iff C1 == ~C2 411 412define i32 @or_and_xor_not_constant_commute0(i32 %a, i32 %b) { 413; CHECK-LABEL: @or_and_xor_not_constant_commute0( 414; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], 1 415; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], [[B:%.*]] 416; CHECK-NEXT: ret i32 [[XOR]] 417; 418 %or = xor i32 %a, %b 419 %and1 = and i32 %or, 1 420 %and2 = and i32 %b, -2 421 %xor = or i32 %and1, %and2 422 ret i32 %xor 423} 424 425define i9 @or_and_xor_not_constant_commute1(i9 %a, i9 %b) { 426; CHECK-LABEL: @or_and_xor_not_constant_commute1( 427; CHECK-NEXT: [[TMP1:%.*]] = and i9 [[A:%.*]], 42 428; CHECK-NEXT: [[XOR:%.*]] = xor i9 [[TMP1]], [[B:%.*]] 429; CHECK-NEXT: ret i9 [[XOR]] 430; 431 %or = xor i9 %b, %a 432 %and1 = and i9 %or, 42 433 %and2 = and i9 %b, -43 434 %xor = or i9 %and1, %and2 435 ret i9 %xor 436} 437 438define <2 x i9> @or_and_xor_not_constant_commute2_splat(<2 x i9> %a, <2 x i9> %b) { 439; CHECK-LABEL: @or_and_xor_not_constant_commute2_splat( 440; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i9> [[A:%.*]], splat (i9 42) 441; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i9> [[TMP1]], [[B:%.*]] 442; CHECK-NEXT: ret <2 x i9> [[XOR]] 443; 444 %or = xor <2 x i9> %b, %a 445 %and1 = and <2 x i9> %or, <i9 42, i9 42> 446 %and2 = and <2 x i9> %b, <i9 -43, i9 -43> 447 %xor = or <2 x i9> %and2, %and1 448 ret <2 x i9> %xor 449} 450 451define <2 x i9> @or_and_xor_not_constant_commute3_splat(<2 x i9> %a, <2 x i9> %b) { 452; CHECK-LABEL: @or_and_xor_not_constant_commute3_splat( 453; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i9> [[A:%.*]], splat (i9 42) 454; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i9> [[TMP1]], [[B:%.*]] 455; CHECK-NEXT: ret <2 x i9> [[XOR]] 456; 457 %or = xor <2 x i9> %a, %b 458 %and1 = and <2 x i9> %or, <i9 42, i9 42> 459 %and2 = and <2 x i9> %b, <i9 -43, i9 -43> 460 %xor = or <2 x i9> %and2, %and1 461 ret <2 x i9> %xor 462} 463 464define i8 @not_or(i8 %x) { 465; CHECK-LABEL: @not_or( 466; CHECK-NEXT: [[NOTX:%.*]] = xor i8 [[X:%.*]], -1 467; CHECK-NEXT: [[OR:%.*]] = or i8 [[NOTX]], 7 468; CHECK-NEXT: ret i8 [[OR]] 469; 470 %notx = xor i8 %x, -1 471 %or = or i8 %notx, 7 472 ret i8 %or 473} 474 475define i8 @not_or_xor(i8 %x) { 476; CHECK-LABEL: @not_or_xor( 477; CHECK-NEXT: [[NOTX:%.*]] = and i8 [[X:%.*]], -8 478; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[NOTX]], -13 479; CHECK-NEXT: ret i8 [[XOR]] 480; 481 %notx = xor i8 %x, -1 482 %or = or i8 %notx, 7 483 %xor = xor i8 %or, 12 484 ret i8 %xor 485} 486 487define i8 @xor_or(i8 %x) { 488; CHECK-LABEL: @xor_or( 489; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -8 490; CHECK-NEXT: [[OR:%.*]] = xor i8 [[TMP1]], 39 491; CHECK-NEXT: ret i8 [[OR]] 492; 493 %xor = xor i8 %x, 32 494 %or = or i8 %xor, 7 495 ret i8 %or 496} 497 498define i8 @xor_or2(i8 %x) { 499; CHECK-LABEL: @xor_or2( 500; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -8 501; CHECK-NEXT: [[OR:%.*]] = xor i8 [[TMP1]], 39 502; CHECK-NEXT: ret i8 [[OR]] 503; 504 %xor = xor i8 %x, 33 505 %or = or i8 %xor, 7 506 ret i8 %or 507} 508 509define i8 @xor_or_xor(i8 %x) { 510; CHECK-LABEL: @xor_or_xor( 511; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -8 512; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[TMP1]], 43 513; CHECK-NEXT: ret i8 [[XOR2]] 514; 515 %xor1 = xor i8 %x, 33 516 %or = or i8 %xor1, 7 517 %xor2 = xor i8 %or, 12 518 ret i8 %xor2 519} 520 521define i8 @or_xor_or(i8 %x) { 522; CHECK-LABEL: @or_xor_or( 523; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -40 524; CHECK-NEXT: [[OR2:%.*]] = xor i8 [[TMP1]], 47 525; CHECK-NEXT: ret i8 [[OR2]] 526; 527 %or1 = or i8 %x, 33 528 %xor = xor i8 %or1, 12 529 %or2 = or i8 %xor, 7 530 ret i8 %or2 531} 532 533define i8 @test17(i8 %A, i8 %B) { 534; CHECK-LABEL: @test17( 535; CHECK-NEXT: [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]] 536; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[A]], [[B]] 537; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[TMP1]], 33 538; CHECK-NEXT: [[OR:%.*]] = or i8 [[XOR1]], [[XOR2]] 539; CHECK-NEXT: [[RES:%.*]] = mul i8 [[OR]], [[XOR2]] 540; CHECK-NEXT: ret i8 [[RES]] 541; 542 %xor1 = xor i8 %B, %A 543 %not = xor i8 %A, 33 544 %xor2 = xor i8 %not, %B 545 %or = or i8 %xor1, %xor2 546 %res = mul i8 %or, %xor2 ; to increase the use count for the xor 547 ret i8 %res 548} 549 550define i8 @test18(i8 %A, i8 %B) { 551; CHECK-LABEL: @test18( 552; CHECK-NEXT: [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]] 553; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[A]], [[B]] 554; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[TMP1]], 33 555; CHECK-NEXT: [[OR:%.*]] = or i8 [[XOR2]], [[XOR1]] 556; CHECK-NEXT: [[RES:%.*]] = mul i8 [[OR]], [[XOR2]] 557; CHECK-NEXT: ret i8 [[RES]] 558; 559 %xor1 = xor i8 %B, %A 560 %not = xor i8 %A, 33 561 %xor2 = xor i8 %not, %B 562 %or = or i8 %xor2, %xor1 563 %res = mul i8 %or, %xor2 ; to increase the use count for the xor 564 ret i8 %res 565} 566 567; ((x | y) ^ (~x | ~y)) -> ~(x ^ y) 568define i32 @test19(i32 %x, i32 %y) { 569; CHECK-LABEL: @test19( 570; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 571; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1 572; CHECK-NEXT: ret i32 [[XOR]] 573; 574 %noty = xor i32 %y, -1 575 %notx = xor i32 %x, -1 576 %or1 = or i32 %x, %y 577 %or2 = or i32 %notx, %noty 578 %xor = xor i32 %or1, %or2 579 ret i32 %xor 580} 581 582; ((x | y) ^ (~y | ~x)) -> ~(x ^ y) 583define i32 @test20(i32 %x, i32 %y) { 584; CHECK-LABEL: @test20( 585; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 586; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1 587; CHECK-NEXT: ret i32 [[XOR]] 588; 589 %noty = xor i32 %y, -1 590 %notx = xor i32 %x, -1 591 %or1 = or i32 %x, %y 592 %or2 = or i32 %noty, %notx 593 %xor = xor i32 %or1, %or2 594 ret i32 %xor 595} 596 597; ((~x | ~y) ^ (x | y)) -> ~(x ^ y) 598define i32 @test21(i32 %x, i32 %y) { 599; CHECK-LABEL: @test21( 600; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 601; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1 602; CHECK-NEXT: ret i32 [[XOR]] 603; 604 %noty = xor i32 %y, -1 605 %notx = xor i32 %x, -1 606 %or1 = or i32 %notx, %noty 607 %or2 = or i32 %x, %y 608 %xor = xor i32 %or1, %or2 609 ret i32 %xor 610} 611 612; ((~x | ~y) ^ (y | x)) -> ~(x ^ y) 613define i32 @test22(i32 %x, i32 %y) { 614; CHECK-LABEL: @test22( 615; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]] 616; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1 617; CHECK-NEXT: ret i32 [[XOR]] 618; 619 %noty = xor i32 %y, -1 620 %notx = xor i32 %x, -1 621 %or1 = or i32 %notx, %noty 622 %or2 = or i32 %y, %x 623 %xor = xor i32 %or1, %or2 624 ret i32 %xor 625} 626 627; (X ^ C1) | C2 --> (X | C2) ^ (C1&~C2) 628define i8 @test23(i8 %A) { 629; CHECK-LABEL: @test23( 630; CHECK-NEXT: ret i8 -1 631; 632 %B = or i8 %A, -2 633 %C = xor i8 %B, 13 634 %D = or i8 %C, 1 635 %E = xor i8 %D, 12 636 ret i8 %E 637} 638 639define i8 @test23v(<2 x i8> %A) { 640; CHECK-LABEL: @test23v( 641; CHECK-NEXT: ret i8 -1 642; 643 %B = or <2 x i8> %A, <i8 -2, i8 0> 644 %CV = xor <2 x i8> %B, <i8 13, i8 13> 645 %C = extractelement <2 x i8> %CV, i32 0 646 %D = or i8 %C, 1 647 %E = xor i8 %D, 12 648 ret i8 %E 649} 650 651; ~(a | b) | (~a & b); 652define i32 @PR45977_f1(i32 %a, i32 %b) { 653; CHECK-LABEL: @PR45977_f1( 654; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1 655; CHECK-NEXT: ret i32 [[NOT]] 656; 657 %not = xor i32 %a, -1 658 %andnot = and i32 %not, %b 659 %or = or i32 %a, %b 660 %notor = xor i32 %or, -1 661 %res = or i32 %notor, %andnot 662 ret i32 %res 663} 664 665; (a | b) ^ (a | ~b) 666define i32 @PR45977_f2(i32 %a, i32 %b) { 667; CHECK-LABEL: @PR45977_f2( 668; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1 669; CHECK-NEXT: ret i32 [[TMP1]] 670; 671 %or = or i32 %a, %b 672 %not = xor i32 %b, -1 673 %ornot = or i32 %a, %not 674 %res = xor i32 %or, %ornot 675 ret i32 %res 676} 677 678define i8 @or_xor_common_op_commute0(i8 %x, i8 %y, i8 %z) { 679; CHECK-LABEL: @or_xor_common_op_commute0( 680; CHECK-NEXT: [[OR:%.*]] = or i8 [[X:%.*]], [[Y:%.*]] 681; CHECK-NEXT: [[R:%.*]] = or i8 [[OR]], [[Z:%.*]] 682; CHECK-NEXT: ret i8 [[R]] 683; 684 %or = or i8 %x, %y 685 %xor = xor i8 %x, %z 686 %r = or i8 %or, %xor 687 ret i8 %r 688} 689 690define i8 @or_xor_common_op_commute1(i8 %x, i8 %y, i8 %z) { 691; CHECK-LABEL: @or_xor_common_op_commute1( 692; CHECK-NEXT: [[OR:%.*]] = or i8 [[Y:%.*]], [[X:%.*]] 693; CHECK-NEXT: call void @use(i8 [[OR]]) 694; CHECK-NEXT: [[R:%.*]] = or i8 [[OR]], [[Z:%.*]] 695; CHECK-NEXT: ret i8 [[R]] 696; 697 %or = or i8 %y, %x 698 call void @use(i8 %or) 699 %xor = xor i8 %x, %z 700 %r = or i8 %or, %xor 701 ret i8 %r 702} 703 704define i8 @or_xor_common_op_commute2(i8 %x, i8 %y, i8 %z) { 705; CHECK-LABEL: @or_xor_common_op_commute2( 706; CHECK-NEXT: [[OR:%.*]] = or i8 [[X:%.*]], [[Y:%.*]] 707; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[Z:%.*]], [[X]] 708; CHECK-NEXT: call void @use(i8 [[XOR]]) 709; CHECK-NEXT: [[R:%.*]] = or i8 [[OR]], [[Z]] 710; CHECK-NEXT: ret i8 [[R]] 711; 712 %or = or i8 %x, %y 713 %xor = xor i8 %z, %x 714 call void @use(i8 %xor) 715 %r = or i8 %or, %xor 716 ret i8 %r 717} 718 719define i8 @or_xor_common_op_commute3(i8 %x, i8 %y, i8 %z) { 720; CHECK-LABEL: @or_xor_common_op_commute3( 721; CHECK-NEXT: [[OR:%.*]] = or i8 [[Y:%.*]], [[X:%.*]] 722; CHECK-NEXT: call void @use(i8 [[OR]]) 723; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[Z:%.*]], [[X]] 724; CHECK-NEXT: call void @use(i8 [[XOR]]) 725; CHECK-NEXT: [[R:%.*]] = or i8 [[OR]], [[Z]] 726; CHECK-NEXT: ret i8 [[R]] 727; 728 %or = or i8 %y, %x 729 call void @use(i8 %or) 730 %xor = xor i8 %z, %x 731 call void @use(i8 %xor) 732 %r = or i8 %or, %xor 733 ret i8 %r 734} 735 736define <2 x i8> @or_xor_common_op_commute4(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 737; CHECK-LABEL: @or_xor_common_op_commute4( 738; CHECK-NEXT: [[OR:%.*]] = or <2 x i8> [[X:%.*]], [[Y:%.*]] 739; CHECK-NEXT: [[R:%.*]] = or <2 x i8> [[OR]], [[Z:%.*]] 740; CHECK-NEXT: ret <2 x i8> [[R]] 741; 742 %or = or <2 x i8> %x, %y 743 %xor = xor <2 x i8> %x, %z 744 %r = or <2 x i8> %xor, %or 745 ret <2 x i8> %r 746} 747 748define i8 @or_xor_common_op_commute5(i8 %x, i8 %y, i8 %z) { 749; CHECK-LABEL: @or_xor_common_op_commute5( 750; CHECK-NEXT: [[OR:%.*]] = or i8 [[Y:%.*]], [[X:%.*]] 751; CHECK-NEXT: [[R:%.*]] = or i8 [[OR]], [[Z:%.*]] 752; CHECK-NEXT: ret i8 [[R]] 753; 754 %or = or i8 %y, %x 755 %xor = xor i8 %x, %z 756 %r = or i8 %xor, %or 757 ret i8 %r 758} 759 760define i8 @or_xor_common_op_commute6(i8 %x, i8 %y, i8 %z) { 761; CHECK-LABEL: @or_xor_common_op_commute6( 762; CHECK-NEXT: [[OR:%.*]] = or i8 [[X:%.*]], [[Y:%.*]] 763; CHECK-NEXT: [[R:%.*]] = or i8 [[OR]], [[Z:%.*]] 764; CHECK-NEXT: ret i8 [[R]] 765; 766 %or = or i8 %x, %y 767 %xor = xor i8 %z, %x 768 %r = or i8 %xor, %or 769 ret i8 %r 770} 771 772define i8 @or_xor_common_op_commute7(i8 %x, i8 %y, i8 %z) { 773; CHECK-LABEL: @or_xor_common_op_commute7( 774; CHECK-NEXT: [[OR:%.*]] = or i8 [[Y:%.*]], [[X:%.*]] 775; CHECK-NEXT: [[R:%.*]] = or i8 [[OR]], [[Z:%.*]] 776; CHECK-NEXT: ret i8 [[R]] 777; 778 %or = or i8 %y, %x 779 %xor = xor i8 %z, %x 780 %r = or i8 %xor, %or 781 ret i8 %r 782} 783 784; negative test - need common operand 785 786define i8 @or_xor_notcommon_op(i8 %x, i8 %y, i8 %z, i8 %q) { 787; CHECK-LABEL: @or_xor_notcommon_op( 788; CHECK-NEXT: [[OR:%.*]] = or i8 [[X:%.*]], [[Y:%.*]] 789; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[Q:%.*]], [[Z:%.*]] 790; CHECK-NEXT: [[R:%.*]] = or i8 [[OR]], [[XOR]] 791; CHECK-NEXT: ret i8 [[R]] 792; 793 %or = or i8 %x, %y 794 %xor = xor i8 %q, %z 795 %r = or i8 %or, %xor 796 ret i8 %r 797} 798 799define i4 @or_not_xor_common_op_commute0(i4 %x, i4 %y, i4 %z) { 800; CHECK-LABEL: @or_not_xor_common_op_commute0( 801; CHECK-NEXT: [[TMP1:%.*]] = and i4 [[X:%.*]], [[Y:%.*]] 802; CHECK-NEXT: [[NAND:%.*]] = xor i4 [[TMP1]], -1 803; CHECK-NEXT: [[O2:%.*]] = or i4 [[Z:%.*]], [[NAND]] 804; CHECK-NEXT: ret i4 [[O2]] 805; 806 %notx = xor i4 %x, -1 807 %xor = xor i4 %x, %y 808 %o1 = or i4 %notx, %z 809 %o2 = or i4 %o1, %xor 810 ret i4 %o2 811} 812 813define i8 @or_not_xor_common_op_commute1(i8 %x, i8 %y, i8 %z) { 814; CHECK-LABEL: @or_not_xor_common_op_commute1( 815; CHECK-NEXT: [[NOTX:%.*]] = xor i8 [[X:%.*]], -1 816; CHECK-NEXT: call void @use(i8 [[NOTX]]) 817; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], [[Y:%.*]] 818; CHECK-NEXT: [[NAND:%.*]] = xor i8 [[TMP1]], -1 819; CHECK-NEXT: [[O2:%.*]] = or i8 [[Z:%.*]], [[NAND]] 820; CHECK-NEXT: ret i8 [[O2]] 821; 822 %notx = xor i8 %x, -1 823 call void @use(i8 %notx) 824 %xor = xor i8 %x, %y 825 %o1 = or i8 %notx, %z 826 %o2 = or i8 %xor, %o1 827 ret i8 %o2 828} 829 830define i8 @or_not_xor_common_op_commute2(i8 %x, i8 %y, i8 %p) { 831; CHECK-LABEL: @or_not_xor_common_op_commute2( 832; CHECK-NEXT: [[Z:%.*]] = sub i8 0, [[P:%.*]] 833; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], [[Y:%.*]] 834; CHECK-NEXT: [[NAND:%.*]] = xor i8 [[TMP1]], -1 835; CHECK-NEXT: [[O2:%.*]] = or i8 [[NAND]], [[Z]] 836; CHECK-NEXT: ret i8 [[O2]] 837; 838 %z = sub i8 0, %p ; thwart complexity-based canonicalizaion 839 %notx = xor i8 %x, -1 840 %xor = xor i8 %x, %y 841 %o1 = or i8 %z, %notx 842 %o2 = or i8 %xor, %o1 843 ret i8 %o2 844} 845 846define i8 @or_not_xor_common_op_commute3(i8 %x, i8 %y, i8 %p) { 847; CHECK-LABEL: @or_not_xor_common_op_commute3( 848; CHECK-NEXT: [[Z:%.*]] = sub i8 0, [[P:%.*]] 849; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], [[Y:%.*]] 850; CHECK-NEXT: [[NAND:%.*]] = xor i8 [[TMP1]], -1 851; CHECK-NEXT: [[O2:%.*]] = or i8 [[NAND]], [[Z]] 852; CHECK-NEXT: ret i8 [[O2]] 853; 854 %z = sub i8 0, %p ; thwart complexity-based canonicalizaion 855 %notx = xor i8 %x, -1 856 %xor = xor i8 %x, %y 857 %o1 = or i8 %z, %notx 858 %o2 = or i8 %o1, %xor 859 ret i8 %o2 860} 861 862define <2 x i4> @or_not_xor_common_op_commute4(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) { 863; CHECK-LABEL: @or_not_xor_common_op_commute4( 864; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[Y:%.*]], [[X:%.*]] 865; CHECK-NEXT: [[NAND:%.*]] = xor <2 x i4> [[TMP1]], splat (i4 -1) 866; CHECK-NEXT: [[O2:%.*]] = or <2 x i4> [[Z:%.*]], [[NAND]] 867; CHECK-NEXT: ret <2 x i4> [[O2]] 868; 869 %notx = xor <2 x i4> %x, <i4 -1, i4 -1> 870 %xor = xor <2 x i4> %y, %x 871 %o1 = or <2 x i4> %notx, %z 872 %o2 = or <2 x i4> %o1, %xor 873 ret <2 x i4> %o2 874} 875 876define i8 @or_not_xor_common_op_commute5(i8 %x, i8 %y, i8 %z) { 877; CHECK-LABEL: @or_not_xor_common_op_commute5( 878; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y:%.*]], [[X:%.*]] 879; CHECK-NEXT: [[NAND:%.*]] = xor i8 [[TMP1]], -1 880; CHECK-NEXT: [[O2:%.*]] = or i8 [[Z:%.*]], [[NAND]] 881; CHECK-NEXT: ret i8 [[O2]] 882; 883 %notx = xor i8 %x, -1 884 %xor = xor i8 %y, %x 885 %o1 = or i8 %notx, %z 886 %o2 = or i8 %xor, %o1 887 ret i8 %o2 888} 889 890define i8 @or_not_xor_common_op_commute6(i8 %x, i8 %y, i8 %p) { 891; CHECK-LABEL: @or_not_xor_common_op_commute6( 892; CHECK-NEXT: [[Z:%.*]] = sub i8 0, [[P:%.*]] 893; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y:%.*]], [[X:%.*]] 894; CHECK-NEXT: [[NAND:%.*]] = xor i8 [[TMP1]], -1 895; CHECK-NEXT: [[O2:%.*]] = or i8 [[NAND]], [[Z]] 896; CHECK-NEXT: ret i8 [[O2]] 897; 898 %z = sub i8 0, %p ; thwart complexity-based canonicalizaion 899 %notx = xor i8 %x, -1 900 %xor = xor i8 %y, %x 901 %o1 = or i8 %z, %notx 902 %o2 = or i8 %xor, %o1 903 ret i8 %o2 904} 905 906define i8 @or_not_xor_common_op_commute7(i8 %x, i8 %y, i8 %p) { 907; CHECK-LABEL: @or_not_xor_common_op_commute7( 908; CHECK-NEXT: [[Z:%.*]] = sub i8 0, [[P:%.*]] 909; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y:%.*]], [[X:%.*]] 910; CHECK-NEXT: [[NAND:%.*]] = xor i8 [[TMP1]], -1 911; CHECK-NEXT: [[O2:%.*]] = or i8 [[NAND]], [[Z]] 912; CHECK-NEXT: ret i8 [[O2]] 913; 914 %z = sub i8 0, %p ; thwart complexity-based canonicalizaion 915 %notx = xor i8 %x, -1 916 %xor = xor i8 %y, %x 917 %o1 = or i8 %z, %notx 918 %o2 = or i8 %o1, %xor 919 ret i8 %o2 920} 921 922; negative test - too many uses for basic check (but this could be enhanced) 923 924define i8 @or_not_xor_common_op_use1(i8 %x, i8 %y, i8 %z) { 925; CHECK-LABEL: @or_not_xor_common_op_use1( 926; CHECK-NEXT: [[NOTX:%.*]] = xor i8 [[X:%.*]], -1 927; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X]], [[Y:%.*]] 928; CHECK-NEXT: call void @use(i8 [[XOR]]) 929; CHECK-NEXT: [[O1:%.*]] = or i8 [[Z:%.*]], [[NOTX]] 930; CHECK-NEXT: [[O2:%.*]] = or i8 [[XOR]], [[O1]] 931; CHECK-NEXT: ret i8 [[O2]] 932; 933 %notx = xor i8 %x, -1 934 %xor = xor i8 %x, %y 935 call void @use(i8 %xor) 936 %o1 = or i8 %notx, %z 937 %o2 = or i8 %xor, %o1 938 ret i8 %o2 939} 940 941; negative test - too many uses 942 943define i8 @or_not_xor_common_op_use2(i8 %x, i8 %y, i8 %z) { 944; CHECK-LABEL: @or_not_xor_common_op_use2( 945; CHECK-NEXT: [[NOTX:%.*]] = xor i8 [[X:%.*]], -1 946; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X]], [[Y:%.*]] 947; CHECK-NEXT: [[O1:%.*]] = or i8 [[Z:%.*]], [[NOTX]] 948; CHECK-NEXT: call void @use(i8 [[O1]]) 949; CHECK-NEXT: [[O2:%.*]] = or i8 [[XOR]], [[O1]] 950; CHECK-NEXT: ret i8 [[O2]] 951; 952 %notx = xor i8 %x, -1 953 %xor = xor i8 %x, %y 954 %o1 = or i8 %notx, %z 955 call void @use(i8 %o1) 956 %o2 = or i8 %xor, %o1 957 ret i8 %o2 958} 959 960define i4 @or_nand_xor_common_op_commute0(i4 %x, i4 %y, i4 %z) { 961; CHECK-LABEL: @or_nand_xor_common_op_commute0( 962; CHECK-NEXT: [[AND:%.*]] = and i4 [[X:%.*]], [[Z:%.*]] 963; CHECK-NEXT: [[TMP1:%.*]] = and i4 [[AND]], [[Y:%.*]] 964; CHECK-NEXT: [[R:%.*]] = xor i4 [[TMP1]], -1 965; CHECK-NEXT: ret i4 [[R]] 966; 967 %and = and i4 %x, %z 968 %nand = xor i4 %and, -1 969 %xor = xor i4 %x, %y 970 %r = or i4 %nand, %xor 971 ret i4 %r 972} 973 974define <2 x i4> @or_nand_xor_common_op_commute1(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) { 975; CHECK-LABEL: @or_nand_xor_common_op_commute1( 976; CHECK-NEXT: [[AND:%.*]] = and <2 x i4> [[Z:%.*]], [[X:%.*]] 977; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[AND]], [[Y:%.*]] 978; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], splat (i4 -1) 979; CHECK-NEXT: ret <2 x i4> [[R]] 980; 981 %and = and <2 x i4> %z, %x 982 %nand = xor <2 x i4> %and, <i4 poison, i4 -1> 983 %xor = xor <2 x i4> %x, %y 984 %r = or <2 x i4> %xor, %nand 985 ret <2 x i4> %r 986} 987 988define i8 @or_nand_xor_common_op_commute2(i8 %x, i8 %y, i8 %z) { 989; CHECK-LABEL: @or_nand_xor_common_op_commute2( 990; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Z:%.*]] 991; CHECK-NEXT: call void @use(i8 [[AND]]) 992; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[AND]], [[Y:%.*]] 993; CHECK-NEXT: [[R:%.*]] = xor i8 [[TMP1]], -1 994; CHECK-NEXT: ret i8 [[R]] 995; 996 %and = and i8 %x, %z 997 call void @use(i8 %and) 998 %nand = xor i8 %and, -1 999 %xor = xor i8 %y, %x 1000 %r = or i8 %nand, %xor 1001 ret i8 %r 1002} 1003 1004define i8 @or_nand_xor_common_op_commute3(i8 %x, i8 %y, i8 %z) { 1005; CHECK-LABEL: @or_nand_xor_common_op_commute3( 1006; CHECK-NEXT: [[AND:%.*]] = and i8 [[Z:%.*]], [[X:%.*]] 1007; CHECK-NEXT: [[NAND:%.*]] = xor i8 [[AND]], -1 1008; CHECK-NEXT: call void @use(i8 [[NAND]]) 1009; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[AND]], [[Y:%.*]] 1010; CHECK-NEXT: [[R:%.*]] = xor i8 [[TMP1]], -1 1011; CHECK-NEXT: ret i8 [[R]] 1012; 1013 %and = and i8 %z, %x 1014 %nand = xor i8 %and, -1 1015 call void @use(i8 %nand) 1016 %xor = xor i8 %y, %x 1017 %r = or i8 %xor, %nand 1018 ret i8 %r 1019} 1020 1021define i8 @or_nand_xor_common_op_commute3_use2(i8 %x, i8 %y, i8 %z) { 1022; CHECK-LABEL: @or_nand_xor_common_op_commute3_use2( 1023; CHECK-NEXT: [[AND:%.*]] = and i8 [[Z:%.*]], [[X:%.*]] 1024; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[Y:%.*]], [[X]] 1025; CHECK-NEXT: call void @use(i8 [[XOR]]) 1026; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[AND]], [[Y]] 1027; CHECK-NEXT: [[R:%.*]] = xor i8 [[TMP1]], -1 1028; CHECK-NEXT: ret i8 [[R]] 1029; 1030 %and = and i8 %z, %x 1031 %nand = xor i8 %and, -1 1032 %xor = xor i8 %y, %x 1033 call void @use(i8 %xor) 1034 %r = or i8 %xor, %nand 1035 ret i8 %r 1036} 1037 1038; negative test - too many extra uses 1039 1040define i8 @or_nand_xor_common_op_commute3_use3(i8 %x, i8 %y, i8 %z) { 1041; CHECK-LABEL: @or_nand_xor_common_op_commute3_use3( 1042; CHECK-NEXT: [[AND:%.*]] = and i8 [[Z:%.*]], [[X:%.*]] 1043; CHECK-NEXT: [[NAND:%.*]] = xor i8 [[AND]], -1 1044; CHECK-NEXT: call void @use(i8 [[NAND]]) 1045; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[Y:%.*]], [[X]] 1046; CHECK-NEXT: call void @use(i8 [[XOR]]) 1047; CHECK-NEXT: [[R:%.*]] = or i8 [[XOR]], [[NAND]] 1048; CHECK-NEXT: ret i8 [[R]] 1049; 1050 %and = and i8 %z, %x 1051 %nand = xor i8 %and, -1 1052 call void @use(i8 %nand) 1053 %xor = xor i8 %y, %x 1054 call void @use(i8 %xor) 1055 %r = or i8 %xor, %nand 1056 ret i8 %r 1057} 1058 1059; (a ^ 4) & (a ^ ~4) -> -1 1060define i32 @PR75692_1(i32 %x) { 1061; CHECK-LABEL: @PR75692_1( 1062; CHECK-NEXT: ret i32 -1 1063; 1064 %t2 = xor i32 %x, 4 1065 %t3 = xor i32 %x, -5 1066 %t4 = or i32 %t2, %t3 1067 ret i32 %t4 1068} 1069 1070; (a ^ 4) & (a ^ 3) is not -1 1071define i32 @PR75692_2(i32 %x) { 1072; CHECK-LABEL: @PR75692_2( 1073; CHECK-NEXT: [[T2:%.*]] = xor i32 [[X:%.*]], 4 1074; CHECK-NEXT: [[T3:%.*]] = xor i32 [[X]], -4 1075; CHECK-NEXT: [[T4:%.*]] = or i32 [[T2]], [[T3]] 1076; CHECK-NEXT: ret i32 [[T4]] 1077; 1078 %t2 = xor i32 %x, 4 1079 %t3 = xor i32 %x, -4 1080 %t4 = or i32 %t2, %t3 1081 ret i32 %t4 1082} 1083 1084; (a ^ 4) & (b ^ ~4) is not -1, since a != b is possible 1085define i32 @PR75692_3(i32 %x, i32 %y) { 1086; CHECK-LABEL: @PR75692_3( 1087; CHECK-NEXT: [[T2:%.*]] = xor i32 [[X:%.*]], 4 1088; CHECK-NEXT: [[T3:%.*]] = xor i32 [[Y:%.*]], -5 1089; CHECK-NEXT: [[T4:%.*]] = or i32 [[T2]], [[T3]] 1090; CHECK-NEXT: ret i32 [[T4]] 1091; 1092 %t2 = xor i32 %x, 4 1093 %t3 = xor i32 %y, -5 1094 %t4 = or i32 %t2, %t3 1095 ret i32 %t4 1096} 1097 1098define i32 @or_xor_not(i32 %x, i32 %y) { 1099; CHECK-LABEL: @or_xor_not( 1100; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], -1 1101; CHECK-NEXT: [[OR1:%.*]] = or i32 [[Y:%.*]], [[TMP1]] 1102; CHECK-NEXT: ret i32 [[OR1]] 1103; 1104 %not = xor i32 %y, -1 1105 %xor = xor i32 %x, %not 1106 %or1 = or i32 %xor, %y 1107 ret i32 %or1 1108} 1109 1110define i32 @or_xor_not_uses1(i32 %x, i32 %y) { 1111; CHECK-LABEL: @or_xor_not_uses1( 1112; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[Y:%.*]], -1 1113; CHECK-NEXT: call void @use(i32 [[NOT]]) 1114; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], -1 1115; CHECK-NEXT: [[OR1:%.*]] = or i32 [[Y]], [[TMP1]] 1116; CHECK-NEXT: ret i32 [[OR1]] 1117; 1118 %not = xor i32 %y, -1 1119 call void @use(i32 %not) 1120 %xor = xor i32 %x, %not 1121 %or1 = or i32 %xor, %y 1122 ret i32 %or1 1123} 1124 1125define i32 @or_xor_not_uses2(i32 %x, i32 %y) { 1126; CHECK-LABEL: @or_xor_not_uses2( 1127; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]] 1128; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1 1129; CHECK-NEXT: call void @use(i32 [[XOR]]) 1130; CHECK-NEXT: [[OR1:%.*]] = or i32 [[Y]], [[XOR]] 1131; CHECK-NEXT: ret i32 [[OR1]] 1132; 1133 %not = xor i32 %y, -1 1134 %xor = xor i32 %x, %not 1135 call void @use(i32 %xor) 1136 %or1 = or i32 %xor, %y 1137 ret i32 %or1 1138} 1139 1140define i32 @or_xor_and_commuted1(i32 %x, i32 %y) { 1141; CHECK-LABEL: @or_xor_and_commuted1( 1142; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]] 1143; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], -1 1144; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[TMP1]] 1145; CHECK-NEXT: ret i32 [[OR1]] 1146; 1147 %yy = mul i32 %y, %y ; thwart complexity-based ordering 1148 %not = xor i32 %yy, -1 1149 %xor = xor i32 %not, %x 1150 %or1 = or i32 %yy, %xor 1151 ret i32 %or1 1152} 1153 1154define i32 @or_xor_and_commuted2(i32 %x, i32 %y) { 1155; CHECK-LABEL: @or_xor_and_commuted2( 1156; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]] 1157; CHECK-NEXT: [[XX:%.*]] = mul i32 [[X:%.*]], [[X]] 1158; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[XX]], -1 1159; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[TMP1]] 1160; CHECK-NEXT: ret i32 [[OR1]] 1161; 1162 %yy = mul i32 %y, %y ; thwart complexity-based ordering 1163 %xx = mul i32 %x, %x ; thwart complexity-based ordering 1164 %not = xor i32 %yy, -1 1165 %xor = xor i32 %xx, %not 1166 %or1 = or i32 %xor, %yy 1167 ret i32 %or1 1168} 1169 1170; (A ^ B) | ((B ^ C) ^ A) -> (A ^ B) | C and commuted variants. 1171 1172define i32 @or_xor_tree_0000(i32 %ax, i32 %bx, i32 %cx) { 1173; CHECK-LABEL: @or_xor_tree_0000( 1174; CHECK-NEXT: [[A:%.*]] = mul i32 [[AX:%.*]], 42 1175; CHECK-NEXT: [[B:%.*]] = mul i32 [[BX:%.*]], 42 1176; CHECK-NEXT: [[C:%.*]] = mul i32 [[CX:%.*]], 42 1177; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[A]], [[B]] 1178; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[C]] 1179; CHECK-NEXT: ret i32 [[OR]] 1180; 1181 %a = mul i32 %ax, 42 1182 %b = mul i32 %bx, 42 1183 %c = mul i32 %cx, 42 1184 %xor1 = xor i32 %a, %b 1185 %xor2 = xor i32 %b, %c 1186 %xor3 = xor i32 %xor2, %a 1187 %or = or i32 %xor1, %xor3 1188 ret i32 %or 1189} 1190 1191define i32 @or_xor_tree_0001(i32 %ax, i32 %bx, i32 %cx) { 1192; CHECK-LABEL: @or_xor_tree_0001( 1193; CHECK-NEXT: [[A:%.*]] = mul i32 [[AX:%.*]], 42 1194; CHECK-NEXT: [[B:%.*]] = mul i32 [[BX:%.*]], 42 1195; CHECK-NEXT: [[C:%.*]] = mul i32 [[CX:%.*]], 42 1196; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[A]] 1197; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[C]] 1198; CHECK-NEXT: ret i32 [[OR]] 1199; 1200 %a = mul i32 %ax, 42 1201 %b = mul i32 %bx, 42 1202 %c = mul i32 %cx, 42 1203 %xor1 = xor i32 %b, %a 1204 %xor2 = xor i32 %b, %c 1205 %xor3 = xor i32 %xor2, %a 1206 %or = or i32 %xor1, %xor3 1207 ret i32 %or 1208} 1209 1210define i32 @or_xor_tree_0010(i32 %ax, i32 %bx, i32 %cx) { 1211; CHECK-LABEL: @or_xor_tree_0010( 1212; CHECK-NEXT: [[A:%.*]] = mul i32 [[AX:%.*]], 42 1213; CHECK-NEXT: [[B:%.*]] = mul i32 [[BX:%.*]], 42 1214; CHECK-NEXT: [[C:%.*]] = mul i32 [[CX:%.*]], 42 1215; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[A]], [[B]] 1216; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[C]] 1217; CHECK-NEXT: ret i32 [[OR]] 1218; 1219 %a = mul i32 %ax, 42 1220 %b = mul i32 %bx, 42 1221 %c = mul i32 %cx, 42 1222 %xor1 = xor i32 %a, %b 1223 %xor2 = xor i32 %c, %b 1224 %xor3 = xor i32 %xor2, %a 1225 %or = or i32 %xor1, %xor3 1226 ret i32 %or 1227} 1228 1229define i32 @or_xor_tree_0011(i32 %ax, i32 %bx, i32 %cx) { 1230; CHECK-LABEL: @or_xor_tree_0011( 1231; CHECK-NEXT: [[A:%.*]] = mul i32 [[AX:%.*]], 42 1232; CHECK-NEXT: [[B:%.*]] = mul i32 [[BX:%.*]], 42 1233; CHECK-NEXT: [[C:%.*]] = mul i32 [[CX:%.*]], 42 1234; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[A]] 1235; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[C]] 1236; CHECK-NEXT: ret i32 [[OR]] 1237; 1238 %a = mul i32 %ax, 42 1239 %b = mul i32 %bx, 42 1240 %c = mul i32 %cx, 42 1241 %xor1 = xor i32 %b, %a 1242 %xor2 = xor i32 %c, %b 1243 %xor3 = xor i32 %xor2, %a 1244 %or = or i32 %xor1, %xor3 1245 ret i32 %or 1246} 1247 1248define i32 @or_xor_tree_0100(i32 %ax, i32 %bx, i32 %cx) { 1249; CHECK-LABEL: @or_xor_tree_0100( 1250; CHECK-NEXT: [[A:%.*]] = mul i32 [[AX:%.*]], 42 1251; CHECK-NEXT: [[B:%.*]] = mul i32 [[BX:%.*]], 42 1252; CHECK-NEXT: [[C:%.*]] = mul i32 [[CX:%.*]], 42 1253; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[A]], [[B]] 1254; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[C]] 1255; CHECK-NEXT: ret i32 [[OR]] 1256; 1257 %a = mul i32 %ax, 42 1258 %b = mul i32 %bx, 42 1259 %c = mul i32 %cx, 42 1260 %xor1 = xor i32 %a, %b 1261 %xor2 = xor i32 %b, %c 1262 %xor3 = xor i32 %a, %xor2 1263 %or = or i32 %xor1, %xor3 1264 ret i32 %or 1265} 1266 1267define i32 @or_xor_tree_0101(i32 %ax, i32 %bx, i32 %cx) { 1268; CHECK-LABEL: @or_xor_tree_0101( 1269; CHECK-NEXT: [[A:%.*]] = mul i32 [[AX:%.*]], 42 1270; CHECK-NEXT: [[B:%.*]] = mul i32 [[BX:%.*]], 42 1271; CHECK-NEXT: [[C:%.*]] = mul i32 [[CX:%.*]], 42 1272; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[A]] 1273; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[C]] 1274; CHECK-NEXT: ret i32 [[OR]] 1275; 1276 %a = mul i32 %ax, 42 1277 %b = mul i32 %bx, 42 1278 %c = mul i32 %cx, 42 1279 %xor1 = xor i32 %b, %a 1280 %xor2 = xor i32 %b, %c 1281 %xor3 = xor i32 %a, %xor2 1282 %or = or i32 %xor1, %xor3 1283 ret i32 %or 1284} 1285 1286define i32 @or_xor_tree_0110(i32 %ax, i32 %bx, i32 %cx) { 1287; CHECK-LABEL: @or_xor_tree_0110( 1288; CHECK-NEXT: [[A:%.*]] = mul i32 [[AX:%.*]], 42 1289; CHECK-NEXT: [[B:%.*]] = mul i32 [[BX:%.*]], 42 1290; CHECK-NEXT: [[C:%.*]] = mul i32 [[CX:%.*]], 42 1291; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[A]], [[B]] 1292; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[C]] 1293; CHECK-NEXT: ret i32 [[OR]] 1294; 1295 %a = mul i32 %ax, 42 1296 %b = mul i32 %bx, 42 1297 %c = mul i32 %cx, 42 1298 %xor1 = xor i32 %a, %b 1299 %xor2 = xor i32 %c, %b 1300 %xor3 = xor i32 %a, %xor2 1301 %or = or i32 %xor1, %xor3 1302 ret i32 %or 1303} 1304 1305define i32 @or_xor_tree_0111(i32 %ax, i32 %bx, i32 %cx) { 1306; CHECK-LABEL: @or_xor_tree_0111( 1307; CHECK-NEXT: [[A:%.*]] = mul i32 [[AX:%.*]], 42 1308; CHECK-NEXT: [[B:%.*]] = mul i32 [[BX:%.*]], 42 1309; CHECK-NEXT: [[C:%.*]] = mul i32 [[CX:%.*]], 42 1310; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[A]] 1311; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[C]] 1312; CHECK-NEXT: ret i32 [[OR]] 1313; 1314 %a = mul i32 %ax, 42 1315 %b = mul i32 %bx, 42 1316 %c = mul i32 %cx, 42 1317 %xor1 = xor i32 %b, %a 1318 %xor2 = xor i32 %c, %b 1319 %xor3 = xor i32 %a, %xor2 1320 %or = or i32 %xor1, %xor3 1321 ret i32 %or 1322} 1323 1324define i32 @or_xor_tree_1000(i32 %ax, i32 %bx, i32 %cx) { 1325; CHECK-LABEL: @or_xor_tree_1000( 1326; CHECK-NEXT: [[A:%.*]] = mul i32 [[AX:%.*]], 42 1327; CHECK-NEXT: [[B:%.*]] = mul i32 [[BX:%.*]], 42 1328; CHECK-NEXT: [[C:%.*]] = mul i32 [[CX:%.*]], 42 1329; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[A]], [[B]] 1330; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[C]] 1331; CHECK-NEXT: ret i32 [[OR]] 1332; 1333 %a = mul i32 %ax, 42 1334 %b = mul i32 %bx, 42 1335 %c = mul i32 %cx, 42 1336 %xor1 = xor i32 %a, %b 1337 %xor2 = xor i32 %b, %c 1338 %xor3 = xor i32 %xor2, %a 1339 %or = or i32 %xor3, %xor1 1340 ret i32 %or 1341} 1342 1343define i32 @or_xor_tree_1001(i32 %ax, i32 %bx, i32 %cx) { 1344; CHECK-LABEL: @or_xor_tree_1001( 1345; CHECK-NEXT: [[A:%.*]] = mul i32 [[AX:%.*]], 42 1346; CHECK-NEXT: [[B:%.*]] = mul i32 [[BX:%.*]], 42 1347; CHECK-NEXT: [[C:%.*]] = mul i32 [[CX:%.*]], 42 1348; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[A]] 1349; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[C]] 1350; CHECK-NEXT: ret i32 [[OR]] 1351; 1352 %a = mul i32 %ax, 42 1353 %b = mul i32 %bx, 42 1354 %c = mul i32 %cx, 42 1355 %xor1 = xor i32 %b, %a 1356 %xor2 = xor i32 %b, %c 1357 %xor3 = xor i32 %xor2, %a 1358 %or = or i32 %xor3, %xor1 1359 ret i32 %or 1360} 1361 1362define i32 @or_xor_tree_1010(i32 %ax, i32 %bx, i32 %cx) { 1363; CHECK-LABEL: @or_xor_tree_1010( 1364; CHECK-NEXT: [[A:%.*]] = mul i32 [[AX:%.*]], 42 1365; CHECK-NEXT: [[B:%.*]] = mul i32 [[BX:%.*]], 42 1366; CHECK-NEXT: [[C:%.*]] = mul i32 [[CX:%.*]], 42 1367; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[A]], [[B]] 1368; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[C]] 1369; CHECK-NEXT: ret i32 [[OR]] 1370; 1371 %a = mul i32 %ax, 42 1372 %b = mul i32 %bx, 42 1373 %c = mul i32 %cx, 42 1374 %xor1 = xor i32 %a, %b 1375 %xor2 = xor i32 %c, %b 1376 %xor3 = xor i32 %xor2, %a 1377 %or = or i32 %xor3, %xor1 1378 ret i32 %or 1379} 1380 1381define i32 @or_xor_tree_1011(i32 %ax, i32 %bx, i32 %cx) { 1382; CHECK-LABEL: @or_xor_tree_1011( 1383; CHECK-NEXT: [[A:%.*]] = mul i32 [[AX:%.*]], 42 1384; CHECK-NEXT: [[B:%.*]] = mul i32 [[BX:%.*]], 42 1385; CHECK-NEXT: [[C:%.*]] = mul i32 [[CX:%.*]], 42 1386; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[A]] 1387; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[C]] 1388; CHECK-NEXT: ret i32 [[OR]] 1389; 1390 %a = mul i32 %ax, 42 1391 %b = mul i32 %bx, 42 1392 %c = mul i32 %cx, 42 1393 %xor1 = xor i32 %b, %a 1394 %xor2 = xor i32 %c, %b 1395 %xor3 = xor i32 %xor2, %a 1396 %or = or i32 %xor3, %xor1 1397 ret i32 %or 1398} 1399 1400define i32 @or_xor_tree_1100(i32 %ax, i32 %bx, i32 %cx) { 1401; CHECK-LABEL: @or_xor_tree_1100( 1402; CHECK-NEXT: [[A:%.*]] = mul i32 [[AX:%.*]], 42 1403; CHECK-NEXT: [[B:%.*]] = mul i32 [[BX:%.*]], 42 1404; CHECK-NEXT: [[C:%.*]] = mul i32 [[CX:%.*]], 42 1405; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[A]], [[B]] 1406; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[C]] 1407; CHECK-NEXT: ret i32 [[OR]] 1408; 1409 %a = mul i32 %ax, 42 1410 %b = mul i32 %bx, 42 1411 %c = mul i32 %cx, 42 1412 %xor1 = xor i32 %a, %b 1413 %xor2 = xor i32 %b, %c 1414 %xor3 = xor i32 %a, %xor2 1415 %or = or i32 %xor3, %xor1 1416 ret i32 %or 1417} 1418 1419define i32 @or_xor_tree_1101(i32 %ax, i32 %bx, i32 %cx) { 1420; CHECK-LABEL: @or_xor_tree_1101( 1421; CHECK-NEXT: [[A:%.*]] = mul i32 [[AX:%.*]], 42 1422; CHECK-NEXT: [[B:%.*]] = mul i32 [[BX:%.*]], 42 1423; CHECK-NEXT: [[C:%.*]] = mul i32 [[CX:%.*]], 42 1424; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[A]] 1425; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[C]] 1426; CHECK-NEXT: ret i32 [[OR]] 1427; 1428 %a = mul i32 %ax, 42 1429 %b = mul i32 %bx, 42 1430 %c = mul i32 %cx, 42 1431 %xor1 = xor i32 %b, %a 1432 %xor2 = xor i32 %b, %c 1433 %xor3 = xor i32 %a, %xor2 1434 %or = or i32 %xor3, %xor1 1435 ret i32 %or 1436} 1437 1438define i32 @or_xor_tree_1110(i32 %ax, i32 %bx, i32 %cx) { 1439; CHECK-LABEL: @or_xor_tree_1110( 1440; CHECK-NEXT: [[A:%.*]] = mul i32 [[AX:%.*]], 42 1441; CHECK-NEXT: [[B:%.*]] = mul i32 [[BX:%.*]], 42 1442; CHECK-NEXT: [[C:%.*]] = mul i32 [[CX:%.*]], 42 1443; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[A]], [[B]] 1444; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[C]] 1445; CHECK-NEXT: ret i32 [[OR]] 1446; 1447 %a = mul i32 %ax, 42 1448 %b = mul i32 %bx, 42 1449 %c = mul i32 %cx, 42 1450 %xor1 = xor i32 %a, %b 1451 %xor2 = xor i32 %c, %b 1452 %xor3 = xor i32 %a, %xor2 1453 %or = or i32 %xor3, %xor1 1454 ret i32 %or 1455} 1456 1457define i32 @or_xor_tree_1111(i32 %ax, i32 %bx, i32 %cx) { 1458; CHECK-LABEL: @or_xor_tree_1111( 1459; CHECK-NEXT: [[A:%.*]] = mul i32 [[AX:%.*]], 42 1460; CHECK-NEXT: [[B:%.*]] = mul i32 [[BX:%.*]], 42 1461; CHECK-NEXT: [[C:%.*]] = mul i32 [[CX:%.*]], 42 1462; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[A]] 1463; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR1]], [[C]] 1464; CHECK-NEXT: ret i32 [[OR]] 1465; 1466 %a = mul i32 %ax, 42 1467 %b = mul i32 %bx, 42 1468 %c = mul i32 %cx, 42 1469 %xor1 = xor i32 %b, %a 1470 %xor2 = xor i32 %c, %b 1471 %xor3 = xor i32 %a, %xor2 1472 %or = or i32 %xor3, %xor1 1473 ret i32 %or 1474} 1475