The vector shift operation in WebAssembly uses an i32 shift amount type,
while the LLVM IR requires binary operator uses the same type of operands.
When the shift amount operand is splated from a different block, the splat source
will not be exported and the vector shift will be unrolled to scalar shifts.
This patch enables the vector shift to identify the splat source value from
the other block, and generate expected WebAssembly bytecode when lowering.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Time | Test | |
---|---|---|
60,030 ms | x64 debian > MLIR.Examples/standalone::test.toy |
Event Timeline
This is to resolve a WebAssembly codegen issue when vector shift is used in a loop, while the shift amount is initialized outside the loop. Could you help take a look? Thanks!
Thanks for the patch! It looks like this will be a nice improvement.
@craig.topper, it would be great to get your comments as well, as someone more familiar with the target-independent infrastructure here.
llvm/include/llvm/CodeGen/SelectionDAG.h | ||
---|---|---|
2459–2460 | It would be good to add a comment describing the contents of this map. | |
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp | ||
840 | Why allow null instruction pointers here? It would seem simpler to ensure that callers pass a valid instruction and to assume we have a valid instruction here. | |
844 | What is the benefit of including isShiftAmountScalar() here, given that we know it is always true? | |
llvm/test/CodeGen/WebAssembly/simd-shift-in-loop.ll | ||
2 | What do you think about using the auto-update script for this test? The output would be more verbose, but it would also be easy to update if anything changes, and I think it would be helpful to see that the whole function is emitted correctly. | |
17 | Can we add a test where the vshift is a phi, just to show that that still works correctly? |
Thank you Thomas for the comments! Please see my updates in the new revision.
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp | ||
---|---|---|
840 | This is a fast check on the outside block when visit the splat vector, and don't know yet if the splat vector will be used by a shift op. | |
844 | This will be called in SelectionDAGBuilder to skip the optimizaiton for other platforms when visit shift. | |
llvm/test/CodeGen/WebAssembly/simd-shift-in-loop.ll | ||
2 | Sure. Previously I make it simple to avoid mismatch on unrelated changes. But if we have an auto-update script that would be helpful to verify the whole function directly. | |
17 | Sure. I have added one more test. |
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp | ||
---|---|---|
840 | Oh I see, that makes sense. | |
844 | We know that the isShiftAmountScalar() here will be the WebAssemblyTargetLowering version of isShiftAmountScalar(), so it will always be true, right? So this line could be: return I->isShift() && I->getOperand(1) == Splat; |
Could this use the TargetLowering::shouldSinkOperands hook to get CodeGenPrepare to move the splat into the loop. ARM, X86, and RISC-V all do that.
Thanks for the suggestion! I have revised the code to use this existing hook. Please help take a look again. @craig.topper @tlively Thanks!
Sure thing. I'll use your author email from the other patches in your phabricator profile.
It would be good to add a comment describing the contents of this map.