brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.0 KiB · fa44694 Raw
532 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; (~A | ~B) == ~(A & B)5 6define i43 @demorgan_or_apint1(i43 %A, i43 %B) {7; CHECK-LABEL: @demorgan_or_apint1(8; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = and i43 [[A:%.*]], [[B:%.*]]9; CHECK-NEXT:    [[C:%.*]] = xor i43 [[C_DEMORGAN]], -110; CHECK-NEXT:    ret i43 [[C]]11;12  %NotA = xor i43 %A, -113  %NotB = xor i43 %B, -114  %C = or i43 %NotA, %NotB15  ret i43 %C16}17 18; (~A | ~B) == ~(A & B)19 20define i129 @demorgan_or_apint2(i129 %A, i129 %B) {21; CHECK-LABEL: @demorgan_or_apint2(22; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = and i129 [[A:%.*]], [[B:%.*]]23; CHECK-NEXT:    [[C:%.*]] = xor i129 [[C_DEMORGAN]], -124; CHECK-NEXT:    ret i129 [[C]]25;26  %NotA = xor i129 %A, -127  %NotB = xor i129 %B, -128  %C = or i129 %NotA, %NotB29  ret i129 %C30}31 32; (~A & ~B) == ~(A | B)33 34define i477 @demorgan_and_apint1(i477 %A, i477 %B) {35; CHECK-LABEL: @demorgan_and_apint1(36; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = or i477 [[A:%.*]], [[B:%.*]]37; CHECK-NEXT:    [[C:%.*]] = xor i477 [[C_DEMORGAN]], -138; CHECK-NEXT:    ret i477 [[C]]39;40  %NotA = xor i477 %A, -141  %NotB = xor i477 %B, -142  %C = and i477 %NotA, %NotB43  ret i477 %C44}45 46; (~A & ~B) == ~(A | B)47 48define i129 @demorgan_and_apint2(i129 %A, i129 %B) {49; CHECK-LABEL: @demorgan_and_apint2(50; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = or i129 [[A:%.*]], [[B:%.*]]51; CHECK-NEXT:    [[C:%.*]] = xor i129 [[C_DEMORGAN]], -152; CHECK-NEXT:    ret i129 [[C]]53;54  %NotA = xor i129 %A, -155  %NotB = xor i129 %B, -156  %C = and i129 %NotA, %NotB57  ret i129 %C58}59 60; (~A & ~B) == ~(A | B)61 62define i65 @demorgan_and_apint3(i65 %A, i65 %B) {63; CHECK-LABEL: @demorgan_and_apint3(64; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = or i65 [[A:%.*]], [[B:%.*]]65; CHECK-NEXT:    [[C:%.*]] = xor i65 [[C_DEMORGAN]], -166; CHECK-NEXT:    ret i65 [[C]]67;68  %NotA = xor i65 %A, -169  %NotB = xor i65 -1, %B70  %C = and i65 %NotA, %NotB71  ret i65 %C72}73 74; (~A & ~B) == ~(A | B)75 76define i66 @demorgan_and_apint4(i66 %A, i66 %B) {77; CHECK-LABEL: @demorgan_and_apint4(78; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = or i66 [[A:%.*]], [[B:%.*]]79; CHECK-NEXT:    [[C:%.*]] = xor i66 [[C_DEMORGAN]], -180; CHECK-NEXT:    ret i66 [[C]]81;82  %NotA = xor i66 %A, -183  %NotB = xor i66 %B, -184  %C = and i66 %NotA, %NotB85  ret i66 %C86}87 88; (~A & ~B) == ~(A | B)89 90define i47 @demorgan_and_apint5(i47 %A, i47 %B) {91; CHECK-LABEL: @demorgan_and_apint5(92; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = or i47 [[A:%.*]], [[B:%.*]]93; CHECK-NEXT:    [[C:%.*]] = xor i47 [[C_DEMORGAN]], -194; CHECK-NEXT:    ret i47 [[C]]95;96  %NotA = xor i47 %A, -197  %NotB = xor i47 %B, -198  %C = and i47 %NotA, %NotB99  ret i47 %C100}101 102; This is confirming that 2 transforms work together:103; ~(~A & ~B) --> A | B104 105define i32 @test3(i32 %A, i32 %B) {106; CHECK-LABEL: @test3(107; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = or i32 [[A:%.*]], [[B:%.*]]108; CHECK-NEXT:    ret i32 [[C_DEMORGAN]]109;110  %nota = xor i32 %A, -1111  %notb = xor i32 %B, -1112  %c = and i32 %nota, %notb113  %notc = xor i32 %c, -1114  ret i32 %notc115}116 117; Invert a constant if needed:118; ~(~A & 5) --> A | ~5119 120define i32 @test4(i32 %A) {121; CHECK-LABEL: @test4(122; CHECK-NEXT:    [[NOTC:%.*]] = or i32 [[A:%.*]], -6123; CHECK-NEXT:    ret i32 [[NOTC]]124;125  %nota = xor i32 %A, -1126  %c = and i32 %nota, 5127  %notc = xor i32 %c, -1128  ret i32 %notc129}130 131; Test the mirror of DeMorgan's law with an extra 'not'.132; ~(~A | ~B) --> A & B133 134define i32 @test5(i32 %A, i32 %B) {135; CHECK-LABEL: @test5(136; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = and i32 [[A:%.*]], [[B:%.*]]137; CHECK-NEXT:    ret i32 [[C_DEMORGAN]]138;139  %nota = xor i32 %A, -1140  %notb = xor i32 %B, -1141  %c = or i32 %nota, %notb142  %notc = xor i32 %c, -1143  ret i32 %notc144}145 146; Repeat with weird types for extra coverage.147; ~(~A & ~B) --> A | B148 149define i47 @test3_apint(i47 %A, i47 %B) {150; CHECK-LABEL: @test3_apint(151; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = or i47 [[A:%.*]], [[B:%.*]]152; CHECK-NEXT:    ret i47 [[C_DEMORGAN]]153;154  %nota = xor i47 %A, -1155  %notb = xor i47 %B, -1156  %c = and i47 %nota, %notb157  %notc = xor i47 %c, -1158  ret i47 %notc159}160 161; ~(~A & 5) --> A | ~5162 163define i61 @test4_apint(i61 %A) {164; CHECK-LABEL: @test4_apint(165; CHECK-NEXT:    [[NOTA:%.*]] = and i61 [[A:%.*]], 5166; CHECK-NEXT:    [[C:%.*]] = xor i61 [[NOTA]], 5167; CHECK-NEXT:    ret i61 [[C]]168;169  %nota = xor i61 %A, -1170  %c = and i61 %nota, 5    ; 5 = ~c2171  %notc = xor i61 %c, -1172  ret i61 %c173}174 175; ~(~A | ~B) --> A & B176 177define i71 @test5_apint(i71 %A, i71 %B) {178; CHECK-LABEL: @test5_apint(179; CHECK-NEXT:    [[C_DEMORGAN:%.*]] = and i71 [[A:%.*]], [[B:%.*]]180; CHECK-NEXT:    ret i71 [[C_DEMORGAN]]181;182  %nota = xor i71 %A, -1183  %notb = xor i71 %B, -1184  %c = or i71 %nota, %notb185  %notc = xor i71 %c, -1186  ret i71 %notc187}188 189; ~(~A & B) --> (A | ~B)190 191define i8 @demorgan_nand(i8 %A, i8 %B) {192; CHECK-LABEL: @demorgan_nand(193; CHECK-NEXT:    [[B_NOT:%.*]] = xor i8 [[B:%.*]], -1194; CHECK-NEXT:    [[NOTC:%.*]] = or i8 [[A:%.*]], [[B_NOT]]195; CHECK-NEXT:    ret i8 [[NOTC]]196;197  %notx = xor i8 %A, -1198  %c = and i8 %notx, %B199  %notc = xor i8 %c, -1200  ret i8 %notc201}202 203; ~(~A & B) --> (A | ~B)204 205define i7 @demorgan_nand_apint1(i7 %A, i7 %B) {206; CHECK-LABEL: @demorgan_nand_apint1(207; CHECK-NEXT:    [[B_NOT:%.*]] = xor i7 [[B:%.*]], -1208; CHECK-NEXT:    [[NOTC:%.*]] = or i7 [[A:%.*]], [[B_NOT]]209; CHECK-NEXT:    ret i7 [[NOTC]]210;211  %nota = xor i7 %A, -1212  %c = and i7 %nota, %B213  %notc = xor i7 %c, -1214  ret i7 %notc215}216 217; ~(~A & B) --> (A | ~B)218 219define i117 @demorgan_nand_apint2(i117 %A, i117 %B) {220; CHECK-LABEL: @demorgan_nand_apint2(221; CHECK-NEXT:    [[B_NOT:%.*]] = xor i117 [[B:%.*]], -1222; CHECK-NEXT:    [[NOTC:%.*]] = or i117 [[A:%.*]], [[B_NOT]]223; CHECK-NEXT:    ret i117 [[NOTC]]224;225  %nota = xor i117 %A, -1226  %c = and i117 %nota, %B227  %notc = xor i117 %c, -1228  ret i117 %notc229}230 231; ~(~A | B) --> (A & ~B)232 233define i8 @demorgan_nor(i8 %A, i8 %B) {234; CHECK-LABEL: @demorgan_nor(235; CHECK-NEXT:    [[B_NOT:%.*]] = xor i8 [[B:%.*]], -1236; CHECK-NEXT:    [[NOTC:%.*]] = and i8 [[A:%.*]], [[B_NOT]]237; CHECK-NEXT:    ret i8 [[NOTC]]238;239  %notx = xor i8 %A, -1240  %c = or i8 %notx, %B241  %notc = xor i8 %c, -1242  ret i8 %notc243}244 245; ~(~A | B) --> (A & ~B) - what if we use one of the intermediate results?246 247define i8 @demorgan_nor_use2a(i8 %A, i8 %B) {248; CHECK-LABEL: @demorgan_nor_use2a(249; CHECK-NEXT:    [[NOTA:%.*]] = xor i8 [[A:%.*]], -1250; CHECK-NEXT:    [[USE2A:%.*]] = mul i8 [[NOTA]], 23251; CHECK-NEXT:    [[B_NOT:%.*]] = xor i8 [[B:%.*]], -1252; CHECK-NEXT:    [[NOTC:%.*]] = and i8 [[A]], [[B_NOT]]253; CHECK-NEXT:    [[R:%.*]] = sdiv i8 [[NOTC]], [[USE2A]]254; CHECK-NEXT:    ret i8 [[R]]255;256  %nota = xor i8 %A, -1257  %use2a = mul i8 %nota, 23258  %c = or i8 %nota, %B259  %notc = xor i8 %c, -1260  %r = sdiv i8 %notc, %use2a261  ret i8 %r262}263 264; ~(~A | B) --> (A & ~B) - what if we use one of the intermediate results?265 266define i8 @demorgan_nor_use2b(i8 %A, i8 %B) {267; CHECK-LABEL: @demorgan_nor_use2b(268; CHECK-NEXT:    [[USE2B:%.*]] = mul i8 [[B:%.*]], 23269; CHECK-NEXT:    [[B_NOT:%.*]] = xor i8 [[B]], -1270; CHECK-NEXT:    [[NOTC:%.*]] = and i8 [[A:%.*]], [[B_NOT]]271; CHECK-NEXT:    [[R:%.*]] = sdiv i8 [[NOTC]], [[USE2B]]272; CHECK-NEXT:    ret i8 [[R]]273;274  %use2b = mul i8 %B, 23275  %nota = xor i8 %A, -1276  %c = or i8 %nota, %B277  %notc = xor i8 %c, -1278  %r = sdiv i8 %notc, %use2b279  ret i8 %r280}281 282; ~(~A | B) --> (A & ~B) - what if we use one of the intermediate results?283 284define i8 @demorgan_nor_use2c(i8 %A, i8 %B) {285; CHECK-LABEL: @demorgan_nor_use2c(286; CHECK-NEXT:    [[NOTA:%.*]] = xor i8 [[A:%.*]], -1287; CHECK-NEXT:    [[C:%.*]] = or i8 [[B:%.*]], [[NOTA]]288; CHECK-NEXT:    [[USE2C:%.*]] = mul i8 [[C]], 23289; CHECK-NEXT:    [[NOTC:%.*]] = xor i8 [[C]], -1290; CHECK-NEXT:    [[R:%.*]] = sdiv i8 [[NOTC]], [[USE2C]]291; CHECK-NEXT:    ret i8 [[R]]292;293  %nota = xor i8 %A, -1294  %c = or i8 %nota, %B295  %use2c = mul i8 %c, 23296  %notc = xor i8 %c, -1297  %r = sdiv i8 %notc, %use2c298  ret i8 %r299}300 301; ~(~A | B) --> (A & ~B) - what if we use two of the intermediate results?302 303define i8 @demorgan_nor_use2ab(i8 %A, i8 %B) {304; CHECK-LABEL: @demorgan_nor_use2ab(305; CHECK-NEXT:    [[USE2B:%.*]] = mul i8 [[B:%.*]], 23306; CHECK-NEXT:    [[NOTA:%.*]] = xor i8 [[A:%.*]], -1307; CHECK-NEXT:    [[USE2A:%.*]] = mul i8 [[NOTA]], 17308; CHECK-NEXT:    [[B_NOT:%.*]] = xor i8 [[B]], -1309; CHECK-NEXT:    [[NOTC:%.*]] = and i8 [[A]], [[B_NOT]]310; CHECK-NEXT:    [[R1:%.*]] = sdiv i8 [[NOTC]], [[USE2B]]311; CHECK-NEXT:    [[R2:%.*]] = sdiv i8 [[R1]], [[USE2A]]312; CHECK-NEXT:    ret i8 [[R2]]313;314  %use2b = mul i8 %B, 23315  %nota = xor i8 %A, -1316  %use2a = mul i8 %nota, 17317  %c = or i8 %nota, %B318  %notc = xor i8 %c, -1319  %r1 = sdiv i8 %notc, %use2b320  %r2 = sdiv i8 %r1, %use2a321  ret i8 %r2322}323 324; ~(~A | B) --> (A & ~B) - what if we use two of the intermediate results?325 326define i8 @demorgan_nor_use2ac(i8 %A, i8 %B) {327; CHECK-LABEL: @demorgan_nor_use2ac(328; CHECK-NEXT:    [[NOTA:%.*]] = xor i8 [[A:%.*]], -1329; CHECK-NEXT:    [[USE2A:%.*]] = mul i8 [[NOTA]], 17330; CHECK-NEXT:    [[C:%.*]] = or i8 [[B:%.*]], [[NOTA]]331; CHECK-NEXT:    [[USE2C:%.*]] = mul i8 [[C]], 23332; CHECK-NEXT:    [[NOTC:%.*]] = xor i8 [[C]], -1333; CHECK-NEXT:    [[R1:%.*]] = sdiv i8 [[NOTC]], [[USE2C]]334; CHECK-NEXT:    [[R2:%.*]] = sdiv i8 [[R1]], [[USE2A]]335; CHECK-NEXT:    ret i8 [[R2]]336;337  %nota = xor i8 %A, -1338  %use2a = mul i8 %nota, 17339  %c = or i8 %nota, %B340  %use2c = mul i8 %c, 23341  %notc = xor i8 %c, -1342  %r1 = sdiv i8 %notc, %use2c343  %r2 = sdiv i8 %r1, %use2a344  ret i8 %r2345}346 347; ~(~A | B) --> (A & ~B) - what if we use two of the intermediate results?348 349define i8 @demorgan_nor_use2bc(i8 %A, i8 %B) {350; CHECK-LABEL: @demorgan_nor_use2bc(351; CHECK-NEXT:    [[USE2B:%.*]] = mul i8 [[B:%.*]], 23352; CHECK-NEXT:    [[NOTA:%.*]] = xor i8 [[A:%.*]], -1353; CHECK-NEXT:    [[C:%.*]] = or i8 [[B]], [[NOTA]]354; CHECK-NEXT:    [[USE2C:%.*]] = mul i8 [[C]], 23355; CHECK-NEXT:    [[NOTC:%.*]] = xor i8 [[C]], -1356; CHECK-NEXT:    [[R1:%.*]] = sdiv i8 [[NOTC]], [[USE2C]]357; CHECK-NEXT:    [[R2:%.*]] = sdiv i8 [[R1]], [[USE2B]]358; CHECK-NEXT:    ret i8 [[R2]]359;360  %use2b = mul i8 %B, 23361  %nota = xor i8 %A, -1362  %c = or i8 %nota, %B363  %use2c = mul i8 %c, 23364  %notc = xor i8 %c, -1365  %r1 = sdiv i8 %notc, %use2c366  %r2 = sdiv i8 %r1, %use2b367  ret i8 %r2368}369 370; Do not apply DeMorgan's Law to constants. We prefer 'not' ops.371 372define i32 @demorganize_constant1(i32 %a) {373; CHECK-LABEL: @demorganize_constant1(374; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 15375; CHECK-NEXT:    [[AND1:%.*]] = xor i32 [[AND]], -1376; CHECK-NEXT:    ret i32 [[AND1]]377;378  %and = and i32 %a, 15379  %and1 = xor i32 %and, -1380  ret i32 %and1381}382 383; Do not apply DeMorgan's Law to constants. We prefer 'not' ops.384 385define i32 @demorganize_constant2(i32 %a) {386; CHECK-LABEL: @demorganize_constant2(387; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], -16388; CHECK-NEXT:    [[AND1:%.*]] = xor i32 [[TMP1]], -16389; CHECK-NEXT:    ret i32 [[AND1]]390;391  %and = or i32 %a, 15392  %and1 = xor i32 %and, -1393  ret i32 %and1394}395 396; PR22723: Recognize DeMorgan's Laws when obfuscated by zexts.397 398define i32 @demorgan_or_zext(i1 %X, i1 %Y) {399; CHECK-LABEL: @demorgan_or_zext(400; CHECK-NEXT:    [[OR1_DEMORGAN:%.*]] = and i1 [[X:%.*]], [[Y:%.*]]401; CHECK-NEXT:    [[OR1:%.*]] = xor i1 [[OR1_DEMORGAN]], true402; CHECK-NEXT:    [[OR:%.*]] = zext i1 [[OR1]] to i32403; CHECK-NEXT:    ret i32 [[OR]]404;405  %zextX = zext i1 %X to i32406  %zextY = zext i1 %Y to i32407  %notX  = xor i32 %zextX, 1408  %notY  = xor i32 %zextY, 1409  %or    = or i32 %notX, %notY410  ret i32 %or411}412 413define i32 @demorgan_and_zext(i1 %X, i1 %Y) {414; CHECK-LABEL: @demorgan_and_zext(415; CHECK-NEXT:    [[AND1_DEMORGAN:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]416; CHECK-NEXT:    [[AND1:%.*]] = xor i1 [[AND1_DEMORGAN]], true417; CHECK-NEXT:    [[AND:%.*]] = zext i1 [[AND1]] to i32418; CHECK-NEXT:    ret i32 [[AND]]419;420  %zextX = zext i1 %X to i32421  %zextY = zext i1 %Y to i32422  %notX  = xor i32 %zextX, 1423  %notY  = xor i32 %zextY, 1424  %and   = and i32 %notX, %notY425  ret i32 %and426}427 428define <2 x i32> @demorgan_or_zext_vec(<2 x i1> %X, <2 x i1> %Y) {429; CHECK-LABEL: @demorgan_or_zext_vec(430; CHECK-NEXT:    [[OR1_DEMORGAN:%.*]] = and <2 x i1> [[X:%.*]], [[Y:%.*]]431; CHECK-NEXT:    [[OR1:%.*]] = xor <2 x i1> [[OR1_DEMORGAN]], splat (i1 true)432; CHECK-NEXT:    [[OR:%.*]] = zext <2 x i1> [[OR1]] to <2 x i32>433; CHECK-NEXT:    ret <2 x i32> [[OR]]434;435  %zextX = zext <2 x i1> %X to <2 x i32>436  %zextY = zext <2 x i1> %Y to <2 x i32>437  %notX  = xor <2 x i32> %zextX, <i32 1, i32 1>438  %notY  = xor <2 x i32> %zextY, <i32 1, i32 1>439  %or    = or <2 x i32> %notX, %notY440  ret <2 x i32> %or441}442 443define <2 x i32> @demorgan_and_zext_vec(<2 x i1> %X, <2 x i1> %Y) {444; CHECK-LABEL: @demorgan_and_zext_vec(445; CHECK-NEXT:    [[AND1_DEMORGAN:%.*]] = or <2 x i1> [[X:%.*]], [[Y:%.*]]446; CHECK-NEXT:    [[AND1:%.*]] = xor <2 x i1> [[AND1_DEMORGAN]], splat (i1 true)447; CHECK-NEXT:    [[AND:%.*]] = zext <2 x i1> [[AND1]] to <2 x i32>448; CHECK-NEXT:    ret <2 x i32> [[AND]]449;450  %zextX = zext <2 x i1> %X to <2 x i32>451  %zextY = zext <2 x i1> %Y to <2 x i32>452  %notX  = xor <2 x i32> %zextX, <i32 1, i32 1>453  %notY  = xor <2 x i32> %zextY, <i32 1, i32 1>454  %and   = and <2 x i32> %notX, %notY455  ret <2 x i32> %and456}457 458define i32 @PR28476(i32 %x, i32 %y) {459; CHECK-LABEL: @PR28476(460; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq i32 [[X:%.*]], 0461; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[Y:%.*]], 0462; CHECK-NEXT:    [[AND_NOT:%.*]] = or i1 [[CMP0]], [[CMP1]]463; CHECK-NEXT:    [[COND:%.*]] = zext i1 [[AND_NOT]] to i32464; CHECK-NEXT:    ret i32 [[COND]]465;466  %cmp0 = icmp ne i32 %x, 0467  %cmp1 = icmp ne i32 %y, 0468  %and = and i1 %cmp0, %cmp1469  %zext = zext i1 %and to i32470  %cond = xor i32 %zext, 1471  ret i32 %cond472}473 474define i32 @PR28476_logical(i32 %x, i32 %y) {475; CHECK-LABEL: @PR28476_logical(476; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq i32 [[X:%.*]], 0477; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[Y:%.*]], 0478; CHECK-NEXT:    [[AND_NOT:%.*]] = select i1 [[CMP0]], i1 true, i1 [[CMP1]]479; CHECK-NEXT:    [[COND:%.*]] = zext i1 [[AND_NOT]] to i32480; CHECK-NEXT:    ret i32 [[COND]]481;482  %cmp0 = icmp ne i32 %x, 0483  %cmp1 = icmp ne i32 %y, 0484  %and = select i1 %cmp0, i1 %cmp1, i1 false485  %zext = zext i1 %and to i32486  %cond = xor i32 %zext, 1487  ret i32 %cond488}489 490; ~(~(a | b) | (a & b)) --> (a | b) & ~(a & b) -> a ^ b491 492define i32 @demorgan_plus_and_to_xor(i32 %a, i32 %b) {493; CHECK-LABEL: @demorgan_plus_and_to_xor(494; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]495; CHECK-NEXT:    ret i32 [[TMP1]]496;497  %or = or i32 %b, %a498  %notor = xor i32 %or, -1499  %and = and i32 %b, %a500  %or2 = or i32 %and, %notor501  %not = xor i32 %or2, -1502  ret i32 %not503}504 505define <4 x i32> @demorgan_plus_and_to_xor_vec(<4 x i32> %a, <4 x i32> %b) {506; CHECK-LABEL: @demorgan_plus_and_to_xor_vec(507; CHECK-NEXT:    [[TMP1:%.*]] = xor <4 x i32> [[A:%.*]], [[B:%.*]]508; CHECK-NEXT:    ret <4 x i32> [[TMP1]]509;510  %or = or <4 x i32> %a, %b511  %notor = xor <4 x i32> %or, < i32 -1, i32 -1, i32 -1, i32 -1 >512  %and = and <4 x i32> %a, %b513  %or2 = or <4 x i32> %and, %notor514  %not = xor <4 x i32> %or2, < i32 -1, i32 -1, i32 -1, i32 -1 >515  ret <4 x i32> %not516}517 518; (a ^ b) | ~(a | b) --> ~(a & b)519 520define i32 @PR45984(i32 %0, i32 %1) {521; CHECK-LABEL: @PR45984(522; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP1:%.*]], [[TMP0:%.*]]523; CHECK-NEXT:    [[TMP4:%.*]] = xor i32 [[TMP3]], -1524; CHECK-NEXT:    ret i32 [[TMP4]]525;526  %3 = xor i32 %1, %0527  %4 = or i32 %1, %0528  %5 = xor i32 %4, -1529  %6 = or i32 %3, %5530  ret i32 %6531}532