Ignore:
Timestamp:
Nov 30, 2015, 4:30:02 PM (4 years ago)
Author:
nmedfort
Message:

More work on n-ary operations. Unresolved bug in DistributionPass?.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/pablo/codegenstate.cpp

    r4878 r4885  
    9191    }
    9292    else if (Not * not1 = dyn_cast<Not>(expr)) {
    93         return not1->getExpr();
     93        return not1->getOperand(0);
    9494    }
    9595    return insertAtInsertionPoint(new Not(expr, makeName("not_")));
     
    105105    }
    106106    else if (Not * not1 = dyn_cast<Not>(expr)) {       
    107         return renameNonNamedNode(not1->getExpr(), std::move(prefix));
     107        return renameNonNamedNode(not1->getOperand(0), std::move(prefix));
    108108    }
    109109    return insertAtInsertionPoint(new Not(expr, makeName(prefix, false)));
     
    232232        return expr1;
    233233    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
    234         if (equals(not1->getExpr(), expr2)) {
     234        if (Not * not2 = dyn_cast<Not>(expr2)) {
     235            return createNot(createOr(not1->getOperand(0), not2->getOperand(0)));
     236        } else if (equals(not1->getOperand(0), expr2)) {
    235237            return createZeroes();
    236238        }
    237239    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
    238         if (equals(expr1, not2->getExpr())) {
     240        if (equals(expr1, not2->getOperand(0))) {
    239241            return createZeroes();
    240242        }
     
    248250        }
    249251    }
     252    if (isa<Not>(expr1) || expr1 > expr2) {
     253        std::swap(expr1, expr2);
     254    }
    250255    return insertAtInsertionPoint(new And(expr1, expr2, makeName("and_")));
    251 }
    252 
    253 And * PabloBlock::createAnd(const unsigned operands, PabloAST * value) {
    254     return insertAtInsertionPoint(new And(operands, value, makeName("and_")));
    255256}
    256257
     
    258259    assert (expr1 && expr2);
    259260    if (isa<Zeroes>(expr2) || isa<Ones>(expr1)) {
    260         return expr2;
    261     } else if (isa<Zeroes>(expr1) || isa<Ones>(expr2) || equals(expr1, expr2)){
    262         return expr1;
     261        return renameNonNamedNode(expr2, std::move(prefix));
     262    }
     263    else if (isa<Zeroes>(expr1) || isa<Ones>(expr2) || equals(expr1, expr2)){
     264        return renameNonNamedNode(expr1, std::move(prefix));
    263265    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
    264         if (equals(not1->getExpr(), expr2)) {
     266        if (Not * not2 = dyn_cast<Not>(expr2)) {
     267            return createNot(createOr(not1->getOperand(0), not2->getOperand(0)), prefix);
     268        }
     269        else if (equals(not1->getOperand(0), expr2)) {
    265270            return createZeroes();
    266271        }
    267272    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
    268         if (equals(expr1, not2->getExpr())) {
     273        if (equals(expr1, not2->getOperand(0))) {
    269274            return createZeroes();
    270275        }
    271     } if (Or * or1 = dyn_cast<Or>(expr1)) {
     276    } else if (Or * or1 = dyn_cast<Or>(expr1)) {
    272277        if (equals(or1->getOperand(0), expr2) || equals(or1->getOperand(1), expr2)) {
    273             return expr2; // (a √ b) ∧ a = a
     278            return expr2;
    274279        }
    275280    } else if (Or * or2 = dyn_cast<Or>(expr2)) {
     
    278283        }
    279284    }
     285    if (isa<Not>(expr1) || expr1 > expr2) {
     286        std::swap(expr1, expr2);
     287    }
    280288    return insertAtInsertionPoint(new And(expr1, expr2, makeName(prefix, false)));
     289}
     290
     291And * PabloBlock::createAnd(const unsigned operands, PabloAST * value) {
     292    return insertAtInsertionPoint(new And(operands, value, makeName("and_")));
    281293}
    282294
     
    285297    if (isa<Zeroes>(expr1) || isa<Ones>(expr2)){
    286298        return expr2;
    287     } else if (isa<Zeroes>(expr2) || isa<Ones>(expr1) || equals(expr1, expr2)) {
     299    }
     300    if (isa<Zeroes>(expr2) || isa<Ones>(expr1) || equals(expr1, expr2)) {
     301        return expr1;
     302    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
     303        // ¬a√b = ¬¬(¬a√b) = ¬(a ∧ ¬b)
     304        return createNot(createAnd(not1->getOperand(0), createNot(expr2)));
     305    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
     306        // a√¬b = ¬¬(¬b√a) = ¬(b ∧ ¬a)
     307        return createNot(createAnd(not2->getOperand(0), createNot(expr1)));
     308    } else if (equals(expr1, expr2)) {
    288309        return expr1;
    289310    } else if (And * and1 = dyn_cast<And>(expr1)) {
    290         if (equals(and1->getOperand(0), expr2) || equals(and1->getOperand(1), expr2)){
    291             return expr2; // (a ∧ b) √ a = a
     311        if (And * and2 = dyn_cast<And>(expr2)) {
     312            PabloAST * const expr1a = and1->getOperand(0);
     313            PabloAST * const expr1b = and1->getOperand(1);
     314            PabloAST * const expr2a = and2->getOperand(0);
     315            PabloAST * const expr2b = and2->getOperand(1);
     316            //These optimizations factor out common components that can occur when sets are formed by union
     317            //(e.g., union of [a-z] and [A-Z].
     318            if (equals(expr1a, expr2a)) {
     319                return createAnd(expr1a, createOr(expr1b, expr2b));
     320            } else if (equals(expr1b, expr2b)) {
     321                return createAnd(expr1b, createOr(expr1a, expr2a));
     322            } else if (equals(expr1a, expr2b)) {
     323                return createAnd(expr1a, createOr(expr1b, expr2a));
     324            } else if (equals(expr1b, expr2a)) {
     325                return createAnd(expr1b, createOr(expr1a, expr2b));
     326            }
     327        } else if (equals(and1->getOperand(0), expr2) || equals(and1->getOperand(1), expr2)){
     328            // (a∧b) √ a = a
     329            return expr2;
    292330        }
    293331    } else if (And * and2 = dyn_cast<And>(expr2)) {
     
    296334        }
    297335    }
     336    if (expr1 > expr2) {
     337        std::swap(expr1, expr2);
     338    }
    298339    return insertAtInsertionPoint(new Or(expr1, expr2, makeName("or_")));
    299 }
    300 
    301 Or * PabloBlock::createOr(const unsigned operands, PabloAST * value) {
    302     return insertAtInsertionPoint(new Or(operands, value, makeName("or_")));
    303340}
    304341
     
    306343    assert (expr1 && expr2);
    307344    if (isa<Zeroes>(expr1) || isa<Ones>(expr2)){
    308         return expr2;
    309     } else if (isa<Zeroes>(expr2) || isa<Ones>(expr1) || equals(expr1, expr2)) {
    310         return expr1;
     345        return renameNonNamedNode(expr2, std::move(prefix));
     346    }
     347    else if (isa<Zeroes>(expr2) || isa<Ones>(expr1) || equals(expr1, expr2)) {
     348        return renameNonNamedNode(expr1, std::move(prefix));
     349    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
     350        // ¬a√b = ¬¬(¬a√b) = ¬(a ∧ ¬b)
     351        return createNot(createAnd(not1->getOperand(0), createNot(expr2)), prefix);
     352    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
     353        // a√¬b = ¬¬(¬b√a) = ¬(b ∧ ¬a)
     354        return createNot(createAnd(not2->getOperand(0), createNot(expr1)), prefix);
    311355    } else if (And * and1 = dyn_cast<And>(expr1)) {
    312         if (equals(and1->getOperand(0), expr2) || equals(and1->getOperand(1), expr2)){
    313             return expr2; // (a ∧ b) √ a = a
     356        if (And * and2 = dyn_cast<And>(expr2)) {
     357            PabloAST * const expr1a = and1->getOperand(0);
     358            PabloAST * const expr1b = and1->getOperand(1);
     359            PabloAST * const expr2a = and2->getOperand(0);
     360            PabloAST * const expr2b = and2->getOperand(1);
     361            //These optimizations factor out common components that can occur when sets are formed by union
     362            //(e.g., union of [a-z] and [A-Z].
     363            if (equals(expr1a, expr2a)) {
     364                return createAnd(expr1a, createOr(expr1b, expr2b), prefix);
     365            } else if (equals(expr1b, expr2b)) {
     366                return createAnd(expr1b, createOr(expr1a, expr2a), prefix);
     367            } else if (equals(expr1a, expr2b)) {
     368                return createAnd(expr1a, createOr(expr1b, expr2a), prefix);
     369            } else if (equals(expr1b, expr2a)) {
     370                return createAnd(expr1b, createOr(expr1a, expr2b), prefix);
     371            }
     372        } else if (equals(and1->getOperand(0), expr2) || equals(and1->getOperand(1), expr2)) {
     373            // (a∧b) √ a = a
     374            return expr2;
    314375        }
    315376    } else if (And * and2 = dyn_cast<And>(expr2)) {
     
    318379        }
    319380    }
     381    if (expr1 > expr2) {
     382        std::swap(expr1, expr2);
     383    }
    320384    return insertAtInsertionPoint(new Or(expr1, expr2, makeName(prefix, false)));
     385}
     386
     387Or * PabloBlock::createOr(const unsigned operands, PabloAST * value) {
     388    return insertAtInsertionPoint(new Or(operands, value, makeName("or_")));
    321389}
    322390
     
    325393    if (expr1 == expr2) {
    326394        return PabloBlock::createZeroes();
     395    }
     396    if (isa<Ones>(expr1)) {
     397        return createNot(expr2);
    327398    } else if (isa<Zeroes>(expr1)){
    328399        return expr2;
     400    } else if (isa<Ones>(expr2)) {
     401        return createNot(expr1);
    329402    } else if (isa<Zeroes>(expr2)){
    330403        return expr1;
    331     } else if (isa<Not>(expr1) && isa<Not>(expr2)) {
    332         return createXor(cast<Not>(expr1)->getExpr(), cast<Not>(expr2)->getExpr());
     404    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
     405        if (Not * not2 = dyn_cast<Not>(expr2)) {
     406            return createXor(not1->getOperand(0), not2->getOperand(0));
     407        }
     408    }
     409    if (expr1 > expr2) {
     410        std::swap(expr1, expr2);
    333411    }
    334412    return insertAtInsertionPoint(new Xor(expr1, expr2, makeName("xor_")));
     
    339417    if (expr1 == expr2) {
    340418        return PabloBlock::createZeroes();
     419    }
     420    if (isa<Ones>(expr1)) {
     421        return createNot(expr2, prefix);
    341422    } else if (isa<Zeroes>(expr1)){
    342423        return expr2;
     424    } else if (isa<Ones>(expr2)) {
     425        return createNot(expr1, prefix);
    343426    } else if (isa<Zeroes>(expr2)){
    344427        return expr1;
    345     } else if (isa<Not>(expr1) && isa<Not>(expr2)) {
    346         return createXor(cast<Not>(expr1)->getExpr(), cast<Not>(expr2)->getExpr());
     428    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
     429        if (Not * not2 = dyn_cast<Not>(expr2)) {
     430            return createXor(not1->getOperand(0), not2->getOperand(0), prefix);
     431        }
     432    }
     433    if (expr1 > expr2) {
     434        std::swap(expr1, expr2);
    347435    }
    348436    return insertAtInsertionPoint(new Xor(expr1, expr2, makeName(prefix, false)));
    349437}
    350 
    351 
    352 //PabloAST * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2) {
    353 //    assert (expr1 && expr2);
    354 //    if (isa<Zeroes>(expr2) || isa<Ones>(expr1)) {
    355 //        return expr2;
    356 //    } else if (isa<Zeroes>(expr1) || isa<Ones>(expr2) || equals(expr1, expr2)){
    357 //        return expr1;
    358 //    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
    359 //        if (Not * not2 = dyn_cast<Not>(expr2)) {
    360 //            return createNot(createOr(not1->getExpr(), not2->getExpr()));
    361 //        } else if (equals(not1->getExpr(), expr2)) {
    362 //            return createZeroes();
    363 //        }
    364 //    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
    365 //        if (equals(expr1, not2->getExpr())) {
    366 //            return createZeroes();
    367 //        }
    368 //    } else if (Or * or1 = dyn_cast<Or>(expr1)) {
    369 //        if (equals(or1->getOperand(0), expr2) || equals(or1->getOperand(1), expr2)) {
    370 //            return expr2;
    371 //        }
    372 //    } else if (Or * or2 = dyn_cast<Or>(expr2)) {
    373 //        if (equals(or2->getOperand(0), expr1) || equals(or2->getOperand(1), expr1)) {
    374 //            return expr1;
    375 //        }
    376 //    }
    377 //    if (isa<Not>(expr1) || expr1 > expr2) {
    378 //        std::swap(expr1, expr2);
    379 //    }
    380 //    return insertAtInsertionPoint(new And(expr1, expr2, makeName("and_")));
    381 //}
    382 
    383 //PabloAST * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2, const std::string prefix) {
    384 //    assert (expr1 && expr2);
    385 //    if (isa<Zeroes>(expr2) || isa<Ones>(expr1)) {
    386 //        return renameNonNamedNode(expr2, std::move(prefix));
    387 //    } else if (isa<Zeroes>(expr1) || isa<Ones>(expr2) || equals(expr1, expr2)){
    388 //        return renameNonNamedNode(expr1, std::move(prefix));
    389 //    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
    390 //        if (Not * not2 = dyn_cast<Not>(expr2)) {
    391 //            return createNot(createOr(not1->getExpr(), not2->getExpr()), prefix);
    392 //        }
    393 //        else if (equals(not1->getExpr(), expr2)) {
    394 //            return createZeroes();
    395 //        }
    396 //    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
    397 //        if (equals(expr1, not2->getExpr())) {
    398 //            return createZeroes();
    399 //        }
    400 //    } else if (Or * or1 = dyn_cast<Or>(expr1)) {
    401 //        if (equals(or1->getOperand(0), expr2) || equals(or1->getOperand(1), expr2)) {
    402 //            return expr2;
    403 //        }
    404 //    } else if (Or * or2 = dyn_cast<Or>(expr2)) {
    405 //        if (equals(or2->getOperand(0), expr1) || equals(or2->getOperand(1), expr1)) {
    406 //            return expr1;
    407 //        }
    408 //    }
    409 //    if (isa<Not>(expr1) || expr1 > expr2) {
    410 //        std::swap(expr1, expr2);
    411 //    }
    412 //    return insertAtInsertionPoint(new And(expr1, expr2, makeName(prefix, false)));
    413 //}
    414 
    415 //PabloAST * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2) {
    416 //    assert (expr1 && expr2);
    417 //    if (isa<Zeroes>(expr1) || isa<Ones>(expr2)){
    418 //        return expr2;
    419 //    }
    420 //    if (isa<Zeroes>(expr2) || isa<Ones>(expr1) || equals(expr1, expr2)) {
    421 //        return expr1;
    422 //    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
    423 //        // ¬a√b = ¬¬(¬a√b) = ¬(a ∧ ¬b)
    424 //        return createNot(createAnd(not1->getExpr(), createNot(expr2)));
    425 //    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
    426 //        // a√¬b = ¬¬(¬b√a) = ¬(b ∧ ¬a)
    427 //        return createNot(createAnd(not2->getExpr(), createNot(expr1)));
    428 //    } else if (equals(expr1, expr2)) {
    429 //        return expr1;
    430 //    } else if (And * and1 = dyn_cast<And>(expr1)) {
    431 //        if (And * and2 = dyn_cast<And>(expr2)) {
    432 //            PabloAST * const expr1a = and1->getOperand(0);
    433 //            PabloAST * const expr1b = and1->getOperand(1);
    434 //            PabloAST * const expr2a = and2->getOperand(0);
    435 //            PabloAST * const expr2b = and2->getOperand(1);
    436 //            //These optimizations factor out common components that can occur when sets are formed by union
    437 //            //(e.g., union of [a-z] and [A-Z].
    438 //            if (equals(expr1a, expr2a)) {
    439 //                return createAnd(expr1a, createOr(expr1b, expr2b));
    440 //            } else if (equals(expr1b, expr2b)) {
    441 //                return createAnd(expr1b, createOr(expr1a, expr2a));
    442 //            } else if (equals(expr1a, expr2b)) {
    443 //                return createAnd(expr1a, createOr(expr1b, expr2a));
    444 //            } else if (equals(expr1b, expr2a)) {
    445 //                return createAnd(expr1b, createOr(expr1a, expr2b));
    446 //            }
    447 //        } else if (equals(and1->getOperand(0), expr2) || equals(and1->getOperand(1), expr2)){
    448 //            // (a∧b) √ a = a
    449 //            return expr2;
    450 //        }
    451 //    } else if (And * and2 = dyn_cast<And>(expr2)) {
    452 //        if (equals(and2->getOperand(0), expr1) || equals(and2->getOperand(1), expr1)) {
    453 //            return expr1;
    454 //        }
    455 //    }
    456 //    if (expr1 > expr2) {
    457 //        std::swap(expr1, expr2);
    458 //    }
    459 //    return insertAtInsertionPoint(new Or(expr1, expr2, makeName("or_")));
    460 //}
    461 
    462 //PabloAST * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2, const std::string prefix) {
    463 //    assert (expr1 && expr2);
    464 //    if (isa<Zeroes>(expr1) || isa<Ones>(expr2)){
    465 //        return renameNonNamedNode(expr2, std::move(prefix));
    466 //    }
    467 //    else if (isa<Zeroes>(expr2) || isa<Ones>(expr1) || equals(expr1, expr2)) {
    468 //        return renameNonNamedNode(expr1, std::move(prefix));
    469 //    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
    470 //        // ¬a√b = ¬¬(¬a√b) = ¬(a ∧ ¬b)
    471 //        return createNot(createAnd(not1->getExpr(), createNot(expr2)), prefix);
    472 //    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
    473 //        // a√¬b = ¬¬(¬b√a) = ¬(b ∧ ¬a)
    474 //        return createNot(createAnd(not2->getExpr(), createNot(expr1)), prefix);
    475 //    } else if (And * and1 = dyn_cast<And>(expr1)) {
    476 //        if (And * and2 = dyn_cast<And>(expr2)) {
    477 //            PabloAST * const expr1a = and1->getOperand(0);
    478 //            PabloAST * const expr1b = and1->getOperand(1);
    479 //            PabloAST * const expr2a = and2->getOperand(0);
    480 //            PabloAST * const expr2b = and2->getOperand(1);
    481 //            //These optimizations factor out common components that can occur when sets are formed by union
    482 //            //(e.g., union of [a-z] and [A-Z].
    483 //            if (equals(expr1a, expr2a)) {
    484 //                return createAnd(expr1a, createOr(expr1b, expr2b), prefix);
    485 //            } else if (equals(expr1b, expr2b)) {
    486 //                return createAnd(expr1b, createOr(expr1a, expr2a), prefix);
    487 //            } else if (equals(expr1a, expr2b)) {
    488 //                return createAnd(expr1a, createOr(expr1b, expr2a), prefix);
    489 //            } else if (equals(expr1b, expr2a)) {
    490 //                return createAnd(expr1b, createOr(expr1a, expr2b), prefix);
    491 //            }
    492 //        } else if (equals(and1->getOperand(0), expr2) || equals(and1->getOperand(1), expr2)) {
    493 //            // (a∧b) √ a = a
    494 //            return expr2;
    495 //        }
    496 //    } else if (And * and2 = dyn_cast<And>(expr2)) {
    497 //        if (equals(and2->getOperand(0), expr1) || equals(and2->getOperand(1), expr1)) {
    498 //            return expr1;
    499 //        }
    500 //    }
    501 //    if (expr1 > expr2) {
    502 //        std::swap(expr1, expr2);
    503 //    }
    504 //    return insertAtInsertionPoint(new Or(expr1, expr2, makeName(prefix, false)));
    505 //}
    506 
    507 //PabloAST * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2) {
    508 //    assert (expr1 && expr2);
    509 //    if (expr1 == expr2) {
    510 //        return PabloBlock::createZeroes();
    511 //    }
    512 //    if (isa<Ones>(expr1)) {
    513 //        return createNot(expr2);
    514 //    } else if (isa<Zeroes>(expr1)){
    515 //        return expr2;
    516 //    } else if (isa<Ones>(expr2)) {
    517 //        return createNot(expr1);
    518 //    } else if (isa<Zeroes>(expr2)){
    519 //        return expr1;
    520 //    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
    521 //        if (Not * not2 = dyn_cast<Not>(expr2)) {
    522 //            return createXor(not1->getExpr(), not2->getExpr());
    523 //        }
    524 //    }
    525 //    if (expr1 > expr2) {
    526 //        std::swap(expr1, expr2);
    527 //    }
    528 //    return insertAtInsertionPoint(new Xor(expr1, expr2, makeName("xor_")));
    529 //}
    530 
    531 //PabloAST * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2, const std::string prefix) {
    532 //    assert (expr1 && expr2);
    533 //    if (expr1 == expr2) {
    534 //        return PabloBlock::createZeroes();
    535 //    }
    536 //    if (isa<Ones>(expr1)) {
    537 //        return createNot(expr2, prefix);
    538 //    } else if (isa<Zeroes>(expr1)){
    539 //        return expr2;
    540 //    } else if (isa<Ones>(expr2)) {
    541 //        return createNot(expr1, prefix);
    542 //    } else if (isa<Zeroes>(expr2)){
    543 //        return expr1;
    544 //    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
    545 //        if (Not * not2 = dyn_cast<Not>(expr2)) {
    546 //            return createXor(not1->getExpr(), not2->getExpr(), prefix);
    547 //        }
    548 //    }
    549 //    if (expr1 > expr2) {
    550 //        std::swap(expr1, expr2);
    551 //    }
    552 //    return insertAtInsertionPoint(new Xor(expr1, expr2, makeName(prefix, false)));
    553 //}
    554438
    555439/// TERNARY CREATE FUNCTION
     
    571455    } else if (equals(trueExpr, falseExpr)) {
    572456        return trueExpr;
    573     } else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getExpr(), falseExpr)) {
     457    } else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getOperand(0), falseExpr)) {
    574458        return createXor(condition, falseExpr);
    575     } else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getExpr())){
     459    } else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getOperand(0))){
    576460        return createXor(condition, falseExpr);
    577461    }
     
    599483        return createAnd(condition, trueExpr, prefix);
    600484    }
    601     else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getExpr(), falseExpr)) {
     485    else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getOperand(0), falseExpr)) {
    602486        return createXor(condition, falseExpr, prefix);
    603487    }
    604     else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getExpr())){
     488    else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getOperand(0))){
    605489        return createXor(condition, falseExpr, prefix);
    606490    }
Note: See TracChangeset for help on using the changeset viewer.