This is an archive of the discontinued LLVM Phabricator instance.

[WebAssembly] Do not omit range checks for i64 switches
ClosedPublic

Authored by tlively on Jul 1 2020, 5:55 PM.

Details

Summary

Since the br_table instruction takes an i32, switches over
i64s (and larger integers) must use the i32.wrap_i64 instruction to
truncate the table index. This truncation makes numbers just over 2^32
indistinguishable from small numbers, so it was a miscompilation to
omit the range check preceding these br_tables. This change fixes the
problem by skipping the "fixing" of the br_table when the range check
is an i64 instruction.

Fixes PR46447.

Diff Detail

Event Timeline

tlively created this revision.Jul 1 2020, 5:55 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 1 2020, 5:55 PM
tlively edited the summary of this revision. (Show Details)Jul 1 2020, 5:56 PM

It looks like this pattern-matches on the switch's input. Does that mean that if we see a valid wrap there, we would also optimize this less?

That is, the invalid case is

switch (value64) { .. }

but a valid case is

switch (int32_t(value64)) { .. }

i.e. if there is a wrap that the user wrote, it's a valid wrap and we don't need a bounds check, as opposed to an "internal" wrap added by LLVM's codegen?

tlively updated this revision to Diff 275467.Jul 3 2020, 4:00 PM
  • Check the range check condition rather than the index source

Good point, that was a problem. I changed the implementation to examine the range check rather than the table index and added a test for this case.

tlively edited the summary of this revision. (Show Details)Jul 3 2020, 4:03 PM
kripken accepted this revision.Jul 3 2020, 4:30 PM

Thanks!

This revision is now accepted and ready to land.Jul 3 2020, 4:30 PM
This revision was automatically updated to reflect the committed changes.