llvm.org GIT mirror llvm / 95ab326
Add 'CHECK-DAG' support Refer to 'FileCheck.rst'f for details of 'CHECK-DAG'. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181827 91177308-0d34-0410-b5e6-96231b3b80d8 Michael Liao 6 years ago
4 changed file(s) with 318 addition(s) and 35 deletion(s). Raw diff Collapse all Expand all
193193 ; CHECK: ret i8
194194 }
195195
196 The "CHECK-DAG:" directive
197 ~~~~~~~~~~~~~~~~~~~~~~~~~~
198
199 If it's necessary to match strings that don't occur in a strictly sequential
200 order, "``CHECK-DAG:``" could be used to verify them between two matches (or
201 before the first match, or after the last match). For example, clang emits
202 vtable globals in reverse order. Using ``CHECK-DAG:``, we can keep the checks
203 in the natural order:
204
205 .. code-block:: c++
206
207 // RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
208
209 struct Foo { virtual void method(); };
210 Foo f; // emit vtable
211 // CHECK-DAG: @_ZTV3Foo =
212
213 struct Bar { virtual void method(); };
214 Bar b;
215 // CHECK-DAG: @_ZTV3Bar =
216
217
218 With captured variables, ``CHECK-DAG:`` is able to match valid topological
219 orderings of a DAG with edges from the definition of a variable to its use.
220 It's useful, e.g., when your test cases need to match different output
221 sequences from the instruction scheduler. For example,
222
223 .. code-block:: llvm
224
225 ; CHECK-DAG: add [[REG1:r[0-9]+]], r1, r2
226 ; CHECK-DAG: add [[REG2:r[0-9]+]], r3, r4
227 ; CHECK: mul r5, [[REG1]], [[REG2]]
228
229 In this case, any order of that two ``add`` instructions will be allowed.
230
231 ``CHECK-NOT:`` directives could be mixed with ``CHECK-DAG:`` directives to
232 exclude strings between the surrounding ``CHECK-DAG:`` directives. As a result,
233 the surrounding ``CHECK-DAG:`` directives cannot be reordered, i.e. all
234 occurrences matching ``CHECK-DAG:`` before ``CHECK-NOT:`` must not fall behind
235 occurrences matching ``CHECK-DAG:`` after ``CHECK-NOT:``. For example,
236
237 .. code-block:: llvm
238
239 ; CHECK-DAG: BEFORE
240 ; CHECK-NOT: NOT
241 ; CHECK-DAG: AFTER
242
243 This case will reject input strings where ``BEFORE`` occurs after ``AFTER``.
244
196245 FileCheck Pattern Matching Syntax
197246 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
198247
0 ; RUN: not FileCheck -check-prefix=X1 -input-file %s %s
1 ; RUN: not FileCheck -check-prefix=X2 -input-file %s %s
2 ; RUN: not FileCheck -check-prefix=X3 -input-file %s %s
3 ; RUN: not FileCheck -check-prefix=X4 -input-file %s %s
4 ; RUN: not FileCheck -check-prefix=X5 -input-file %s %s
5 ; RUN: not FileCheck -check-prefix=X6 -input-file %s %s
6
7 __x1
8 add r10, r1, r2
9 add r11, r3, r4
10 mul r5, r10, r12
11 __x1
12
13 ; X1: __x1
14 ; X1-DAG: add [[REG1:r[0-9]+]], r1, r2
15 ; X1-DAG: add [[REG2:r[0-9]+]], r3, r4
16 ; X1: mul r5, [[REG1]], [[REG2]]
17 ; X1: __x1
18
19 __x2
20 mul r11, r3, r4
21 mul r10, r1, r2
22 add r5, r11, r11
23 __x2
24
25 ; X2: __x2
26 ; X2-DAG: mul [[REG1:r[0-9]+]], r1, r2
27 ; X2-DAG: mul [[REG2:r[0-9]+]], r3, r4
28 ; X2: add r5, [[REG1]], [[REG2]]
29 ; X2: __x2
30
31 __x3
32 add r11, r3, r4
33 add r12, r1, r2
34 mul r5, r10, r11
35 __x3
36
37 ; X3: __x3
38 ; X3-DAG: add [[REG1:r[0-9]+]], r1, r2
39 ; X3-DAG: add [[REG2:r[0-9]+]], r3, r4
40 ; X3-DAG: mul r5, [[REG1]], [[REG2]]
41 ; X3: __x3
42
43 __x4
44 add r11, r3, r4
45 add r12, r1, r2
46 not
47 mul r5, r12, r11
48 __x4
49
50 ; X4: __x4
51 ; X4-DAG: add [[REG1:r[0-9]+]], r1, r2
52 ; X4-DAG: add [[REG2:r[0-9]+]], r3, r4
53 ; X4-NOT: not
54 ; X4-DAG: mul r5, [[REG1]], [[REG2]]
55 ; X4: __x4
56
57 __x5
58 mul r5, r12, r11
59 add r11, r3, r4
60 add r12, r1, r2
61 not
62 __x5
63
64 ; X5: __x5
65 ; X5-DAG: add [[REG1:r[0-9]+]], r1, r2
66 ; X5-DAG: add [[REG2:r[0-9]+]], r3, r4
67 ; X5-NOT: not
68 ; X5-DAG: mul r5, [[REG1]], [[REG2]]
69 ; X5: __x5
70
71 __x6
72 add r11, r3, r4
73 mul r6, r12, r11
74 add r12, r1, r2
75 mul r5, r12, r11
76 __x6
77
78 ; X6: __x6
79 ; X6-DAG: add [[REG1:r[0-9]+]], r1, r2
80 ; X6-DAG: add [[REG2:r[0-9]+]], r3, r4
81 ; X6-NOT: not
82 ; X6-DAG: mul r5, [[REG1]], [[REG2]]
83 ; X6-DAG: mul r6, [[REG1]], [[REG2]]
84 ; X6: __x6
0 ; RUN: FileCheck -input-file %s %s
1
2 add r10, r1, r2
3 add r11, r3, r4
4 mul r5, r10, r11
5
6 mul r11, r3, r4
7 mul r10, r1, r2
8 add r5, r10, r11
9
10 add r11, r3, r4
11 add r10, r1, r2
12 mul r5, r10, r11
13
14 ; CHECK-DAG: add [[REG1:r[0-9]+]], r1, r2
15 ; CHECK-DAG: add [[REG2:r[0-9]+]], r3, r4
16 ; CHECK: mul r5, [[REG1]], [[REG2]]
17
18 ; CHECK-DAG: mul [[REG1:r[0-9]+]], r1, r2
19 ; CHECK-DAG: mul [[REG2:r[0-9]+]], r3, r4
20 ; CHECK: add r5, [[REG1]], [[REG2]]
21
22 ; CHECK-DAG: add [[REG1:r[0-9]+]], r1, r2
23 ; CHECK-DAG: add [[REG2:r[0-9]+]], r3, r4
24 ; CHECK-DAG: mul r5, [[REG1]], [[REG2]]
5959 /// used for trailing CHECK-NOTs.
6060 bool MatchEOF;
6161
62 /// MatchNot
63 bool MatchNot;
64
65 /// MatchDag
66 bool MatchDag;
67
6268 /// FixedStr - If non-empty, this pattern is a fixed string match with the
6369 /// specified fixed string.
6470 StringRef FixedStr;
8288
8389 public:
8490
85 Pattern(bool matchEOF = false) : MatchEOF(matchEOF) { }
91 Pattern(bool matchEOF = false)
92 : MatchEOF(matchEOF), MatchNot(false), MatchDag(false) { }
8693
8794 /// getLoc - Return the location in source code.
8895 SMLoc getLoc() const { return PatternLoc; }
106113 /// involving this pattern.
107114 void PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
108115 const StringMap &VariableTable) const;
116
117 void setMatchNot(bool Not) { MatchNot = Not; }
118 bool getMatchNot() const { return MatchNot; }
119
120 void setMatchDag(bool Dag) { MatchDag = Dag; }
121 bool getMatchDag() const { return MatchDag; }
109122
110123 private:
111124 static void AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr);
580593 /// to a CHECK: directive.
581594 bool IsCheckNext;
582595
583 /// NotStrings - These are all of the strings that are disallowed from
596 /// DagNotStrings - These are all of the strings that are disallowed from
584597 /// occurring between this match string and the previous one (or start of
585598 /// file).
586 std::vector NotStrings;
599 std::vector DagNotStrings;
587600
588601 CheckString(const Pattern &P, SMLoc L, bool isCheckNext)
589602 : Pat(P), Loc(L), IsCheckNext(isCheckNext) {}
590603
591 /// Check - Match check string and its "not strings".
604 /// Check - Match check string and its "not strings" and/or "dag strings".
592605 size_t Check(const SourceMgr &SM, StringRef Buffer, size_t &MatchLen,
593606 StringMap &VariableTable) const;
594607
597610
598611 /// CheckNot - Verify there's no "not strings" in the given buffer.
599612 bool CheckNot(const SourceMgr &SM, StringRef Buffer,
613 const std::vector &NotStrings,
600614 StringMap &VariableTable) const;
615
616 /// CheckDag - Match "dag strings" and their mixed "not strings".
617 size_t CheckDag(const SourceMgr &SM, StringRef Buffer,
618 std::vector &NotStrings,
619 StringMap &VariableTable) const;
601620 };
602621
603622 /// Canonicalize whitespaces in the input file. Line endings are replaced
662681
663682 // Find all instances of CheckPrefix followed by : in the file.
664683 StringRef Buffer = F->getBuffer();
665 std::vector NotMatches;
684 std::vector DagNotMatches;
666685
667686 // LineNumber keeps track of the line on which CheckPrefix instances are
668687 // found.
683702
684703 // When we find a check prefix, keep track of whether we find CHECK: or
685704 // CHECK-NEXT:
686 bool IsCheckNext = false, IsCheckNot = false;
705 bool IsCheckNext = false, IsCheckNot = false, IsCheckDag = false;
687706
688707 // Verify that the : is present after the prefix.
689708 if (Buffer[CheckPrefix.size()] == ':') {
696715 memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) {
697716 Buffer = Buffer.substr(CheckPrefix.size()+5);
698717 IsCheckNot = true;
718 } else if (Buffer.size() > CheckPrefix.size()+5 &&
719 memcmp(Buffer.data()+CheckPrefix.size(), "-DAG:", 5) == 0) {
720 Buffer = Buffer.substr(CheckPrefix.size()+5);
721 IsCheckDag = true;
699722 } else {
700723 Buffer = Buffer.substr(1);
701724 continue;
715738 Pattern P;
716739 if (P.ParsePattern(Buffer.substr(0, EOL), SM, LineNumber))
717740 return true;
741
742 P.setMatchNot(IsCheckNot);
743 P.setMatchDag(IsCheckDag);
718744
719745 Buffer = Buffer.substr(EOL);
720746
727753 return true;
728754 }
729755
730 // Handle CHECK-NOT.
731 if (IsCheckNot) {
732 NotMatches.push_back(P);
756 // Handle CHECK-DAG/-NOT.
757 if (IsCheckDag || IsCheckNot) {
758 DagNotMatches.push_back(P);
733759 continue;
734760 }
735761
737763 CheckStrings.push_back(CheckString(P,
738764 PatternLoc,
739765 IsCheckNext));
740 std::swap(NotMatches, CheckStrings.back().NotStrings);
741 }
742
743 // Add an EOF pattern for any trailing CHECK-NOTs.
744 if (!NotMatches.empty()) {
766 std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
767 }
768
769 // Add an EOF pattern for any trailing CHECK-DAG/-NOTs.
770 if (!DagNotMatches.empty()) {
745771 CheckStrings.push_back(CheckString(Pattern(true),
746772 SMLoc::getFromPointer(Buffer.data()),
747773 false));
748 std::swap(NotMatches, CheckStrings.back().NotStrings);
774 std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
749775 }
750776
751777 if (CheckStrings.empty()) {
757783 return false;
758784 }
759785
786 static void PrintCheckFailed(const SourceMgr &SM, const SMLoc &Loc,
787 const Pattern &Pat, StringRef Buffer,
788 StringMap &VariableTable) {
789 // Otherwise, we have an error, emit an error message.
790 SM.PrintMessage(Loc, SourceMgr::DK_Error,
791 "expected string not found in input");
792
793 // Print the "scanning from here" line. If the current position is at the
794 // end of a line, advance to the start of the next line.
795 Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));
796
797 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
798 "scanning from here");
799
800 // Allow the pattern to print additional information if desired.
801 Pat.PrintFailureInfo(SM, Buffer, VariableTable);
802 }
803
760804 static void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr,
761805 StringRef Buffer,
762806 StringMap &VariableTable) {
763 // Otherwise, we have an error, emit an error message.
764 SM.PrintMessage(CheckStr.Loc, SourceMgr::DK_Error,
765 "expected string not found in input");
766
767 // Print the "scanning from here" line. If the current position is at the
768 // end of a line, advance to the start of the next line.
769 Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));
770
771 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
772 "scanning from here");
773
774 // Allow the pattern to print additional information if desired.
775 CheckStr.Pat.PrintFailureInfo(SM, Buffer, VariableTable);
807 PrintCheckFailed(SM, CheckStr.Loc, CheckStr.Pat, Buffer, VariableTable);
776808 }
777809
778810 /// CountNumNewlinesBetween - Count the number of newlines in the specified
798830 size_t CheckString::Check(const SourceMgr &SM, StringRef Buffer,
799831 size_t &MatchLen,
800832 StringMap &VariableTable) const {
801 size_t MatchPos = Pat.Match(Buffer, MatchLen, VariableTable);
833 size_t LastPos = 0;
834 std::vector NotStrings;
835
836 // Match "dag strings" (with mixed "not strings" if any).
837 LastPos = CheckDag(SM, Buffer, NotStrings, VariableTable);
838 if (LastPos == StringRef::npos)
839 return StringRef::npos;
840
841 // Match itself from the last position after matching CHECK-DAG.
842 StringRef MatchBuffer = Buffer.substr(LastPos);
843 size_t MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable);
802844 if (MatchPos == StringRef::npos) {
803 PrintCheckFailed(SM, *this, Buffer, VariableTable);
845 PrintCheckFailed(SM, *this, MatchBuffer, VariableTable);
804846 return StringRef::npos;
805847 }
806
807 StringRef SkippedRegion = Buffer.substr(0, MatchPos);
848 MatchPos += LastPos;
849
850 StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
808851
809852 // If this check is a "CHECK-NEXT", verify that the previous match was on
810853 // the previous line (i.e. that there is one newline between them).
813856
814857 // If this match had "not strings", verify that they don't exist in the
815858 // skipped region.
816 if (CheckNot(SM, SkippedRegion, VariableTable))
859 if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable))
817860 return StringRef::npos;
818861
819862 return MatchPos;
856899 }
857900
858901 bool CheckString::CheckNot(const SourceMgr &SM, StringRef Buffer,
902 const std::vector &NotStrings,
859903 StringMap &VariableTable) const {
860904 for (unsigned ChunkNo = 0, e = NotStrings.size();
861905 ChunkNo != e; ++ChunkNo) {
906 const Pattern *Pat = NotStrings[ChunkNo];
907 assert(Pat->getMatchNot() && "Expect CHECK-NOT!");
908
862909 size_t MatchLen = 0;
863 size_t Pos = NotStrings[ChunkNo].Match(Buffer, MatchLen, VariableTable);
910 size_t Pos = Pat->Match(Buffer, MatchLen, VariableTable);
864911
865912 if (Pos == StringRef::npos) continue;
866913
867914 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()+Pos),
868915 SourceMgr::DK_Error,
869916 CheckPrefix+"-NOT: string occurred!");
870 SM.PrintMessage(NotStrings[ChunkNo].getLoc(), SourceMgr::DK_Note,
917 SM.PrintMessage(Pat->getLoc(), SourceMgr::DK_Note,
871918 CheckPrefix+"-NOT: pattern specified here");
872919 return true;
873920 }
874921
875922 return false;
923 }
924
925 size_t CheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
926 std::vector &NotStrings,
927 StringMap &VariableTable) const {
928 if (DagNotStrings.empty())
929 return 0;
930
931 size_t LastPos = 0;
932 size_t StartPos = LastPos;
933
934 for (unsigned ChunkNo = 0, e = DagNotStrings.size();
935 ChunkNo != e; ++ChunkNo) {
936 const Pattern &Pat = DagNotStrings[ChunkNo];
937
938 assert((Pat.getMatchDag() ^ Pat.getMatchNot()) &&
939 "Invalid CHECK-DAG or CHECK-NOT!");
940
941 if (Pat.getMatchNot()) {
942 NotStrings.push_back(&Pat);
943 continue;
944 }
945
946 assert(Pat.getMatchDag() && "Expect CHECK-DAG!");
947
948 size_t MatchLen = 0, MatchPos;
949
950 // CHECK-DAG always matches from the start.
951 StringRef MatchBuffer = Buffer.substr(StartPos);
952 MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable);
953 // With a group of CHECK-DAGs, a single mismatching means the match on
954 // that group of CHECK-DAGs fails immediately.
955 if (MatchPos == StringRef::npos) {
956 PrintCheckFailed(SM, Pat.getLoc(), Pat, MatchBuffer, VariableTable);
957 return StringRef::npos;
958 }
959 // Re-calc it as the offset relative to the start of the original string.
960 MatchPos += StartPos;
961
962 if (!NotStrings.empty()) {
963 if (MatchPos < LastPos) {
964 // Reordered?
965 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + MatchPos),
966 SourceMgr::DK_Error,
967 CheckPrefix+"-DAG: found a match of CHECK-DAG"
968 " reordering across a CHECK-NOT");
969 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + LastPos),
970 SourceMgr::DK_Note,
971 CheckPrefix+"-DAG: the farthest match of CHECK-DAG"
972 " is found here");
973 SM.PrintMessage(NotStrings[0]->getLoc(), SourceMgr::DK_Note,
974 CheckPrefix+"-NOT: the crossed pattern specified"
975 " here");
976 SM.PrintMessage(Pat.getLoc(), SourceMgr::DK_Note,
977 CheckPrefix+"-DAG: the reordered pattern specified"
978 " here");
979 return StringRef::npos;
980 }
981 // All subsequent CHECK-DAGs should be matched from the farthest
982 // position of all precedent CHECK-DAGs (including this one.)
983 StartPos = LastPos;
984 // If there's CHECK-NOTs between two CHECK-DAGs or from CHECK to
985 // CHECK-DAG, verify that there's no 'not' strings occurred in that
986 // region.
987 StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
988 size_t Pos = CheckNot(SM, SkippedRegion, NotStrings, VariableTable);
989 if (Pos != StringRef::npos)
990 return StringRef::npos;
991 // Clear "not strings".
992 NotStrings.clear();
993 }
994
995 // Update the last position with CHECK-DAG matches.
996 LastPos = std::max(MatchPos + MatchLen, LastPos);
997 }
998
999 return LastPos;
8761000 }
8771001
8781002 int main(int argc, char **argv) {