[PATCH] D147504: [WebAssembly] `AsmTypeCheck` support to br instr
Heejin Ahn via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun Apr 9 06:18:26 PDT 2023
aheejin added a comment.
This will have conflicts with D147852 <https://reviews.llvm.org/D147852>, so depending on which lands first, the other needs to resolve them. D147852 <https://reviews.llvm.org/D147852> doesn't intend to add new functionalities (like `br` checking here) though; it just handles other block-ending instructions in the same way as `end_block`.
================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp:54-57
+WebAssemblyAsmOperandFrame::WebAssemblyAsmOperandFrame(
+ FrameType FrameType, const SmallVectorImpl<wasm::ValType> &Stack,
+ const wasm::WasmSignature &Signature)
+ : Type(FrameType), EnterStack(Stack.begin(), Stack.end()), Sig(Signature) {}
----------------
I think you can move this to the header, given that this doesn't have a body
================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp:63
+ case FrameType::Loop:
+ // https://webassembly.github.io/spec/core/valid/instructions.html#xref-syntax-instructions-syntax-instr-control-mathsf-loop-xref-syntax-instructions-syntax-blocktype-mathit-blocktype-xref-syntax-instructions-syntax-instr-mathit-instr-ast-xref-syntax-instructions-syntax-instr-control-mathsf-end
+ return OperandStack{Sig.Params.begin(), Sig.Params.end()};
----------------
I don't think we need to link the formal spec here; it's assumed the implementer and the reader of this file either knows or is able to look for it. We don't link it elsewhere in the file either.
================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp:167-168
+static std::optional<std::string>
+checkStackTop(SmallVectorImpl<wasm::ValType> const &ExpectedStackTop,
+ SmallVectorImpl<wasm::ValType> const &Got) {
+ for (size_t I = 0; I < ExpectedStackTop.size(); I++) {
----------------
================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp:187
+ std::to_string(BrLevel) + " (max " +
+ std::to_string(BrStack.size()) + ")");
+ const llvm::WebAssemblyAsmOperandFrame &Frame =
----------------
Shouldn't we do -1? If not, the message can be something like
```
br: invalid depth 3 (max 3)
```
But -1 also has a problem, because when `BrStack` is empty it will print something like
```
br: invalid depth 0 (max -1)
```
So if we want to print `(max N)`, it would be better to handle that case smoothly too.
================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp:192
+ checkStackTop(Frame.getResultType(), Stack);
+ if (StackCheckResult.has_value())
+ return typeError(ErrorLoc,
----------------
================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp:202
+ BrStack.push_back(WebAssemblyAsmOperandFrame{Type, Stack, LastSig});
+ // check signature
+ WebAssemblyAsmOperandFrame::OperandStack EnterStack =
----------------
================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp:204
+ WebAssemblyAsmOperandFrame::OperandStack EnterStack =
+ BrStack.back().getEnterStack();
+ for (wasm::ValType VT : llvm::reverse(LastSig.Params))
----------------
TODO aheejin copy? do we use this later again?
================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp:218
- for (size_t i = 0; i < LastSig.Returns.size(); i++) {
- auto EVT = LastSig.Returns[i];
- auto PVT = Stack[Stack.size() - LastSig.Returns.size() + i];
- if (PVT != EVT)
- return typeError(
- ErrorLoc, StringRef("end got ") + WebAssembly::typeToString(PVT) +
- ", expected " + WebAssembly::typeToString(EVT));
+ if (StackCheckResult.has_value())
+ return typeError(ErrorLoc,
----------------
================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp:221-222
+ StringRef{"end "} + StringRef{StackCheckResult.value()});
+ // in some cases (unreachable / br), `Stack` will be invalid and need to be
+ // recover
+ if (RecoverEnter)
----------------
================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp:226-227
+ else {
+ if (Unreachable)
+ Stack = BrStack.pop_back_val().applySignature();
+ else
----------------
Why is this and what does this code do?
================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp:236-240
bool WebAssemblyAsmTypeCheck::checkSig(SMLoc ErrorLoc,
- const wasm::WasmSignature& Sig) {
+ const wasm::WasmSignature &Sig) {
for (auto VT : llvm::reverse(Sig.Params))
- if (popType(ErrorLoc, VT)) return true;
+ if (popType(ErrorLoc, VT))
+ return true;
----------------
I think you applied `clang-format` to the whole file. While we try to keep files clang-formatted, I think it'd be better not to mix this with other functionality changes. Can you revert this?
Tip: `git clang-format main` will clang-format only the changed lines, not the whole file. You can replace `main` with another branch or a commit if necessary.
================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp:279
return typeError(ErrorLoc, StringRef("symbol ") + WasmSym->getName() +
- " missing .globaltype");
+ " missing .globaltype");
}
----------------
Please revert unrelated clang-format changes
================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp:417-420
+ if (popType(ErrorLoc, wasm::ValType::I32))
+ return true;
+ if (checkSig(ErrorLoc, LastSig))
+ return true;
----------------
Please revert unrelated clang-format changes
================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp:433-434
" missing .functype");
- if (checkSig(ErrorLoc, *Sig)) return true;
+ if (checkSig(ErrorLoc, *Sig))
+ return true;
if (Name == "return_call" && endOfFunction(ErrorLoc))
----------------
Please revert unrelated clang-format changes
================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp:482-484
+ if (Name == "if" &&
+ checkBlockIn(WebAssemblyAsmOperandFrame::FrameType::If, ErrorLoc, Inst))
+ return true;
----------------
While is this here, while other block-like instructions (`block`, `try`, and `loop`) are checked separately (line 391-402) above?
================
Comment at: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.h:41
+ const wasm::WasmSignature &Signature);
+ OperandStack const &getEnterStack() const { return EnterStack; }
+ OperandStack getResultType() const;
----------------
================
Comment at: llvm/test/MC/WebAssembly/basic-assembly.s:84-88
+ drop
+ drop
+ i32.const 1
+ if # void
+ i32.const 1
----------------
Why is this change necessary?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D147504/new/
https://reviews.llvm.org/D147504
More information about the llvm-commits
mailing list