@@ -651,3 +651,128 @@ TEST_F(SelectionDAGPatternMatchTest, matchAdvancedProperties) {
651
651
EXPECT_TRUE (sd_match (Add, DAG.get (),
652
652
m_LegalOp (m_IntegerVT (m_Add (m_Value (), m_Value ())))));
653
653
}
654
+
655
+ TEST_F (SelectionDAGPatternMatchTest, matchReassociatableOp) {
656
+ using namespace SDPatternMatch ;
657
+
658
+ SDLoc DL;
659
+ auto Int32VT = EVT::getIntegerVT (Context, 32 );
660
+
661
+ SDValue Op0 = DAG->getCopyFromReg (DAG->getEntryNode (), DL, 1 , Int32VT);
662
+ SDValue Op1 = DAG->getCopyFromReg (DAG->getEntryNode (), DL, 2 , Int32VT);
663
+ SDValue Op2 = DAG->getCopyFromReg (DAG->getEntryNode (), DL, 3 , Int32VT);
664
+ SDValue Op3 = DAG->getCopyFromReg (DAG->getEntryNode (), DL, 8 , Int32VT);
665
+
666
+ // (Op0 + Op1) + (Op2 + Op3)
667
+ SDValue ADD01 = DAG->getNode (ISD::ADD, DL, Int32VT, Op0, Op1);
668
+ SDValue ADD23 = DAG->getNode (ISD::ADD, DL, Int32VT, Op2, Op3);
669
+ SDValue ADD = DAG->getNode (ISD::ADD, DL, Int32VT, ADD01, ADD23);
670
+
671
+ EXPECT_FALSE (sd_match (ADD01, m_ReassociatableAdd (m_Value ())));
672
+ EXPECT_TRUE (sd_match (ADD01, m_ReassociatableAdd (m_Value (), m_Value ())));
673
+ EXPECT_TRUE (sd_match (ADD23, m_ReassociatableAdd (m_Value (), m_Value ())));
674
+ EXPECT_TRUE (sd_match (
675
+ ADD, m_ReassociatableAdd (m_Value (), m_Value (), m_Value (), m_Value ())));
676
+
677
+ // Op0 + (Op1 + (Op2 + Op3))
678
+ SDValue ADD123 = DAG->getNode (ISD::ADD, DL, Int32VT, Op1, ADD23);
679
+ SDValue ADD0123 = DAG->getNode (ISD::ADD, DL, Int32VT, Op0, ADD123);
680
+ EXPECT_TRUE (
681
+ sd_match (ADD123, m_ReassociatableAdd (m_Value (), m_Value (), m_Value ())));
682
+ EXPECT_TRUE (sd_match (ADD0123, m_ReassociatableAdd (m_Value (), m_Value (),
683
+ m_Value (), m_Value ())));
684
+
685
+ // (Op0 - Op1) + (Op2 - Op3)
686
+ SDValue SUB01 = DAG->getNode (ISD::SUB, DL, Int32VT, Op0, Op1);
687
+ SDValue SUB23 = DAG->getNode (ISD::SUB, DL, Int32VT, Op2, Op3);
688
+ SDValue ADDS0123 = DAG->getNode (ISD::ADD, DL, Int32VT, SUB01, SUB23);
689
+
690
+ EXPECT_FALSE (sd_match (SUB01, m_ReassociatableAdd (m_Value (), m_Value ())));
691
+ EXPECT_FALSE (sd_match (ADDS0123, m_ReassociatableAdd (m_Value (), m_Value (),
692
+ m_Value (), m_Value ())));
693
+
694
+ // SUB + SUB matches (Op0 - Op1) + (Op2 - Op3)
695
+ EXPECT_TRUE (
696
+ sd_match (ADDS0123, m_ReassociatableAdd (m_Sub (m_Value (), m_Value ()),
697
+ m_Sub (m_Value (), m_Value ()))));
698
+ EXPECT_FALSE (sd_match (ADDS0123, m_ReassociatableAdd (m_Value (), m_Value (),
699
+ m_Value (), m_Value ())));
700
+
701
+ // (Op0 * Op1) * (Op2 * Op3)
702
+ SDValue MUL01 = DAG->getNode (ISD::MUL, DL, Int32VT, Op0, Op1);
703
+ SDValue MUL23 = DAG->getNode (ISD::MUL, DL, Int32VT, Op2, Op3);
704
+ SDValue MUL = DAG->getNode (ISD::MUL, DL, Int32VT, MUL01, MUL23);
705
+
706
+ EXPECT_TRUE (sd_match (MUL01, m_ReassociatableMul (m_Value (), m_Value ())));
707
+ EXPECT_TRUE (sd_match (MUL23, m_ReassociatableMul (m_Value (), m_Value ())));
708
+ EXPECT_TRUE (sd_match (
709
+ MUL, m_ReassociatableMul (m_Value (), m_Value (), m_Value (), m_Value ())));
710
+
711
+ // Op0 * (Op1 * (Op2 * Op3))
712
+ SDValue MUL123 = DAG->getNode (ISD::MUL, DL, Int32VT, Op1, MUL23);
713
+ SDValue MUL0123 = DAG->getNode (ISD::MUL, DL, Int32VT, Op0, MUL123);
714
+ EXPECT_TRUE (
715
+ sd_match (MUL123, m_ReassociatableMul (m_Value (), m_Value (), m_Value ())));
716
+ EXPECT_TRUE (sd_match (MUL0123, m_ReassociatableMul (m_Value (), m_Value (),
717
+ m_Value (), m_Value ())));
718
+
719
+ // (Op0 - Op1) * (Op2 - Op3)
720
+ SDValue MULS0123 = DAG->getNode (ISD::MUL, DL, Int32VT, SUB01, SUB23);
721
+ EXPECT_TRUE (
722
+ sd_match (MULS0123, m_ReassociatableMul (m_Sub (m_Value (), m_Value ()),
723
+ m_Sub (m_Value (), m_Value ()))));
724
+ EXPECT_FALSE (sd_match (MULS0123, m_ReassociatableMul (m_Value (), m_Value (),
725
+ m_Value (), m_Value ())));
726
+
727
+ // (Op0 && Op1) && (Op2 && Op3)
728
+ SDValue AND01 = DAG->getNode (ISD::AND, DL, Int32VT, Op0, Op1);
729
+ SDValue AND23 = DAG->getNode (ISD::AND, DL, Int32VT, Op2, Op3);
730
+ SDValue AND = DAG->getNode (ISD::AND, DL, Int32VT, AND01, AND23);
731
+
732
+ EXPECT_TRUE (sd_match (AND01, m_ReassociatableAnd (m_Value (), m_Value ())));
733
+ EXPECT_TRUE (sd_match (AND23, m_ReassociatableAnd (m_Value (), m_Value ())));
734
+ EXPECT_TRUE (sd_match (
735
+ AND, m_ReassociatableAnd (m_Value (), m_Value (), m_Value (), m_Value ())));
736
+
737
+ // Op0 && (Op1 && (Op2 && Op3))
738
+ SDValue AND123 = DAG->getNode (ISD::AND, DL, Int32VT, Op1, AND23);
739
+ SDValue AND0123 = DAG->getNode (ISD::AND, DL, Int32VT, Op0, AND123);
740
+ EXPECT_TRUE (
741
+ sd_match (AND123, m_ReassociatableAnd (m_Value (), m_Value (), m_Value ())));
742
+ EXPECT_TRUE (sd_match (AND0123, m_ReassociatableAnd (m_Value (), m_Value (),
743
+ m_Value (), m_Value ())));
744
+
745
+ // (Op0 - Op1) && (Op2 - Op3)
746
+ SDValue ANDS0123 = DAG->getNode (ISD::AND, DL, Int32VT, SUB01, SUB23);
747
+ EXPECT_TRUE (
748
+ sd_match (ANDS0123, m_ReassociatableAnd (m_Sub (m_Value (), m_Value ()),
749
+ m_Sub (m_Value (), m_Value ()))));
750
+ EXPECT_FALSE (sd_match (ANDS0123, m_ReassociatableAnd (m_Value (), m_Value (),
751
+ m_Value (), m_Value ())));
752
+
753
+ // (Op0 || Op1) || (Op2 || Op3)
754
+ SDValue OR01 = DAG->getNode (ISD::OR, DL, Int32VT, Op0, Op1);
755
+ SDValue OR23 = DAG->getNode (ISD::OR, DL, Int32VT, Op2, Op3);
756
+ SDValue OR = DAG->getNode (ISD::OR, DL, Int32VT, OR01, OR23);
757
+
758
+ EXPECT_TRUE (sd_match (OR01, m_ReassociatableOr (m_Value (), m_Value ())));
759
+ EXPECT_TRUE (sd_match (OR23, m_ReassociatableOr (m_Value (), m_Value ())));
760
+ EXPECT_TRUE (sd_match (
761
+ OR, m_ReassociatableOr (m_Value (), m_Value (), m_Value (), m_Value ())));
762
+
763
+ // Op0 || (Op1 || (Op2 || Op3))
764
+ SDValue OR123 = DAG->getNode (ISD::OR, DL, Int32VT, Op1, OR23);
765
+ SDValue OR0123 = DAG->getNode (ISD::OR, DL, Int32VT, Op0, OR123);
766
+ EXPECT_TRUE (
767
+ sd_match (OR123, m_ReassociatableOr (m_Value (), m_Value (), m_Value ())));
768
+ EXPECT_TRUE (sd_match (
769
+ OR0123, m_ReassociatableOr (m_Value (), m_Value (), m_Value (), m_Value ())));
770
+
771
+ // (Op0 - Op1) || (Op2 - Op3)
772
+ SDValue ORS0123 = DAG->getNode (ISD::OR, DL, Int32VT, SUB01, SUB23);
773
+ EXPECT_TRUE (
774
+ sd_match (ORS0123, m_ReassociatableOr (m_Sub (m_Value (), m_Value ()),
775
+ m_Sub (m_Value (), m_Value ()))));
776
+ EXPECT_FALSE (sd_match (
777
+ ORS0123, m_ReassociatableOr (m_Value (), m_Value (), m_Value (), m_Value ())));
778
+ }
0 commit comments