Skip to content

Require then and else with if #6201

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

Merged
merged 2 commits into from
Jan 4, 2024
Merged

Require then and else with if #6201

merged 2 commits into from
Jan 4, 2024

Conversation

tlively
Copy link
Member

@tlively tlively commented Jan 4, 2024

We previously supported (and primarily used) a non-standard text format for
conditionals in which the condition, if-true expression, and if-false expression
were all simply s-expression children of the if expression. The standard text
format, however, requires the use of then and else forms to introduce the
if-true and if-false arms of the conditional. Update the legacy text parser to
require the standard format and update all tests to match. Update the printer to
print the standard format as well.

The .wast and .wat test inputs were mechanically updated with this script:
https://gist.github.com/tlively/85ae7f01f92f772241ec994c840ccbb1

We previously supported (and primarily used) a non-standard text format for
conditionals in which the condition, if-true expression, and if-false expression
were all simply s-expression children of the `if` expression. The standard text
format, however, requires the use of `then` and `else` forms to introduce the
if-true and if-false arms of the conditional. Update the legacy text parser to
require the standard format and update all tests to match. Update the printer to
print the standard format as well.

The .wast and .wat test inputs were mechanically updated with this script:
https://gist.github.com/tlively/85ae7f01f92f772241ec994c840ccbb1
@tlively tlively requested a review from kripken January 4, 2024 19:52
@tlively
Copy link
Member Author

tlively commented Jan 4, 2024

Current dependencies on/for this PR:

This stack of pull requests is managed by Graphite.

@tlively
Copy link
Member Author

tlively commented Jan 4, 2024

I strongly recommend hiding whitespace when viewing the diff 😆

Copy link
Member

@kripken kripken left a comment

Choose a reason for hiding this comment

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

Ah, this must have changed when wasm switched to a stack machine... because it is needed to identify structural children.

lgtm % questions

@@ -65,7 +67,7 @@ TEST_F(CFGTest, Print) {
;; preds: [3], succs: [6]
4:
6: i32.const 3
7: block
7: block (result i32)
Copy link
Member

Choose a reason for hiding this comment

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

Unrelated change?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, this is a necessary change. Probably due to a difference in finalization between the parsing for block and the parsing for then, but not sure it's worth digging into more.

Copy link
Member

Choose a reason for hiding this comment

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

Makes sense, it's probably that.

$12$hi = i64toi32_i32$2;
if (($0_1 | 0) == (i64toi32_i32$3 | 0) & ($0$hi | 0) == (i64toi32_i32$1 | 0) | 0) {
$8 = 1;
$8$hi = 0;
Copy link
Member

Choose a reason for hiding this comment

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

I am surprised to see codegen changes here. This change even looks non-NFC. Do you know why this changed?

Copy link
Member Author

Choose a reason for hiding this comment

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

It looks like the source file contains then and else blocks containing single instructions. Those were previously parsed as singleton blocks, but now they're parsed as the actual instructions. I think that change to the IR probably explains the different output here.

Copy link
Member

Choose a reason for hiding this comment

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

Could be. But looking at the output it's not obvious to me if it is or isn't a regression (line 21 is gone, for example - these aren't just renamed variables, there is a structural change), so I think it's worth investigating. Let me know if you'd like help with that.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, I verified that the different parsing behavior explains this. I ran wasm2js on one of the source functions with and without the special case for singleton then and else blocks and the output had precisely these differences.

Copy link
Member

Choose a reason for hiding this comment

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

Great, thanks!

@tlively
Copy link
Member Author

tlively commented Jan 4, 2024

Merge activity

@tlively tlively merged commit a58281c into main Jan 4, 2024
@tlively tlively deleted the standard-if-then-else branch January 4, 2024 22:25
@kripken
Copy link
Member

kripken commented Jan 4, 2024

I see a fuzzer error shortly after this landed which bisects down to this:

running testcase handler: Wasm2JS                                                              
wasm-opt out/test/a.wasm --legalize-js-interface -o /usr/local/google/home/azakai/Dev/2-binaryen
/out/test/a.wasm.temp.wasm                                                                                                                                                                    
wasm-opt out/test/a.wasm.temp.wasm -o out/test/a.wa
sm.temp.wasm --stub-unsupported-js --dealign --alignment-lowering
wasm-opt out/test/a.wasm.temp.wasm -o out/test/b.wa
sm.temp.wasm --roundtrip -O1 --optimize-casts --code-pushing --simplify-locals-notee
wasm-opt out/test/a.wasm.temp.wasm --emit-js-wrapper=/dev/stdout
warning: no passes specified, not doing any work
warning: no output file specified, not emitting output
wasm2js out/test/a.wasm.temp.wasm --emscripten -O --deterministic
terminate called after throwing an instance of 'wasm::SParseException'                                                                                                                        

That is on seed 10441444793052190197.

Reduced testcase:

(module
 (type $0 (func (result i32)))
 (func $0 (result i32)
  (i32.popcnt
   (i32.const 0)
  )
 )
)

STR:

$ bin/wasm-as w.wat -o a.wasm
$ bin/wasm2js a.wasm
terminate called after throwing an instance of 'wasm::SParseException'
Aborted

Oddly it's not a text format issue, as it happens when parsing a binary..?

@tlively

kripken added a commit that referenced this pull request Jan 6, 2024
The intrinsics file changed in #6201 and somehow CMake doesn't automatically
update itself, and needs a manual step for people with existing checkouts (a new
fresh checkout always works). To avoid annoyance for existing checkouts, rename
the vars, which forces CMake to recompute the contents.
radekdoulik pushed a commit to dotnet/binaryen that referenced this pull request Jul 12, 2024
We previously supported (and primarily used) a non-standard text format for
conditionals in which the condition, if-true expression, and if-false expression
were all simply s-expression children of the `if` expression. The standard text
format, however, requires the use of `then` and `else` forms to introduce the
if-true and if-false arms of the conditional. Update the legacy text parser to
require the standard format and update all tests to match. Update the printer to
print the standard format as well.

The .wast and .wat test inputs were mechanically updated with this script:
https://gist.github.com/tlively/85ae7f01f92f772241ec994c840ccbb1
radekdoulik pushed a commit to dotnet/binaryen that referenced this pull request Jul 12, 2024
The intrinsics file changed in WebAssembly#6201 and somehow CMake doesn't automatically
update itself, and needs a manual step for people with existing checkouts (a new
fresh checkout always works). To avoid annoyance for existing checkouts, rename
the vars, which forces CMake to recompute the contents.
@gkdn gkdn mentioned this pull request Aug 31, 2024
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.

2 participants