[llvm] r283503 - [WebAssemby] Implement block signatures.

Dan Gohman via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 6 15:29:33 PDT 2016


Author: djg
Date: Thu Oct  6 17:29:32 2016
New Revision: 283503

URL: http://llvm.org/viewvc/llvm-project?rev=283503&view=rev
Log:
[WebAssemby] Implement block signatures.

Per spec changes, this implements block signatures, and adds just enough
logic to produce correct block signatures at the ends of functions.

Differential Revision: https://reviews.llvm.org/D25144

Modified:
    llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp
    llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h
    llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
    llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
    llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h
    llvm/trunk/test/CodeGen/WebAssembly/cfg-stackify.ll
    llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll
    llvm/trunk/test/CodeGen/WebAssembly/switch.ll

Modified: llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp?rev=283503&r1=283502&r2=283503&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp Thu Oct  6 17:29:32 2016
@@ -195,6 +195,26 @@ WebAssemblyInstPrinter::printWebAssembly
   O << ":p2align=" << Imm;
 }
 
+void
+WebAssemblyInstPrinter::printWebAssemblySignatureOperand(const MCInst *MI,
+                                                         unsigned OpNo,
+                                                         raw_ostream &O) {
+  int64_t Imm = MI->getOperand(OpNo).getImm();
+  switch (Imm) {
+  case WebAssembly::Void: break;
+  case WebAssembly::I32: O << "i32"; break;
+  case WebAssembly::I64: O << "i64"; break;
+  case WebAssembly::F32: O << "f32"; break;
+  case WebAssembly::F64: O << "f64"; break;
+  case WebAssembly::I8x16: O << "i8x16"; break;
+  case WebAssembly::I16x8: O << "i16x8"; break;
+  case WebAssembly::I32x4: O << "i32x4"; break;
+  case WebAssembly::I64x2: O << "i32x4"; break;
+  case WebAssembly::F32x4: O << "f32x4"; break;
+  case WebAssembly::F64x2: O << "f64x2"; break;
+  }
+}
+
 const char *llvm::WebAssembly::TypeToString(MVT Ty) {
   switch (Ty.SimpleTy) {
   case MVT::i32:

Modified: llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h?rev=283503&r1=283502&r2=283503&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h Thu Oct  6 17:29:32 2016
@@ -39,6 +39,8 @@ public:
   void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
   void printWebAssemblyP2AlignOperand(const MCInst *MI, unsigned OpNo,
                                       raw_ostream &O);
+  void printWebAssemblySignatureOperand(const MCInst *MI, unsigned OpNo,
+                                        raw_ostream &O);
 
   // Autogenerated by tblgen.
   void printInstruction(const MCInst *MI, raw_ostream &O);

Modified: llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h?rev=283503&r1=283502&r2=283503&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h Thu Oct  6 17:29:32 2016
@@ -53,7 +53,9 @@ enum OperandType {
   /// 64-bit floating-point immediates.
   OPERAND_F64IMM,
   /// p2align immediate for load and store address alignment.
-  OPERAND_P2ALIGN
+  OPERAND_P2ALIGN,
+  /// signature immediate for block/loop.
+  OPERAND_SIGNATURE
 };
 
 /// WebAssembly-specific directive identifiers.
@@ -63,7 +65,7 @@ enum Directive {
   DotResult = UINT64_MAX - 1,  ///< .result
   DotLocal = UINT64_MAX - 2,   ///< .local
   DotEndFunc = UINT64_MAX - 3, ///< .endfunc
-  DotIndIdx = UINT64_MAX - 4,  /// < .indidx
+  DotIndIdx = UINT64_MAX - 4,  ///< .indidx
 };
 
 } // end namespace WebAssembly
@@ -141,6 +143,21 @@ static const unsigned StoreAddressOperan
 static const unsigned LoadP2AlignOperandNo = 3;
 static const unsigned StoreP2AlignOperandNo = 2;
 
+/// This is used to indicate block signatures.
+enum ExprType {
+  Void = 0,
+  I32  = 1,
+  I64  = 2,
+  F32  = 3,
+  F64  = 4,
+  I8x16 = 5,
+  I16x8 = 6,
+  I32x4 = 7,
+  I64x2 = 8,
+  F32x4 = 9,
+  F64x2 = 10
+};
+
 } // end namespace WebAssembly
 } // end namespace llvm
 

Modified: llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp?rev=283503&r1=283502&r2=283503&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp Thu Oct  6 17:29:32 2016
@@ -65,14 +65,17 @@ void WebAssemblyTargetAsmStreamer::emitL
 void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; }
 
 void WebAssemblyTargetAsmStreamer::emitIndirectFunctionType(
-    StringRef name, SmallVectorImpl<MVT> &SignatureVTs, size_t NumResults) {
+    StringRef name, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
   OS << "\t.functype\t" << name;
-  if (NumResults == 0)
+  if (Results.empty())
     OS << ", void";
-  for (auto Ty : SignatureVTs) {
-    OS << ", " << WebAssembly::TypeToString(Ty);
+  else {
+    assert(Results.size() == 1);
+    OS << ", " << WebAssembly::TypeToString(Results.front());
   }
-  OS << "\n";
+  for (auto Ty : Params)
+    OS << ", " << WebAssembly::TypeToString(Ty);
+  OS << '\n';
 }
 
 void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) {

Modified: llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h?rev=283503&r1=283502&r2=283503&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h Thu Oct  6 17:29:32 2016
@@ -39,8 +39,8 @@ public:
   virtual void emitEndFunc() = 0;
   /// .functype
   virtual void emitIndirectFunctionType(StringRef name,
-                                        SmallVectorImpl<MVT> &SignatureVTs,
-                                        size_t NumResults) {
+                                        SmallVectorImpl<MVT> &Params,
+                                        SmallVectorImpl<MVT> &Results) {
     llvm_unreachable("emitIndirectFunctionType not implemented");
   }
   /// .indidx
@@ -59,8 +59,8 @@ public:
   void emitLocal(ArrayRef<MVT> Types) override;
   void emitEndFunc() override;
   void emitIndirectFunctionType(StringRef name,
-                                SmallVectorImpl<MVT> &SignatureVTs,
-                                size_t NumResults) override;
+                                SmallVectorImpl<MVT> &Params,
+                                SmallVectorImpl<MVT> &Results) override;
   void emitIndIdx(const MCExpr *Value) override;
 };
 

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp?rev=283503&r1=283502&r2=283503&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp Thu Oct  6 17:29:32 2016
@@ -121,45 +121,16 @@ WebAssemblyTargetStreamer *WebAssemblyAs
 //===----------------------------------------------------------------------===//
 // WebAssemblyAsmPrinter Implementation.
 //===----------------------------------------------------------------------===//
-static void ComputeLegalValueVTs(const Function &F, const TargetMachine &TM,
-                                 Type *Ty, SmallVectorImpl<MVT> &ValueVTs) {
-  const DataLayout &DL(F.getParent()->getDataLayout());
-  const WebAssemblyTargetLowering &TLI =
-      *TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering();
-  SmallVector<EVT, 4> VTs;
-  ComputeValueVTs(TLI, DL, Ty, VTs);
-
-  for (EVT VT : VTs) {
-    unsigned NumRegs = TLI.getNumRegisters(F.getContext(), VT);
-    MVT RegisterVT = TLI.getRegisterType(F.getContext(), VT);
-    for (unsigned i = 0; i != NumRegs; ++i)
-      ValueVTs.push_back(RegisterVT);
-  }
-}
 
 void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
   for (const auto &F : M) {
     // Emit function type info for all undefined functions
     if (F.isDeclarationForLinker() && !F.isIntrinsic()) {
-      SmallVector<MVT, 4> SignatureVTs;
-      ComputeLegalValueVTs(F, TM, F.getReturnType(), SignatureVTs);
-      size_t NumResults = SignatureVTs.size();
-      if (SignatureVTs.size() > 1) {
-        // WebAssembly currently can't lower returns of multiple values without
-        // demoting to sret (see WebAssemblyTargetLowering::CanLowerReturn). So
-        // replace multiple return values with a pointer parameter.
-        SignatureVTs.clear();
-        SignatureVTs.push_back(
-            MVT::getIntegerVT(M.getDataLayout().getPointerSizeInBits()));
-        NumResults = 0;
-      }
-
-      for (auto &Arg : F.args()) {
-        ComputeLegalValueVTs(F, TM, Arg.getType(), SignatureVTs);
-      }
-
-      getTargetStreamer()->emitIndirectFunctionType(F.getName(), SignatureVTs,
-                                                    NumResults);
+      SmallVector<MVT, 4> Results;
+      SmallVector<MVT, 4> Params;
+      ComputeSignatureVTs(F, TM, Params, Results);
+      getTargetStreamer()->emitIndirectFunctionType(F.getName(), Params,
+                                                    Results);
     }
   }
 }

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp?rev=283503&r1=283502&r2=283503&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp Thu Oct  6 17:29:32 2016
@@ -309,7 +309,8 @@ static bool IsChild(const MachineInstr &
 static void PlaceBlockMarker(
     MachineBasicBlock &MBB, MachineFunction &MF,
     SmallVectorImpl<MachineBasicBlock *> &ScopeTops,
-    DenseMap<const MachineInstr *, const MachineBasicBlock *> &LoopTops,
+    DenseMap<const MachineInstr *, MachineInstr *> &BlockTops,
+    DenseMap<const MachineInstr *, MachineInstr *> &LoopTops,
     const WebAssemblyInstrInfo &TII,
     const MachineLoopInfo &MLI,
     MachineDominatorTree &MDT,
@@ -372,15 +373,19 @@ static void PlaceBlockMarker(
   }
 
   // Add the BLOCK.
-  BuildMI(*Header, InsertPos, DebugLoc(), TII.get(WebAssembly::BLOCK));
+  MachineInstr *Begin = BuildMI(*Header, InsertPos, DebugLoc(),
+                                TII.get(WebAssembly::BLOCK))
+      .addImm(WebAssembly::Void);
 
   // Mark the end of the block.
   InsertPos = MBB.begin();
   while (InsertPos != MBB.end() &&
          InsertPos->getOpcode() == WebAssembly::END_LOOP &&
-         LoopTops[&*InsertPos]->getNumber() >= Header->getNumber())
+         LoopTops[&*InsertPos]->getParent()->getNumber() >= Header->getNumber())
     ++InsertPos;
-  BuildMI(MBB, InsertPos, DebugLoc(), TII.get(WebAssembly::END_BLOCK));
+  MachineInstr *End = BuildMI(MBB, InsertPos, DebugLoc(),
+                              TII.get(WebAssembly::END_BLOCK));
+  BlockTops[End] = Begin;
 
   // Track the farthest-spanning scope that ends at this point.
   int Number = MBB.getNumber();
@@ -393,7 +398,7 @@ static void PlaceBlockMarker(
 static void PlaceLoopMarker(
     MachineBasicBlock &MBB, MachineFunction &MF,
     SmallVectorImpl<MachineBasicBlock *> &ScopeTops,
-    DenseMap<const MachineInstr *, const MachineBasicBlock *> &LoopTops,
+    DenseMap<const MachineInstr *, MachineInstr *> &LoopTops,
     const WebAssemblyInstrInfo &TII, const MachineLoopInfo &MLI) {
   MachineLoop *Loop = MLI.getLoopFor(&MBB);
   if (!Loop || Loop->getHeader() != &MBB)
@@ -418,12 +423,14 @@ static void PlaceLoopMarker(
   while (InsertPos != MBB.end() &&
          InsertPos->getOpcode() == WebAssembly::END_LOOP)
     ++InsertPos;
-  BuildMI(MBB, InsertPos, DebugLoc(), TII.get(WebAssembly::LOOP));
+  MachineInstr *Begin = BuildMI(MBB, InsertPos, DebugLoc(),
+                                TII.get(WebAssembly::LOOP))
+      .addImm(WebAssembly::Void);
 
   // Mark the end of the loop.
   MachineInstr *End = BuildMI(*AfterLoop, AfterLoop->begin(), DebugLoc(),
                               TII.get(WebAssembly::END_LOOP));
-  LoopTops[End] = &MBB;
+  LoopTops[End] = Begin;
 
   assert((!ScopeTops[AfterLoop->getNumber()] ||
           ScopeTops[AfterLoop->getNumber()]->getNumber() < MBB.getNumber()) &&
@@ -445,6 +452,56 @@ GetDepth(const SmallVectorImpl<const Mac
   return Depth;
 }
 
+/// In normal assembly languages, when the end of a function is unreachable,
+/// because the function ends in an infinite loop or a noreturn call or similar,
+/// it isn't necessary to worry about the function return type at the end of
+/// the function, because it's never reached. However, in WebAssembly, blocks
+/// that end at the function end need to have a return type signature that
+/// matches the function signature, even though it's unreachable. This function
+/// checks for such cases and fixes up the signatures.
+static void FixEndsAtEndOfFunction(
+    MachineFunction &MF,
+    const WebAssemblyFunctionInfo &MFI,
+    DenseMap<const MachineInstr *, MachineInstr *> &BlockTops,
+    DenseMap<const MachineInstr *, MachineInstr *> &LoopTops) {
+  assert(MFI.getResults().size() <= 1);
+
+  if (MFI.getResults().empty())
+    return;
+
+  WebAssembly::ExprType retType;
+  switch (MFI.getResults().front().SimpleTy) {
+  case MVT::i32: retType = WebAssembly::I32; break;
+  case MVT::i64: retType = WebAssembly::I64; break;
+  case MVT::f32: retType = WebAssembly::F32; break;
+  case MVT::f64: retType = WebAssembly::F64; break;
+  case MVT::v16i8: retType = WebAssembly::I8x16; break;
+  case MVT::v8i16: retType = WebAssembly::I16x8; break;
+  case MVT::v4i32: retType = WebAssembly::I32x4; break;
+  case MVT::v2i64: retType = WebAssembly::I64x2; break;
+  case MVT::v4f32: retType = WebAssembly::F32x4; break;
+  case MVT::v2f64: retType = WebAssembly::F64x2; break;
+  default: llvm_unreachable("unexpected return type");
+  }
+
+  for (MachineBasicBlock &MBB : reverse(MF)) {
+    for (MachineInstr &MI : reverse(MBB)) {
+      if (MI.isPosition() || MI.isDebugValue())
+        continue;
+      if (MI.getOpcode() == WebAssembly::END_BLOCK) {
+        BlockTops[&MI]->getOperand(0).setImm(int32_t(retType));
+        continue;
+      }
+      if (MI.getOpcode() == WebAssembly::END_LOOP) {
+        LoopTops[&MI]->getOperand(0).setImm(int32_t(retType));
+        continue;
+      }
+      // Something other than an `end`. We're done.
+      return;
+    }
+  }
+}
+
 /// Insert LOOP and BLOCK markers at appropriate places.
 static void PlaceMarkers(MachineFunction &MF, const MachineLoopInfo &MLI,
                          const WebAssemblyInstrInfo &TII,
@@ -457,15 +514,18 @@ static void PlaceMarkers(MachineFunction
   // we may insert at the end.
   SmallVector<MachineBasicBlock *, 8> ScopeTops(MF.getNumBlockIDs() + 1);
 
-  // For eacn LOOP_END, the corresponding LOOP.
-  DenseMap<const MachineInstr *, const MachineBasicBlock *> LoopTops;
+  // For each LOOP_END, the corresponding LOOP.
+  DenseMap<const MachineInstr *, MachineInstr *> LoopTops;
+
+  // For each END_BLOCK, the corresponding BLOCK.
+  DenseMap<const MachineInstr *, MachineInstr *> BlockTops;
 
   for (auto &MBB : MF) {
     // Place the LOOP for MBB if MBB is the header of a loop.
     PlaceLoopMarker(MBB, MF, ScopeTops, LoopTops, TII, MLI);
 
     // Place the BLOCK for MBB if MBB is branched to from above.
-    PlaceBlockMarker(MBB, MF, ScopeTops, LoopTops, TII, MLI, MDT, MFI);
+    PlaceBlockMarker(MBB, MF, ScopeTops, BlockTops, LoopTops, TII, MLI, MDT, MFI);
   }
 
   // Now rewrite references to basic blocks to be depth immediates.
@@ -486,7 +546,7 @@ static void PlaceMarkers(MachineFunction
         Stack.push_back(&MBB);
         break;
       case WebAssembly::END_LOOP:
-        Stack.push_back(LoopTops[&MI]);
+        Stack.push_back(LoopTops[&MI]->getParent());
         break;
       default:
         if (MI.isTerminator()) {
@@ -505,6 +565,10 @@ static void PlaceMarkers(MachineFunction
     }
   }
   assert(Stack.empty() && "Control flow should be balanced");
+
+  // Fix up block/loop signatures at the end of the function to conform to
+  // WebAssembly's rules.
+  FixEndsAtEndOfFunction(MF, MFI, BlockTops, LoopTops);
 }
 
 bool WebAssemblyCFGStackify::runOnMachineFunction(MachineFunction &MF) {

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp?rev=283503&r1=283502&r2=283503&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp Thu Oct  6 17:29:32 2016
@@ -481,12 +481,12 @@ SDValue WebAssemblyTargetLowering::Lower
     SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
     const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
     SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
-  MachineFunction &MF = DAG.getMachineFunction();
-  auto *MFI = MF.getInfo<WebAssemblyFunctionInfo>();
-
   if (!CallingConvSupported(CallConv))
     fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");
 
+  MachineFunction &MF = DAG.getMachineFunction();
+  auto *MFI = MF.getInfo<WebAssemblyFunctionInfo>();
+
   // Set up the incoming ARGUMENTS value, which serves to represent the liveness
   // of the incoming values before they're represented by virtual registers.
   MF.getRegInfo().addLiveIn(WebAssembly::ARGUMENTS);
@@ -526,6 +526,13 @@ SDValue WebAssemblyTargetLowering::Lower
     MFI->addParam(PtrVT);
   }
 
+  // Record the number and types of results.
+  SmallVector<MVT, 4> Params;
+  SmallVector<MVT, 4> Results;
+  ComputeSignatureVTs(*MF.getFunction(), DAG.getTarget(), Params, Results);
+  for (MVT VT : Results)
+    MFI->addResult(VT);
+
   return Chain;
 }
 

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td?rev=283503&r1=283502&r2=283503&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td Thu Oct  6 17:29:32 2016
@@ -61,8 +61,8 @@ def BR_TABLE_I64 : I<(outs), (ins I64:$i
 // use/clobber VALUE_STACK to prevent them from being moved into the middle of
 // an expression tree.
 let Uses = [VALUE_STACK], Defs = [VALUE_STACK] in {
-def BLOCK     : I<(outs), (ins), [], "block", 0x01>;
-def LOOP      : I<(outs), (ins), [], "loop", 0x02>;
+def BLOCK     : I<(outs), (ins Signature:$sig), [], "block   \t$sig", 0x01>;
+def LOOP      : I<(outs), (ins Signature:$sig), [], "loop    \t$sig", 0x02>;
 def END_BLOCK : I<(outs), (ins), [], "end_block">;
 def END_LOOP  : I<(outs), (ins), [], "end_loop">;
 } // Uses = [VALUE_STACK], Defs = [VALUE_STACK]

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td?rev=283503&r1=283502&r2=283503&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td Thu Oct  6 17:29:32 2016
@@ -89,6 +89,12 @@ def P2Align : Operand<i32> {
 }
 } // OperandType = "OPERAND_P2ALIGN"
 
+let OperandType = "OPERAND_SIGNATURE" in {
+def Signature : Operand<i32> {
+  let PrintMethod = "printWebAssemblySignatureOperand";
+}
+} // OperandType = "OPERAND_SIGNATURE"
+
 } // OperandNamespace = "WebAssembly"
 
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp?rev=283503&r1=283502&r2=283503&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp Thu Oct  6 17:29:32 2016
@@ -14,6 +14,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "WebAssemblyMachineFunctionInfo.h"
+#include "WebAssemblyISelLowering.h"
+#include "WebAssemblySubtarget.h"
+#include "llvm/CodeGen/Analysis.h"
 using namespace llvm;
 
 WebAssemblyFunctionInfo::~WebAssemblyFunctionInfo() {}
@@ -23,3 +26,37 @@ void WebAssemblyFunctionInfo::initWARegs
   unsigned Reg = UnusedReg;
   WARegs.resize(MF.getRegInfo().getNumVirtRegs(), Reg);
 }
+
+void llvm::ComputeLegalValueVTs(const Function &F, const TargetMachine &TM,
+                                Type *Ty, SmallVectorImpl<MVT> &ValueVTs) {
+  const DataLayout &DL(F.getParent()->getDataLayout());
+  const WebAssemblyTargetLowering &TLI =
+      *TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering();
+  SmallVector<EVT, 4> VTs;
+  ComputeValueVTs(TLI, DL, Ty, VTs);
+
+  for (EVT VT : VTs) {
+    unsigned NumRegs = TLI.getNumRegisters(F.getContext(), VT);
+    MVT RegisterVT = TLI.getRegisterType(F.getContext(), VT);
+    for (unsigned i = 0; i != NumRegs; ++i)
+      ValueVTs.push_back(RegisterVT);
+  }
+}
+
+void llvm::ComputeSignatureVTs(const Function &F, const TargetMachine &TM,
+                               SmallVectorImpl<MVT> &Params,
+                               SmallVectorImpl<MVT> &Results) {
+  ComputeLegalValueVTs(F, TM, F.getReturnType(), Results);
+
+  if (Results.size() > 1) {
+    // WebAssembly currently can't lower returns of multiple values without
+    // demoting to sret (see WebAssemblyTargetLowering::CanLowerReturn). So
+    // replace multiple return values with a pointer parameter.
+    Results.clear();
+    Params.push_back(
+        MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits()));
+  }
+
+  for (auto &Arg : F.args())
+    ComputeLegalValueVTs(F, TM, Arg.getType(), Params);
+}

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h?rev=283503&r1=283502&r2=283503&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h Thu Oct  6 17:29:32 2016
@@ -27,6 +27,7 @@ class WebAssemblyFunctionInfo final : pu
   MachineFunction &MF;
 
   std::vector<MVT> Params;
+  std::vector<MVT> Results;
 
   /// A mapping from CodeGen vreg index to WebAssembly register number.
   std::vector<unsigned> WARegs;
@@ -51,6 +52,9 @@ class WebAssemblyFunctionInfo final : pu
   void addParam(MVT VT) { Params.push_back(VT); }
   const std::vector<MVT> &getParams() const { return Params; }
 
+  void addResult(MVT VT) { Results.push_back(VT); }
+  const std::vector<MVT> &getResults() const { return Results; }
+
   unsigned getVarargBufferVreg() const {
     assert(VarargVreg != -1U && "Vararg vreg hasn't been set");
     return VarargVreg;
@@ -88,6 +92,13 @@ class WebAssemblyFunctionInfo final : pu
   }
 };
 
+void ComputeLegalValueVTs(const Function &F, const TargetMachine &TM,
+                          Type *Ty, SmallVectorImpl<MVT> &ValueVTs);
+
+void ComputeSignatureVTs(const Function &F, const TargetMachine &TM,
+                         SmallVectorImpl<MVT> &Params,
+                         SmallVectorImpl<MVT> &Results);
+
 } // end namespace llvm
 
 #endif

Modified: llvm/trunk/test/CodeGen/WebAssembly/cfg-stackify.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/cfg-stackify.ll?rev=283503&r1=283502&r2=283503&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/cfg-stackify.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/cfg-stackify.ll Thu Oct  6 17:29:32 2016
@@ -105,7 +105,7 @@ back:
 
 ; CHECK-LABEL: test2:
 ; CHECK-NOT: local
-; CHECK: block{{$}}
+; CHECK: block   {{$}}
 ; CHECK: br_if 0, {{[^,]+}}{{$}}
 ; CHECK: .LBB2_{{[0-9]+}}:
 ; CHECK: loop
@@ -116,7 +116,7 @@ back:
 ; CHECK: return{{$}}
 ; OPT-LABEL: test2:
 ; OPT-NOT: local
-; OPT: block{{$}}
+; OPT: block   {{$}}
 ; OPT: br_if 0, {{[^,]+}}{{$}}
 ; OPT: .LBB2_{{[0-9]+}}:
 ; OPT: loop
@@ -151,13 +151,13 @@ for.end:
 }
 
 ; CHECK-LABEL: doublediamond:
-; CHECK: block{{$}}
-; CHECK-NEXT: block{{$}}
+; CHECK: block   {{$}}
+; CHECK-NEXT: block   {{$}}
 ; CHECK: br_if 0, ${{[^,]+}}{{$}}
 ; CHECK: br 1{{$}}
 ; CHECK: .LBB3_2:
 ; CHECK-NEXT: end_block{{$}}
-; CHECK: block{{$}}
+; CHECK: block   {{$}}
 ; CHECK: br_if 0, ${{[^,]+}}{{$}}
 ; CHECK: br 1{{$}}
 ; CHECK: .LBB3_4:
@@ -167,9 +167,9 @@ for.end:
 ; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
 ; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
 ; OPT-LABEL: doublediamond:
-; OPT:      block{{$}}
-; OPT-NEXT: block{{$}}
-; OPT-NEXT: block{{$}}
+; OPT:      block   {{$}}
+; OPT-NEXT: block   {{$}}
+; OPT-NEXT: block   {{$}}
 ; OPT:      br_if 0, ${{[^,]+}}{{$}}
 ; OPT:      br_if 1, ${{[^,]+}}{{$}}
 ; OPT:      br 2{{$}}
@@ -204,12 +204,12 @@ exit:
 }
 
 ; CHECK-LABEL: triangle:
-; CHECK: block{{$}}
+; CHECK: block   {{$}}
 ; CHECK: br_if 0, $1{{$}}
 ; CHECK: .LBB4_2:
 ; CHECK: return
 ; OPT-LABEL: triangle:
-; OPT: block{{$}}
+; OPT: block   {{$}}
 ; OPT: br_if 0, $1{{$}}
 ; OPT: .LBB4_2:
 ; OPT: return
@@ -227,8 +227,8 @@ exit:
 }
 
 ; CHECK-LABEL: diamond:
-; CHECK: block{{$}}
-; CHECK: block{{$}}
+; CHECK: block   {{$}}
+; CHECK: block   {{$}}
 ; CHECK: br_if 0, $1{{$}}
 ; CHECK: br 1{{$}}
 ; CHECK: .LBB5_2:
@@ -236,8 +236,8 @@ exit:
 ; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
 ; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
 ; OPT-LABEL: diamond:
-; OPT: block{{$}}
-; OPT: block{{$}}
+; OPT: block   {{$}}
+; OPT: block   {{$}}
 ; OPT: br_if 0, {{[^,]+}}{{$}}
 ; OPT: br 1{{$}}
 ; OPT: .LBB5_2:
@@ -275,16 +275,18 @@ entry:
 ; CHECK-LABEL: minimal_loop:
 ; CHECK-NOT: br
 ; CHECK: .LBB7_1:
+; CHECK: loop i32
 ; CHECK: i32.store 0($0), $pop{{[0-9]+}}{{$}}
 ; CHECK: br 0{{$}}
 ; CHECK: .LBB7_2:
 ; OPT-LABEL: minimal_loop:
 ; OPT-NOT: br
 ; OPT: .LBB7_1:
+; OPT: loop i32
 ; OPT: i32.store 0($0), $pop{{[0-9]+}}{{$}}
 ; OPT: br 0{{$}}
 ; OPT: .LBB7_2:
-define void @minimal_loop(i32* %p) {
+define i32 @minimal_loop(i32* %p) {
 entry:
   store volatile i32 0, i32* %p
   br label %loop
@@ -296,7 +298,7 @@ loop:
 ; CHECK-LABEL: simple_loop:
 ; CHECK-NOT: br
 ; CHECK: .LBB8_1:
-; CHECK: loop{{$}}
+; CHECK: loop    {{$}}
 ; CHECK: br_if 0, $pop{{[0-9]+}}{{$}}
 ; CHECK-NEXT: end_loop{{$}}
 ; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
@@ -304,7 +306,7 @@ loop:
 ; OPT-LABEL: simple_loop:
 ; OPT-NOT: br
 ; OPT: .LBB8_1:
-; OPT: loop{{$}}
+; OPT: loop    {{$}}
 ; OPT: br_if 0, {{[^,]+}}{{$}}
 ; OPT-NEXT: end_loop{{$}}
 ; OPT: i32.const $push{{[0-9]+}}=, 0{{$}}
@@ -323,17 +325,17 @@ exit:
 }
 
 ; CHECK-LABEL: doubletriangle:
-; CHECK: block{{$}}
+; CHECK: block   {{$}}
 ; CHECK: br_if 0, $0{{$}}
-; CHECK: block{{$}}
+; CHECK: block   {{$}}
 ; CHECK: br_if 0, $1{{$}}
 ; CHECK: .LBB9_3:
 ; CHECK: .LBB9_4:
 ; CHECK: return
 ; OPT-LABEL: doubletriangle:
-; OPT: block{{$}}
+; OPT: block   {{$}}
 ; OPT: br_if 0, $0{{$}}
-; OPT: block{{$}}
+; OPT: block   {{$}}
 ; OPT: br_if 0, $1{{$}}
 ; OPT: .LBB9_3:
 ; OPT: .LBB9_4:
@@ -359,8 +361,8 @@ exit:
 }
 
 ; CHECK-LABEL: ifelse_earlyexits:
-; CHECK: block{{$}}
-; CHECK: block{{$}}
+; CHECK: block   {{$}}
+; CHECK: block   {{$}}
 ; CHECK: br_if 0, $0{{$}}
 ; CHECK: br 1{{$}}
 ; CHECK: .LBB10_2:
@@ -369,8 +371,8 @@ exit:
 ; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
 ; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
 ; OPT-LABEL: ifelse_earlyexits:
-; OPT: block{{$}}
-; OPT: block{{$}}
+; OPT: block   {{$}}
+; OPT: block   {{$}}
 ; OPT: br_if 0, {{[^,]+}}{{$}}
 ; OPT: br_if 1, $1{{$}}
 ; OPT: br 1{{$}}
@@ -400,13 +402,13 @@ exit:
 
 ; CHECK-LABEL: doublediamond_in_a_loop:
 ; CHECK: .LBB11_1:
-; CHECK: loop{{$}}
-; CHECK: block{{$}}
+; CHECK: loop i32{{$}}
+; CHECK: block   {{$}}
 ; CHECK: br_if           0, $0{{$}}
 ; CHECK: br              1{{$}}
 ; CHECK: .LBB11_3:
 ; CHECK: end_block{{$}}
-; CHECK: block{{$}}
+; CHECK: block   {{$}}
 ; CHECK: br_if           0, $1{{$}}
 ; CHECK: br              1{{$}}
 ; CHECK: .LBB11_5:
@@ -415,10 +417,10 @@ exit:
 ; CHECK-NEXT: end_loop{{$}}
 ; OPT-LABEL: doublediamond_in_a_loop:
 ; OPT:      .LBB11_1:
-; OPT:      loop{{$}}
-; OPT:      block{{$}}
+; OPT:      loop i32{{$}}
+; OPT:      block   {{$}}
 ; OPT:      br_if           0, {{[^,]+}}{{$}}
-; OPT:      block{{$}}
+; OPT:      block   {{$}}
 ; OPT:      br_if           0, {{[^,]+}}{{$}}
 ; OPT:      br              2{{$}}
 ; OPT-NEXT: .LBB11_4:
@@ -429,7 +431,7 @@ exit:
 ; OPT:      br              0{{$}}
 ; OPT:      .LBB11_6:
 ; OPT-NEXT: end_loop{{$}}
-define void @doublediamond_in_a_loop(i32 %a, i32 %b, i32* %p) {
+define i32 @doublediamond_in_a_loop(i32 %a, i32 %b, i32* %p) {
 entry:
   br label %header
 header:
@@ -513,14 +515,14 @@ if.end:
 
 ; CHECK-LABEL: test4:
 ; CHECK-NEXT: .param       i32{{$}}
-; CHECK:      block{{$}}
-; CHECK-NEXT: block{{$}}
+; CHECK:      block   {{$}}
+; CHECK-NEXT: block   {{$}}
 ; CHECK:      br_if       0, $pop{{[0-9]+}}{{$}}
 ; CHECK:      br_if       1, $pop{{[0-9]+}}{{$}}
 ; CHECK:      br          1{{$}}
 ; CHECK-NEXT: .LBB13_3:
 ; CHECK-NEXT: end_block{{$}}
-; CHECK-NEXT: block{{$}}
+; CHECK-NEXT: block   {{$}}
 ; CHECK:      br_if 0, $pop{{[0-9]+}}{{$}}
 ; CHECK:      br_if 1, $pop{{[0-9]+}}{{$}}
 ; CHECK-NEXT: .LBB13_5:
@@ -531,14 +533,14 @@ if.end:
 ; CHECK-NEXT: return{{$}}
 ; OPT-LABEL: test4:
 ; OPT-NEXT: .param       i32{{$}}
-; OPT:      block{{$}}
-; OPT-NEXT: block{{$}}
+; OPT:      block   {{$}}
+; OPT-NEXT: block   {{$}}
 ; OPT:      br_if       0, $pop{{[0-9]+}}{{$}}
 ; OPT:      br_if       1, $pop{{[0-9]+}}{{$}}
 ; OPT:      br          1{{$}}
 ; OPT-NEXT: .LBB13_3:
 ; OPT-NEXT: end_block{{$}}
-; OPT-NEXT: block{{$}}
+; OPT-NEXT: block   {{$}}
 ; OPT:      br_if       0, $pop{{[0-9]+}}{{$}}
 ; OPT:      br_if       1, $pop{{[0-9]+}}{{$}}
 ; OPT-NEXT: .LBB13_5:
@@ -574,8 +576,8 @@ default:
 
 ; CHECK-LABEL: test5:
 ; CHECK:       .LBB14_1:
-; CHECK-NEXT:  block{{$}}
-; CHECK-NEXT:  loop{{$}}
+; CHECK-NEXT:  block   {{$}}
+; CHECK-NEXT:  loop    {{$}}
 ; CHECK:       br_if 1, {{[^,]+}}{{$}}
 ; CHECK:       br_if 0, {{[^,]+}}{{$}}
 ; CHECK-NEXT:  end_loop{{$}}
@@ -584,8 +586,8 @@ default:
 ; CHECK:       return{{$}}
 ; OPT-LABEL: test5:
 ; OPT:       .LBB14_1:
-; OPT-NEXT:  block{{$}}
-; OPT-NEXT:  loop{{$}}
+; OPT-NEXT:  block   {{$}}
+; OPT-NEXT:  loop    {{$}}
 ; OPT:       br_if 1, {{[^,]+}}{{$}}
 ; OPT:       br_if 0, {{[^,]+}}{{$}}
 ; OPT-NEXT:  end_loop{{$}}
@@ -619,9 +621,9 @@ return:
 
 ; CHECK-LABEL: test6:
 ; CHECK:       .LBB15_1:
-; CHECK-NEXT:  block{{$}}
-; CHECK-NEXT:  block{{$}}
-; CHECK-NEXT:  loop{{$}}
+; CHECK-NEXT:  block   {{$}}
+; CHECK-NEXT:  block   {{$}}
+; CHECK-NEXT:  loop    {{$}}
 ; CHECK-NOT:   block
 ; CHECK:       br_if 2, {{[^,]+}}{{$}}
 ; CHECK-NOT:   block
@@ -640,9 +642,9 @@ return:
 ; CHECK:       return{{$}}
 ; OPT-LABEL: test6:
 ; OPT:       .LBB15_1:
-; OPT-NEXT:  block{{$}}
-; OPT-NEXT:  block{{$}}
-; OPT-NEXT:  loop{{$}}
+; OPT-NEXT:  block   {{$}}
+; OPT-NEXT:  block   {{$}}
+; OPT-NEXT:  loop    {{$}}
 ; OPT-NOT:   block
 ; OPT:       br_if 2, {{[^,]+}}{{$}}
 ; OPT-NOT:   block
@@ -693,9 +695,9 @@ second:
 
 ; CHECK-LABEL: test7:
 ; CHECK:       .LBB16_1:
-; CHECK-NEXT:  loop{{$}}
+; CHECK-NEXT:  loop    {{$}}
 ; CHECK-NOT:   block
-; CHECK:       block{{$}}
+; CHECK:       block   {{$}}
 ; CHECK:       br_if 0, {{[^,]+}}{{$}}
 ; CHECK-NOT:   block
 ; CHECK:       br_if 1, {{[^,]+}}{{$}}
@@ -711,9 +713,9 @@ second:
 ; OPT-LABEL: test7:
 ; OPT:       .LBB16_1:
 ; OPT-NEXT:  block
-; OPT-NEXT:  loop{{$}}
+; OPT-NEXT:  loop    {{$}}
 ; OPT-NOT:   block
-; OPT:       block{{$}}
+; OPT:       block   {{$}}
 ; OPT-NOT:   block
 ; OPT:       br_if 0, {{[^,]+}}{{$}}
 ; OPT-NOT:   block
@@ -760,7 +762,7 @@ u1:
 
 ; CHECK-LABEL: test8:
 ; CHECK:       .LBB17_1:
-; CHECK-NEXT:  loop{{$}}
+; CHECK-NEXT:  loop i32{{$}}
 ; CHECK-NEXT:  i32.const $push{{[^,]+}}, 0{{$}}
 ; CHECK-NEXT:  br_if    0, {{[^,]+}}{{$}}
 ; CHECK-NEXT:  br       0{{$}}
@@ -768,13 +770,13 @@ u1:
 ; CHECK-NEXT:  end_loop{{$}}
 ; OPT-LABEL: test8:
 ; OPT:       .LBB17_1:
-; OPT-NEXT:  loop{{$}}
+; OPT-NEXT:  loop i32{{$}}
 ; OPT-NEXT:  i32.const $push{{[^,]+}}, 0{{$}}
 ; OPT-NEXT:  br_if    0, {{[^,]+}}{{$}}
 ; OPT-NEXT:  br       0{{$}}
 ; OPT-NEXT:  .LBB17_2:
 ; OPT-NEXT:  end_loop{{$}}
-define void @test8() {
+define i32 @test8() {
 bb:
   br label %bb1
 
@@ -796,14 +798,14 @@ bb3:
 
 ; CHECK-LABEL: test9:
 ; CHECK:       .LBB18_1:
-; CHECK-NEXT:  block{{$}}
-; CHECK-NEXT:  loop{{$}}
+; CHECK-NEXT:  block   {{$}}
+; CHECK-NEXT:  loop    {{$}}
 ; CHECK-NOT:   block
 ; CHECK:       br_if     1, {{[^,]+}}{{$}}
 ; CHECK-NEXT:  .LBB18_2:
-; CHECK-NEXT:  loop{{$}}
+; CHECK-NEXT:  loop    {{$}}
 ; CHECK-NOT:   block
-; CHECK:       block{{$}}
+; CHECK:       block   {{$}}
 ; CHECK-NOT:   block
 ; CHECK:       br_if     0, {{[^,]+}}{{$}}
 ; CHECK-NOT:   block
@@ -821,14 +823,14 @@ bb3:
 ; CHECK:       return{{$}}
 ; OPT-LABEL: test9:
 ; OPT:       .LBB18_1:
-; OPT-NEXT:  block{{$}}
-; OPT-NEXT:  loop{{$}}
+; OPT-NEXT:  block   {{$}}
+; OPT-NEXT:  loop    {{$}}
 ; OPT-NOT:   block
 ; OPT:       br_if     1, {{[^,]+}}{{$}}
 ; OPT-NEXT:  .LBB18_2:
-; OPT-NEXT:  loop{{$}}
+; OPT-NEXT:  loop    {{$}}
 ; OPT-NOT:   block
-; OPT:       block{{$}}
+; OPT:       block   {{$}}
 ; OPT-NOT:   block
 ; OPT:       br_if     0, {{[^,]+}}{{$}}
 ; OPT-NOT:   block
@@ -880,18 +882,18 @@ end:
 
 ; CHECK-LABEL: test10:
 ; CHECK:       .LBB19_1:
-; CHECK-NEXT:  loop{{$}}
+; CHECK-NEXT:  loop    {{$}}
 ; CHECK-NOT:   block
 ; CHECK:       br_if    0, {{[^,]+}}{{$}}
 ; CHECK:       .LBB19_3:
-; CHECK-NEXT:  block{{$}}
-; CHECK-NEXT:  loop{{$}}
+; CHECK-NEXT:  block   {{$}}
+; CHECK-NEXT:  loop    {{$}}
 ; CHECK-NOT:   block
 ; CHECK:       .LBB19_4:
-; CHECK-NEXT:  loop{{$}}
+; CHECK-NEXT:  loop    {{$}}
 ; CHECK-NOT:   block
 ; CHECK:       br_if    3, {{[^,]+}}{{$}}
-; CHECK:       block{{$}}
+; CHECK:       block   {{$}}
 ; CHECK:       br_table  {{[^,]+}}, 1, 0, 4, 2, 3, 1{{$}}
 ; CHECK-NEXT:  .LBB19_6:
 ; CHECK-NEXT:  end_block{{$}}
@@ -905,15 +907,15 @@ end:
 ; CHECK-NEXT:  .LBB19_8:
 ; OPT-LABEL: test10:
 ; OPT:       .LBB19_1:
-; OPT-NEXT:  loop{{$}}
+; OPT-NEXT:  loop    {{$}}
 ; OPT-NOT:   block
 ; OPT:       br_if    0, {{[^,]+}}{{$}}
 ; OPT:       .LBB19_3:
-; OPT-NEXT:  block{{$}}
-; OPT-NEXT:  loop{{$}}
+; OPT-NEXT:  block   {{$}}
+; OPT-NEXT:  loop    {{$}}
 ; OPT-NOT:   block
 ; OPT:       .LBB19_4:
-; OPT-NEXT:  loop{{$}}
+; OPT-NEXT:  loop    {{$}}
 ; OPT-NOT:   block
 ; OPT:       br_if    3, {{[^,]+}}{{$}}
 ; OPT:       block
@@ -966,13 +968,13 @@ bb6:
 ; Test a CFG DAG with interesting merging.
 
 ; CHECK-LABEL: test11:
-; CHECK:       block{{$}}
-; CHECK-NEXT:  block{{$}}
-; CHECK-NEXT:  block{{$}}
-; CHECK-NEXT:  block{{$}}
+; CHECK:       block   {{$}}
+; CHECK-NEXT:  block   {{$}}
+; CHECK-NEXT:  block   {{$}}
+; CHECK-NEXT:  block   {{$}}
 ; CHECK:       br_if        0, {{[^,]+}}{{$}}
 ; CHECK-NOT:   block
-; CHECK:       block{{$}}
+; CHECK:       block   {{$}}
 ; CHECK-NEXT:  i32.const
 ; CHECK-NEXT:  br_if        0, {{[^,]+}}{{$}}
 ; CHECK-NOT:   block
@@ -1000,11 +1002,11 @@ bb6:
 ; CHECK-NOT:   block
 ; CHECK:       return{{$}}
 ; OPT-LABEL: test11:
-; OPT:       block{{$}}
-; OPT-NEXT:  block{{$}}
+; OPT:       block   {{$}}
+; OPT-NEXT:  block   {{$}}
 ; OPT:       br_if        0, $pop{{[0-9]+}}{{$}}
 ; OPT-NOT:   block
-; OPT:       block{{$}}
+; OPT:       block   {{$}}
 ; OPT-NEXT:  i32.const
 ; OPT-NEXT:  br_if        0, {{[^,]+}}{{$}}
 ; OPT-NOT:   block
@@ -1016,7 +1018,7 @@ bb6:
 ; OPT-NEXT:  .LBB20_4:
 ; OPT-NEXT:  end_block{{$}}
 ; OPT-NOT:   block
-; OPT:       block{{$}}
+; OPT:       block   {{$}}
 ; OPT-NOT:   block
 ; OPT:       br_if        0, $pop{{[0-9]+}}{{$}}
 ; OPT-NOT:   block
@@ -1063,11 +1065,11 @@ bb8:
 
 ; CHECK-LABEL: test12:
 ; CHECK:       .LBB21_1:
-; CHECK-NEXT:  block{{$}}
-; CHECK-NEXT:  loop{{$}}
+; CHECK-NEXT:  block   {{$}}
+; CHECK-NEXT:  loop    {{$}}
 ; CHECK-NOT:   block
-; CHECK:       block{{$}}
-; CHECK-NEXT:  block{{$}}
+; CHECK:       block   {{$}}
+; CHECK-NEXT:  block   {{$}}
 ; CHECK:       br_if       0, {{[^,]+}}{{$}}
 ; CHECK-NOT:   block
 ; CHECK:       br_if       1, {{[^,]+}}{{$}}
@@ -1090,11 +1092,11 @@ bb8:
 ; CHECK-NEXT:  return{{$}}
 ; OPT-LABEL: test12:
 ; OPT:       .LBB21_1:
-; OPT-NEXT:  block{{$}}
-; OPT-NEXT:  loop{{$}}
+; OPT-NEXT:  block   {{$}}
+; OPT-NEXT:  loop    {{$}}
 ; OPT-NOT:   block
-; OPT:       block{{$}}
-; OPT-NEXT:  block{{$}}
+; OPT:       block   {{$}}
+; OPT-NEXT:  block   {{$}}
 ; OPT:       br_if       0, {{[^,]+}}{{$}}
 ; OPT-NOT:   block
 ; OPT:       br_if       1, {{[^,]+}}{{$}}
@@ -1143,10 +1145,10 @@ bb7:
 
 ; CHECK-LABEL: test13:
 ; CHECK-NEXT:  .local i32{{$}}
-; CHECK-NEXT:  block{{$}}
-; CHECK-NEXT:  block{{$}}
+; CHECK-NEXT:  block   {{$}}
+; CHECK-NEXT:  block   {{$}}
 ; CHECK:       br_if 0, $pop0{{$}}
-; CHECK:       block{{$}}
+; CHECK:       block   {{$}}
 ; CHECK:       br_if 0, $pop3{{$}}
 ; CHECK:       .LBB22_3:
 ; CHECK-NEXT:  end_block{{$}}
@@ -1160,10 +1162,10 @@ bb7:
 ; CHECK-NEXT:  unreachable{{$}}
 ; OPT-LABEL: test13:
 ; OPT-NEXT:  .local i32{{$}}
-; OPT-NEXT:  block{{$}}
-; OPT-NEXT:  block{{$}}
+; OPT-NEXT:  block   {{$}}
+; OPT-NEXT:  block   {{$}}
 ; OPT:       br_if 0, $pop0{{$}}
-; OPT:       block{{$}}
+; OPT:       block   {{$}}
 ; OPT:       br_if 0, $pop3{{$}}
 ; OPT:       .LBB22_3:
 ; OPT-NEXT:  end_block{{$}}
@@ -1197,12 +1199,12 @@ bb5:
 
 ; CHECK-LABEL: test14:
 ; CHECK-NEXT: .LBB23_1:{{$}}
-; CHECK-NEXT:     loop{{$}}
+; CHECK-NEXT:     loop    {{$}}
 ; CHECK-NEXT:     i32.const   $push0=, 0{{$}}
 ; CHECK-NEXT:     br_if       0, $pop0{{$}}
 ; CHECK-NEXT:     end_loop{{$}}
 ; CHECK-NEXT: .LBB23_3:{{$}}
-; CHECK-NEXT:     loop{{$}}
+; CHECK-NEXT:     loop    {{$}}
 ; CHECK-NEXT:     i32.const   $push1=, 0{{$}}
 ; CHECK-NEXT:     br_if       0, $pop1{{$}}
 ; CHECK-NEXT:     end_loop{{$}}
@@ -1261,9 +1263,9 @@ bb50:
 ; CHECK-NEXT:   block
 ; CHECK:        br_if       0, $pop{{.*}}{{$}}
 ; CHECK:        .LBB24_2:
-; CHECK-NEXT:   block{{$}}
-; CHECK-NEXT:   block{{$}}
-; CHECK-NEXT:   loop{{$}}
+; CHECK-NEXT:   block   {{$}}
+; CHECK-NEXT:   block   {{$}}
+; CHECK-NEXT:   loop    {{$}}
 ; CHECK:        br_if       1, $pop{{.*}}{{$}}
 ; CHECK:        br_if       0, ${{.*}}{{$}}
 ; CHECK-NEXT:   br          2{{$}}

Modified: llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll?rev=283503&r1=283502&r2=283503&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll Thu Oct  6 17:29:32 2016
@@ -84,7 +84,7 @@ define i32 @no_sink_readonly_call(i32 %x
 ; CHECK-LABEL: stack_uses:
 ; CHECK: .param i32, i32, i32, i32{{$}}
 ; CHECK-NEXT: .result i32{{$}}
-; CHECK-NEXT: block{{$}}
+; CHECK-NEXT: block   {{$}}
 ; CHECK-NEXT: i32.const   $push[[L13:[0-9]+]]=, 1{{$}}
 ; CHECK-NEXT: i32.lt_s    $push[[L0:[0-9]+]]=, $0, $pop[[L13]]{{$}}
 ; CHECK-NEXT: i32.const   $push[[L1:[0-9]+]]=, 2{{$}}
@@ -127,7 +127,7 @@ false:
 ; CHECK-LABEL: multiple_uses:
 ; CHECK: .param       i32, i32, i32{{$}}
 ; CHECK-NEXT: .local       i32{{$}}
-; CHECK-NEXT: block{{$}}
+; CHECK-NEXT: block   {{$}}
 ; CHECK-NEXT: i32.load    $push[[NUM0:[0-9]+]]=, 0($2){{$}}
 ; CHECK-NEXT: tee_local   $push[[NUM1:[0-9]+]]=, $3=, $pop[[NUM0]]{{$}}
 ; CHECK-NEXT: i32.ge_u    $push[[NUM2:[0-9]+]]=, $pop[[NUM1]], $1{{$}}

Modified: llvm/trunk/test/CodeGen/WebAssembly/switch.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/switch.ll?rev=283503&r1=283502&r2=283503&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/switch.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/switch.ll Thu Oct  6 17:29:32 2016
@@ -14,13 +14,13 @@ declare void @foo4()
 declare void @foo5()
 
 ; CHECK-LABEL: bar32:
-; CHECK: block{{$}}
-; CHECK: block{{$}}
-; CHECK: block{{$}}
-; CHECK: block{{$}}
-; CHECK: block{{$}}
-; CHECK: block{{$}}
-; CHECK: block{{$}}
+; CHECK: block   {{$}}
+; CHECK: block   {{$}}
+; CHECK: block   {{$}}
+; CHECK: block   {{$}}
+; CHECK: block   {{$}}
+; CHECK: block   {{$}}
+; CHECK: block   {{$}}
 ; CHECK: br_table {{[^,]+}}, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 4, 5, 0{{$}}
 ; CHECK: .LBB0_2:
 ; CHECK:   call foo0 at FUNCTION{{$}}
@@ -94,13 +94,13 @@ sw.epilog:
 }
 
 ; CHECK-LABEL: bar64:
-; CHECK: block{{$}}
-; CHECK: block{{$}}
-; CHECK: block{{$}}
-; CHECK: block{{$}}
-; CHECK: block{{$}}
-; CHECK: block{{$}}
-; CHECK: block{{$}}
+; CHECK: block   {{$}}
+; CHECK: block   {{$}}
+; CHECK: block   {{$}}
+; CHECK: block   {{$}}
+; CHECK: block   {{$}}
+; CHECK: block   {{$}}
+; CHECK: block   {{$}}
 ; CHECK: br_table {{[^,]+}}, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 4, 5, 0{{$}}
 ; CHECK: .LBB1_2:
 ; CHECK:   call foo0 at FUNCTION{{$}}




More information about the llvm-commits mailing list