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

Instruction::has_side_effects and Instrinsic::has_side_effects are not accurate. #4237

Closed
TomAFrench opened this issue Feb 2, 2024 · 4 comments · Fixed by #4945
Closed
Assignees
Labels
bug Something isn't working

Comments

@TomAFrench
Copy link
Member

There's a number of Instructions and Intrinsics which use the side_effects_enabled_var variables in ACIR gen. This has a couple of knock-on-effects:

  • We perform dead instruction elimination were we (maybe?) shouldn't.
    • e.g. We can perform array accesses past the end of the array as long as we don't use the read value.
  • It makes it harder to implement SSA passes such as in feat: add remove_enable_side_effects SSA pass #4224
    • We can no longer easily determine whether a particular Instruction::EnableSideEffects any of the following instructions before we hit the next Instruction::EnableSideEffects.

The list that comes to mind of instructions/intrinsics which should

@github-project-automation github-project-automation bot moved this to 📋 Backlog in Noir Feb 2, 2024
@TomAFrench TomAFrench added the bug Something isn't working label Feb 2, 2024
@jfecher
Copy link
Contributor

jfecher commented Feb 2, 2024

I'm still unsure why has_side_effects is inaccurate after reading the description here.

We perform dead instruction elimination were we (maybe?) shouldn't.

I can see the argument for keeping the error in this case but I'm also alright with enabling more optimizations by keeping the behavior as-is. Unlike e.g. printing, retrieving an element from an array is primarily done to get the actual element rather than doing so to perform the bounds check.

It makes it harder to implement SSA passes such as in #4224

I'm not sure what the motivation for a remove_enable_side_effects instruction would be since there's no motivation explained in the PR. From the name I would think it'd have the same behavior as enable_side_effects u1 0. Can you elaborate why we can't determine if an enable side effects instruction enables side effects in the following instructions or not? I could see not knowing because the argument is dependent on a program input, but it sounds like that's not what this was getting at.

@TomAFrench
Copy link
Member Author

Can you elaborate why we can't determine if an enable side effects instruction enables side effects in the following instructions or not? I could see not knowing because the argument is dependent on a program input, but it sounds like that's not what this was getting at.

In this PR I'm attempting to maximise the number of instructions for which side effects are turned on for as this allows us to maximise the usage of constraint information in #4060. I'm then delaying any Instruction::EnableSideEffects instructions so that I insert them immediately before an instruction which uses side_effects_enabled_var. The trouble is that the instructions listed in this issue report that they don't make use of side_effects_enabled_var but then do. I'm then not inserting the Instruction::EnableSideEffects where I should and then we end up performing incorrect reads/writes.

I'm also alright with enabling more optimizations by keeping the behavior as-is. Unlike e.g. printing, retrieving an element from an array is primarily done to get the actual element rather than doing so to perform the bounds check.

Yeah, I get this point of view. It's only really an issue if you start messing about with Instruction::EnableSideEffects, if you leave them where they are then things are fine.

@Savio-Sou Savio-Sou moved this from 📋 Backlog to 🤔 Grooming in Noir Feb 23, 2024
@TomAFrench
Copy link
Member Author

I've done a little thinking on this and perhaps the issue is that we're overloading has_side_effects to mean two things where splitting it would make things clearer? has_side_effects currently implies both that we inject a predicate during acirgen as well as the instruction having side effects which mean it should be kept in the circuit even if the instruction results are unused (except in the cases where it isn't).

Might it be best to split this into requires_acirgen_predicate and can_eliminate_if_unused? We should then consider whether is_pure falls into some combination of these (seems like it's just !requires_acirgen_predicate?)

@jfecher
Copy link
Contributor

jfecher commented Mar 6, 2024

@TomAFrench that sounds good to me. I'm all in favor of more specific names and splitting out different use cases from each other if needed.

@Savio-Sou Savio-Sou moved this from 🤔 Grooming to 📋 Backlog in Noir Mar 8, 2024
@TomAFrench TomAFrench assigned guipublic and unassigned jfecher Apr 19, 2024
@TomAFrench TomAFrench moved this from 📋 Backlog to 🤔 Grooming in Noir May 3, 2024
@TomAFrench TomAFrench moved this from 🤔 Grooming to 🏗 In progress in Noir May 3, 2024
github-merge-queue bot pushed a commit that referenced this issue May 3, 2024
# Description

## Problem\*

Resolves #4237 

## Summary\*
I replace is_pure() and has_side_effect() by can_be_replaced() and
can_eliminate_if_unused(), the former using
requires_acir_gen_predicate() which indicates if the instructions will
depend on the side_effect_enabled variable.


## Additional Context
I did not renamed has_side_effect() for Intrinsic because I believe the
name is accurate here.


## Documentation\*

Check one:
- [X] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[For Experimental Features]** Documentation to be submitted in a
separate PR.

# PR Checklist\*

- [X] I have tested the changes locally.
- [X] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
@github-project-automation github-project-automation bot moved this from 🏗 In progress to ✅ Done in Noir May 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: ✅ Done
Development

Successfully merging a pull request may close this issue.

3 participants