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

JF Bastien via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 17 20:23:12 PST 2015


Ah OK. No concerns then, thanks!

On Tue, Nov 17, 2015 at 6:33 PM, Dan Gohman <sunfish at mozilla.com> wrote:

> Yes, the former. Inline assembly doesn't use special syntax in the output.
> To make it valid, the user has to write code using the same assembler
> syntax as the rest of the code the compiler is emitting.
>
> Dan
>
> On Tue, Nov 17, 2015 at 2:56 PM, JF Bastien <jfb at chromium.org> wrote:
>
>> I'm wondering if you see this as a pure LLVM thing that disappears in the
>> final assembly / binary code, or if tools that consume assembly / binary
>> code also have to understand this inline assembly. I'm totally fine with
>> the former, and am slightly concerned by the later (it could work, but we
>> have to make sure we spec it right). From your description it sounds like
>> it's only the former you're going for?
>>
>> On Tue, Nov 17, 2015 at 12:11 PM, Dan Gohman <sunfish at mozilla.com> wrote:
>>
>>> asm("" : "=r" (x)) is a convenient way to force a use of x in a register
>>> while introducing minimal disruption, for the purpose of writing a compiler
>>> test. One can create a variety of contrived constraints this way.
>>>
>>> Also, inline asm is convenient for writing tests of WebAssembly engines
>>> too, where one wants to craft a very specific code sequence in the middle
>>> of a larger program without having to write the whole function in assembly.
>>>
>>> This just adds the "r", " m", and "i" constraints. We won't need a lot
>>> more because the ISA is very regular. Which other tools are you concerned
>>> about?
>>>
>>> Dan
>>>
>>> On Tue, Nov 17, 2015 at 10:46 AM, JF Bastien <jfb at chromium.org> wrote:
>>>
>>>> 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/0b614531/attachment.html>


More information about the llvm-commits mailing list