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