Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capture variables from successful combination of sub-matches #65

Open
Declan-ARM opened this issue May 16, 2024 · 4 comments
Open

Capture variables from successful combination of sub-matches #65

Declan-ARM opened this issue May 16, 2024 · 4 comments

Comments

@Declan-ARM
Copy link

Hi there (cross-post from re2),

Hopefully not a silly question, but is there a way to capture the variables of all possible matches and perform checks with them?

For example, if I use the following made-up SPIR-V:

    %end = OpVariable %_ptr_Function_int Function
     %15 = OpLoad %int %n
     %16 = OpLoad %int %n
           OpStore %end %16

...the following checks will return false...

const std::string check = R"(
    CHECK:    [[END:%\w+]] = OpVariable
    CHECK: [[LOADED:%\w+]] = OpLoad %int %n
    CHECK:                   OpStore [[END]] [[LOADED]]
)";

...despite OpStore %end %16 being a possibility.

Is there a better syntactical way to capture all possible versions of what LOADED might be and return success if a match is found with one of these versions (instead of stopping after the first match)?

@dneto0
Copy link
Collaborator

dneto0 commented Jan 9, 2025

sorry for the long inattention.

This is a really good question. I don't know how to achieve this with the current set of rules.
I also don't know how to do it with upstream FileCheck.

The requirement is that a rule would have to be matched one-or-more times, like the + modifier in a regular expression.
The way effcee operates, it builds a list of checks, and then 'resolves' each as they are matched. (There's extra complexity with CHECK-NOTs, but set that aside). Currently a check is fully consumed and forgotten once it is resolved once.

If I were to address this, I'd probably add -LAST variants for all the postive directives: CHECK-LAST certainly and maybe CHECK-NEXT-LAST CHECK-SAME-LAST, CHECK-DAG-LAST, CHECK-LABEL-LAST (this last one seems excessive and redundant)
The semantics would be: resolve the check but remain available to be resolved again. The trickiness comes in the interaction with CHECK-NOT, described here:

// We mark a negative check as resolved when it is the earliest unresolved

@dneto0
Copy link
Collaborator

dneto0 commented Jan 9, 2025

But I'm not sure that would really solve your problem, because if you wrote patterns:

const std::string check = R"(
    CHECK:         [[END:%\w+]] = OpVariable
    CHECK-LAST: [[LOADED:%\w+]] = OpLoad %int %n
    CHECK:                        OpStore [[END]] [[LOADED]]
)";

then it would fail if presented with input:

    %end = OpVariable %_ptr_Function_int Function
     %15 = OpLoad %int %n
     %16 = OpLoad %int %n
           OpStore %end %15

@Declan-ARM
Copy link
Author

You're a gentleman, David - thank you for responding, regardless.

It was a really interesting problem, at the time - from memory, I believe we managed to find a way to make things work(ish) with CHECK-DAG.

Perhaps, some kind of CHECK-MULTIPLE might be useful, in the future, where the LOADED variable would be something like a std::unordered_set<T> that allows for checks for the existence of at least one of the potential combinations.

Happy to close now, unless you want to keep open for future work.

@dneto0
Copy link
Collaborator

dneto0 commented Jan 9, 2025

Thanks.

Let's keep this open.

Clearly we don't update this much (a.k.a. "it's stable and does its job"), but I'd like to keep the idea around.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants