@@ -514,8 +514,8 @@ TEST(CodeMoverUtils, IsSafeToMoveTest1) {
514
514
515
515
// Moving instruction to non control flow equivalent places are not
516
516
// supported.
517
- EXPECT_FALSE (isSafeToMoveBefore (*SI_A5, *Entry-> getTerminator (), DT,
518
- &PDT, &DI));
517
+ EXPECT_FALSE (
518
+ isSafeToMoveBefore (*SI_A5, *Entry-> getTerminator (), DT, &PDT, &DI));
519
519
520
520
// Moving PHINode is not supported.
521
521
EXPECT_FALSE (isSafeToMoveBefore (PN, *PN.getNextNode ()->getNextNode (),
@@ -652,3 +652,205 @@ TEST(CodeMoverUtils, IsSafeToMoveTest4) {
652
652
EXPECT_FALSE (isSafeToMoveBefore (*SubInst, *AddInst, DT, &PDT, &DI));
653
653
});
654
654
}
655
+
656
+ TEST (CodeMoverUtils, IsSafeToMoveTest5) {
657
+ LLVMContext C;
658
+
659
+ std::unique_ptr<Module> M =
660
+ parseIR (C, R"( define void @dependence(i32* noalias %A, i32* noalias %B){
661
+ entry:
662
+ store i32 0, i32* %A, align 4 ; storeA0
663
+ store i32 2, i32* %A, align 4 ; storeA1
664
+ %tmp0 = load i32, i32* %A, align 4 ; loadA0
665
+ store i32 1, i32* %B, align 4 ; storeB0
666
+ %tmp1 = load i32, i32* %A, align 4 ; loadA1
667
+ store i32 2, i32* %A, align 4 ; storeA2
668
+ store i32 4, i32* %B, align 4 ; StoreB1
669
+ %tmp2 = load i32, i32* %A, align 4 ; loadA2
670
+ %tmp3 = load i32, i32* %A, align 4 ; loadA3
671
+ %tmp4 = load i32, i32* %B, align 4 ; loadB2
672
+ %tmp5 = load i32, i32* %B, align 4 ; loadB3
673
+ ret void
674
+ })" );
675
+
676
+ run (*M, " dependence" ,
677
+ [&](Function &F, DominatorTree &DT, PostDominatorTree &PDT,
678
+ DependenceInfo &DI) {
679
+ Instruction *LoadA0 = getInstructionByName (F, " tmp0" );
680
+ Instruction *LoadA1 = getInstructionByName (F, " tmp1" );
681
+ Instruction *LoadA2 = getInstructionByName (F, " tmp2" );
682
+ Instruction *LoadA3 = getInstructionByName (F, " tmp3" );
683
+ Instruction *LoadB2 = getInstructionByName (F, " tmp4" );
684
+ Instruction *LoadB3 = getInstructionByName (F, " tmp5" );
685
+ Instruction *StoreA1 = LoadA0->getPrevNode ();
686
+ Instruction *StoreA0 = StoreA1->getPrevNode ();
687
+ Instruction *StoreB0 = LoadA0->getNextNode ();
688
+ Instruction *StoreB1 = LoadA2->getPrevNode ();
689
+ Instruction *StoreA2 = StoreB1->getPrevNode ();
690
+
691
+ // Input forward dependency
692
+ EXPECT_TRUE (isSafeToMoveBefore (*LoadA2, *LoadB2, DT, &PDT, &DI));
693
+ // Input backward dependency
694
+ EXPECT_TRUE (isSafeToMoveBefore (*LoadA3, *LoadA2, DT, &PDT, &DI));
695
+
696
+ // Output forward dependency
697
+ EXPECT_FALSE (isSafeToMoveBefore (*StoreA0, *LoadA0, DT, &PDT, &DI));
698
+ // Output backward dependency
699
+ EXPECT_FALSE (isSafeToMoveBefore (*StoreA1, *StoreA0, DT, &PDT, &DI));
700
+
701
+ // Flow forward dependency
702
+ EXPECT_FALSE (isSafeToMoveBefore (*StoreA1, *StoreB0, DT, &PDT, &DI));
703
+ // Flow backward dependency
704
+ EXPECT_FALSE (isSafeToMoveBefore (*LoadA0, *StoreA1, DT, &PDT, &DI));
705
+
706
+ // Anti forward dependency
707
+ EXPECT_FALSE (isSafeToMoveBefore (*LoadA1, *StoreB1, DT, &PDT, &DI));
708
+ // Anti backward dependency
709
+ EXPECT_FALSE (isSafeToMoveBefore (*StoreA2, *LoadA1, DT, &PDT, &DI));
710
+
711
+ // No input backward dependency
712
+ EXPECT_TRUE (isSafeToMoveBefore (*LoadB2, *LoadA3, DT, &PDT, &DI));
713
+ // No input forward dependency
714
+ EXPECT_TRUE (isSafeToMoveBefore (*LoadA3, *LoadB3, DT, &PDT, &DI));
715
+
716
+ // No Output forward dependency
717
+ EXPECT_TRUE (isSafeToMoveBefore (*StoreA2, *LoadA2, DT, &PDT, &DI));
718
+ // No Output backward dependency
719
+ EXPECT_TRUE (isSafeToMoveBefore (*StoreB1, *StoreA2, DT, &PDT, &DI));
720
+
721
+ // No flow forward dependency
722
+ EXPECT_TRUE (isSafeToMoveBefore (*StoreB0, *StoreA2, DT, &PDT, &DI));
723
+ // No flow backward dependency
724
+ EXPECT_TRUE (isSafeToMoveBefore (*LoadA1, *StoreB0, DT, &PDT, &DI));
725
+
726
+ // No anti backward dependency
727
+ EXPECT_TRUE (isSafeToMoveBefore (*StoreB0, *LoadA0, DT, &PDT, &DI));
728
+ // No anti forward dependency
729
+ EXPECT_TRUE (isSafeToMoveBefore (*LoadA0, *LoadA1, DT, &PDT, &DI));
730
+ });
731
+ }
732
+
733
+ TEST (CodeMoverUtils, IsSafeToMoveTest6) {
734
+ LLVMContext C;
735
+
736
+ std::unique_ptr<Module> M = parseIR (
737
+ C, R"( define void @dependence(i1 %cond, i32* noalias %A, i32* noalias %B){
738
+ entry:
739
+ br i1 %cond, label %bb0, label %bb1
740
+ bb0:
741
+ br label %bb1
742
+ bb1:
743
+ store i32 0, i32* %A, align 4 ; storeA0
744
+ br i1 %cond, label %bb2, label %bb3
745
+ bb2:
746
+ br label %bb3
747
+ bb3:
748
+ store i32 2, i32* %A, align 4 ; storeA1
749
+ br i1 %cond, label %bb4, label %bb5
750
+ bb4:
751
+ br label %bb5
752
+ bb5:
753
+ %tmp0 = load i32, i32* %A, align 4 ; loadA0
754
+ br i1 %cond, label %bb6, label %bb7
755
+ bb6:
756
+ br label %bb7
757
+ bb7:
758
+ store i32 1, i32* %B, align 4 ; storeB0
759
+ br i1 %cond, label %bb8, label %bb9
760
+ bb8:
761
+ br label %bb9
762
+ bb9:
763
+ %tmp1 = load i32, i32* %A, align 4 ; loadA1
764
+ br i1 %cond, label %bb10, label %bb11
765
+ bb10:
766
+ br label %bb11
767
+ bb11:
768
+ store i32 2, i32* %A, align 4 ; storeA2
769
+ br i1 %cond, label %bb12, label %bb13
770
+ bb12:
771
+ br label %bb13
772
+ bb13:
773
+ store i32 4, i32* %B, align 4 ; StoreB1
774
+ br i1 %cond, label %bb14, label %bb15
775
+ bb14:
776
+ br label %bb15
777
+ bb15:
778
+ %tmp2 = load i32, i32* %A, align 4 ; loadA2
779
+ br i1 %cond, label %bb16, label %bb17
780
+ bb16:
781
+ br label %bb17
782
+ bb17:
783
+ %tmp3 = load i32, i32* %A, align 4 ; loadA3
784
+ br i1 %cond, label %bb18, label %bb19
785
+ bb18:
786
+ br label %bb19
787
+ bb19:
788
+ %tmp4 = load i32, i32* %B, align 4 ; loadB2
789
+ br i1 %cond, label %bb20, label %bb21
790
+ bb20:
791
+ br label %bb21
792
+ bb21:
793
+ %tmp5 = load i32, i32* %B, align 4 ; loadB3
794
+ ret void
795
+ })" );
796
+ run (*M, " dependence" ,
797
+ [&](Function &F, DominatorTree &DT, PostDominatorTree &PDT,
798
+ DependenceInfo &DI) {
799
+ BasicBlock *BB1 = getBasicBlockByName (F, " bb1" );
800
+ BasicBlock *BB3 = getBasicBlockByName (F, " bb3" );
801
+ BasicBlock *BB7 = getBasicBlockByName (F, " bb7" );
802
+ BasicBlock *BB11 = getBasicBlockByName (F, " bb11" );
803
+ BasicBlock *BB13 = getBasicBlockByName (F, " bb13" );
804
+ Instruction *LoadA0 = getInstructionByName (F, " tmp0" );
805
+ Instruction *LoadA1 = getInstructionByName (F, " tmp1" );
806
+ Instruction *LoadA2 = getInstructionByName (F, " tmp2" );
807
+ Instruction *LoadA3 = getInstructionByName (F, " tmp3" );
808
+ Instruction *LoadB2 = getInstructionByName (F, " tmp4" );
809
+ Instruction *LoadB3 = getInstructionByName (F, " tmp5" );
810
+ Instruction &StoreA1 = BB3->front ();
811
+ Instruction &StoreA0 = BB1->front ();
812
+ Instruction &StoreB0 = BB7->front ();
813
+ Instruction &StoreB1 = BB13->front ();
814
+ Instruction &StoreA2 = BB11->front ();
815
+
816
+ // Input forward dependency
817
+ EXPECT_TRUE (isSafeToMoveBefore (*LoadA2, *LoadB2, DT, &PDT, &DI));
818
+ // Input backward dependency
819
+ EXPECT_TRUE (isSafeToMoveBefore (*LoadA3, *LoadA2, DT, &PDT, &DI));
820
+
821
+ // Output forward dependency
822
+ EXPECT_FALSE (isSafeToMoveBefore (StoreA0, *LoadA0, DT, &PDT, &DI));
823
+ // Output backward dependency
824
+ EXPECT_FALSE (isSafeToMoveBefore (StoreA1, StoreA0, DT, &PDT, &DI));
825
+
826
+ // Flow forward dependency
827
+ EXPECT_FALSE (isSafeToMoveBefore (StoreA1, StoreB0, DT, &PDT, &DI));
828
+ // Flow backward dependency
829
+ EXPECT_FALSE (isSafeToMoveBefore (*LoadA0, StoreA1, DT, &PDT, &DI));
830
+
831
+ // Anti forward dependency
832
+ EXPECT_FALSE (isSafeToMoveBefore (*LoadA1, StoreB1, DT, &PDT, &DI));
833
+ // Anti backward dependency
834
+ EXPECT_FALSE (isSafeToMoveBefore (StoreA2, *LoadA1, DT, &PDT, &DI));
835
+
836
+ // No input backward dependency
837
+ EXPECT_TRUE (isSafeToMoveBefore (*LoadB2, *LoadA3, DT, &PDT, &DI));
838
+ // No input forward dependency
839
+ EXPECT_TRUE (isSafeToMoveBefore (*LoadA3, *LoadB3, DT, &PDT, &DI));
840
+
841
+ // No Output forward dependency
842
+ EXPECT_TRUE (isSafeToMoveBefore (StoreA2, *LoadA2, DT, &PDT, &DI));
843
+ // No Output backward dependency
844
+ EXPECT_TRUE (isSafeToMoveBefore (StoreB1, StoreA2, DT, &PDT, &DI));
845
+
846
+ // No flow forward dependency
847
+ EXPECT_TRUE (isSafeToMoveBefore (StoreB0, StoreA2, DT, &PDT, &DI));
848
+ // No flow backward dependency
849
+ EXPECT_TRUE (isSafeToMoveBefore (*LoadA1, StoreB0, DT, &PDT, &DI));
850
+
851
+ // No anti backward dependency
852
+ EXPECT_TRUE (isSafeToMoveBefore (StoreB0, *LoadA0, DT, &PDT, &DI));
853
+ // No anti forward dependency
854
+ EXPECT_TRUE (isSafeToMoveBefore (*LoadA0, *LoadA1, DT, &PDT, &DI));
855
+ });
856
+ }
0 commit comments