@@ -2521,26 +2521,31 @@ bool isKnownNonZero(const Value* V, unsigned Depth, const Query& Q) {
2521
2521
return isKnownNonZero (V, DemandedElts, Depth, Q);
2522
2522
}
2523
2523
2524
- // / If the pair of operators are the same invertible function of a single
2525
- // / operand return the index of that operand. Otherwise, return None. An
2526
- // / invertible function is one that is 1-to-1 and maps every input value
2527
- // / to exactly one output value. This is equivalent to saying that Op1
2528
- // / and Op2 are equal exactly when the specified pair of operands are equal,
2529
- // / (except that Op1 and Op2 may be poison more often.)
2530
- static Optional<unsigned > getInvertibleOperand (const Operator *Op1,
2531
- const Operator *Op2) {
2524
+ // / If the pair of operators are the same invertible function, return the
2525
+ // / the operands of the function corresponding to each input. Otherwise,
2526
+ // / return None. An invertible function is one that is 1-to-1 and maps
2527
+ // / every input value to exactly one output value. This is equivalent to
2528
+ // / saying that Op1 and Op2 are equal exactly when the specified pair of
2529
+ // / operands are equal, (except that Op1 and Op2 may be poison more often.)
2530
+ static Optional<std::pair<Value*, Value*>>
2531
+ getInvertibleOperands (const Operator *Op1,
2532
+ const Operator *Op2) {
2532
2533
if (Op1->getOpcode () != Op2->getOpcode ())
2533
2534
return None;
2534
2535
2536
+ auto getOperands = [&](unsigned OpNum) -> auto {
2537
+ return std::make_pair (Op1->getOperand (OpNum), Op2->getOperand (OpNum));
2538
+ };
2539
+
2535
2540
switch (Op1->getOpcode ()) {
2536
2541
default :
2537
2542
break ;
2538
2543
case Instruction::Add:
2539
2544
case Instruction::Sub:
2540
2545
if (Op1->getOperand (0 ) == Op2->getOperand (0 ))
2541
- return 1 ;
2546
+ return getOperands ( 1 ) ;
2542
2547
if (Op1->getOperand (1 ) == Op2->getOperand (1 ))
2543
- return 0 ;
2548
+ return getOperands ( 0 ) ;
2544
2549
break ;
2545
2550
case Instruction::Mul: {
2546
2551
// invertible if A * B == (A * B) mod 2^N where A, and B are integers
@@ -2556,7 +2561,7 @@ static Optional<unsigned> getInvertibleOperand(const Operator *Op1,
2556
2561
if (Op1->getOperand (1 ) == Op2->getOperand (1 ) &&
2557
2562
isa<ConstantInt>(Op1->getOperand (1 )) &&
2558
2563
!cast<ConstantInt>(Op1->getOperand (1 ))->isZero ())
2559
- return 0 ;
2564
+ return getOperands ( 0 ) ;
2560
2565
break ;
2561
2566
}
2562
2567
case Instruction::Shl: {
@@ -2569,7 +2574,7 @@ static Optional<unsigned> getInvertibleOperand(const Operator *Op1,
2569
2574
break ;
2570
2575
2571
2576
if (Op1->getOperand (1 ) == Op2->getOperand (1 ))
2572
- return 0 ;
2577
+ return getOperands ( 0 ) ;
2573
2578
break ;
2574
2579
}
2575
2580
case Instruction::AShr:
@@ -2580,13 +2585,13 @@ static Optional<unsigned> getInvertibleOperand(const Operator *Op1,
2580
2585
break ;
2581
2586
2582
2587
if (Op1->getOperand (1 ) == Op2->getOperand (1 ))
2583
- return 0 ;
2588
+ return getOperands ( 0 ) ;
2584
2589
break ;
2585
2590
}
2586
2591
case Instruction::SExt:
2587
2592
case Instruction::ZExt:
2588
2593
if (Op1->getOperand (0 )->getType () == Op2->getOperand (0 )->getType ())
2589
- return 0 ;
2594
+ return getOperands ( 0 ) ;
2590
2595
break ;
2591
2596
case Instruction::PHI: {
2592
2597
const PHINode *PN1 = cast<PHINode>(Op1);
@@ -2604,19 +2609,20 @@ static Optional<unsigned> getInvertibleOperand(const Operator *Op1,
2604
2609
!matchSimpleRecurrence (PN2, BO2, Start2, Step2))
2605
2610
break ;
2606
2611
2607
- Optional<unsigned > Idx = getInvertibleOperand (cast<Operator>(BO1),
2608
- cast<Operator>(BO2));
2609
- if (!Idx || *Idx != 0 )
2610
- break ;
2611
- if (BO1->getOperand (*Idx) != PN1 || BO2->getOperand (*Idx) != PN2)
2612
+ auto Values = getInvertibleOperands (cast<Operator>(BO1),
2613
+ cast<Operator>(BO2));
2614
+ if (!Values)
2615
+ break ;
2616
+
2617
+ // We have to be careful of mutually defined recurrences here. Ex:
2618
+ // * X_i = X_(i-1) OP Y_(i-1), and Y_i = X_(i-1) OP V
2619
+ // * X_i = Y_i = X_(i-1) OP Y_(i-1)
2620
+ // The invertibility of these is complicated, and not worth reasoning
2621
+ // about (yet?).
2622
+ if (Values->first != PN1 || Values->second != PN2)
2612
2623
break ;
2613
2624
2614
- // Phi operands might not be in the same order. TODO: generalize
2615
- // interface to return pair of operands.
2616
- if (PN1->getOperand (0 ) == BO1 && PN2->getOperand (0 ) == BO2)
2617
- return 1 ;
2618
- if (PN1->getOperand (1 ) == BO1 && PN2->getOperand (1 ) == BO2)
2619
- return 0 ;
2625
+ return std::make_pair (Start1, Start2);
2620
2626
}
2621
2627
}
2622
2628
return None;
@@ -2713,11 +2719,9 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
2713
2719
auto *O1 = dyn_cast<Operator>(V1);
2714
2720
auto *O2 = dyn_cast<Operator>(V2);
2715
2721
if (O1 && O2 && O1->getOpcode () == O2->getOpcode ()) {
2716
- if (Optional<unsigned > Opt = getInvertibleOperand (O1, O2)) {
2717
- unsigned Idx = *Opt;
2718
- return isKnownNonEqual (O1->getOperand (Idx), O2->getOperand (Idx),
2719
- Depth + 1 , Q);
2720
- }
2722
+ if (auto Values = getInvertibleOperands (O1, O2))
2723
+ return isKnownNonEqual (Values->first , Values->second , Depth + 1 , Q);
2724
+
2721
2725
if (const PHINode *PN1 = dyn_cast<PHINode>(V1)) {
2722
2726
const PHINode *PN2 = cast<PHINode>(V2);
2723
2727
// FIXME: This is missing a generalization to handle the case where one is
0 commit comments