[llvm] r317707 - [WebAssembly] Revise the strategy for inline asm.

Chandler Carruth via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 4 07:13:03 PDT 2018


It's possible it didn't start with this commit, but WebAssembly assert
fails on inline-asm MI nodes when expensive-checks are enabled. There
likely isn't a wasm bot with these checks enabled, it'd be good to add one.

The crash for me looks like:
******************** TEST 'LLVM :: CodeGen/WebAssembly/inline-asm.ll'
FAILED ********************
                                                         [110/9639]
Script:
--
: 'RUN: at line 1';   /home/chandlerc/src/llvm/build/dev/bin/llc <
/home/chandlerc/src/llvm/project/llvm/test/CodeGen/WebAssembly/inline-asm.ll
-asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-r
egisters -no-integrated-as |
/home/chandlerc/src/llvm/build/dev/bin/FileCheck
/home/chandlerc/src/llvm/project/llvm/test/CodeGen/WebAssembly/inline-asm.ll
--
Exit Code: 2

Command Output (stderr):
--

# After WebAssembly Explicit Locals
# Machine code for function foo: NoPHIs, TracksLiveness
Function Live Ins: $arguments

bb.0.entry:
  liveins: $arguments
  INLINEASM &"# $0 = aaa($1)" [sideeffect] [attdialect], $0:[regdef:I32],
0, $1:[reguse:I32], 0, !0
  %3:i32 = GET_LOCAL_I32 0, implicit-def $arguments
  RETURN_I32 %3:i32, implicit-def dead $arguments

# End machine code for function foo.

*** Bad machine code: Instruction has operand with wrong parent set ***
- function:    foo
- basic block: %bb.0 entry (0x4454b98)
- instruction: INLINEASM &"# $0 = aaa($1)" [sideeffect] [attdialect],
$0:[regdef:I32], 0, $1:[reguse:I32], 0, !0
Stack dump:
0.      Program arguments: /home/chandlerc/src/llvm/build/dev/bin/llc
-asm-verbose=false -disable-wasm-fallthrough-return-opt
-wasm-keep-registers -no-integrated-as
1.      Running pass 'Function Pass Manager' on module '<stdin>'.
2.      Running pass 'Verify generated machine code' on function '@foo'
#0 0x00000000032401a4 llvm::sys::PrintStackTrace(llvm::raw_ostream&)
/home/chandlerc/src/llvm/project/llvm/lib/Support/Unix/Signals.inc:490:13
#1 0x0000000003240391 PrintStackTraceSignalHandler(void*)
/home/chandlerc/src/llvm/project/llvm/lib/Support/Unix/Signals.inc:554:1
#2 0x000000000323e4e5 llvm::sys::RunSignalHandlers()
/home/chandlerc/src/llvm/project/llvm/lib/Support/Signals.cpp:68:18
#3 0x00000000032404c1 SignalHandler(int)
/home/chandlerc/src/llvm/project/llvm/lib/Support/Unix/Signals.inc:353:1
#4 0x00007f805ea74610 __restore_rt (/lib64/libpthread.so.0+0x14610)
#5 0x00000000029d7e11 getDesc
/home/chandlerc/src/llvm/project/llvm/include/llvm/CodeGen/MachineInstr.h:400:48
#6 0x00000000029d7e11 (anonymous
namespace)::MachineVerifier::visitMachineOperand(llvm::MachineOperand
const*, unsigned int)
/home/chandlerc/src/llvm/project/llvm/lib/CodeGen/MachineVerifier.cpp:1097:0
#7 0x00000000029d4328 (anonymous
namespace)::MachineVerifier::verify(llvm::MachineFunction&)
/home/chandlerc/src/llvm/project/llvm/lib/CodeGen/MachineVerifier.cpp:426:64


On Wed, Nov 8, 2017 at 8:18 PM Dan Gohman via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: djg
> Date: Wed Nov  8 11:18:08 2017
> New Revision: 317707
>
> URL: http://llvm.org/viewvc/llvm-project?rev=317707&view=rev
> Log:
> [WebAssembly] Revise the strategy for inline asm.
>
> Previously, an "r" constraint would mean the compiler provides a value
> on WebAssembly's operand stack. This was tricky to use properly,
> particularly since it isn't possible to declare a new local from within
> an inline asm string.
>
> With this patch, "r" provides the value in a WebAssembly local, and the
> local index is provided to the inline asm string. This requires inline
> asm to use get_local and set_local to read the register. This does
> potentially result in larger code size, however inline asm should
> hopefully be quite rare in WebAssembly.
>
> This also means that the "m" constraint can no longer be supported, as
> WebAssembly has nothing like a "memory operand" that includes an
> implicit get_local.
>
> This fixes PR34599 for the wasm32-unknown-unknown-wasm target (though
> not for the ELF target).
>
> Modified:
>     llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
>     llvm/trunk/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
>     llvm/trunk/test/CodeGen/WebAssembly/inline-asm.ll
>
> Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp?rev=317707&r1=317706&r2=317707&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp (original)
> +++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp Wed Nov  8
> 11:18:08 2017
> @@ -267,12 +267,11 @@ bool WebAssemblyAsmPrinter::PrintAsmMemo
>    if (AsmVariant != 0)
>      report_fatal_error("There are no defined alternate asm variants");
>
> -  if (!ExtraCode) {
> -    // TODO: For now, we just hard-code 0 as the constant offset; teach
> -    // SelectInlineAsmMemoryOperand how to do address mode matching.
> -    OS << "0(" + regToString(MI->getOperand(OpNo)) + ')';
> -    return false;
> -  }
> +  // The current approach to inline asm is that "r" constraints are
> expressed
> +  // as local indices, rather than values on the operand stack. This
> simplifies
> +  // using "r" as it eliminates the need to push and pop the values in a
> +  // particular order, however it also makes it impossible to have an "m"
> +  // constraint. So we don't support it.
>
>    return AsmPrinter::PrintAsmMemoryOperand(MI, OpNo, AsmVariant,
> ExtraCode, OS);
>  }
>
> Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp?rev=317707&r1=317706&r2=317707&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
> (original)
> +++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp Wed
> Nov  8 11:18:08 2017
> @@ -294,6 +294,17 @@ bool WebAssemblyExplicitLocals::runOnMac
>
>          unsigned OldReg = MO.getReg();
>
> +        // Inline asm may have a def in the middle of the operands. Our
> contract
> +        // with inline asm register operands is to provide local indices
> as
> +        // immediates.
> +        if (MO.isDef()) {
> +          assert(MI.getOpcode() == TargetOpcode::INLINEASM);
> +          unsigned LocalId = getLocalId(Reg2Local, CurLocal, OldReg);
> +          MRI.removeRegOperandFromUseList(&MO);
> +          MO = MachineOperand::CreateImm(LocalId);
> +          continue;
> +        }
> +
>          // If we see a stackified register, prepare to insert subsequent
>          // get_locals before the start of its tree.
>          if (MFI.isVRegStackified(OldReg)) {
> @@ -301,6 +312,15 @@ bool WebAssemblyExplicitLocals::runOnMac
>            continue;
>          }
>
> +        // Our contract with inline asm register operands is to provide
> local
> +        // indices as immediates.
> +        if (MI.getOpcode() == TargetOpcode::INLINEASM) {
> +          unsigned LocalId = getLocalId(Reg2Local, CurLocal, OldReg);
> +          MRI.removeRegOperandFromUseList(&MO);
> +          MO = MachineOperand::CreateImm(LocalId);
> +          continue;
> +        }
> +
>          // Insert a get_local.
>          unsigned LocalId = getLocalId(Reg2Local, CurLocal, OldReg);
>          const TargetRegisterClass *RC = MRI.getRegClass(OldReg);
>
> Modified: llvm/trunk/test/CodeGen/WebAssembly/inline-asm.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/inline-asm.ll?rev=317707&r1=317706&r2=317707&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/CodeGen/WebAssembly/inline-asm.ll (original)
> +++ llvm/trunk/test/CodeGen/WebAssembly/inline-asm.ll Wed Nov  8 11:18:08
> 2017
> @@ -1,4 +1,4 @@
> -; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt
> -disable-wasm-explicit-locals -no-integrated-as | FileCheck %s
> +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt
> -no-integrated-as | FileCheck %s
>
>  ; Test basic inline assembly. Pass -no-integrated-as since these aren't
>  ; actually valid assembly syntax.
> @@ -10,33 +10,24 @@ target triple = "wasm32-unknown-unknown-
>  ; CHECK-NEXT: .param i32{{$}}
>  ; CHECK-NEXT: .result i32{{$}}
>  ; CHECK-NEXT: #APP{{$}}
> -; CHECK-NEXT: # $0 = aaa($0){{$}}
> +; CHECK-NEXT: # 0 = aaa(0){{$}}
>  ; CHECK-NEXT: #NO_APP{{$}}
> -; CHECK-NEXT: return $0{{$}}
> +; CHECK-NEXT: get_local $push0=, 0{{$}}
> +; CHECK-NEXT: return $pop0{{$}}
>  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, i32{{$}}
> -; CHECK-NEXT: #APP{{$}}
> -; CHECK-NEXT: # 0($1) = bbb(0($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: # 0 = ccc(42){{$}}
>  ; CHECK-NEXT: #NO_APP{{$}}
> -; CHECK-NEXT: return $0{{$}}
> +; CHECK-NEXT: get_local $push0=, 0{{$}}
> +; CHECK-NEXT: return $pop0{{$}}
>  define i32 @imm() {
>  entry:
>    %0 = tail call i32 asm sideeffect "# $0 = ccc($1)", "=r,i"(i32 42) #0,
> !srcloc !2
> @@ -47,9 +38,10 @@ entry:
>  ; CHECK-NEXT: .param i64{{$}}
>  ; CHECK-NEXT: .result i64{{$}}
>  ; CHECK-NEXT: #APP{{$}}
> -; CHECK-NEXT: # $0 = aaa($0){{$}}
> +; CHECK-NEXT: # 0 = aaa(0){{$}}
>  ; CHECK-NEXT: #NO_APP{{$}}
> -; CHECK-NEXT: return $0{{$}}
> +; CHECK-NEXT: get_local $push0=, 0{{$}}
> +; CHECK-NEXT: return $pop0{{$}}
>  define i64 @foo_i64(i64 %r) {
>  entry:
>    %0 = tail call i64 asm sideeffect "# $0 = aaa($1)", "=r,r"(i64 %r) #0,
> !srcloc !0
> @@ -57,16 +49,20 @@ entry:
>  }
>
>  ; CHECK-LABEL: X_i16:
> -; CHECK: foo $1{{$}}
> -; CHECK: i32.store16 0($0), $1{{$}}
> +; CHECK: foo 1{{$}}
> +; CHECK: get_local $push[[S0:[0-9]+]]=, 0{{$}}
> +; CHECK-NEXT: get_local $push[[S1:[0-9]+]]=, 1{{$}}
> +; CHECK-NEXT: i32.store16 0($pop[[S0]]), $pop[[S1]]{{$}}
>  define void @X_i16(i16 * %t) {
>    call void asm sideeffect "foo $0",
> "=*X,~{dirflag},~{fpsr},~{flags},~{memory}"(i16* %t)
>    ret void
>  }
>
>  ; CHECK-LABEL: X_ptr:
> -; CHECK: foo $1{{$}}
> -; CHECK: i32.store 0($0), $1{{$}}
> +; CHECK: foo 1{{$}}
> +; CHECK: get_local $push[[S0:[0-9]+]]=, 0{{$}}
> +; CHECK-NEXT: get_local $push[[S1:[0-9]+]]=, 1{{$}}
> +; CHECK-NEXT: i32.store 0($pop[[S0]]), $pop[[S1]]{{$}}
>  define void @X_ptr(i16 ** %t) {
>    call void asm sideeffect "foo $0",
> "=*X,~{dirflag},~{fpsr},~{flags},~{memory}"(i16** %t)
>    ret void
> @@ -87,6 +83,20 @@ define void @varname() {
>    ret void
>  }
>
> +; CHECK-LABEL: r_constraint
> +; CHECK:      i32.const $push[[S0:[0-9]+]]=, 0{{$}}
> +; CHECK-NEXT: set_local [[L0:[0-9]+]], $pop[[S0]]{{$}}
> +; CHECK-NEXT: i32.const $push[[S1:[0-9]+]]=, 37{{$}}
> +; CHECK-NEXT: set_local [[L1:[0-9]+]], $pop[[S1]]{{$}}
> +; CHECK:      foo [[L2:[0-9]+]], 1, [[L0]], [[L1]]{{$}}
> +; CHECK:      get_local $push{{[0-9]+}}=, [[L2]]{{$}}
> +define hidden i32 @r_constraint(i32 %a, i32 %y) {
> +entry:
> +  %z = bitcast i32 0 to i32
> +  %t0 = tail call i32 asm "foo $0, $1, $2, $3", "=r,r,r,r"(i32 %y, i32
> %z, i32 37) #0, !srcloc !0
> +  ret i32 %t0
> +}
> +
>  attributes #0 = { nounwind }
>
>  !0 = !{i32 47}
>
>
> _______________________________________________
> 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/20180904/f0656a91/attachment.html>


More information about the llvm-commits mailing list