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

Fix potential unsafe swizzle optimizations #298

Merged
merged 1 commit into from
Apr 17, 2023

Conversation

jwatzman
Copy link
Contributor

The optimization in #253 is unsafe -- vec3(a.x) and vec3(x) are not equivalent. For a single-element swizzles, they are only sure to be safe if they are the Nth argument to a vecN constructor. This change counts the number of arguments, and only allows a single-element swizzle to be optimized in that case.

This does miss some edge cases -- for example, I think the swizzle in code like vec3(foo.xy, bar.x) is safe to remove (vec3(foo.xy, bar)) but that doesn't seem to actually happen in any of the examples in this repo, and it's super tricky to get right in practise (if foo.xy is some variable instead of a swizzle right there), etc etc. So there is potentially still something on the table, but at least for the cases available this is good enough for now.

Fixes #297

Copy link
Owner

@laurentlb laurentlb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative could be to do the transformation only when there are at least two arguments in the constructor call?


float withExtraComponentsUnsafe(in vec3 a) {
vec3 v1 = vec3(a.x);
vec3 v2 = vec3(1.0, a.x);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative could be to do the transformation only when there are at least two arguments in the constructor call?

If I understand you, that would apply to calls like this, which are AIUI unsafe to transform (this is equivalent to vec3(1.0, a.xx) not vec3(1.0, a.xy)).

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vec3(1.0, a) is equivalent to vec3(1.0, a.xy)

So I think that a.xy can become a whenever it's the last argument and there's more than one argument.

Comment on lines 25 to +26
vec4 v4 = vec4(v2, v3.xy);
return v2.x + v3.x + v4.x;
vec3 v5 = vec3(1, v3.rg);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I think that a.xy can become a whenever it's the last argument and there's more than one argument.

Again, assuming I understand you correctly -- that is also properly handled by this PR, and tested via these cases here?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alright, I think we can merge

Thank!

The optimization in laurentlb#253 is unsafe -- `vec3(a.x)` and `vec3(x)` are not
equivalent. For a single-element swizzles, they are only sure to be safe
if they are the Nth argument to a vecN constructor. This change counts
the number of arguments, and only allows a single-element swizzle to be
optimized in that case.

This does miss some edge cases -- for example, I think the swizzle in
code like `vec3(foo.xy, bar.x)` is safe to remove (`vec3(foo.xy, bar)`)
but that doesn't seem to actually happen in any of the examples in this
repo, and it's super tricky to get right in practise (if `foo.xy` is
some variable instead of a swizzle right there), etc etc. So there is
potentially still something on the table, but at least for the cases
available this is good enough for now.

Fixes laurentlb#297
@laurentlb laurentlb merged commit ae8445c into laurentlb:master Apr 17, 2023
laurentlb pushed a commit that referenced this pull request Apr 30, 2023
The optimization in #253 is unsafe -- `vec3(a.x)` and `vec3(x)` are not
equivalent. For a single-element swizzles, they are only sure to be safe
if they are the Nth argument to a vecN constructor. This change counts
the number of arguments, and only allows a single-element swizzle to be
optimized in that case.

This does miss some edge cases -- for example, I think the swizzle in
code like `vec3(foo.xy, bar.x)` is safe to remove (`vec3(foo.xy, bar)`)
but that doesn't seem to actually happen in any of the examples in this
repo, and it's super tricky to get right in practise (if `foo.xy` is
some variable instead of a swizzle right there), etc etc. So there is
potentially still something on the table, but at least for the cases
available this is good enough for now.

Fixes #297
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

Successfully merging this pull request may close these issues.

Incorrect removal of swizzle in vec3
2 participants