FileCheck: combining -DAG and -NOT

If you look at the FileCheck documentation page:
http://llvm.org/docs/CommandGuide/FileCheck.html
you'll find this intriguing example of combining -DAG with -NOT
(slightly amended to avoid some potential confusion):

; CHECK-DAG: BEFORE
; CHECK-NOT: BETWEEN
; CHECK-DAG: AFTER

The page says this will reject the sequence "AFTER BEFORE", which is
correct. It's intuitively obvious that it will also reject the text
"BEFORE BETWEEN AFTER" as well.

Pop Quiz: Will it accept or reject "BEFORE AFTER BETWEEN"?
No, don't go try it, that's cheating; what do you *think* will happen?
Take a minute, I won't mind.

I’d probably have expected the behavior it has - that -DAG and -NOT are not ordered with respect to each other, and form a bag of things ordered with respect to enclosing CHECK:s.

If you want to try turning it into an error, you could find all the places we do use interspersed -DAG and -NOT and have a discussion about whether they’re more buggy than they are useful/correct.

Nope. Sorry, your expectation is incorrect.

“BETWEEN BEFORE AFTER” would be accepted, because: (1) the first –DAG matches BEFORE; (2) the –NOT range starts at the preceding match-point, i.e. the (end of the) BEFORE, thus does not find BETWEEN; (3) the second –DAG starts at the same point as the –NOT.

That is, the first –DAG and the following –NOT are ordered; the –NOT and the subsequent –DAG are not ordered.

You most certainly cannot intermix them freely and expect them all to look at the same range; that is explicitly not the documented (or actual) behavior.

–paulr

Yeah, fair - thanks for the explanation/correction/etc.

That does seem a bit odd. Dunno.

+Michael Liao, who originally implemented the –DAG feature AFAICT. Hopefully the address I found by web searching is correct.

If you want to try turning it into an error, you could find all the places we do use interspersed -DAG and -NOT and have a discussion about whether they’re more buggy than they are useful/correct.

I errored on –NOT followed by –DAG, which caught 44 tests (two of which are in FileCheck’s own tests, but those are not elaborate enough to tell what the intent was). As a side project this will take a little time to work through, especially as about half are in CodeGen tests for unfamiliar targets.

Commentary in FileCheck itself can easily be interpreted to mean the intent was that –NOT would scan the region between the points defined by the last match of the preceding DAG group (which the code gets right) and the first match of the following DAG group (which the code does not get right). But the commentary is not really that clear.

–paulr

FWIW This is the behavior I would expect intuitively.

+Michael Liao, who originally implemented the –DAG feature AFAICT.
Hopefully the address I found by web searching is correct.

If you want to try turning it into an error, you could find all the
places we do use interspersed -DAG and -NOT and have a discussion
about whether they're more buggy than they are useful/correct.

I errored on –NOT followed by –DAG, which caught 44 tests (two of
which are in FileCheck's own tests, but those are not elaborate
enough to tell what the intent was). As a side project this will
take a little time to work through, especially as about half are in
CodeGen tests for unfamiliar targets.

Commentary in FileCheck itself can easily be interpreted to mean the
intent was that –NOT would scan the region between the points defined
by the last match of the preceding DAG group (which the code gets
right) and the first match of the following DAG group (which the code
does not get right). But the commentary is not really that clear.

That's the intention of the original design. CHECK-NOT never occurs
before we find the start point (the start of file by default) and end
point (the end of file by default.) All other points are through other
CHECKs, including CHECK-DAG but excluding CHECK-NOT. So that, if you
use CHECK-NOT, you need to be aware of how that range is defined. As
CHECK-DAG pattern matches a group of pattern in any order, the match
point of that group of CHECK-DAG (a consecutive CHECK-DAGs without any
other CHECKs interleaved) is always the point where one of that pgroup
is matched. If one CHECK-DAG is separated by any other CHECKs
(including CHECK-NOT) from preceding CHECK-DAGs, it is not in the
preceding group of CHECK-DAG. That's way how we could check the order
where a group of patterns should never occur before another group of
patterns.

Thanks
- Michael