-
Notifications
You must be signed in to change notification settings - Fork 745
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
Do not code fold ifs with concrete arms #7110
Closed
+179
−111
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -83,11 +83,18 @@ | |
) | ||
) | ||
;; CHECK: (func $negative-zero-b (result f32) | ||
;; CHECK-NEXT: (drop | ||
;; CHECK-NEXT: (if (result f32) | ||
;; CHECK-NEXT: (i32.const 0) | ||
;; CHECK-NEXT: ) | ||
;; CHECK-NEXT: (block $label$0 (result f32) | ||
;; CHECK-NEXT: (f32.const -0) | ||
;; CHECK-NEXT: (then | ||
;; CHECK-NEXT: (block $label$0 (result f32) | ||
;; CHECK-NEXT: (f32.const -0) | ||
;; CHECK-NEXT: ) | ||
;; CHECK-NEXT: ) | ||
;; CHECK-NEXT: (else | ||
;; CHECK-NEXT: (block $label$1 (result f32) | ||
;; CHECK-NEXT: (f32.const -0) | ||
;; CHECK-NEXT: ) | ||
;; CHECK-NEXT: ) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was valid before, so this looks like a regression to me? I may be missing the reason you say this change is needed, sorry. |
||
;; CHECK-NEXT: ) | ||
;; CHECK-NEXT: ) | ||
(func $negative-zero-b (result f32) | ||
|
@@ -106,11 +113,18 @@ | |
) | ||
) | ||
;; CHECK: (func $negative-zero-c (result f32) | ||
;; CHECK-NEXT: (drop | ||
;; CHECK-NEXT: (if (result f32) | ||
;; CHECK-NEXT: (i32.const 0) | ||
;; CHECK-NEXT: ) | ||
;; CHECK-NEXT: (block $label$0 (result f32) | ||
;; CHECK-NEXT: (f32.const 0) | ||
;; CHECK-NEXT: (then | ||
;; CHECK-NEXT: (block $label$0 (result f32) | ||
;; CHECK-NEXT: (f32.const 0) | ||
;; CHECK-NEXT: ) | ||
;; CHECK-NEXT: ) | ||
;; CHECK-NEXT: (else | ||
;; CHECK-NEXT: (block $label$1 (result f32) | ||
;; CHECK-NEXT: (f32.const 0) | ||
;; CHECK-NEXT: ) | ||
;; CHECK-NEXT: ) | ||
;; CHECK-NEXT: ) | ||
;; CHECK-NEXT: ) | ||
(func $negative-zero-c (result f32) | ||
|
@@ -482,3 +496,36 @@ | |
) | ||
) | ||
) | ||
|
||
(module | ||
;; CHECK: (type $0 (func)) | ||
|
||
;; CHECK: (func $unreachable-if-concrete-arms | ||
;; CHECK-NEXT: (drop | ||
;; CHECK-NEXT: (if (result i32) | ||
;; CHECK-NEXT: (unreachable) | ||
;; CHECK-NEXT: (then | ||
;; CHECK-NEXT: (i32.const 1) | ||
;; CHECK-NEXT: ) | ||
;; CHECK-NEXT: (else | ||
;; CHECK-NEXT: (nop) | ||
;; CHECK-NEXT: (i32.const 1) | ||
;; CHECK-NEXT: ) | ||
;; CHECK-NEXT: ) | ||
;; CHECK-NEXT: ) | ||
;; CHECK-NEXT: (unreachable) | ||
;; CHECK-NEXT: ) | ||
(func $unreachable-if-concrete-arms | ||
(if (result i32) | ||
(unreachable) | ||
(then | ||
(i32.const 1) | ||
) | ||
(else | ||
(nop) | ||
(i32.const 1) | ||
) | ||
) | ||
(unreachable) | ||
) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't support that for brs, but for ifs I think we can? New line 259 has the logic to keep the concrete type the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment on lines 502 to 508 explains one of the places that assumes we never have to handle folding concrete types.
The comment
// we must ensure we present the same type as the if had
on line 258 is also wrong; if anif
is unreachable because of an unreachable condition, theifTrue
arm might have some other type.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment on line 502 looks correct to me, but it relates to blocks and brs, and not ifs, unless I'm confused?
Good point about unreachability, it is possible we aren't handling that well enough here. But I think we can add that without removing this optimization.
But with that said, I see we have that merging of arms logic in OptimizeInstructions:
binaryen/src/passes/OptimizeInstructions.cpp
Line 1140 in 485ac7d
So this looks like a redundant optimization actually, and perhaps we can remove it from here. But it is possible we don't handle unreachability fully there, so that might need fixing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The merging of if arms is handled by the same code that optimizes blocks and brs, so it’s not really possible that we support concrete types for one and not the others. It just happened to work out by accident until now because of the extra refinalization.
I’ll look into whether we can remove the optimizations of Ifs here completely or support concrete types for all folded branches.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the folding in OptimizeInstructions can completely replace the optimizations here because it only works if the arms are completely identical, whereas this pass only requires identical suffixes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, it looks like line 251 compares the entire ifTrue and ifFalse arms, while 263+ looks at suffixes. Was your change needed for one of the two?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test introduced here exposed bugs in the suffix folding code (in the presence of relaxed unreachable ifs), but #7094 also has to fix a bug with the folding of equivalent arms, so both kinds of If optimizations here are broken in the presence of concrete arms.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new test below has unreachability, and I agree we should fix that handling here if needed.
What I don't follow is why we need to stop optimizing reachable cases. The first part of the test diff (where my comment is) looks like a regression. Can we not avoid that?