This is an archive of the discontinued LLVM Phabricator instance.

[WebAssembly] Fold xor by inverting branch target
ClosedPublic

Authored by samparker on Mar 23 2021, 4:09 AM.

Details

Summary

I noticed this pattern appearing when running the bullet physics engine on node. Folding away the xor looks beneficial for different architectures and runtimes, speedups:

BenchmarkMacbook m1 (node)Macbook m1 (wasmtime)Ryzen 3 (node)
Bullet1.4%0.5%1%
Adobe2.4%0.8%2.3%

I have performed this transformation directly in v8 too and the numbers correlate.

Diff Detail

Event Timeline

samparker created this revision.Mar 23 2021, 4:09 AM
samparker requested review of this revision.Mar 23 2021, 4:09 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 23 2021, 4:09 AM
Herald added a subscriber: aheejin. · View Herald Transcript
samparker edited the summary of this revision. (Show Details)Mar 23 2021, 4:11 AM
samparker edited the summary of this revision. (Show Details)
samparker added inline comments.Mar 23 2021, 7:19 AM
llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td
33

Ah, I've remembered that I thought I should check that the incoming I32 is indeed a boolean value.

kripken added inline comments.Mar 23 2021, 7:57 PM
llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td
33

Yes, this seems like a valid pattern for any boolean value, not just one flowing into a br? That is,

bool(x) ^ 1 => !bool(x)

or in wasm

(i32.xor X (i32.const 1)) => (i32.eqz X)

tlively added inline comments.Mar 23 2021, 8:36 PM
llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td
33

Is there a good way to check for boolean values from tablegen patterns?

craig.topper added inline comments.
llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td
33

You'd need to use a PatFrag to call computeKnownBits I think.

Thanks all. I've added a PatLeaf to detect a boolean, but I wasn't sure how to write a negative test using LLVM IR considering that the branch always takes an i1. Any ideas?

Thanks all. I've added a PatLeaf to detect a boolean, but I wasn't sure how to write a negative test using LLVM IR considering that the branch always takes an i1. Any ideas?

If you're starting from brcond, I don't think you need the check. I think the input to brcond should agree with the what the target has defined for getBooleanContents. I assume that's ZeroOrOne for WebAssembly. If you were to generalize this for xors not being used by a brcond you would need a check.

@samparker Can you add tests that do explicit xors in the IR to show that it is not folded out where it shouldn't be?

llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td
29–31

This looks generally useful; Can you move it to WebAssemblyInstrInfo.td and add a TODO about using it in more places?

33

@craig.topper, by

If you're starting from brcond, I don't think you need the check.

Do you mean that we shouldn't need to use bool_node here?

Can you add tests that do explicit xors in the IR to show that it is not folded out where it shouldn't be?

Well this is what I mean, that I don't think this is possible. Writing a test in IR, the br has to take an i1, though this is expanded to i32 during codegen. I could write some IR tests with xors, but they should all be valid. AFAIK, I'd need a way of writing a test input in selection dag form to write a negative test. I have missed some FP conditions in the existing tests, so I'm going to add those.

samparker updated this revision to Diff 334373.Mar 31 2021, 1:33 AM
  • Moved PatLeaf to top-level file.
  • Added tests for missing FP conditions.
  • Added switch tests.
tlively accepted this revision.Mar 31 2021, 12:21 PM

Looks good, thanks! Do you need me to land this for you?

This revision is now accepted and ready to land.Mar 31 2021, 12:21 PM

Cheers! And no thanks - I've had commit access for a few years.

This revision was landed with ongoing or failed builds.Apr 1 2021, 1:24 AM
This revision was automatically updated to reflect the committed changes.
sbc100 added inline comments.Apr 4 2021, 6:23 PM
llvm/test/CodeGen/WebAssembly/comparisons-f32.ll
304

Probably cleaner not to include C++ name mangling here. Maybe just call1?

samparker added inline comments.Apr 6 2021, 1:01 AM
llvm/test/CodeGen/WebAssembly/comparisons-f32.ll
304