brintos

brintos / llvm-project-archived public Read only

0
0
Text · 41.4 KiB · b05ff15 Raw
1475 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=instcombine < %s | FileCheck %s3 4declare void @use(i8)5 6; X | ~(X | Y) --> X | ~Y7 8define i32 @test1(i32 %x, i32 %y) {9; CHECK-LABEL: @test1(10; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y:%.*]], -111; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X:%.*]], [[TMP1]]12; CHECK-NEXT:    ret i32 [[Z]]13;14  %or = or i32 %x, %y15  %not = xor i32 %or, -116  %z = or i32 %x, %not17  ret i32 %z18}19 20; Commute (rename) the inner 'or' operands:21; Y | ~(X | Y) --> ~X | Y22 23define i32 @test2(i32 %x, i32 %y) {24; CHECK-LABEL: @test2(25; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], -126; CHECK-NEXT:    [[Z:%.*]] = or i32 [[Y:%.*]], [[TMP1]]27; CHECK-NEXT:    ret i32 [[Z]]28;29  %or = or i32 %x, %y30  %not = xor i32 %or, -131  %z = or i32 %y, %not32  ret i32 %z33}34 35; X | ~(X ^ Y) --> X | ~Y36 37define i32 @test3(i32 %x, i32 %y) {38; CHECK-LABEL: @test3(39; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y:%.*]], -140; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X:%.*]], [[TMP1]]41; CHECK-NEXT:    ret i32 [[Z]]42;43  %xor = xor i32 %x, %y44  %not = xor i32 %xor, -145  %z = or i32 %x, %not46  ret i32 %z47}48 49; Commute (rename) the 'xor' operands:50; Y | ~(X ^ Y) --> ~X | Y51 52define i32 @test4(i32 %x, i32 %y) {53; CHECK-LABEL: @test4(54; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], -155; CHECK-NEXT:    [[Z:%.*]] = or i32 [[Y:%.*]], [[TMP1]]56; CHECK-NEXT:    ret i32 [[Z]]57;58  %xor = xor i32 %x, %y59  %not = xor i32 %xor, -160  %z = or i32 %y, %not61  ret i32 %z62}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]], -170; CHECK-NEXT:    ret i32 [[Z]]71;72  %xor = xor i32 %x, %y73  %notx = xor i32 %x, -174  %z = or i32 %xor, %notx75  ret i32 %z76}77 78; Commute the 'or' operands79; ~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, %y88  %notx = xor <2 x i4> %x, <i4 -1, i4 -1>89  %z = or <2 x i4> %notx, %xor90  ret <2 x i4> %z91}92 93; Commute the inner 'xor' operands94; (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]], -1100; CHECK-NEXT:    ret i64 [[Z]]101;102  %xor = xor i64 %y, %x103  %notx = xor i64 %x, -1104  %z = or i64  %xor, %notx105  ret i64 %z106}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:%.*]], -1112; CHECK-NEXT:    store i8 [[NOTX]], ptr [[DST:%.*]], align 1113; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X]], [[Y:%.*]]114; CHECK-NEXT:    [[Z:%.*]] = xor i8 [[TMP1]], -1115; CHECK-NEXT:    ret i8 [[Z]]116;117  %xor = xor i8 %x, %y118  %notx = xor i8 %x, -1119  store i8 %notx, ptr %dst120  %z = or i8 %notx, %xor121  ret i8 %z122}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 4129; CHECK-NEXT:    [[TMP1:%.*]] = and i65 [[X]], [[Y]]130; CHECK-NEXT:    [[Z:%.*]] = xor i65 [[TMP1]], -1131; CHECK-NEXT:    ret i65 [[Z]]132;133  %xor = xor i65 %x, %y134  store i65 %xor, ptr %dst135  %notx = xor i65 %x, -1136  %z = or i65 %notx, %xor137  ret i65 %z138}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 2144; CHECK-NEXT:    [[NOTX:%.*]] = xor i16 [[X]], -1145; CHECK-NEXT:    store i16 [[NOTX]], ptr [[DST_NOT:%.*]], align 2146; CHECK-NEXT:    [[Z:%.*]] = or i16 [[XOR]], [[NOTX]]147; CHECK-NEXT:    ret i16 [[Z]]148;149  %xor = xor i16 %x, %y150  store i16 %xor, ptr %dst_xor151  %notx = xor i16 %x, -1152  store i16 %notx, ptr %dst_not153  %z = or i16 %notx, %xor154  ret i16 %z155}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, %y163  %z = or i8 %xor, %x164  ret i8 %z165}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, %x175  call void @use(i8 %xor)176  %z = or i8 %xor, %x177  ret i8 %z178}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:%.*]], 5183; CHECK-NEXT:    [[Z:%.*]] = or i8 [[X]], [[Y:%.*]]184; CHECK-NEXT:    ret i8 [[Z]]185;186  %x = xor i8 %p, 5 ; thwart complexity-based canonicalization187  %xor = xor i8 %x, %y188  %z = or i8 %x, %xor189  ret i8 %z190}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:%.*]], 5195; 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 canonicalization200  %y = mul i8 %q, %q ; thwart complexity-based canonicalization201  %xor = xor i8 %y, %x202  %z = or i8 %x, %xor203  ret i8 %z204}205 206define i32 @test8(i32 %x, i32 %y) {207; CHECK-LABEL: @test8(208; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], -1209; CHECK-NEXT:    [[Z:%.*]] = or i32 [[Y:%.*]], [[TMP1]]210; CHECK-NEXT:    ret i32 [[Z]]211;212  %not = xor i32 %y, -1213  %xor = xor i32 %x, %not214  %z = or i32 %y, %xor215  ret i32 %z216}217 218define i32 @test9(i32 %x, i32 %y) {219; CHECK-LABEL: @test9(220; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y:%.*]], -1221; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X:%.*]], [[TMP1]]222; CHECK-NEXT:    ret i32 [[Z]]223;224  %not = xor i32 %x, -1225  %xor = xor i32 %not, %y226  %z = or i32 %x, %xor227  ret i32 %z228}229 230; (A ^ B) | (~A ^ B) --> -1231 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]], -1237; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[XOR2]]238; CHECK-NEXT:    ret i32 [[OR]]239;240  %xor1 = xor i32 %B, %A241  %not = xor i32 %A, -1242  %xor2 = xor i32 %not, %B243  %or = or i32 %xor1, %xor2244  ret i32 %or245}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]], -1252; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[XOR2]]253; CHECK-NEXT:    ret i32 [[OR]]254;255  %xor1 = xor i32 %B, %A256  %not = xor i32 %A, -1257  %xor2 = xor i32 %not, %B258  %or = or i32 %xor2, %xor1259  ret i32 %or260}261 262define i32 @test10_extrause(i32 %A, i32 %B, ptr %dst) {263; CHECK-LABEL: @test10_extrause(264; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[A:%.*]], -1265; CHECK-NEXT:    store i32 [[NOT]], ptr [[DST:%.*]], align 4266; CHECK-NEXT:    ret i32 -1267;268  %xor1 = xor i32 %B, %A269  %not = xor i32 %A, -1270  store i32 %not, ptr %dst271  %xor2 = xor i32 %not, %B272  %or = or i32 %xor1, %xor2273  ret i32 %or274}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:%.*]], -1279; CHECK-NEXT:    store i32 [[NOT]], ptr [[DST:%.*]], align 4280; CHECK-NEXT:    ret i32 -1281;282  %xor1 = xor i32 %B, %A283  %not = xor i32 %A, -1284  store i32 %not, ptr %dst285  %xor2 = xor i32 %not, %B286  %or = or i32 %xor2, %xor1287  ret i32 %or288}289 290; (A ^ B) | ~(A ^ B) --> -1291define 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]], -1296; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[NOT]]297; CHECK-NEXT:    ret i32 [[OR]]298;299  %xor1 = xor i32 %B, %A300  %xor2 = xor i32 %A, %B301  %not = xor i32 %xor2, -1302  %or = or i32 %xor1, %not303  ret i32 %or304}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, %y313  %neg = xor i32 %x, -1314  %xor = xor i32 %neg, %y315  %and = and i32 %or, %xor316  ret i32 %and317}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, -1326  %xor = xor i32 %neg, %y327  %or = or i32 %x, %y328  %and = and i32 %xor, %or329  ret i32 %and330}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, -1338  %xor = xor i32 %neg, %y339  %or = or i32 %y, %x340  %and = and i32 %xor, %or341  ret i32 %and342}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, %x351  %2 = or i32 %y, %x352  %3 = xor i32 %2, %1353  ret i32 %3354}355 356; ((x | ~y) ^ (~x | y)) -> x ^ y357define 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, -1363  %notx = xor i32 %x, -1364  %or1 = or i32 %x, %noty365  %or2 = or i32 %notx, %y366  %xor = xor i32 %or1, %or2367  ret i32 %xor368}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, -1376  %notx = xor i32 %x, -1377  %or1 = or i32 %noty, %x378  %or2 = or i32 %notx, %y379  %xor = xor i32 %or1, %or2380  ret i32 %xor381}382 383; ((x & ~y) ^ (~x & y)) -> x ^ y384define 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, -1390  %notx = xor i32 %x, -1391  %and1 = and i32 %x, %noty392  %and2 = and i32 %notx, %y393  %xor = xor i32 %and1, %and2394  ret i32 %xor395}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, -1403  %notx = xor i32 %x, -1404  %and1 = and i32 %noty, %x405  %and2 = and i32 %notx, %y406  %xor = xor i32 %and1, %and2407  ret i32 %xor408}409 410; ((a ^ b) & C1) | (b & C2) -> (a & C1) ^ b iff C1 == ~C2411 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:%.*]], 1415; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], [[B:%.*]]416; CHECK-NEXT:    ret i32 [[XOR]]417;418  %or = xor i32 %a, %b419  %and1 = and i32 %or, 1420  %and2 = and i32 %b, -2421  %xor = or i32 %and1, %and2422  ret i32 %xor423}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:%.*]], 42428; CHECK-NEXT:    [[XOR:%.*]] = xor i9 [[TMP1]], [[B:%.*]]429; CHECK-NEXT:    ret i9 [[XOR]]430;431  %or = xor i9 %b, %a432  %and1 = and i9 %or, 42433  %and2 = and i9 %b, -43434  %xor = or i9 %and1, %and2435  ret i9 %xor436}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, %a445  %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, %and1448  ret <2 x i9> %xor449}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, %b458  %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, %and1461  ret <2 x i9> %xor462}463 464define i8 @not_or(i8 %x) {465; CHECK-LABEL: @not_or(466; CHECK-NEXT:    [[NOTX:%.*]] = xor i8 [[X:%.*]], -1467; CHECK-NEXT:    [[OR:%.*]] = or i8 [[NOTX]], 7468; CHECK-NEXT:    ret i8 [[OR]]469;470  %notx = xor i8 %x, -1471  %or = or i8 %notx, 7472  ret i8 %or473}474 475define i8 @not_or_xor(i8 %x) {476; CHECK-LABEL: @not_or_xor(477; CHECK-NEXT:    [[NOTX:%.*]] = and i8 [[X:%.*]], -8478; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[NOTX]], -13479; CHECK-NEXT:    ret i8 [[XOR]]480;481  %notx = xor i8 %x, -1482  %or = or i8 %notx, 7483  %xor = xor i8 %or, 12484  ret i8 %xor485}486 487define i8 @xor_or(i8 %x) {488; CHECK-LABEL: @xor_or(489; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -8490; CHECK-NEXT:    [[OR:%.*]] = xor i8 [[TMP1]], 39491; CHECK-NEXT:    ret i8 [[OR]]492;493  %xor = xor i8 %x, 32494  %or = or i8 %xor, 7495  ret i8 %or496}497 498define i8 @xor_or2(i8 %x) {499; CHECK-LABEL: @xor_or2(500; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -8501; CHECK-NEXT:    [[OR:%.*]] = xor i8 [[TMP1]], 39502; CHECK-NEXT:    ret i8 [[OR]]503;504  %xor = xor i8 %x, 33505  %or = or i8 %xor, 7506  ret i8 %or507}508 509define i8 @xor_or_xor(i8 %x) {510; CHECK-LABEL: @xor_or_xor(511; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -8512; CHECK-NEXT:    [[XOR2:%.*]] = xor i8 [[TMP1]], 43513; CHECK-NEXT:    ret i8 [[XOR2]]514;515  %xor1 = xor i8 %x, 33516  %or = or i8 %xor1, 7517  %xor2 = xor i8 %or, 12518  ret i8 %xor2519}520 521define i8 @or_xor_or(i8 %x) {522; CHECK-LABEL: @or_xor_or(523; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -40524; CHECK-NEXT:    [[OR2:%.*]] = xor i8 [[TMP1]], 47525; CHECK-NEXT:    ret i8 [[OR2]]526;527  %or1 = or i8 %x, 33528  %xor = xor i8 %or1, 12529  %or2 = or i8 %xor, 7530  ret i8 %or2531}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]], 33538; 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, %A543  %not = xor i8 %A, 33544  %xor2 = xor i8 %not, %B545  %or = or i8 %xor1, %xor2546  %res = mul i8 %or, %xor2 ; to increase the use count for the xor547  ret i8 %res548}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]], 33555; 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, %A560  %not = xor i8 %A, 33561  %xor2 = xor i8 %not, %B562  %or = or i8 %xor2, %xor1563  %res = mul i8 %or, %xor2 ; to increase the use count for the xor564  ret i8 %res565}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]], -1572; CHECK-NEXT:    ret i32 [[XOR]]573;574  %noty = xor i32 %y, -1575  %notx = xor i32 %x, -1576  %or1 = or i32 %x, %y577  %or2 = or i32 %notx, %noty578  %xor = xor i32 %or1, %or2579  ret i32 %xor580}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]], -1587; CHECK-NEXT:    ret i32 [[XOR]]588;589  %noty = xor i32 %y, -1590  %notx = xor i32 %x, -1591  %or1 = or i32 %x, %y592  %or2 = or i32 %noty, %notx593  %xor = xor i32 %or1, %or2594  ret i32 %xor595}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]], -1602; CHECK-NEXT:    ret i32 [[XOR]]603;604  %noty = xor i32 %y, -1605  %notx = xor i32 %x, -1606  %or1 = or i32 %notx, %noty607  %or2 = or i32 %x, %y608  %xor = xor i32 %or1, %or2609  ret i32 %xor610}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]], -1617; CHECK-NEXT:    ret i32 [[XOR]]618;619  %noty = xor i32 %y, -1620  %notx = xor i32 %x, -1621  %or1 = or i32 %notx, %noty622  %or2 = or i32 %y, %x623  %xor = xor i32 %or1, %or2624  ret i32 %xor625}626 627; (X ^ C1) | C2 --> (X | C2) ^ (C1&~C2)628define i8 @test23(i8 %A) {629; CHECK-LABEL: @test23(630; CHECK-NEXT:    ret i8 -1631;632  %B = or i8 %A, -2633  %C = xor i8 %B, 13634  %D = or i8 %C, 1635  %E = xor i8 %D, 12636  ret i8 %E637}638 639define i8 @test23v(<2 x i8> %A) {640; CHECK-LABEL: @test23v(641; CHECK-NEXT:    ret i8 -1642;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 0646  %D = or i8 %C, 1647  %E = xor i8 %D, 12648  ret i8 %E649}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:%.*]], -1655; CHECK-NEXT:    ret i32 [[NOT]]656;657  %not = xor i32 %a, -1658  %andnot = and i32 %not, %b659  %or = or i32 %a, %b660  %notor = xor i32 %or, -1661  %res = or i32 %notor, %andnot662  ret i32 %res663}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:%.*]], -1669; CHECK-NEXT:    ret i32 [[TMP1]]670;671  %or = or i32 %a, %b672  %not = xor i32 %b, -1673  %ornot = or i32 %a, %not674  %res = xor i32 %or, %ornot675  ret i32 %res676}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, %y685  %xor = xor i8 %x, %z686  %r = or i8 %or, %xor687  ret i8 %r688}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, %x698  call void @use(i8 %or)699  %xor = xor i8 %x, %z700  %r = or i8 %or, %xor701  ret i8 %r702}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, %y713  %xor = xor i8 %z, %x714  call void @use(i8 %xor)715  %r = or i8 %or, %xor716  ret i8 %r717}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, %x729  call void @use(i8 %or)730  %xor = xor i8 %z, %x731  call void @use(i8 %xor)732  %r = or i8 %or, %xor733  ret i8 %r734}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, %y743  %xor = xor <2 x i8> %x, %z744  %r = or <2 x i8> %xor, %or745  ret <2 x i8> %r746}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, %x755  %xor = xor i8 %x, %z756  %r = or i8 %xor, %or757  ret i8 %r758}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, %y767  %xor = xor i8 %z, %x768  %r = or i8 %xor, %or769  ret i8 %r770}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, %x779  %xor = xor i8 %z, %x780  %r = or i8 %xor, %or781  ret i8 %r782}783 784; negative test - need common operand785 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, %y794  %xor = xor i8 %q, %z795  %r = or i8 %or, %xor796  ret i8 %r797}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]], -1803; CHECK-NEXT:    [[O2:%.*]] = or i4 [[Z:%.*]], [[NAND]]804; CHECK-NEXT:    ret i4 [[O2]]805;806  %notx = xor i4 %x, -1807  %xor = xor i4 %x, %y808  %o1 = or i4 %notx, %z809  %o2 = or i4 %o1, %xor810  ret i4 %o2811}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:%.*]], -1816; CHECK-NEXT:    call void @use(i8 [[NOTX]])817; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X]], [[Y:%.*]]818; CHECK-NEXT:    [[NAND:%.*]] = xor i8 [[TMP1]], -1819; CHECK-NEXT:    [[O2:%.*]] = or i8 [[Z:%.*]], [[NAND]]820; CHECK-NEXT:    ret i8 [[O2]]821;822  %notx = xor i8 %x, -1823  call void @use(i8 %notx)824  %xor = xor i8 %x, %y825  %o1 = or i8 %notx, %z826  %o2 = or i8 %xor, %o1827  ret i8 %o2828}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]], -1835; CHECK-NEXT:    [[O2:%.*]] = or i8 [[NAND]], [[Z]]836; CHECK-NEXT:    ret i8 [[O2]]837;838  %z = sub i8 0, %p ; thwart complexity-based canonicalizaion839  %notx = xor i8 %x, -1840  %xor = xor i8 %x, %y841  %o1 = or i8 %z, %notx842  %o2 = or i8 %xor, %o1843  ret i8 %o2844}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]], -1851; CHECK-NEXT:    [[O2:%.*]] = or i8 [[NAND]], [[Z]]852; CHECK-NEXT:    ret i8 [[O2]]853;854  %z = sub i8 0, %p ; thwart complexity-based canonicalizaion855  %notx = xor i8 %x, -1856  %xor = xor i8 %x, %y857  %o1 = or i8 %z, %notx858  %o2 = or i8 %o1, %xor859  ret i8 %o2860}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, %x871  %o1 = or <2 x i4> %notx, %z872  %o2 = or <2 x i4> %o1, %xor873  ret <2 x i4> %o2874}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]], -1880; CHECK-NEXT:    [[O2:%.*]] = or i8 [[Z:%.*]], [[NAND]]881; CHECK-NEXT:    ret i8 [[O2]]882;883  %notx = xor i8 %x, -1884  %xor = xor i8 %y, %x885  %o1 = or i8 %notx, %z886  %o2 = or i8 %xor, %o1887  ret i8 %o2888}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]], -1895; CHECK-NEXT:    [[O2:%.*]] = or i8 [[NAND]], [[Z]]896; CHECK-NEXT:    ret i8 [[O2]]897;898  %z = sub i8 0, %p ; thwart complexity-based canonicalizaion899  %notx = xor i8 %x, -1900  %xor = xor i8 %y, %x901  %o1 = or i8 %z, %notx902  %o2 = or i8 %xor, %o1903  ret i8 %o2904}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]], -1911; CHECK-NEXT:    [[O2:%.*]] = or i8 [[NAND]], [[Z]]912; CHECK-NEXT:    ret i8 [[O2]]913;914  %z = sub i8 0, %p ; thwart complexity-based canonicalizaion915  %notx = xor i8 %x, -1916  %xor = xor i8 %y, %x917  %o1 = or i8 %z, %notx918  %o2 = or i8 %o1, %xor919  ret i8 %o2920}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:%.*]], -1927; 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, -1934  %xor = xor i8 %x, %y935  call void @use(i8 %xor)936  %o1 = or i8 %notx, %z937  %o2 = or i8 %xor, %o1938  ret i8 %o2939}940 941; negative test - too many uses942 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:%.*]], -1946; 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, -1953  %xor = xor i8 %x, %y954  %o1 = or i8 %notx, %z955  call void @use(i8 %o1)956  %o2 = or i8 %xor, %o1957  ret i8 %o2958}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]], -1965; CHECK-NEXT:    ret i4 [[R]]966;967  %and = and i4 %x, %z968  %nand = xor i4 %and, -1969  %xor = xor i4 %x, %y970  %r = or i4 %nand, %xor971  ret i4 %r972}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, %x982  %nand = xor <2 x i4> %and, <i4 poison, i4 -1>983  %xor = xor <2 x i4> %x, %y984  %r = or <2 x i4> %xor, %nand985  ret <2 x i4> %r986}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]], -1994; CHECK-NEXT:    ret i8 [[R]]995;996  %and = and i8 %x, %z997  call void @use(i8 %and)998  %nand = xor i8 %and, -1999  %xor = xor i8 %y, %x1000  %r = or i8 %nand, %xor1001  ret i8 %r1002}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]], -11008; CHECK-NEXT:    call void @use(i8 [[NAND]])1009; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[AND]], [[Y:%.*]]1010; CHECK-NEXT:    [[R:%.*]] = xor i8 [[TMP1]], -11011; CHECK-NEXT:    ret i8 [[R]]1012;1013  %and = and i8 %z, %x1014  %nand = xor i8 %and, -11015  call void @use(i8 %nand)1016  %xor = xor i8 %y, %x1017  %r = or i8 %xor, %nand1018  ret i8 %r1019}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]], -11028; CHECK-NEXT:    ret i8 [[R]]1029;1030  %and = and i8 %z, %x1031  %nand = xor i8 %and, -11032  %xor = xor i8 %y, %x1033  call void @use(i8 %xor)1034  %r = or i8 %xor, %nand1035  ret i8 %r1036}1037 1038; negative test - too many extra uses1039 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]], -11044; 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, %x1051  %nand = xor i8 %and, -11052  call void @use(i8 %nand)1053  %xor = xor i8 %y, %x1054  call void @use(i8 %xor)1055  %r = or i8 %xor, %nand1056  ret i8 %r1057}1058 1059; (a ^ 4) & (a ^ ~4) -> -11060define i32 @PR75692_1(i32 %x) {1061; CHECK-LABEL: @PR75692_1(1062; CHECK-NEXT:    ret i32 -11063;1064  %t2 = xor i32 %x, 41065  %t3 = xor i32 %x, -51066  %t4 = or i32 %t2, %t31067  ret i32 %t41068}1069 1070; (a ^ 4) & (a ^ 3) is not -11071define i32 @PR75692_2(i32 %x) {1072; CHECK-LABEL: @PR75692_2(1073; CHECK-NEXT:    [[T2:%.*]] = xor i32 [[X:%.*]], 41074; CHECK-NEXT:    [[T3:%.*]] = xor i32 [[X]], -41075; CHECK-NEXT:    [[T4:%.*]] = or i32 [[T2]], [[T3]]1076; CHECK-NEXT:    ret i32 [[T4]]1077;1078  %t2 = xor i32 %x, 41079  %t3 = xor i32 %x, -41080  %t4 = or i32 %t2, %t31081  ret i32 %t41082}1083 1084; (a ^ 4) & (b ^ ~4) is not -1, since a != b is possible1085define i32 @PR75692_3(i32 %x, i32 %y) {1086; CHECK-LABEL: @PR75692_3(1087; CHECK-NEXT:    [[T2:%.*]] = xor i32 [[X:%.*]], 41088; CHECK-NEXT:    [[T3:%.*]] = xor i32 [[Y:%.*]], -51089; CHECK-NEXT:    [[T4:%.*]] = or i32 [[T2]], [[T3]]1090; CHECK-NEXT:    ret i32 [[T4]]1091;1092  %t2 = xor i32 %x, 41093  %t3 = xor i32 %y, -51094  %t4 = or i32 %t2, %t31095  ret i32 %t41096}1097 1098define i32 @or_xor_not(i32 %x, i32 %y) {1099; CHECK-LABEL: @or_xor_not(1100; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], -11101; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[TMP1]]1102; CHECK-NEXT:    ret i32 [[OR1]]1103;1104  %not = xor i32 %y, -11105  %xor = xor i32 %x, %not1106  %or1 = or i32 %xor, %y1107  ret i32 %or11108}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:%.*]], -11113; CHECK-NEXT:    call void @use(i32 [[NOT]])1114; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], -11115; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y]], [[TMP1]]1116; CHECK-NEXT:    ret i32 [[OR1]]1117;1118  %not = xor i32 %y, -11119  call void @use(i32 %not)1120  %xor = xor i32 %x, %not1121  %or1 = or i32 %xor, %y1122  ret i32 %or11123}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]], -11129; 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, -11134  %xor = xor i32 %x, %not1135  call void @use(i32 %xor)1136  %or1 = or i32 %xor, %y1137  ret i32 %or11138}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:%.*]], -11144; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[YY]], [[TMP1]]1145; CHECK-NEXT:    ret i32 [[OR1]]1146;1147  %yy = mul i32 %y, %y ; thwart complexity-based ordering1148  %not = xor i32 %yy, -11149  %xor = xor i32 %not, %x1150  %or1 = or i32 %yy, %xor1151  ret i32 %or11152}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]], -11159; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[YY]], [[TMP1]]1160; CHECK-NEXT:    ret i32 [[OR1]]1161;1162  %yy = mul i32 %y, %y ; thwart complexity-based ordering1163  %xx = mul i32 %x, %x ; thwart complexity-based ordering1164  %not = xor i32 %yy, -11165  %xor = xor i32 %xx, %not1166  %or1 = or i32 %xor, %yy1167  ret i32 %or11168}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:%.*]], 421175; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 421176; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 421177; 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, 421182  %b = mul i32 %bx, 421183  %c = mul i32 %cx, 421184  %xor1 = xor i32 %a, %b1185  %xor2 = xor i32 %b, %c1186  %xor3 = xor i32 %xor2, %a1187  %or = or i32 %xor1, %xor31188  ret i32 %or1189}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:%.*]], 421194; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 421195; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 421196; 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, 421201  %b = mul i32 %bx, 421202  %c = mul i32 %cx, 421203  %xor1 = xor i32 %b, %a1204  %xor2 = xor i32 %b, %c1205  %xor3 = xor i32 %xor2, %a1206  %or = or i32 %xor1, %xor31207  ret i32 %or1208}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:%.*]], 421213; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 421214; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 421215; 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, 421220  %b = mul i32 %bx, 421221  %c = mul i32 %cx, 421222  %xor1 = xor i32 %a, %b1223  %xor2 = xor i32 %c, %b1224  %xor3 = xor i32 %xor2, %a1225  %or = or i32 %xor1, %xor31226  ret i32 %or1227}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:%.*]], 421232; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 421233; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 421234; 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, 421239  %b = mul i32 %bx, 421240  %c = mul i32 %cx, 421241  %xor1 = xor i32 %b, %a1242  %xor2 = xor i32 %c, %b1243  %xor3 = xor i32 %xor2, %a1244  %or = or i32 %xor1, %xor31245  ret i32 %or1246}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:%.*]], 421251; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 421252; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 421253; 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, 421258  %b = mul i32 %bx, 421259  %c = mul i32 %cx, 421260  %xor1 = xor i32 %a, %b1261  %xor2 = xor i32 %b, %c1262  %xor3 = xor i32 %a, %xor21263  %or = or i32 %xor1, %xor31264  ret i32 %or1265}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:%.*]], 421270; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 421271; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 421272; 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, 421277  %b = mul i32 %bx, 421278  %c = mul i32 %cx, 421279  %xor1 = xor i32 %b, %a1280  %xor2 = xor i32 %b, %c1281  %xor3 = xor i32 %a, %xor21282  %or = or i32 %xor1, %xor31283  ret i32 %or1284}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:%.*]], 421289; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 421290; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 421291; 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, 421296  %b = mul i32 %bx, 421297  %c = mul i32 %cx, 421298  %xor1 = xor i32 %a, %b1299  %xor2 = xor i32 %c, %b1300  %xor3 = xor i32 %a, %xor21301  %or = or i32 %xor1, %xor31302  ret i32 %or1303}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:%.*]], 421308; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 421309; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 421310; 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, 421315  %b = mul i32 %bx, 421316  %c = mul i32 %cx, 421317  %xor1 = xor i32 %b, %a1318  %xor2 = xor i32 %c, %b1319  %xor3 = xor i32 %a, %xor21320  %or = or i32 %xor1, %xor31321  ret i32 %or1322}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:%.*]], 421327; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 421328; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 421329; 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, 421334  %b = mul i32 %bx, 421335  %c = mul i32 %cx, 421336  %xor1 = xor i32 %a, %b1337  %xor2 = xor i32 %b, %c1338  %xor3 = xor i32 %xor2, %a1339  %or = or i32 %xor3, %xor11340  ret i32 %or1341}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:%.*]], 421346; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 421347; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 421348; 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, 421353  %b = mul i32 %bx, 421354  %c = mul i32 %cx, 421355  %xor1 = xor i32 %b, %a1356  %xor2 = xor i32 %b, %c1357  %xor3 = xor i32 %xor2, %a1358  %or = or i32 %xor3, %xor11359  ret i32 %or1360}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:%.*]], 421365; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 421366; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 421367; 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, 421372  %b = mul i32 %bx, 421373  %c = mul i32 %cx, 421374  %xor1 = xor i32 %a, %b1375  %xor2 = xor i32 %c, %b1376  %xor3 = xor i32 %xor2, %a1377  %or = or i32 %xor3, %xor11378  ret i32 %or1379}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:%.*]], 421384; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 421385; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 421386; 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, 421391  %b = mul i32 %bx, 421392  %c = mul i32 %cx, 421393  %xor1 = xor i32 %b, %a1394  %xor2 = xor i32 %c, %b1395  %xor3 = xor i32 %xor2, %a1396  %or = or i32 %xor3, %xor11397  ret i32 %or1398}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:%.*]], 421403; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 421404; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 421405; 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, 421410  %b = mul i32 %bx, 421411  %c = mul i32 %cx, 421412  %xor1 = xor i32 %a, %b1413  %xor2 = xor i32 %b, %c1414  %xor3 = xor i32 %a, %xor21415  %or = or i32 %xor3, %xor11416  ret i32 %or1417}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:%.*]], 421422; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 421423; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 421424; 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, 421429  %b = mul i32 %bx, 421430  %c = mul i32 %cx, 421431  %xor1 = xor i32 %b, %a1432  %xor2 = xor i32 %b, %c1433  %xor3 = xor i32 %a, %xor21434  %or = or i32 %xor3, %xor11435  ret i32 %or1436}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:%.*]], 421441; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 421442; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 421443; 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, 421448  %b = mul i32 %bx, 421449  %c = mul i32 %cx, 421450  %xor1 = xor i32 %a, %b1451  %xor2 = xor i32 %c, %b1452  %xor3 = xor i32 %a, %xor21453  %or = or i32 %xor3, %xor11454  ret i32 %or1455}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:%.*]], 421460; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 421461; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 421462; 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, 421467  %b = mul i32 %bx, 421468  %c = mul i32 %cx, 421469  %xor1 = xor i32 %b, %a1470  %xor2 = xor i32 %c, %b1471  %xor3 = xor i32 %a, %xor21472  %or = or i32 %xor3, %xor11473  ret i32 %or1474}1475