[llvm] r252997 - [WebAssembly] Inline asm support.

JF Bastien via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 17 10:46:47 PST 2015


Do you have concrete examples in mind? This was a tad surprising to folks
here (self included), and I want to make sure that all our tools support
the same feature set (i.e. we don't end up with the slightly mad situation
of GCC inline asm).

On Tue, Nov 17, 2015 at 7:09 AM, Dan Gohman <sunfish at mozilla.com> wrote:

> We do have __builtin functions for all instructions not accessible through
> plain C syntax, so inline asm will almost never be needed. However, inline
> asm is a useful tool for writing certain kinds of testcases, both  for LLVM
> itself and for the underlying platform.
>
> Dan
>
>
> On Mon, Nov 16, 2015 at 4:51 PM, JF Bastien <jfb at chromium.org> wrote:
>
>> (catching up on email post-vacation)
>>
>> I'm a bit confused about this: the code looks like what I'd expect, but I
>> thought we weren't going to do inline asm. Could you clarify the usecase? I
>> thought we'd do calls to the embedders / syscalls through extern C
>> functions, so I'm not sure I get the use for inline asm.
>>
>> On Thu, Nov 12, 2015 at 5:42 PM, Dan Gohman via llvm-commits <
>> llvm-commits at lists.llvm.org> wrote:
>>
>>> Author: djg
>>> Date: Thu Nov 12 19:42:29 2015
>>> New Revision: 252997
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=252997&view=rev
>>> Log:
>>> [WebAssembly] Inline asm support.
>>>
>>> Added:
>>>     llvm/trunk/test/CodeGen/WebAssembly/inline-asm.ll
>>> Modified:
>>>     llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
>>>     llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
>>>     llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
>>>     llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h
>>>
>>> Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp?rev=252997&r1=252996&r2=252997&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
>>> (original)
>>> +++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp Thu Nov
>>> 12 19:42:29 2015
>>> @@ -77,6 +77,12 @@ private:
>>>    void EmitFunctionBodyStart() override;
>>>    void EmitInstruction(const MachineInstr *MI) override;
>>>    void EmitEndOfAsmFile(Module &M) override;
>>> +  bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
>>> +                       unsigned AsmVariant, const char *ExtraCode,
>>> +                       raw_ostream &OS) override;
>>> +  bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
>>> +                             unsigned AsmVariant, const char *ExtraCode,
>>> +                             raw_ostream &OS) override;
>>>
>>>    std::string getRegTypeName(unsigned RegNo) const;
>>>    const char *toString(MVT VT) const;
>>> @@ -275,6 +281,41 @@ void WebAssemblyAsmPrinter::EmitEndOfAsm
>>>      OutStreamer->EmitRawText(Text.substr(0, Text.size() - 1));
>>>  }
>>>
>>> +bool WebAssemblyAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
>>> +                                            unsigned OpNo, unsigned
>>> AsmVariant,
>>> +                                            const char *ExtraCode,
>>> +                                            raw_ostream &OS) {
>>> +  if (AsmVariant != 0)
>>> +    report_fatal_error("There are no defined alternate asm variants");
>>> +
>>> +  if (!ExtraCode) {
>>> +    const MachineOperand &MO = MI->getOperand(OpNo);
>>> +    if (MO.isImm())
>>> +      OS << MO.getImm();
>>> +    else
>>> +      OS << regToString(MO);
>>> +    return false;
>>> +  }
>>> +
>>> +  return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode,
>>> OS);
>>> +}
>>> +
>>> +bool WebAssemblyAsmPrinter::PrintAsmMemoryOperand(const MachineInstr
>>> *MI,
>>> +                                                  unsigned OpNo,
>>> +                                                  unsigned AsmVariant,
>>> +                                                  const char *ExtraCode,
>>> +                                                  raw_ostream &OS) {
>>> +  if (AsmVariant != 0)
>>> +    report_fatal_error("There are no defined alternate asm variants");
>>> +
>>> +  if (!ExtraCode) {
>>> +    OS << regToString(MI->getOperand(OpNo));
>>> +    return false;
>>> +  }
>>> +
>>> +  return AsmPrinter::PrintAsmMemoryOperand(MI, OpNo, AsmVariant,
>>> ExtraCode, OS);
>>> +}
>>> +
>>>  // Force static initialization.
>>>  extern "C" void LLVMInitializeWebAssemblyAsmPrinter() {
>>>    RegisterAsmPrinter<WebAssemblyAsmPrinter> X(TheWebAssemblyTarget32);
>>>
>>> Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp?rev=252997&r1=252996&r2=252997&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
>>> (original)
>>> +++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp Thu
>>> Nov 12 19:42:29 2015
>>> @@ -56,6 +56,9 @@ public:
>>>
>>>    SDNode *Select(SDNode *Node) override;
>>>
>>> +  bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned
>>> ConstraintID,
>>> +                                    std::vector<SDValue> &OutOps)
>>> override;
>>> +
>>>  // Include the pieces autogenerated from the target description.
>>>  #include "WebAssemblyGenDAGISel.inc"
>>>
>>> @@ -101,6 +104,22 @@ SDNode *WebAssemblyDAGToDAGISel::Select(
>>>    return ResNode;
>>>  }
>>>
>>> +bool WebAssemblyDAGToDAGISel::SelectInlineAsmMemoryOperand(
>>> +    const SDValue &Op, unsigned ConstraintID, std::vector<SDValue>
>>> &OutOps) {
>>> +  switch (ConstraintID) {
>>> +  case InlineAsm::Constraint_i:
>>> +  case InlineAsm::Constraint_m:
>>> +    // We just support simple memory operands that just have a single
>>> address
>>> +    // operand and need no special handling.
>>> +    OutOps.push_back(Op);
>>> +    return false;
>>> +  default:
>>> +    break;
>>> +  }
>>> +
>>> +  return true;
>>> +}
>>> +
>>>  /// This pass converts a legalized DAG into a WebAssembly-specific DAG,
>>> ready
>>>  /// for instruction scheduling.
>>>  FunctionPass *llvm::createWebAssemblyISelDag(WebAssemblyTargetMachine
>>> &TM,
>>>
>>> Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp?rev=252997&r1=252996&r2=252997&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
>>> (original)
>>> +++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp Thu
>>> Nov 12 19:42:29 2015
>>> @@ -211,6 +211,23 @@ WebAssemblyTargetLowering::getTargetNode
>>>    return nullptr;
>>>  }
>>>
>>> +std::pair<unsigned, const TargetRegisterClass *>
>>> +WebAssemblyTargetLowering::getRegForInlineAsmConstraint(
>>> +    const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
>>> +  // First, see if this is a constraint that directly corresponds to a
>>> +  // WebAssembly register class.
>>> +  if (Constraint.size() == 1) {
>>> +    switch (Constraint[0]) {
>>> +    case 'r':
>>> +      return std::make_pair(0U, &WebAssembly::I32RegClass);
>>> +    default:
>>> +      break;
>>> +    }
>>> +  }
>>> +
>>> +  return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint,
>>> VT);
>>> +}
>>> +
>>>
>>>  //===----------------------------------------------------------------------===//
>>>  // WebAssembly Lowering private implementation.
>>>
>>>  //===----------------------------------------------------------------------===//
>>>
>>> Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h?rev=252997&r1=252996&r2=252997&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h
>>> (original)
>>> +++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h Thu Nov
>>> 12 19:42:29 2015
>>> @@ -49,6 +49,9 @@ private:
>>>    bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const
>>> override;
>>>    MVT getScalarShiftAmountTy(const DataLayout &DL, EVT) const override;
>>>    const char *getTargetNodeName(unsigned Opcode) const override;
>>> +  std::pair<unsigned, const TargetRegisterClass *>
>>> +  getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
>>> +                               StringRef Constraint, MVT VT) const
>>> override;
>>>
>>>    SDValue LowerCall(CallLoweringInfo &CLI,
>>>                      SmallVectorImpl<SDValue> &InVals) const override;
>>>
>>> Added: llvm/trunk/test/CodeGen/WebAssembly/inline-asm.ll
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/inline-asm.ll?rev=252997&view=auto
>>>
>>> ==============================================================================
>>> --- llvm/trunk/test/CodeGen/WebAssembly/inline-asm.ll (added)
>>> +++ llvm/trunk/test/CodeGen/WebAssembly/inline-asm.ll Thu Nov 12
>>> 19:42:29 2015
>>> @@ -0,0 +1,53 @@
>>> +; RUN: llc < %s -asm-verbose=false | FileCheck %s
>>> +
>>> +; Test basic inline assembly.
>>> +
>>> +target datalayout = "e-p:32:32-i64:64-n32:64-S128"
>>> +target triple = "wasm32-unknown-unknown"
>>> +
>>> +; CHECK-LABEL: foo:
>>> +; CHECK-NEXT: .param i32{{$}}
>>> +; CHECK-NEXT: .result i32{{$}}
>>> +; CHECK-NEXT: .local i32, i32{{$}}
>>> +; CHECK-NEXT: #APP{{$}}
>>> +; CHECK-NEXT: 1 = aaa(0){{$}}
>>> +; CHECK-NEXT: #NO_APP{{$}}
>>> +; CHECK-NEXT: return (get_local 1){{$}}
>>> +define i32 @foo(i32 %r) {
>>> +entry:
>>> +  %0 = tail call i32 asm sideeffect "$0 = aaa($1)", "=r,r"(i32 %r) #0,
>>> !srcloc !0
>>> +  ret i32 %0
>>> +}
>>> +
>>> +; CHECK-LABEL: bar:
>>> +; CHECK-NEXT: .param i32{{$}}
>>> +; CHECK-NEXT: .param i32{{$}}
>>> +; CHECK-NEXT: .local i32, i32{{$}}
>>> +; CHECK-NEXT: #APP{{$}}
>>> +; CHECK-NEXT: 1 = bbb(0){{$}}
>>> +; CHECK-NEXT: #NO_APP{{$}}
>>> +; CHECK-NEXT: return{{$}}
>>> +define void @bar(i32* %r, i32* %s) {
>>> +entry:
>>> +  tail call void asm sideeffect "$0 = bbb($1)", "=*m,*m"(i32* %s, i32*
>>> %r) #0, !srcloc !1
>>> +  ret void
>>> +}
>>> +
>>> +; CHECK-LABEL: imm:
>>> +; CHECK-NEXT: .result i32{{$}}
>>> +; CHECK-NEXT: .local i32{{$}}
>>> +; CHECK-NEXT: #APP{{$}}
>>> +; CHECK-NEXT: 0 = ccc(42){{$}}
>>> +; CHECK-NEXT: #NO_APP{{$}}
>>> +; CHECK-NEXT: return (get_local 0){{$}}
>>> +define i32 @imm() {
>>> +entry:
>>> +  %0 = tail call i32 asm sideeffect "$0 = ccc($1)", "=r,i"(i32 42) #0,
>>> !srcloc !2
>>> +  ret i32 %0
>>> +}
>>> +
>>> +attributes #0 = { nounwind }
>>> +
>>> +!0 = !{i32 47}
>>> +!1 = !{i32 145}
>>> +!2 = !{i32 231}
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151117/be82ba65/attachment.html>


More information about the llvm-commits mailing list