<div dir="ltr"><div dir="ltr"><div>Hi Chandler,</div><div><br></div><div>Thanks for spotting that! I was able to reproduce it by adding -verify-machineinstrs to llc. I've now fixed it in r341389.<br></div><div><br></div><div>Dan<br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Sep 4, 2018 at 7:13 AM, Chandler Carruth <span dir="ltr"><<a href="mailto:chandlerc@gmail.com" target="_blank">chandlerc@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">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.<div><br></div><div>The crash for me looks like:</div><div><div>******************** TEST 'LLVM :: CodeGen/WebAssembly/inline-<wbr>asm.ll' FAILED ********************                                                                                                         [110/9639]</div><div>Script:</div><div>--</div><div>: 'RUN: at line 1';   /home/chandlerc/src/llvm/<wbr>build/dev/bin/llc < /home/chandlerc/src/llvm/<wbr>project/llvm/test/CodeGen/<wbr>WebAssembly/inline-asm.ll -asm-verbose=false -disable-wasm-fallthrough-<wbr>return-opt -wasm-keep-r</div><div>egisters -no-integrated-as | /home/chandlerc/src/llvm/<wbr>build/dev/bin/FileCheck /home/chandlerc/src/llvm/<wbr>project/llvm/test/CodeGen/<wbr>WebAssembly/inline-asm.ll</div><div>--</div><div>Exit Code: 2</div><div><br></div><div>Command Output (stderr):</div><div>--</div><div><br></div><div># After WebAssembly Explicit Locals</div><div># Machine code for function foo: NoPHIs, TracksLiveness</div><div>Function Live Ins: $arguments</div><div><br></div><div>bb.0.entry:</div><div>  liveins: $arguments</div><div>  INLINEASM &"# $0 = aaa($1)" [sideeffect] [attdialect], $0:[regdef:I32], 0, $1:[reguse:I32], 0, !0</div><div>  %3:i32 = GET_LOCAL_I32 0, implicit-def $arguments</div><div>  RETURN_I32 %3:i32, implicit-def dead $arguments</div><div><br></div><div># End machine code for function foo.</div><div><br></div><div>*** Bad machine code: Instruction has operand with wrong parent set ***</div><div>- function:    foo</div><div>- basic block: %bb.0 entry (0x4454b98)</div><div>- instruction: INLINEASM &"# $0 = aaa($1)" [sideeffect] [attdialect], $0:[regdef:I32], 0, $1:[reguse:I32], 0, !0</div><div>Stack dump:</div><div>0.      Program arguments: /home/chandlerc/src/llvm/<wbr>build/dev/bin/llc -asm-verbose=false -disable-wasm-fallthrough-<wbr>return-opt -wasm-keep-registers -no-integrated-as</div><div>1.      Running pass 'Function Pass Manager' on module '<stdin>'.</div><div>2.      Running pass 'Verify generated machine code' on function '@foo'</div><div>#0 0x00000000032401a4 llvm::sys::PrintStackTrace(<wbr>llvm::raw_ostream&) /home/chandlerc/src/llvm/<wbr>project/llvm/lib/Support/Unix/<wbr>Signals.inc:490:13</div><div>#1 0x0000000003240391 PrintStackTraceSignalHandler(<wbr>void*) /home/chandlerc/src/llvm/<wbr>project/llvm/lib/Support/Unix/<wbr>Signals.inc:554:1</div><div>#2 0x000000000323e4e5 llvm::sys::RunSignalHandlers() /home/chandlerc/src/llvm/<wbr>project/llvm/lib/Support/<wbr>Signals.cpp:68:18</div><div>#3 0x00000000032404c1 SignalHandler(int) /home/chandlerc/src/llvm/<wbr>project/llvm/lib/Support/Unix/<wbr>Signals.inc:353:1</div><div>#4 0x00007f805ea74610 __restore_rt (/lib64/libpthread.so.0+<wbr>0x14610)</div><div>#5 0x00000000029d7e11 getDesc /home/chandlerc/src/llvm/<wbr>project/llvm/include/llvm/<wbr>CodeGen/MachineInstr.h:400:48</div><div>#6 0x00000000029d7e11 (anonymous namespace)::MachineVerifier::<wbr>visitMachineOperand(llvm::<wbr>MachineOperand const*, unsigned int) /home/chandlerc/src/llvm/<wbr>project/llvm/lib/CodeGen/<wbr>MachineVerifier.cpp:1097:0</div><div>#7 0x00000000029d4328 (anonymous namespace)::MachineVerifier::<wbr>verify(llvm::MachineFunction&) /home/chandlerc/src/llvm/<wbr>project/llvm/lib/CodeGen/<wbr>MachineVerifier.cpp:426:64</div></div><div><div class="h5"><div><br></div><div><div><br><div class="gmail_quote"><div dir="ltr">On Wed, Nov 8, 2017 at 8:18 PM Dan Gohman via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: djg<br>
Date: Wed Nov  8 11:18:08 2017<br>
New Revision: 317707<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=317707&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=317707&view=rev</a><br>
Log:<br>
[WebAssembly] Revise the strategy for inline asm.<br>
<br>
Previously, an "r" constraint would mean the compiler provides a value<br>
on WebAssembly's operand stack. This was tricky to use properly,<br>
particularly since it isn't possible to declare a new local from within<br>
an inline asm string.<br>
<br>
With this patch, "r" provides the value in a WebAssembly local, and the<br>
local index is provided to the inline asm string. This requires inline<br>
asm to use get_local and set_local to read the register. This does<br>
potentially result in larger code size, however inline asm should<br>
hopefully be quite rare in WebAssembly.<br>
<br>
This also means that the "m" constraint can no longer be supported, as<br>
WebAssembly has nothing like a "memory operand" that includes an<br>
implicit get_local.<br>
<br>
This fixes PR34599 for the wasm32-unknown-unknown-wasm target (though<br>
not for the ELF target).<br>
<br>
Modified:<br>
    llvm/trunk/lib/Target/<wbr>WebAssembly/<wbr>WebAssemblyAsmPrinter.cpp<br>
    llvm/trunk/lib/Target/<wbr>WebAssembly/<wbr>WebAssemblyExplicitLocals.cpp<br>
    llvm/trunk/test/CodeGen/<wbr>WebAssembly/inline-asm.ll<br>
<br>
Modified: llvm/trunk/lib/Target/<wbr>WebAssembly/<wbr>WebAssemblyAsmPrinter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp?rev=317707&r1=317706&r2=317707&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>WebAssembly/<wbr>WebAssemblyAsmPrinter.cpp?rev=<wbr>317707&r1=317706&r2=317707&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/<wbr>WebAssembly/<wbr>WebAssemblyAsmPrinter.cpp (original)<br>
+++ llvm/trunk/lib/Target/<wbr>WebAssembly/<wbr>WebAssemblyAsmPrinter.cpp Wed Nov  8 11:18:08 2017<br>
@@ -267,12 +267,11 @@ bool WebAssemblyAsmPrinter::<wbr>PrintAsmMemo<br>
   if (AsmVariant != 0)<br>
     report_fatal_error("There are no defined alternate asm variants");<br>
<br>
-  if (!ExtraCode) {<br>
-    // TODO: For now, we just hard-code 0 as the constant offset; teach<br>
-    // SelectInlineAsmMemoryOperand how to do address mode matching.<br>
-    OS << "0(" + regToString(MI->getOperand(<wbr>OpNo)) + ')';<br>
-    return false;<br>
-  }<br>
+  // The current approach to inline asm is that "r" constraints are expressed<br>
+  // as local indices, rather than values on the operand stack. This simplifies<br>
+  // using "r" as it eliminates the need to push and pop the values in a<br>
+  // particular order, however it also makes it impossible to have an "m"<br>
+  // constraint. So we don't support it.<br>
<br>
   return AsmPrinter::<wbr>PrintAsmMemoryOperand(MI, OpNo, AsmVariant, ExtraCode, OS);<br>
 }<br>
<br>
Modified: llvm/trunk/lib/Target/<wbr>WebAssembly/<wbr>WebAssemblyExplicitLocals.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp?rev=317707&r1=317706&r2=317707&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>WebAssembly/<wbr>WebAssemblyExplicitLocals.cpp?<wbr>rev=317707&r1=317706&r2=<wbr>317707&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/<wbr>WebAssembly/<wbr>WebAssemblyExplicitLocals.cpp (original)<br>
+++ llvm/trunk/lib/Target/<wbr>WebAssembly/<wbr>WebAssemblyExplicitLocals.cpp Wed Nov  8 11:18:08 2017<br>
@@ -294,6 +294,17 @@ bool WebAssemblyExplicitLocals::<wbr>runOnMac<br>
<br>
         unsigned OldReg = MO.getReg();<br>
<br>
+        // Inline asm may have a def in the middle of the operands. Our contract<br>
+        // with inline asm register operands is to provide local indices as<br>
+        // immediates.<br>
+        if (MO.isDef()) {<br>
+          assert(MI.getOpcode() == TargetOpcode::INLINEASM);<br>
+          unsigned LocalId = getLocalId(Reg2Local, CurLocal, OldReg);<br>
+          MRI.<wbr>removeRegOperandFromUseList(&<wbr>MO);<br>
+          MO = MachineOperand::CreateImm(<wbr>LocalId);<br>
+          continue;<br>
+        }<br>
+<br>
         // If we see a stackified register, prepare to insert subsequent<br>
         // get_locals before the start of its tree.<br>
         if (MFI.isVRegStackified(OldReg)) {<br>
@@ -301,6 +312,15 @@ bool WebAssemblyExplicitLocals::<wbr>runOnMac<br>
           continue;<br>
         }<br>
<br>
+        // Our contract with inline asm register operands is to provide local<br>
+        // indices as immediates.<br>
+        if (MI.getOpcode() == TargetOpcode::INLINEASM) {<br>
+          unsigned LocalId = getLocalId(Reg2Local, CurLocal, OldReg);<br>
+          MRI.<wbr>removeRegOperandFromUseList(&<wbr>MO);<br>
+          MO = MachineOperand::CreateImm(<wbr>LocalId);<br>
+          continue;<br>
+        }<br>
+<br>
         // Insert a get_local.<br>
         unsigned LocalId = getLocalId(Reg2Local, CurLocal, OldReg);<br>
         const TargetRegisterClass *RC = MRI.getRegClass(OldReg);<br>
<br>
Modified: llvm/trunk/test/CodeGen/<wbr>WebAssembly/inline-asm.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/inline-asm.ll?rev=317707&r1=317706&r2=317707&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>CodeGen/WebAssembly/inline-<wbr>asm.ll?rev=317707&r1=317706&<wbr>r2=317707&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/CodeGen/<wbr>WebAssembly/inline-asm.ll (original)<br>
+++ llvm/trunk/test/CodeGen/<wbr>WebAssembly/inline-asm.ll Wed Nov  8 11:18:08 2017<br>
@@ -1,4 +1,4 @@<br>
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-<wbr>return-opt -disable-wasm-explicit-locals -no-integrated-as | FileCheck %s<br>
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-<wbr>return-opt -no-integrated-as | FileCheck %s<br>
<br>
 ; Test basic inline assembly. Pass -no-integrated-as since these aren't<br>
 ; actually valid assembly syntax.<br>
@@ -10,33 +10,24 @@ target triple = "wasm32-unknown-unknown-<br>
 ; CHECK-NEXT: .param i32{{$}}<br>
 ; CHECK-NEXT: .result i32{{$}}<br>
 ; CHECK-NEXT: #APP{{$}}<br>
-; CHECK-NEXT: # $0 = aaa($0){{$}}<br>
+; CHECK-NEXT: # 0 = aaa(0){{$}}<br>
 ; CHECK-NEXT: #NO_APP{{$}}<br>
-; CHECK-NEXT: return $0{{$}}<br>
+; CHECK-NEXT: get_local $push0=, 0{{$}}<br>
+; CHECK-NEXT: return $pop0{{$}}<br>
 define i32 @foo(i32 %r) {<br>
 entry:<br>
   %0 = tail call i32 asm sideeffect "# $0 = aaa($1)", "=r,r"(i32 %r) #0, !srcloc !0<br>
   ret i32 %0<br>
 }<br>
<br>
-; CHECK-LABEL: bar:<br>
-; CHECK-NEXT: .param i32, i32{{$}}<br>
-; CHECK-NEXT: #APP{{$}}<br>
-; CHECK-NEXT: # 0($1) = bbb(0($0)){{$}}<br>
-; CHECK-NEXT: #NO_APP{{$}}<br>
-; CHECK-NEXT: return{{$}}<br>
-define void @bar(i32* %r, i32* %s) {<br>
-entry:<br>
-  tail call void asm sideeffect "# $0 = bbb($1)", "=*m,*m"(i32* %s, i32* %r) #0, !srcloc !1<br>
-  ret void<br>
-}<br>
-<br>
 ; CHECK-LABEL: imm:<br>
 ; CHECK-NEXT: .result i32{{$}}<br>
+; CHECK-NEXT: .local i32{{$}}<br>
 ; CHECK-NEXT: #APP{{$}}<br>
-; CHECK-NEXT: # $0 = ccc(42){{$}}<br>
+; CHECK-NEXT: # 0 = ccc(42){{$}}<br>
 ; CHECK-NEXT: #NO_APP{{$}}<br>
-; CHECK-NEXT: return $0{{$}}<br>
+; CHECK-NEXT: get_local $push0=, 0{{$}}<br>
+; CHECK-NEXT: return $pop0{{$}}<br>
 define i32 @imm() {<br>
 entry:<br>
   %0 = tail call i32 asm sideeffect "# $0 = ccc($1)", "=r,i"(i32 42) #0, !srcloc !2<br>
@@ -47,9 +38,10 @@ entry:<br>
 ; CHECK-NEXT: .param i64{{$}}<br>
 ; CHECK-NEXT: .result i64{{$}}<br>
 ; CHECK-NEXT: #APP{{$}}<br>
-; CHECK-NEXT: # $0 = aaa($0){{$}}<br>
+; CHECK-NEXT: # 0 = aaa(0){{$}}<br>
 ; CHECK-NEXT: #NO_APP{{$}}<br>
-; CHECK-NEXT: return $0{{$}}<br>
+; CHECK-NEXT: get_local $push0=, 0{{$}}<br>
+; CHECK-NEXT: return $pop0{{$}}<br>
 define i64 @foo_i64(i64 %r) {<br>
 entry:<br>
   %0 = tail call i64 asm sideeffect "# $0 = aaa($1)", "=r,r"(i64 %r) #0, !srcloc !0<br>
@@ -57,16 +49,20 @@ entry:<br>
 }<br>
<br>
 ; CHECK-LABEL: X_i16:<br>
-; CHECK: foo $1{{$}}<br>
-; CHECK: i32.store16 0($0), $1{{$}}<br>
+; CHECK: foo 1{{$}}<br>
+; CHECK: get_local $push[[S0:[0-9]+]]=, 0{{$}}<br>
+; CHECK-NEXT: get_local $push[[S1:[0-9]+]]=, 1{{$}}<br>
+; CHECK-NEXT: i32.store16 0($pop[[S0]]), $pop[[S1]]{{$}}<br>
 define void @X_i16(i16 * %t) {<br>
   call void asm sideeffect "foo $0", "=*X,~{dirflag},~{fpsr},~{<wbr>flags},~{memory}"(i16* %t)<br>
   ret void<br>
 }<br>
<br>
 ; CHECK-LABEL: X_ptr:<br>
-; CHECK: foo $1{{$}}<br>
-; CHECK: i32.store 0($0), $1{{$}}<br>
+; CHECK: foo 1{{$}}<br>
+; CHECK: get_local $push[[S0:[0-9]+]]=, 0{{$}}<br>
+; CHECK-NEXT: get_local $push[[S1:[0-9]+]]=, 1{{$}}<br>
+; CHECK-NEXT: i32.store 0($pop[[S0]]), $pop[[S1]]{{$}}<br>
 define void @X_ptr(i16 ** %t) {<br>
   call void asm sideeffect "foo $0", "=*X,~{dirflag},~{fpsr},~{<wbr>flags},~{memory}"(i16** %t)<br>
   ret void<br>
@@ -87,6 +83,20 @@ define void @varname() {<br>
   ret void<br>
 }<br>
<br>
+; CHECK-LABEL: r_constraint<br>
+; CHECK:      i32.const $push[[S0:[0-9]+]]=, 0{{$}}<br>
+; CHECK-NEXT: set_local [[L0:[0-9]+]], $pop[[S0]]{{$}}<br>
+; CHECK-NEXT: i32.const $push[[S1:[0-9]+]]=, 37{{$}}<br>
+; CHECK-NEXT: set_local [[L1:[0-9]+]], $pop[[S1]]{{$}}<br>
+; CHECK:      foo [[L2:[0-9]+]], 1, [[L0]], [[L1]]{{$}}<br>
+; CHECK:      get_local $push{{[0-9]+}}=, [[L2]]{{$}}<br>
+define hidden i32 @r_constraint(i32 %a, i32 %y) {<br>
+entry:<br>
+  %z = bitcast i32 0 to i32<br>
+  %t0 = tail call i32 asm "foo $0, $1, $2, $3", "=r,r,r,r"(i32 %y, i32 %z, i32 37) #0, !srcloc !0<br>
+  ret i32 %t0<br>
+}<br>
+<br>
 attributes #0 = { nounwind }<br>
<br>
 !0 = !{i32 47}<br>
<br>
<br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div></div></div></div></div>
</blockquote></div><br></div>