How to use FileCheck's CHECK directives efficiently? (original) (raw)
November 4, 2025, 12:45am 1
Let’s say I’m writing a LIT test on some MLIR pass that emits roughly following IR:
%0 = op0
%1 = op1
%2 = op2(%1)
%3 = op3(%0, %1)
Now I need to choose FileCheck’s CHECK directives to use to match such an IR. At the same time, I care about test quality and want CHECKs to be restrictive enough to catch mistakes, but also flexible to allow different variations of valid IRs. The latter would allow to avoid updating the tests every time some minor changes done to the code.
For the IR above we want to express the following:
op0can appear anywhere beforeop3op1can appear anywhere beforeop2op2can appear anywhere beforeop3
The closest forms of an LIT test to the above I see are (treat as pseudo-code):
CHECK-DAG: %[OP0:.+] = op0
CHECK-DAG: %[OP1:.+] = op1
CHECK: %[OP2:.+] = op2(%[[OP1]])
CHECK: %[OP3:.+] = op3(%[[OP0]], %[[OP2]])
Here, if I’m not wrong, we allow op0 to come after op1, guarantee op1 is before op2 is before op3, but do not allow op0 after op2, while it’s a valid case.
Alternative:
CHECK-DAG: %[OP0:.+] = op0
CHECK-DAG: %[OP1:.+] = op1
CHECK-DAG: %[OP2:.+] = op2(%[[OP1]])
CHECK-DAG: %[OP3:.+] = op3(%[[OP0]], %[[OP2]])
Which allows all valid combinations, but also seemingly allow some wrong ones. However, I wonder if it can be argued this options is still fine, as wrong combinations that potentially will be accepted by CHECKs would violate use-def chain, hence verification and fail the test anyway?
What would be the recommended way to write a test in this case?
That’s right, op dominance violations produce a verification error. So I think it’s fine to use CHECK-DAG in the situation that you described. You don’t risk accidentally passing a test that should have failed.