]> granicus.if.org Git - llvm/commitdiff
[WebAssembly] Added default stack-only instruction mode for MC.
authorWouter van Oortmerssen <aardappel@gmail.com>
Fri, 27 Jul 2018 20:56:43 +0000 (20:56 +0000)
committerWouter van Oortmerssen <aardappel@gmail.com>
Fri, 27 Jul 2018 20:56:43 +0000 (20:56 +0000)
Summary:
Moved Explicit Locals pass to last.
Made that pass obligatory.
Made it convert from register to stack based instructions, and removed the registers.
Fixes to related code that was expecting register based instructions.
Added the correct testing flag to all tests, depending on what the
format they were expecting so far.
Translated one test to stack format as example: reg-stackify-stack.ll

tested:
llvm-lit -v `find test -name WebAssembly`
unittests/MC/*

Reviewers: dschuff, sunfish

Subscribers: sbc100, jgravelle-google, eraman, aheejin, llvm-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338164 91177308-0d34-0410-b5e6-96231b3b80d8

89 files changed:
lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
lib/Target/WebAssembly/WebAssemblyInstrMemory.td
lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
test/CodeGen/WebAssembly/address-offsets.ll
test/CodeGen/WebAssembly/atomic-rmw.ll
test/CodeGen/WebAssembly/byval.ll
test/CodeGen/WebAssembly/call.ll
test/CodeGen/WebAssembly/cfg-stackify.ll
test/CodeGen/WebAssembly/cfi.ll
test/CodeGen/WebAssembly/comparisons_f32.ll
test/CodeGen/WebAssembly/comparisons_f64.ll
test/CodeGen/WebAssembly/comparisons_i32.ll
test/CodeGen/WebAssembly/comparisons_i64.ll
test/CodeGen/WebAssembly/conv-trap.ll
test/CodeGen/WebAssembly/conv.ll
test/CodeGen/WebAssembly/copysign-casts.ll
test/CodeGen/WebAssembly/divrem-constant.ll
test/CodeGen/WebAssembly/exception.ll
test/CodeGen/WebAssembly/explicit-locals.mir
test/CodeGen/WebAssembly/f16.ll
test/CodeGen/WebAssembly/f32.ll
test/CodeGen/WebAssembly/f64.ll
test/CodeGen/WebAssembly/fast-isel-br-i1.ll
test/CodeGen/WebAssembly/fast-isel-i24.ll
test/CodeGen/WebAssembly/fast-isel-i256.ll
test/CodeGen/WebAssembly/fast-isel-noreg.ll
test/CodeGen/WebAssembly/fast-isel.ll
test/CodeGen/WebAssembly/frem.ll
test/CodeGen/WebAssembly/func.ll
test/CodeGen/WebAssembly/function-bitcasts-varargs.ll
test/CodeGen/WebAssembly/function-bitcasts.ll
test/CodeGen/WebAssembly/global.ll
test/CodeGen/WebAssembly/i128.ll
test/CodeGen/WebAssembly/i32-load-store-alignment.ll
test/CodeGen/WebAssembly/i32.ll
test/CodeGen/WebAssembly/i64-load-store-alignment.ll
test/CodeGen/WebAssembly/i64.ll
test/CodeGen/WebAssembly/ident.ll
test/CodeGen/WebAssembly/immediates.ll
test/CodeGen/WebAssembly/implicit-def.ll
test/CodeGen/WebAssembly/import-module.ll
test/CodeGen/WebAssembly/indirect-import.ll
test/CodeGen/WebAssembly/inline-asm-m.ll
test/CodeGen/WebAssembly/inline-asm.ll
test/CodeGen/WebAssembly/irreducible-cfg.ll
test/CodeGen/WebAssembly/legalize.ll
test/CodeGen/WebAssembly/libcalls.ll
test/CodeGen/WebAssembly/load-ext-atomic.ll
test/CodeGen/WebAssembly/load-ext.ll
test/CodeGen/WebAssembly/load-store-i1.ll
test/CodeGen/WebAssembly/load.ll
test/CodeGen/WebAssembly/lower-em-ehsjlj-options.ll
test/CodeGen/WebAssembly/lower-global-dtors.ll
test/CodeGen/WebAssembly/mem-intrinsics.ll
test/CodeGen/WebAssembly/memory-addr32.ll
test/CodeGen/WebAssembly/muloti4.ll
test/CodeGen/WebAssembly/negative-base-reg.ll
test/CodeGen/WebAssembly/offset-atomics.ll
test/CodeGen/WebAssembly/offset-fastisel.ll
test/CodeGen/WebAssembly/offset-folding.ll
test/CodeGen/WebAssembly/offset.ll
test/CodeGen/WebAssembly/phi.ll
test/CodeGen/WebAssembly/reg-stackify.ll
test/CodeGen/WebAssembly/return-int32.ll
test/CodeGen/WebAssembly/returned.ll
test/CodeGen/WebAssembly/select.ll
test/CodeGen/WebAssembly/signext-arg.ll
test/CodeGen/WebAssembly/signext-inreg.ll
test/CodeGen/WebAssembly/signext-zeroext.ll
test/CodeGen/WebAssembly/simd-arith.ll
test/CodeGen/WebAssembly/stack-alignment.ll
test/CodeGen/WebAssembly/store-trunc-atomic.ll
test/CodeGen/WebAssembly/store-trunc.ll
test/CodeGen/WebAssembly/store.ll
test/CodeGen/WebAssembly/switch.ll
test/CodeGen/WebAssembly/tls.ll
test/CodeGen/WebAssembly/umulo-i64.ll
test/CodeGen/WebAssembly/unsupported-function-bitcasts.ll
test/CodeGen/WebAssembly/unused-argument.ll
test/CodeGen/WebAssembly/userstack.ll
test/CodeGen/WebAssembly/varargs.ll
test/CodeGen/WebAssembly/vtable.ll
test/MC/Disassembler/WebAssembly/wasm.txt
test/MC/WebAssembly/basic-assembly.s
test/MC/WebAssembly/reloc-code.ll
test/MC/WebAssembly/weak-alias.ll
unittests/MC/Disassembler.cpp

index 2d92b93ca70479d313c577d0a7fbc968cbc42b94..32f34b4522792eba50afc20a1af1728b17bccb70 100644 (file)
@@ -34,27 +34,10 @@ using namespace llvm;
 
 namespace {
 
-// We store register types as SimpleValueType to retain SIMD layout
-// information, but must also be able to supply them as the (unnamed)
-// register enum from WebAssemblyRegisterInfo.td/.inc.
-static unsigned MVTToWasmReg(MVT::SimpleValueType Type) {
-  switch(Type) {
-    case MVT::i32: return WebAssembly::I32_0;
-    case MVT::i64: return WebAssembly::I64_0;
-    case MVT::f32: return WebAssembly::F32_0;
-    case MVT::f64: return WebAssembly::F64_0;
-    case MVT::v16i8: return WebAssembly::V128_0;
-    case MVT::v8i16: return WebAssembly::V128_0;
-    case MVT::v4i32: return WebAssembly::V128_0;
-    case MVT::v4f32: return WebAssembly::V128_0;
-    default: return MVT::INVALID_SIMPLE_VALUE_TYPE;
-  }
-}
-
 /// WebAssemblyOperand - Instances of this class represent the operands in a
 /// parsed WASM machine instruction.
 struct WebAssemblyOperand : public MCParsedAsmOperand {
-  enum KindTy { Token, Local, Stack, Integer, Float, Symbol } Kind;
+  enum KindTy { Token, Integer, Float, Symbol } Kind;
 
   SMLoc StartLoc, EndLoc;
 
@@ -62,19 +45,6 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
     StringRef Tok;
   };
 
-  struct RegOp {
-    // This is a (virtual) local or stack register represented as 0..
-    unsigned RegNo;
-    // In most targets, the register number also encodes the type, but for
-    // wasm we have to track that seperately since we have an unbounded
-    // number of registers.
-    // This has the unfortunate side effect that we supply a different value
-    // to the table-gen matcher at different times in the process (when it
-    // calls getReg() or addRegOperands().
-    // TODO: While this works, it feels brittle. and would be nice to clean up.
-    MVT::SimpleValueType Type;
-  };
-
   struct IntOp {
     int64_t Val;
   };
@@ -89,7 +59,6 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
 
   union {
     struct TokOp Tok;
-    struct RegOp Reg;
     struct IntOp Int;
     struct FltOp Flt;
     struct SymOp Sym;
@@ -97,8 +66,6 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
 
   WebAssemblyOperand(KindTy K, SMLoc Start, SMLoc End, TokOp T)
     : Kind(K), StartLoc(Start), EndLoc(End), Tok(T) {}
-  WebAssemblyOperand(KindTy K, SMLoc Start, SMLoc End, RegOp R)
-    : Kind(K), StartLoc(Start), EndLoc(End), Reg(R) {}
   WebAssemblyOperand(KindTy K, SMLoc Start, SMLoc End, IntOp I)
     : Kind(K), StartLoc(Start), EndLoc(End), Int(I) {}
   WebAssemblyOperand(KindTy K, SMLoc Start, SMLoc End, FltOp F)
@@ -110,14 +77,12 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
   bool isImm() const override { return Kind == Integer ||
                                        Kind == Float ||
                                        Kind == Symbol; }
-  bool isReg() const override { return Kind == Local || Kind == Stack; }
   bool isMem() const override { return false; }
+  bool isReg() const override { return false; }
 
   unsigned getReg() const override {
-    assert(isReg());
-    // This is called from the tablegen matcher (MatchInstructionImpl)
-    // where it expects to match the type of register, see RegOp above.
-    return MVTToWasmReg(Reg.Type);
+    llvm_unreachable("Assembly inspects a register operand");
+    return 0;
   }
 
   StringRef getToken() const {
@@ -128,19 +93,9 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
   SMLoc getStartLoc() const override { return StartLoc; }
   SMLoc getEndLoc() const override { return EndLoc; }
 
-  void addRegOperands(MCInst &Inst, unsigned N) const {
-    assert(N == 1 && "Invalid number of operands!");
-    assert(isReg() && "Not a register operand!");
-    // This is called from the tablegen matcher (MatchInstructionImpl)
-    // where it expects to output the actual register index, see RegOp above.
-    unsigned R = Reg.RegNo;
-    if (Kind == Stack) {
-      // A stack register is represented as a large negative number.
-      // See WebAssemblyRegNumbering::runOnMachineFunction and
-      // getWARegStackId for why this | is needed.
-      R |= INT32_MIN;
-    }
-    Inst.addOperand(MCOperand::createReg(R));
+  void addRegOperands(MCInst &, unsigned) const {
+    // Required by the assembly matcher.
+    llvm_unreachable("Assembly matcher creates register operands");
   }
 
   void addImmOperands(MCInst &Inst, unsigned N) const {
@@ -160,12 +115,6 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
     case Token:
       OS << "Tok:" << Tok.Tok;
       break;
-    case Local:
-      OS << "Loc:" << Reg.RegNo << ":" << static_cast<int>(Reg.Type);
-      break;
-    case Stack:
-      OS << "Stk:" << Reg.RegNo << ":" << static_cast<int>(Reg.Type);
-      break;
     case Integer:
       OS << "Int:" << Int.Val;
       break;
@@ -182,11 +131,6 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
 class WebAssemblyAsmParser final : public MCTargetAsmParser {
   MCAsmParser &Parser;
   MCAsmLexer &Lexer;
-  // These are for the current function being parsed:
-  // These are vectors since register assignments are so far non-sparse.
-  // Replace by map if necessary.
-  std::vector<MVT::SimpleValueType> LocalTypes;
-  std::vector<MVT::SimpleValueType> StackTypes;
   MCSymbol *LastLabel;
 
 public:
@@ -236,68 +180,6 @@ public:
         .Default(MVT::INVALID_SIMPLE_VALUE_TYPE);
   }
 
-  MVT::SimpleValueType &GetType(
-      std::vector<MVT::SimpleValueType> &Types, size_t i) {
-    Types.resize(std::max(i + 1, Types.size()), MVT::INVALID_SIMPLE_VALUE_TYPE);
-    return Types[i];
-  }
-
-  bool ParseReg(OperandVector &Operands, StringRef TypePrefix) {
-    if (Lexer.is(AsmToken::Integer)) {
-      auto &Local = Lexer.getTok();
-      // This is a reference to a local, turn it into a virtual register.
-      auto LocalNo = static_cast<unsigned>(Local.getIntVal());
-      Operands.push_back(make_unique<WebAssemblyOperand>(
-                           WebAssemblyOperand::Local, Local.getLoc(),
-                           Local.getEndLoc(),
-                           WebAssemblyOperand::RegOp{LocalNo,
-                               GetType(LocalTypes, LocalNo)}));
-      Parser.Lex();
-    } else if (Lexer.is(AsmToken::Identifier)) {
-      auto &StackRegTok = Lexer.getTok();
-      // These are push/pop/drop pseudo stack registers, which we turn
-      // into virtual registers also. The stackify pass will later turn them
-      // back into implicit stack references if possible.
-      auto StackReg = StackRegTok.getString();
-      auto StackOp = StackReg.take_while([](char c) { return isalpha(c); });
-      auto Reg = StackReg.drop_front(StackOp.size());
-      unsigned long long ParsedRegNo = 0;
-      if (!Reg.empty() && getAsUnsignedInteger(Reg, 10, ParsedRegNo))
-        return Error("Cannot parse stack register index: ", StackRegTok);
-      unsigned RegNo = static_cast<unsigned>(ParsedRegNo);
-      if (StackOp == "push") {
-        // This defines a result, record register type.
-        auto RegType = ParseRegType(TypePrefix);
-        GetType(StackTypes, RegNo) = RegType;
-        Operands.push_back(make_unique<WebAssemblyOperand>(
-                             WebAssemblyOperand::Stack,
-                             StackRegTok.getLoc(),
-                             StackRegTok.getEndLoc(),
-                             WebAssemblyOperand::RegOp{RegNo, RegType}));
-      } else if (StackOp == "pop") {
-        // This uses a previously defined stack value.
-        auto RegType = GetType(StackTypes, RegNo);
-        Operands.push_back(make_unique<WebAssemblyOperand>(
-                             WebAssemblyOperand::Stack,
-                             StackRegTok.getLoc(),
-                             StackRegTok.getEndLoc(),
-                             WebAssemblyOperand::RegOp{RegNo, RegType}));
-      } else if (StackOp == "drop") {
-        // This operand will be dropped, since it is part of an instruction
-        // whose result is void.
-      } else {
-        return Error("Unknown stack register prefix: ", StackRegTok);
-      }
-      Parser.Lex();
-    } else {
-      return Error(
-            "Expected identifier/integer following $, instead got: ",
-            Lexer.getTok());
-    }
-    IsNext(AsmToken::Equal);
-    return false;
-  }
-
   void ParseSingleInteger(bool IsNegative, OperandVector &Operands) {
     auto &Int = Lexer.getTok();
     int64_t Val = Int.getIntVal();
@@ -310,36 +192,26 @@ public:
 
   bool ParseOperandStartingWithInteger(bool IsNegative,
                                        OperandVector &Operands,
-                                       StringRef InstType) {
+                                       StringRef InstName) {
     ParseSingleInteger(IsNegative, Operands);
-    if (Lexer.is(AsmToken::LParen)) {
-      // Parse load/store operands of the form: offset($reg)align
-      auto &LParen = Lexer.getTok();
-      Operands.push_back(
-            make_unique<WebAssemblyOperand>(WebAssemblyOperand::Token,
-                                            LParen.getLoc(),
-                                            LParen.getEndLoc(),
-                                            WebAssemblyOperand::TokOp{
-                                              LParen.getString()}));
-      Parser.Lex();
-      if (Expect(AsmToken::Dollar, "register")) return true;
-      if (ParseReg(Operands, InstType)) return true;
-      auto &RParen = Lexer.getTok();
-      Operands.push_back(
-            make_unique<WebAssemblyOperand>(WebAssemblyOperand::Token,
-                                            RParen.getLoc(),
-                                            RParen.getEndLoc(),
-                                            WebAssemblyOperand::TokOp{
-                                              RParen.getString()}));
-      if (Expect(AsmToken::RParen, ")")) return true;
-      if (Lexer.is(AsmToken::Integer)) {
+    // FIXME: there is probably a cleaner way to do this.
+    auto IsLoadStore = InstName.startswith("load") ||
+                       InstName.startswith("store") ||
+                       InstName.startswith("atomic_load") ||
+                       InstName.startswith("atomic_store");
+    if (IsLoadStore) {
+      // Parse load/store operands of the form: offset align
+      auto &Offset = Lexer.getTok();
+      if (Offset.is(AsmToken::Integer)) {
         ParseSingleInteger(false, Operands);
       } else {
         // Alignment not specified.
         // FIXME: correctly derive a default from the instruction.
+        // We can't just call WebAssembly::GetDefaultP2Align since we don't have
+        // an opcode until after the assembly matcher.
         Operands.push_back(make_unique<WebAssemblyOperand>(
-                             WebAssemblyOperand::Integer, RParen.getLoc(),
-                             RParen.getEndLoc(), WebAssemblyOperand::IntOp{0}));
+                             WebAssemblyOperand::Integer, Offset.getLoc(),
+                             Offset.getEndLoc(), WebAssemblyOperand::IntOp{0}));
       }
     }
     return false;
@@ -360,11 +232,6 @@ public:
     while (Lexer.isNot(AsmToken::EndOfStatement)) {
       auto &Tok = Lexer.getTok();
       switch (Tok.getKind()) {
-      case AsmToken::Dollar: {
-        Parser.Lex();
-        if (ParseReg(Operands, NamePair.first)) return true;
-        break;
-      }
       case AsmToken::Identifier: {
         auto &Id = Lexer.getTok();
         const MCExpr *Val;
@@ -380,11 +247,11 @@ public:
         Parser.Lex();
         if (Lexer.isNot(AsmToken::Integer))
           return Error("Expected integer instead got: ", Lexer.getTok());
-        if (ParseOperandStartingWithInteger(true, Operands, NamePair.first))
+        if (ParseOperandStartingWithInteger(true, Operands, NamePair.second))
           return true;
         break;
       case AsmToken::Integer:
-        if (ParseOperandStartingWithInteger(false, Operands, NamePair.first))
+        if (ParseOperandStartingWithInteger(false, Operands, NamePair.second))
           return true;
         break;
       case AsmToken::Real: {
@@ -405,35 +272,6 @@ public:
       }
     }
     Parser.Lex();
-    // Call instructions are vararg, but the tablegen matcher doesn't seem to
-    // support that, so for now we strip these extra operands.
-    // This is problematic if these arguments are not simple $pop stack
-    // registers, since e.g. a local register would get lost, so we check for
-    // this. This can be the case when using -disable-wasm-explicit-locals
-    // which currently s2wasm requires.
-    // TODO: Instead, we can move this code to MatchAndEmitInstruction below and
-    // actually generate get_local instructions on the fly.
-    // Or even better, improve the matcher to support vararg?
-    auto IsIndirect = NamePair.second == "call_indirect";
-    if (IsIndirect || NamePair.second == "call") {
-      // Figure out number of fixed operands from the instruction.
-      size_t CallOperands = 1;  // The name token.
-      if (!IsIndirect) CallOperands++;  // The function index.
-      if (!NamePair.first.empty()) CallOperands++;  // The result register.
-      if (Operands.size() > CallOperands) {
-        // Ensure operands we drop are all $pop.
-        for (size_t I = CallOperands; I < Operands.size(); I++) {
-          auto Operand =
-              reinterpret_cast<WebAssemblyOperand *>(Operands[I].get());
-          if (Operand->Kind != WebAssemblyOperand::Stack)
-            Parser.Error(NameLoc,
-              "Call instruction has non-stack arguments, if this code was "
-              "generated with -disable-wasm-explicit-locals please remove it");
-        }
-        // Drop unneeded operands.
-        Operands.resize(CallOperands);
-      }
-    }
     // Block instructions require a signature index, but these are missing in
     // assembly, so we add a dummy one explicitly (since we have no control
     // over signature tables here, we assume these will be regenerated when
@@ -443,17 +281,6 @@ public:
                            WebAssemblyOperand::Integer, NameLoc,
                            NameLoc, WebAssemblyOperand::IntOp{-1}));
     }
-    // These don't specify the type, which has to derived from the local index.
-    if (NamePair.second == "get_local" || NamePair.second == "tee_local") {
-      if (Operands.size() >= 3 && Operands[1]->isReg() &&
-          Operands[2]->isImm()) {
-        auto Op1 = reinterpret_cast<WebAssemblyOperand *>(Operands[1].get());
-        auto Op2 = reinterpret_cast<WebAssemblyOperand *>(Operands[2].get());
-        auto Type = GetType(LocalTypes, static_cast<size_t>(Op2->Int.Val));
-        Op1->Reg.Type = Type;
-        GetType(StackTypes, Op1->Reg.RegNo) = Type;
-      }
-    }
     return false;
   }
 
@@ -477,11 +304,6 @@ public:
             IsNext(AsmToken::At) &&
             Lexer.is(AsmToken::Identifier)))
         return Error("Expected label,@type declaration, got: ", Lexer.getTok());
-      if (Lexer.getTok().getString() == "function") {
-        // Track locals from start of function.
-        LocalTypes.clear();
-        StackTypes.clear();
-      }
       Parser.Lex();
       //Out.EmitSymbolAttribute(??, MCSA_ELF_TypeFunction);
     } else if (DirectiveID.getString() == ".param" ||
@@ -494,7 +316,6 @@ public:
       while (Lexer.is(AsmToken::Identifier)) {
         auto RegType = ParseRegType(Lexer.getTok().getString());
         if (RegType == MVT::INVALID_SIMPLE_VALUE_TYPE) return true;
-        LocalTypes.push_back(RegType);
         if (DirectiveID.getString() == ".param") {
           Params.push_back(RegType);
         } else {
index 1f280e1d13fc4bcb8b744c9ba235a5d517ffcb38..b9fa6bbdf04b5f3f5702ba4b4abf14fbda0313f3 100644 (file)
@@ -169,41 +169,54 @@ void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) {
 
   switch (MI->getOpcode()) {
   case WebAssembly::ARGUMENT_I32:
+  case WebAssembly::ARGUMENT_I32_S:
   case WebAssembly::ARGUMENT_I64:
+  case WebAssembly::ARGUMENT_I64_S:
   case WebAssembly::ARGUMENT_F32:
+  case WebAssembly::ARGUMENT_F32_S:
   case WebAssembly::ARGUMENT_F64:
+  case WebAssembly::ARGUMENT_F64_S:
   case WebAssembly::ARGUMENT_v16i8:
+  case WebAssembly::ARGUMENT_v16i8_S:
   case WebAssembly::ARGUMENT_v8i16:
+  case WebAssembly::ARGUMENT_v8i16_S:
   case WebAssembly::ARGUMENT_v4i32:
+  case WebAssembly::ARGUMENT_v4i32_S:
   case WebAssembly::ARGUMENT_v4f32:
+  case WebAssembly::ARGUMENT_v4f32_S:
     // These represent values which are live into the function entry, so there's
     // no instruction to emit.
     break;
   case WebAssembly::FALLTHROUGH_RETURN_I32:
+  case WebAssembly::FALLTHROUGH_RETURN_I32_S:
   case WebAssembly::FALLTHROUGH_RETURN_I64:
+  case WebAssembly::FALLTHROUGH_RETURN_I64_S:
   case WebAssembly::FALLTHROUGH_RETURN_F32:
+  case WebAssembly::FALLTHROUGH_RETURN_F32_S:
   case WebAssembly::FALLTHROUGH_RETURN_F64:
+  case WebAssembly::FALLTHROUGH_RETURN_F64_S:
   case WebAssembly::FALLTHROUGH_RETURN_v16i8:
+  case WebAssembly::FALLTHROUGH_RETURN_v16i8_S:
   case WebAssembly::FALLTHROUGH_RETURN_v8i16:
+  case WebAssembly::FALLTHROUGH_RETURN_v8i16_S:
   case WebAssembly::FALLTHROUGH_RETURN_v4i32:
-  case WebAssembly::FALLTHROUGH_RETURN_v4f32: {
+  case WebAssembly::FALLTHROUGH_RETURN_v4i32_S:
+  case WebAssembly::FALLTHROUGH_RETURN_v4f32:
+  case WebAssembly::FALLTHROUGH_RETURN_v4f32_S: {
     // These instructions represent the implicit return at the end of a
-    // function body. The operand is always a pop.
-    assert(MFI->isVRegStackified(MI->getOperand(0).getReg()));
-
+    // function body. Always pops one value off the stack.
     if (isVerbose()) {
-      OutStreamer->AddComment("fallthrough-return: $pop" +
-                              Twine(MFI->getWARegStackId(
-                                  MFI->getWAReg(MI->getOperand(0).getReg()))));
+      OutStreamer->AddComment("fallthrough-return-value");
       OutStreamer->AddBlankLine();
     }
     break;
   }
   case WebAssembly::FALLTHROUGH_RETURN_VOID:
+  case WebAssembly::FALLTHROUGH_RETURN_VOID_S:
     // This instruction represents the implicit return at the end of a
     // function body with no return value.
     if (isVerbose()) {
-      OutStreamer->AddComment("fallthrough-return");
+      OutStreamer->AddComment("fallthrough-return-void");
       OutStreamer->AddBlankLine();
     }
     break;
@@ -244,6 +257,9 @@ bool WebAssemblyAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
       OS << MO.getImm();
       return false;
     case MachineOperand::MO_Register:
+      // FIXME: only opcode that still contains registers, as required by
+      // MachineInstr::getDebugVariable().
+      assert(MI->getOpcode() == WebAssembly::INLINEASM);
       OS << regToString(MO);
       return false;
     case MachineOperand::MO_GlobalAddress:
index 8619cbdcb5eed2bd703692fd4187d15e9afa29eb..1cbd9522d3cfe980acf9761505767f3734cee097 100644 (file)
@@ -31,12 +31,21 @@ using namespace llvm;
 
 #define DEBUG_TYPE "wasm-explicit-locals"
 
-// A command-line option to disable this pass. Note that this produces output
-// which is not valid WebAssembly, though it may be more convenient for writing
-// LLVM unit tests with.
-static cl::opt<bool> DisableWebAssemblyExplicitLocals(
-    "disable-wasm-explicit-locals", cl::ReallyHidden,
-    cl::desc("WebAssembly: Disable emission of get_local/set_local."),
+// A command-line option to disable this pass, and keep implicit locals and
+// stackified registers for the purpose of testing with lit/llc ONLY.
+// This produces output which is not valid WebAssembly, and is not supported
+// by assemblers/disassemblers and other MC based tools.
+static cl::opt<bool> RegisterCodeGenTestMode(
+    "wasm-register-codegen-test-mode", cl::Hidden,
+    cl::desc("WebAssembly: output stack registers and implicit locals in"
+             " instruction output for test purposes only."),
+    cl::init(false));
+// This one does explicit locals but keeps stackified registers, as required
+// by some current tests.
+static cl::opt<bool> ExplicitLocalsCodeGenTestMode(
+    "wasm-explicit-locals-codegen-test-mode", cl::Hidden,
+    cl::desc("WebAssembly: output stack registers and explicit locals in"
+             " instruction output for test purposes only."),
     cl::init(false));
 
 namespace {
@@ -59,6 +68,8 @@ public:
 };
 } // end anonymous namespace
 
+unsigned regInstructionToStackInstruction(unsigned OpCode);
+
 char WebAssemblyExplicitLocals::ID = 0;
 INITIALIZE_PASS(WebAssemblyExplicitLocals, DEBUG_TYPE,
                 "Convert registers to WebAssembly locals", false, false)
@@ -162,7 +173,7 @@ static MVT typeForRegClass(const TargetRegisterClass *RC) {
 
 /// Given a MachineOperand of a stackified vreg, return the instruction at the
 /// start of the expression tree.
-static MachineInstr *FindStartOfTree(MachineOperand &MO,
+static MachineInstr *findStartOfTree(MachineOperand &MO,
                                      MachineRegisterInfo &MRI,
                                      WebAssemblyFunctionInfo &MFI) {
   unsigned Reg = MO.getReg();
@@ -173,7 +184,7 @@ static MachineInstr *FindStartOfTree(MachineOperand &MO,
   for (MachineOperand &DefMO : Def->explicit_uses()) {
     if (!DefMO.isReg())
       continue;
-    return FindStartOfTree(DefMO, MRI, MFI);
+    return findStartOfTree(DefMO, MRI, MFI);
   }
 
   // If there were no stackified uses, we've reached the start.
@@ -186,7 +197,7 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
                     << MF.getName() << '\n');
 
   // Disable this pass if directed to do so.
-  if (DisableWebAssemblyExplicitLocals)
+  if (RegisterCodeGenTestMode)
     return false;
 
   bool Changed = false;
@@ -206,19 +217,19 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
       break;
     unsigned Reg = MI.getOperand(0).getReg();
     assert(!MFI.isVRegStackified(Reg));
-    Reg2Local[Reg] = MI.getOperand(1).getImm();
+    Reg2Local[Reg] = static_cast<unsigned>(MI.getOperand(1).getImm());
     MI.eraseFromParent();
     Changed = true;
   }
 
   // Start assigning local numbers after the last parameter.
-  unsigned CurLocal = MFI.getParams().size();
+  unsigned CurLocal = static_cast<unsigned>(MFI.getParams().size());
 
   // Precompute the set of registers that are unused, so that we can insert
   // drops to their defs.
   BitVector UseEmpty(MRI.getNumVirtRegs());
-  for (unsigned i = 0, e = MRI.getNumVirtRegs(); i < e; ++i)
-    UseEmpty[i] = MRI.use_empty(TargetRegisterInfo::index2VirtReg(i));
+  for (unsigned I = 0, E = MRI.getNumVirtRegs(); I < E; ++I)
+    UseEmpty[I] = MRI.use_empty(TargetRegisterInfo::index2VirtReg(I));
 
   // Visit each instruction in the function.
   for (MachineBasicBlock &MBB : MF) {
@@ -322,7 +333,7 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
         // If we see a stackified register, prepare to insert subsequent
         // get_locals before the start of its tree.
         if (MFI.isVRegStackified(OldReg)) {
-          InsertPt = FindStartOfTree(MO, MRI, MFI);
+          InsertPt = findStartOfTree(MO, MRI, MFI);
           continue;
         }
 
@@ -356,37 +367,410 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
         Changed = true;
       }
     }
+
+    if (!ExplicitLocalsCodeGenTestMode) {
+      // Remove all uses of stackified registers to bring the instruction format
+      // into its final stack form, and transition opcodes to their _S variant.
+      // We do this in a seperate loop, since the previous loop adds/removes
+      // instructions.
+      // See comments in lib/Target/WebAssembly/WebAssemblyInstrFormats.td for
+      // details.
+      // TODO: the code above creates new registers which are then removed here.
+      // That code could be slightly simplified by not doing that, though maybe
+      // it is simpler conceptually to keep the code above in "register mode"
+      // until this transition point.
+      for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
+           I != E;) {
+        MachineInstr &MI = *I++;
+        // FIXME: we are not processing inline assembly, which contains register
+        // operands, because it is used by later target generic code.
+        if (MI.isDebugInstr() || MI.isLabel() || MI.isInlineAsm())
+          continue;
+        auto RegOpcode = MI.getOpcode();
+        auto StackOpcode = regInstructionToStackInstruction(RegOpcode);
+        MI.setDesc(TII->get(StackOpcode));
+        // Now remove all register operands.
+        for (auto I = MI.getNumOperands(); I; --I) {
+          auto &MO = MI.getOperand(I - 1);
+          if (MO.isReg()) {
+            MI.RemoveOperand(I - 1);
+            // TODO: we should also update the MFI here or below to reflect the
+            // removed registers? The MFI is about to be deleted anyway, so
+            // maybe that is not worth it?
+          }
+        }
+      }
+    }
   }
 
   // Define the locals.
   // TODO: Sort the locals for better compression.
   MFI.setNumLocals(CurLocal - MFI.getParams().size());
-  for (size_t i = 0, e = MRI.getNumVirtRegs(); i < e; ++i) {
-    unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
-    auto I = Reg2Local.find(Reg);
-    if (I == Reg2Local.end() || I->second < MFI.getParams().size())
+  for (unsigned I = 0, E = MRI.getNumVirtRegs(); I < E; ++I) {
+    unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
+    auto RL = Reg2Local.find(Reg);
+    if (RL == Reg2Local.end() || RL->second < MFI.getParams().size())
       continue;
 
-    MFI.setLocal(I->second - MFI.getParams().size(),
+    MFI.setLocal(RL->second - MFI.getParams().size(),
                  typeForRegClass(MRI.getRegClass(Reg)));
     Changed = true;
   }
 
-#ifndef NDEBUG
-  // Assert that all registers have been stackified at this point.
-  for (const MachineBasicBlock &MBB : MF) {
-    for (const MachineInstr &MI : MBB) {
-      if (MI.isDebugInstr() || MI.isLabel())
-        continue;
-      for (const MachineOperand &MO : MI.explicit_operands()) {
-        assert(
-            (!MO.isReg() || MRI.use_empty(MO.getReg()) ||
-             MFI.isVRegStackified(MO.getReg())) &&
-            "WebAssemblyExplicitLocals failed to stackify a register operand");
-      }
-    }
-  }
-#endif
-
   return Changed;
 }
+
+unsigned regInstructionToStackInstruction(unsigned OpCode) {
+  switch (OpCode) {
+  default:
+    // You may hit this if you add new instructions, please add them below.
+    // For most of these opcodes, this function could have been implemented
+    // as "return OpCode + 1", but since table-gen alphabetically sorts them,
+    // this cannot be guaranteed (see e.g. BR and BR_IF).
+    // The approach below is the same as what the x87 backend does.
+    // TODO(wvo): to make this code cleaner, create a custom tablegen
+    // code generator that emits the table below automatically.
+    llvm_unreachable(
+          "unknown WebAssembly instruction in Explicit Locals pass");
+  case WebAssembly::ABS_F32: return WebAssembly::ABS_F32_S;
+  case WebAssembly::ABS_F64: return WebAssembly::ABS_F64_S;
+  case WebAssembly::ADD_F32: return WebAssembly::ADD_F32_S;
+  case WebAssembly::ADD_F32x4: return WebAssembly::ADD_F32x4_S;
+  case WebAssembly::ADD_F64: return WebAssembly::ADD_F64_S;
+  case WebAssembly::ADD_I16x8: return WebAssembly::ADD_I16x8_S;
+  case WebAssembly::ADD_I32: return WebAssembly::ADD_I32_S;
+  case WebAssembly::ADD_I32x4: return WebAssembly::ADD_I32x4_S;
+  case WebAssembly::ADD_I64: return WebAssembly::ADD_I64_S;
+  case WebAssembly::ADD_I8x16: return WebAssembly::ADD_I8x16_S;
+  case WebAssembly::ADJCALLSTACKDOWN: return WebAssembly::ADJCALLSTACKDOWN_S;
+  case WebAssembly::ADJCALLSTACKUP: return WebAssembly::ADJCALLSTACKUP_S;
+  case WebAssembly::AND_I32: return WebAssembly::AND_I32_S;
+  case WebAssembly::AND_I64: return WebAssembly::AND_I64_S;
+  case WebAssembly::ARGUMENT_EXCEPT_REF: return WebAssembly::ARGUMENT_EXCEPT_REF_S;
+  case WebAssembly::ARGUMENT_F32: return WebAssembly::ARGUMENT_F32_S;
+  case WebAssembly::ARGUMENT_F64: return WebAssembly::ARGUMENT_F64_S;
+  case WebAssembly::ARGUMENT_I32: return WebAssembly::ARGUMENT_I32_S;
+  case WebAssembly::ARGUMENT_I64: return WebAssembly::ARGUMENT_I64_S;
+  case WebAssembly::ARGUMENT_v16i8: return WebAssembly::ARGUMENT_v16i8_S;
+  case WebAssembly::ARGUMENT_v4f32: return WebAssembly::ARGUMENT_v4f32_S;
+  case WebAssembly::ARGUMENT_v4i32: return WebAssembly::ARGUMENT_v4i32_S;
+  case WebAssembly::ARGUMENT_v8i16: return WebAssembly::ARGUMENT_v8i16_S;
+  case WebAssembly::ATOMIC_LOAD16_U_I32: return WebAssembly::ATOMIC_LOAD16_U_I32_S;
+  case WebAssembly::ATOMIC_LOAD16_U_I64: return WebAssembly::ATOMIC_LOAD16_U_I64_S;
+  case WebAssembly::ATOMIC_LOAD32_U_I64: return WebAssembly::ATOMIC_LOAD32_U_I64_S;
+  case WebAssembly::ATOMIC_LOAD8_U_I32: return WebAssembly::ATOMIC_LOAD8_U_I32_S;
+  case WebAssembly::ATOMIC_LOAD8_U_I64: return WebAssembly::ATOMIC_LOAD8_U_I64_S;
+  case WebAssembly::ATOMIC_LOAD_I32: return WebAssembly::ATOMIC_LOAD_I32_S;
+  case WebAssembly::ATOMIC_LOAD_I64: return WebAssembly::ATOMIC_LOAD_I64_S;
+  case WebAssembly::ATOMIC_STORE16_I32: return WebAssembly::ATOMIC_STORE16_I32_S;
+  case WebAssembly::ATOMIC_STORE16_I64: return WebAssembly::ATOMIC_STORE16_I64_S;
+  case WebAssembly::ATOMIC_STORE32_I64: return WebAssembly::ATOMIC_STORE32_I64_S;
+  case WebAssembly::ATOMIC_STORE8_I32: return WebAssembly::ATOMIC_STORE8_I32_S;
+  case WebAssembly::ATOMIC_STORE8_I64: return WebAssembly::ATOMIC_STORE8_I64_S;
+  case WebAssembly::ATOMIC_STORE_I32: return WebAssembly::ATOMIC_STORE_I32_S;
+  case WebAssembly::ATOMIC_STORE_I64: return WebAssembly::ATOMIC_STORE_I64_S;
+  case WebAssembly::BLOCK: return WebAssembly::BLOCK_S;
+  case WebAssembly::BR: return WebAssembly::BR_S;
+  case WebAssembly::BR_IF: return WebAssembly::BR_IF_S;
+  case WebAssembly::BR_TABLE_I32: return WebAssembly::BR_TABLE_I32_S;
+  case WebAssembly::BR_TABLE_I64: return WebAssembly::BR_TABLE_I64_S;
+  case WebAssembly::BR_UNLESS: return WebAssembly::BR_UNLESS_S;
+  case WebAssembly::CALL_EXCEPT_REF: return WebAssembly::CALL_EXCEPT_REF_S;
+  case WebAssembly::CALL_F32: return WebAssembly::CALL_F32_S;
+  case WebAssembly::CALL_F64: return WebAssembly::CALL_F64_S;
+  case WebAssembly::CALL_I32: return WebAssembly::CALL_I32_S;
+  case WebAssembly::CALL_I64: return WebAssembly::CALL_I64_S;
+  case WebAssembly::CALL_INDIRECT_EXCEPT_REF: return WebAssembly::CALL_INDIRECT_EXCEPT_REF_S;
+  case WebAssembly::CALL_INDIRECT_F32: return WebAssembly::CALL_INDIRECT_F32_S;
+  case WebAssembly::CALL_INDIRECT_F64: return WebAssembly::CALL_INDIRECT_F64_S;
+  case WebAssembly::CALL_INDIRECT_I32: return WebAssembly::CALL_INDIRECT_I32_S;
+  case WebAssembly::CALL_INDIRECT_I64: return WebAssembly::CALL_INDIRECT_I64_S;
+  case WebAssembly::CALL_INDIRECT_VOID: return WebAssembly::CALL_INDIRECT_VOID_S;
+  case WebAssembly::CALL_INDIRECT_v16i8: return WebAssembly::CALL_INDIRECT_v16i8_S;
+  case WebAssembly::CALL_INDIRECT_v4f32: return WebAssembly::CALL_INDIRECT_v4f32_S;
+  case WebAssembly::CALL_INDIRECT_v4i32: return WebAssembly::CALL_INDIRECT_v4i32_S;
+  case WebAssembly::CALL_INDIRECT_v8i16: return WebAssembly::CALL_INDIRECT_v8i16_S;
+  case WebAssembly::CALL_VOID: return WebAssembly::CALL_VOID_S;
+  case WebAssembly::CALL_v16i8: return WebAssembly::CALL_v16i8_S;
+  case WebAssembly::CALL_v4f32: return WebAssembly::CALL_v4f32_S;
+  case WebAssembly::CALL_v4i32: return WebAssembly::CALL_v4i32_S;
+  case WebAssembly::CALL_v8i16: return WebAssembly::CALL_v8i16_S;
+  case WebAssembly::CATCHRET: return WebAssembly::CATCHRET_S;
+  case WebAssembly::CATCH_ALL: return WebAssembly::CATCH_ALL_S;
+  case WebAssembly::CATCH_I32: return WebAssembly::CATCH_I32_S;
+  case WebAssembly::CATCH_I64: return WebAssembly::CATCH_I64_S;
+  case WebAssembly::CEIL_F32: return WebAssembly::CEIL_F32_S;
+  case WebAssembly::CEIL_F64: return WebAssembly::CEIL_F64_S;
+  case WebAssembly::CLEANUPRET: return WebAssembly::CLEANUPRET_S;
+  case WebAssembly::CLZ_I32: return WebAssembly::CLZ_I32_S;
+  case WebAssembly::CLZ_I64: return WebAssembly::CLZ_I64_S;
+  case WebAssembly::CONST_F32: return WebAssembly::CONST_F32_S;
+  case WebAssembly::CONST_F64: return WebAssembly::CONST_F64_S;
+  case WebAssembly::CONST_I32: return WebAssembly::CONST_I32_S;
+  case WebAssembly::CONST_I64: return WebAssembly::CONST_I64_S;
+  case WebAssembly::COPYSIGN_F32: return WebAssembly::COPYSIGN_F32_S;
+  case WebAssembly::COPYSIGN_F64: return WebAssembly::COPYSIGN_F64_S;
+  case WebAssembly::COPY_EXCEPT_REF: return WebAssembly::COPY_EXCEPT_REF_S;
+  case WebAssembly::COPY_F32: return WebAssembly::COPY_F32_S;
+  case WebAssembly::COPY_F64: return WebAssembly::COPY_F64_S;
+  case WebAssembly::COPY_I32: return WebAssembly::COPY_I32_S;
+  case WebAssembly::COPY_I64: return WebAssembly::COPY_I64_S;
+  case WebAssembly::COPY_V128: return WebAssembly::COPY_V128_S;
+  case WebAssembly::CTZ_I32: return WebAssembly::CTZ_I32_S;
+  case WebAssembly::CTZ_I64: return WebAssembly::CTZ_I64_S;
+  case WebAssembly::CURRENT_MEMORY_I32: return WebAssembly::CURRENT_MEMORY_I32_S;
+  case WebAssembly::DIV_F32: return WebAssembly::DIV_F32_S;
+  case WebAssembly::DIV_F64: return WebAssembly::DIV_F64_S;
+  case WebAssembly::DIV_S_I32: return WebAssembly::DIV_S_I32_S;
+  case WebAssembly::DIV_S_I64: return WebAssembly::DIV_S_I64_S;
+  case WebAssembly::DIV_U_I32: return WebAssembly::DIV_U_I32_S;
+  case WebAssembly::DIV_U_I64: return WebAssembly::DIV_U_I64_S;
+  case WebAssembly::DROP_EXCEPT_REF: return WebAssembly::DROP_EXCEPT_REF_S;
+  case WebAssembly::DROP_F32: return WebAssembly::DROP_F32_S;
+  case WebAssembly::DROP_F64: return WebAssembly::DROP_F64_S;
+  case WebAssembly::DROP_I32: return WebAssembly::DROP_I32_S;
+  case WebAssembly::DROP_I64: return WebAssembly::DROP_I64_S;
+  case WebAssembly::DROP_V128: return WebAssembly::DROP_V128_S;
+  case WebAssembly::END_BLOCK: return WebAssembly::END_BLOCK_S;
+  case WebAssembly::END_FUNCTION: return WebAssembly::END_FUNCTION_S;
+  case WebAssembly::END_LOOP: return WebAssembly::END_LOOP_S;
+  case WebAssembly::END_TRY: return WebAssembly::END_TRY_S;
+  case WebAssembly::EQZ_I32: return WebAssembly::EQZ_I32_S;
+  case WebAssembly::EQZ_I64: return WebAssembly::EQZ_I64_S;
+  case WebAssembly::EQ_F32: return WebAssembly::EQ_F32_S;
+  case WebAssembly::EQ_F64: return WebAssembly::EQ_F64_S;
+  case WebAssembly::EQ_I32: return WebAssembly::EQ_I32_S;
+  case WebAssembly::EQ_I64: return WebAssembly::EQ_I64_S;
+  case WebAssembly::F32_CONVERT_S_I32: return WebAssembly::F32_CONVERT_S_I32_S;
+  case WebAssembly::F32_CONVERT_S_I64: return WebAssembly::F32_CONVERT_S_I64_S;
+  case WebAssembly::F32_CONVERT_U_I32: return WebAssembly::F32_CONVERT_U_I32_S;
+  case WebAssembly::F32_CONVERT_U_I64: return WebAssembly::F32_CONVERT_U_I64_S;
+  case WebAssembly::F32_DEMOTE_F64: return WebAssembly::F32_DEMOTE_F64_S;
+  case WebAssembly::F32_REINTERPRET_I32: return WebAssembly::F32_REINTERPRET_I32_S;
+  case WebAssembly::F64_CONVERT_S_I32: return WebAssembly::F64_CONVERT_S_I32_S;
+  case WebAssembly::F64_CONVERT_S_I64: return WebAssembly::F64_CONVERT_S_I64_S;
+  case WebAssembly::F64_CONVERT_U_I32: return WebAssembly::F64_CONVERT_U_I32_S;
+  case WebAssembly::F64_CONVERT_U_I64: return WebAssembly::F64_CONVERT_U_I64_S;
+  case WebAssembly::F64_PROMOTE_F32: return WebAssembly::F64_PROMOTE_F32_S;
+  case WebAssembly::F64_REINTERPRET_I64: return WebAssembly::F64_REINTERPRET_I64_S;
+  case WebAssembly::FALLTHROUGH_RETURN_EXCEPT_REF: return WebAssembly::FALLTHROUGH_RETURN_EXCEPT_REF_S;
+  case WebAssembly::FALLTHROUGH_RETURN_F32: return WebAssembly::FALLTHROUGH_RETURN_F32_S;
+  case WebAssembly::FALLTHROUGH_RETURN_F64: return WebAssembly::FALLTHROUGH_RETURN_F64_S;
+  case WebAssembly::FALLTHROUGH_RETURN_I32: return WebAssembly::FALLTHROUGH_RETURN_I32_S;
+  case WebAssembly::FALLTHROUGH_RETURN_I64: return WebAssembly::FALLTHROUGH_RETURN_I64_S;
+  case WebAssembly::FALLTHROUGH_RETURN_VOID: return WebAssembly::FALLTHROUGH_RETURN_VOID_S;
+  case WebAssembly::FALLTHROUGH_RETURN_v16i8: return WebAssembly::FALLTHROUGH_RETURN_v16i8_S;
+  case WebAssembly::FALLTHROUGH_RETURN_v4f32: return WebAssembly::FALLTHROUGH_RETURN_v4f32_S;
+  case WebAssembly::FALLTHROUGH_RETURN_v4i32: return WebAssembly::FALLTHROUGH_RETURN_v4i32_S;
+  case WebAssembly::FALLTHROUGH_RETURN_v8i16: return WebAssembly::FALLTHROUGH_RETURN_v8i16_S;
+  case WebAssembly::FLOOR_F32: return WebAssembly::FLOOR_F32_S;
+  case WebAssembly::FLOOR_F64: return WebAssembly::FLOOR_F64_S;
+  case WebAssembly::FP_TO_SINT_I32_F32: return WebAssembly::FP_TO_SINT_I32_F32_S;
+  case WebAssembly::FP_TO_SINT_I32_F64: return WebAssembly::FP_TO_SINT_I32_F64_S;
+  case WebAssembly::FP_TO_SINT_I64_F32: return WebAssembly::FP_TO_SINT_I64_F32_S;
+  case WebAssembly::FP_TO_SINT_I64_F64: return WebAssembly::FP_TO_SINT_I64_F64_S;
+  case WebAssembly::FP_TO_UINT_I32_F32: return WebAssembly::FP_TO_UINT_I32_F32_S;
+  case WebAssembly::FP_TO_UINT_I32_F64: return WebAssembly::FP_TO_UINT_I32_F64_S;
+  case WebAssembly::FP_TO_UINT_I64_F32: return WebAssembly::FP_TO_UINT_I64_F32_S;
+  case WebAssembly::FP_TO_UINT_I64_F64: return WebAssembly::FP_TO_UINT_I64_F64_S;
+  case WebAssembly::GET_GLOBAL_EXCEPT_REF: return WebAssembly::GET_GLOBAL_EXCEPT_REF_S;
+  case WebAssembly::GET_GLOBAL_F32: return WebAssembly::GET_GLOBAL_F32_S;
+  case WebAssembly::GET_GLOBAL_F64: return WebAssembly::GET_GLOBAL_F64_S;
+  case WebAssembly::GET_GLOBAL_I32: return WebAssembly::GET_GLOBAL_I32_S;
+  case WebAssembly::GET_GLOBAL_I64: return WebAssembly::GET_GLOBAL_I64_S;
+  case WebAssembly::GET_GLOBAL_V128: return WebAssembly::GET_GLOBAL_V128_S;
+  case WebAssembly::GET_LOCAL_EXCEPT_REF: return WebAssembly::GET_LOCAL_EXCEPT_REF_S;
+  case WebAssembly::GET_LOCAL_F32: return WebAssembly::GET_LOCAL_F32_S;
+  case WebAssembly::GET_LOCAL_F64: return WebAssembly::GET_LOCAL_F64_S;
+  case WebAssembly::GET_LOCAL_I32: return WebAssembly::GET_LOCAL_I32_S;
+  case WebAssembly::GET_LOCAL_I64: return WebAssembly::GET_LOCAL_I64_S;
+  case WebAssembly::GET_LOCAL_V128: return WebAssembly::GET_LOCAL_V128_S;
+  case WebAssembly::GE_F32: return WebAssembly::GE_F32_S;
+  case WebAssembly::GE_F64: return WebAssembly::GE_F64_S;
+  case WebAssembly::GE_S_I32: return WebAssembly::GE_S_I32_S;
+  case WebAssembly::GE_S_I64: return WebAssembly::GE_S_I64_S;
+  case WebAssembly::GE_U_I32: return WebAssembly::GE_U_I32_S;
+  case WebAssembly::GE_U_I64: return WebAssembly::GE_U_I64_S;
+  case WebAssembly::GROW_MEMORY_I32: return WebAssembly::GROW_MEMORY_I32_S;
+  case WebAssembly::GT_F32: return WebAssembly::GT_F32_S;
+  case WebAssembly::GT_F64: return WebAssembly::GT_F64_S;
+  case WebAssembly::GT_S_I32: return WebAssembly::GT_S_I32_S;
+  case WebAssembly::GT_S_I64: return WebAssembly::GT_S_I64_S;
+  case WebAssembly::GT_U_I32: return WebAssembly::GT_U_I32_S;
+  case WebAssembly::GT_U_I64: return WebAssembly::GT_U_I64_S;
+  case WebAssembly::I32_EXTEND16_S_I32: return WebAssembly::I32_EXTEND16_S_I32_S;
+  case WebAssembly::I32_EXTEND8_S_I32: return WebAssembly::I32_EXTEND8_S_I32_S;
+  case WebAssembly::I32_REINTERPRET_F32: return WebAssembly::I32_REINTERPRET_F32_S;
+  case WebAssembly::I32_TRUNC_S_F32: return WebAssembly::I32_TRUNC_S_F32_S;
+  case WebAssembly::I32_TRUNC_S_F64: return WebAssembly::I32_TRUNC_S_F64_S;
+  case WebAssembly::I32_TRUNC_S_SAT_F32: return WebAssembly::I32_TRUNC_S_SAT_F32_S;
+  case WebAssembly::I32_TRUNC_S_SAT_F64: return WebAssembly::I32_TRUNC_S_SAT_F64_S;
+  case WebAssembly::I32_TRUNC_U_F32: return WebAssembly::I32_TRUNC_U_F32_S;
+  case WebAssembly::I32_TRUNC_U_F64: return WebAssembly::I32_TRUNC_U_F64_S;
+  case WebAssembly::I32_TRUNC_U_SAT_F32: return WebAssembly::I32_TRUNC_U_SAT_F32_S;
+  case WebAssembly::I32_TRUNC_U_SAT_F64: return WebAssembly::I32_TRUNC_U_SAT_F64_S;
+  case WebAssembly::I32_WRAP_I64: return WebAssembly::I32_WRAP_I64_S;
+  case WebAssembly::I64_EXTEND16_S_I64: return WebAssembly::I64_EXTEND16_S_I64_S;
+  case WebAssembly::I64_EXTEND32_S_I64: return WebAssembly::I64_EXTEND32_S_I64_S;
+  case WebAssembly::I64_EXTEND8_S_I64: return WebAssembly::I64_EXTEND8_S_I64_S;
+  case WebAssembly::I64_EXTEND_S_I32: return WebAssembly::I64_EXTEND_S_I32_S;
+  case WebAssembly::I64_EXTEND_U_I32: return WebAssembly::I64_EXTEND_U_I32_S;
+  case WebAssembly::I64_REINTERPRET_F64: return WebAssembly::I64_REINTERPRET_F64_S;
+  case WebAssembly::I64_TRUNC_S_F32: return WebAssembly::I64_TRUNC_S_F32_S;
+  case WebAssembly::I64_TRUNC_S_F64: return WebAssembly::I64_TRUNC_S_F64_S;
+  case WebAssembly::I64_TRUNC_S_SAT_F32: return WebAssembly::I64_TRUNC_S_SAT_F32_S;
+  case WebAssembly::I64_TRUNC_S_SAT_F64: return WebAssembly::I64_TRUNC_S_SAT_F64_S;
+  case WebAssembly::I64_TRUNC_U_F32: return WebAssembly::I64_TRUNC_U_F32_S;
+  case WebAssembly::I64_TRUNC_U_F64: return WebAssembly::I64_TRUNC_U_F64_S;
+  case WebAssembly::I64_TRUNC_U_SAT_F32: return WebAssembly::I64_TRUNC_U_SAT_F32_S;
+  case WebAssembly::I64_TRUNC_U_SAT_F64: return WebAssembly::I64_TRUNC_U_SAT_F64_S;
+  case WebAssembly::LE_F32: return WebAssembly::LE_F32_S;
+  case WebAssembly::LE_F64: return WebAssembly::LE_F64_S;
+  case WebAssembly::LE_S_I32: return WebAssembly::LE_S_I32_S;
+  case WebAssembly::LE_S_I64: return WebAssembly::LE_S_I64_S;
+  case WebAssembly::LE_U_I32: return WebAssembly::LE_U_I32_S;
+  case WebAssembly::LE_U_I64: return WebAssembly::LE_U_I64_S;
+  case WebAssembly::LOAD16_S_I32: return WebAssembly::LOAD16_S_I32_S;
+  case WebAssembly::LOAD16_S_I64: return WebAssembly::LOAD16_S_I64_S;
+  case WebAssembly::LOAD16_U_I32: return WebAssembly::LOAD16_U_I32_S;
+  case WebAssembly::LOAD16_U_I64: return WebAssembly::LOAD16_U_I64_S;
+  case WebAssembly::LOAD32_S_I64: return WebAssembly::LOAD32_S_I64_S;
+  case WebAssembly::LOAD32_U_I64: return WebAssembly::LOAD32_U_I64_S;
+  case WebAssembly::LOAD8_S_I32: return WebAssembly::LOAD8_S_I32_S;
+  case WebAssembly::LOAD8_S_I64: return WebAssembly::LOAD8_S_I64_S;
+  case WebAssembly::LOAD8_U_I32: return WebAssembly::LOAD8_U_I32_S;
+  case WebAssembly::LOAD8_U_I64: return WebAssembly::LOAD8_U_I64_S;
+  case WebAssembly::LOAD_F32: return WebAssembly::LOAD_F32_S;
+  case WebAssembly::LOAD_F64: return WebAssembly::LOAD_F64_S;
+  case WebAssembly::LOAD_I32: return WebAssembly::LOAD_I32_S;
+  case WebAssembly::LOAD_I64: return WebAssembly::LOAD_I64_S;
+  case WebAssembly::LOOP: return WebAssembly::LOOP_S;
+  case WebAssembly::LT_F32: return WebAssembly::LT_F32_S;
+  case WebAssembly::LT_F64: return WebAssembly::LT_F64_S;
+  case WebAssembly::LT_S_I32: return WebAssembly::LT_S_I32_S;
+  case WebAssembly::LT_S_I64: return WebAssembly::LT_S_I64_S;
+  case WebAssembly::LT_U_I32: return WebAssembly::LT_U_I32_S;
+  case WebAssembly::LT_U_I64: return WebAssembly::LT_U_I64_S;
+  case WebAssembly::MAX_F32: return WebAssembly::MAX_F32_S;
+  case WebAssembly::MAX_F64: return WebAssembly::MAX_F64_S;
+  case WebAssembly::MEMORY_GROW_I32: return WebAssembly::MEMORY_GROW_I32_S;
+  case WebAssembly::MEMORY_SIZE_I32: return WebAssembly::MEMORY_SIZE_I32_S;
+  case WebAssembly::MEM_GROW_I32: return WebAssembly::MEM_GROW_I32_S;
+  case WebAssembly::MEM_SIZE_I32: return WebAssembly::MEM_SIZE_I32_S;
+  case WebAssembly::MIN_F32: return WebAssembly::MIN_F32_S;
+  case WebAssembly::MIN_F64: return WebAssembly::MIN_F64_S;
+  case WebAssembly::MUL_F32: return WebAssembly::MUL_F32_S;
+  case WebAssembly::MUL_F32x4: return WebAssembly::MUL_F32x4_S;
+  case WebAssembly::MUL_F64: return WebAssembly::MUL_F64_S;
+  case WebAssembly::MUL_I16x8: return WebAssembly::MUL_I16x8_S;
+  case WebAssembly::MUL_I32: return WebAssembly::MUL_I32_S;
+  case WebAssembly::MUL_I32x4: return WebAssembly::MUL_I32x4_S;
+  case WebAssembly::MUL_I64: return WebAssembly::MUL_I64_S;
+  case WebAssembly::MUL_I8x16: return WebAssembly::MUL_I8x16_S;
+  case WebAssembly::NEAREST_F32: return WebAssembly::NEAREST_F32_S;
+  case WebAssembly::NEAREST_F64: return WebAssembly::NEAREST_F64_S;
+  case WebAssembly::NEG_F32: return WebAssembly::NEG_F32_S;
+  case WebAssembly::NEG_F64: return WebAssembly::NEG_F64_S;
+  case WebAssembly::NE_F32: return WebAssembly::NE_F32_S;
+  case WebAssembly::NE_F64: return WebAssembly::NE_F64_S;
+  case WebAssembly::NE_I32: return WebAssembly::NE_I32_S;
+  case WebAssembly::NE_I64: return WebAssembly::NE_I64_S;
+  case WebAssembly::NOP: return WebAssembly::NOP_S;
+  case WebAssembly::OR_I32: return WebAssembly::OR_I32_S;
+  case WebAssembly::OR_I64: return WebAssembly::OR_I64_S;
+  case WebAssembly::PCALL_INDIRECT_EXCEPT_REF: return WebAssembly::PCALL_INDIRECT_EXCEPT_REF_S;
+  case WebAssembly::PCALL_INDIRECT_F32: return WebAssembly::PCALL_INDIRECT_F32_S;
+  case WebAssembly::PCALL_INDIRECT_F64: return WebAssembly::PCALL_INDIRECT_F64_S;
+  case WebAssembly::PCALL_INDIRECT_I32: return WebAssembly::PCALL_INDIRECT_I32_S;
+  case WebAssembly::PCALL_INDIRECT_I64: return WebAssembly::PCALL_INDIRECT_I64_S;
+  case WebAssembly::PCALL_INDIRECT_VOID: return WebAssembly::PCALL_INDIRECT_VOID_S;
+  case WebAssembly::PCALL_INDIRECT_v16i8: return WebAssembly::PCALL_INDIRECT_v16i8_S;
+  case WebAssembly::PCALL_INDIRECT_v4f32: return WebAssembly::PCALL_INDIRECT_v4f32_S;
+  case WebAssembly::PCALL_INDIRECT_v4i32: return WebAssembly::PCALL_INDIRECT_v4i32_S;
+  case WebAssembly::PCALL_INDIRECT_v8i16: return WebAssembly::PCALL_INDIRECT_v8i16_S;
+  case WebAssembly::POPCNT_I32: return WebAssembly::POPCNT_I32_S;
+  case WebAssembly::POPCNT_I64: return WebAssembly::POPCNT_I64_S;
+  case WebAssembly::REM_S_I32: return WebAssembly::REM_S_I32_S;
+  case WebAssembly::REM_S_I64: return WebAssembly::REM_S_I64_S;
+  case WebAssembly::REM_U_I32: return WebAssembly::REM_U_I32_S;
+  case WebAssembly::REM_U_I64: return WebAssembly::REM_U_I64_S;
+  case WebAssembly::RETHROW: return WebAssembly::RETHROW_S;
+  case WebAssembly::RETHROW_TO_CALLER: return WebAssembly::RETHROW_TO_CALLER_S;
+  case WebAssembly::RETURN_EXCEPT_REF: return WebAssembly::RETURN_EXCEPT_REF_S;
+  case WebAssembly::RETURN_F32: return WebAssembly::RETURN_F32_S;
+  case WebAssembly::RETURN_F64: return WebAssembly::RETURN_F64_S;
+  case WebAssembly::RETURN_I32: return WebAssembly::RETURN_I32_S;
+  case WebAssembly::RETURN_I64: return WebAssembly::RETURN_I64_S;
+  case WebAssembly::RETURN_VOID: return WebAssembly::RETURN_VOID_S;
+  case WebAssembly::RETURN_v16i8: return WebAssembly::RETURN_v16i8_S;
+  case WebAssembly::RETURN_v4f32: return WebAssembly::RETURN_v4f32_S;
+  case WebAssembly::RETURN_v4i32: return WebAssembly::RETURN_v4i32_S;
+  case WebAssembly::RETURN_v8i16: return WebAssembly::RETURN_v8i16_S;
+  case WebAssembly::ROTL_I32: return WebAssembly::ROTL_I32_S;
+  case WebAssembly::ROTL_I64: return WebAssembly::ROTL_I64_S;
+  case WebAssembly::ROTR_I32: return WebAssembly::ROTR_I32_S;
+  case WebAssembly::ROTR_I64: return WebAssembly::ROTR_I64_S;
+  case WebAssembly::SELECT_EXCEPT_REF: return WebAssembly::SELECT_EXCEPT_REF_S;
+  case WebAssembly::SELECT_F32: return WebAssembly::SELECT_F32_S;
+  case WebAssembly::SELECT_F64: return WebAssembly::SELECT_F64_S;
+  case WebAssembly::SELECT_I32: return WebAssembly::SELECT_I32_S;
+  case WebAssembly::SELECT_I64: return WebAssembly::SELECT_I64_S;
+  case WebAssembly::SET_GLOBAL_EXCEPT_REF: return WebAssembly::SET_GLOBAL_EXCEPT_REF_S;
+  case WebAssembly::SET_GLOBAL_F32: return WebAssembly::SET_GLOBAL_F32_S;
+  case WebAssembly::SET_GLOBAL_F64: return WebAssembly::SET_GLOBAL_F64_S;
+  case WebAssembly::SET_GLOBAL_I32: return WebAssembly::SET_GLOBAL_I32_S;
+  case WebAssembly::SET_GLOBAL_I64: return WebAssembly::SET_GLOBAL_I64_S;
+  case WebAssembly::SET_GLOBAL_V128: return WebAssembly::SET_GLOBAL_V128_S;
+  case WebAssembly::SET_LOCAL_EXCEPT_REF: return WebAssembly::SET_LOCAL_EXCEPT_REF_S;
+  case WebAssembly::SET_LOCAL_F32: return WebAssembly::SET_LOCAL_F32_S;
+  case WebAssembly::SET_LOCAL_F64: return WebAssembly::SET_LOCAL_F64_S;
+  case WebAssembly::SET_LOCAL_I32: return WebAssembly::SET_LOCAL_I32_S;
+  case WebAssembly::SET_LOCAL_I64: return WebAssembly::SET_LOCAL_I64_S;
+  case WebAssembly::SET_LOCAL_V128: return WebAssembly::SET_LOCAL_V128_S;
+  case WebAssembly::SHL_I32: return WebAssembly::SHL_I32_S;
+  case WebAssembly::SHL_I64: return WebAssembly::SHL_I64_S;
+  case WebAssembly::SHR_S_I32: return WebAssembly::SHR_S_I32_S;
+  case WebAssembly::SHR_S_I64: return WebAssembly::SHR_S_I64_S;
+  case WebAssembly::SHR_U_I32: return WebAssembly::SHR_U_I32_S;
+  case WebAssembly::SHR_U_I64: return WebAssembly::SHR_U_I64_S;
+  case WebAssembly::SQRT_F32: return WebAssembly::SQRT_F32_S;
+  case WebAssembly::SQRT_F64: return WebAssembly::SQRT_F64_S;
+  case WebAssembly::STORE16_I32: return WebAssembly::STORE16_I32_S;
+  case WebAssembly::STORE16_I64: return WebAssembly::STORE16_I64_S;
+  case WebAssembly::STORE32_I64: return WebAssembly::STORE32_I64_S;
+  case WebAssembly::STORE8_I32: return WebAssembly::STORE8_I32_S;
+  case WebAssembly::STORE8_I64: return WebAssembly::STORE8_I64_S;
+  case WebAssembly::STORE_F32: return WebAssembly::STORE_F32_S;
+  case WebAssembly::STORE_F64: return WebAssembly::STORE_F64_S;
+  case WebAssembly::STORE_I32: return WebAssembly::STORE_I32_S;
+  case WebAssembly::STORE_I64: return WebAssembly::STORE_I64_S;
+  case WebAssembly::SUB_F32: return WebAssembly::SUB_F32_S;
+  case WebAssembly::SUB_F32x4: return WebAssembly::SUB_F32x4_S;
+  case WebAssembly::SUB_F64: return WebAssembly::SUB_F64_S;
+  case WebAssembly::SUB_I16x8: return WebAssembly::SUB_I16x8_S;
+  case WebAssembly::SUB_I32: return WebAssembly::SUB_I32_S;
+  case WebAssembly::SUB_I32x4: return WebAssembly::SUB_I32x4_S;
+  case WebAssembly::SUB_I64: return WebAssembly::SUB_I64_S;
+  case WebAssembly::SUB_I8x16: return WebAssembly::SUB_I8x16_S;
+  case WebAssembly::TEE_EXCEPT_REF: return WebAssembly::TEE_EXCEPT_REF_S;
+  case WebAssembly::TEE_F32: return WebAssembly::TEE_F32_S;
+  case WebAssembly::TEE_F64: return WebAssembly::TEE_F64_S;
+  case WebAssembly::TEE_I32: return WebAssembly::TEE_I32_S;
+  case WebAssembly::TEE_I64: return WebAssembly::TEE_I64_S;
+  case WebAssembly::TEE_LOCAL_EXCEPT_REF: return WebAssembly::TEE_LOCAL_EXCEPT_REF_S;
+  case WebAssembly::TEE_LOCAL_F32: return WebAssembly::TEE_LOCAL_F32_S;
+  case WebAssembly::TEE_LOCAL_F64: return WebAssembly::TEE_LOCAL_F64_S;
+  case WebAssembly::TEE_LOCAL_I32: return WebAssembly::TEE_LOCAL_I32_S;
+  case WebAssembly::TEE_LOCAL_I64: return WebAssembly::TEE_LOCAL_I64_S;
+  case WebAssembly::TEE_LOCAL_V128: return WebAssembly::TEE_LOCAL_V128_S;
+  case WebAssembly::TEE_V128: return WebAssembly::TEE_V128_S;
+  case WebAssembly::THROW_I32: return WebAssembly::THROW_I32_S;
+  case WebAssembly::THROW_I64: return WebAssembly::THROW_I64_S;
+  case WebAssembly::TRUNC_F32: return WebAssembly::TRUNC_F32_S;
+  case WebAssembly::TRUNC_F64: return WebAssembly::TRUNC_F64_S;
+  case WebAssembly::TRY: return WebAssembly::TRY_S;
+  case WebAssembly::UNREACHABLE: return WebAssembly::UNREACHABLE_S;
+  case WebAssembly::XOR_I32: return WebAssembly::XOR_I32_S;
+  case WebAssembly::XOR_I64: return WebAssembly::XOR_I64_S;
+  }
+}
index 8a49325af2bd90bce194f62e22bd26f351bdc9a8..aac2dbb4a22312b47c6c256a5a3a0fea41f34ba4 100644 (file)
@@ -57,11 +57,12 @@ let Defs = [ARGUMENTS] in {
 
 // Defines atomic and non-atomic loads, regular and extending.
 multiclass WebAssemblyLoad<WebAssemblyRegClass rc, string Name, int Opcode> {
+  let mayLoad = 1 in
   defm "": I<(outs rc:$dst),
              (ins P2Align:$p2align, offset32_op:$off, I32:$addr),
              (outs), (ins P2Align:$p2align, offset32_op:$off),
              [], !strconcat(Name, "\t$dst, ${off}(${addr})${p2align}"),
-             !strconcat(Name, "\t${off}${p2align}"), Opcode>;
+             !strconcat(Name, "\t${off}${p2align}"), Opcode>;
 }
 
 // Basic load.
@@ -307,12 +308,13 @@ let Defs = [ARGUMENTS] in {
 
 // Defines atomic and non-atomic stores, regular and truncating
 multiclass WebAssemblyStore<WebAssemblyRegClass rc, string Name, int Opcode> {
+  let mayStore = 1 in
   defm "" : I<(outs),
               (ins P2Align:$p2align, offset32_op:$off, I32:$addr, rc:$val),
               (outs),
               (ins P2Align:$p2align, offset32_op:$off), [],
               !strconcat(Name, "\t${off}(${addr})${p2align}, $val"),
-              !strconcat(Name, "\t${off}${p2align}"), Opcode>;
+              !strconcat(Name, "\t${off}${p2align}"), Opcode>;
 }
 // Basic store.
 // Note: WebAssembly inverts SelectionDAG's usual operand order.
@@ -470,12 +472,12 @@ defm CURRENT_MEMORY_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
 
 // Grow memory.
 defm MEMORY_GROW_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
-                         (outs), (ins i32imm:$flags, I32:$delta),
+                         (outs), (ins i32imm:$flags),
                          [(set I32:$dst,
                            (int_wasm_memory_grow (i32 imm:$flags),
                              I32:$delta))],
                          "memory.grow\t$dst, $flags, $delta",
-                         "memory.grow\t$flags, $delta", 0x3f>,
+                         "memory.grow\t$flags", 0x3f>,
                        Requires<[HasAddr32]>;
 defm MEM_GROW_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
                       (outs), (ins i32imm:$flags),
index 7c10f022cbbcfb3b535e5486d65db74434cfffac..1c69dcc89f27b9f5aff47c67aacfe563012b3856 100644 (file)
@@ -317,9 +317,6 @@ void WebAssemblyPassConfig::addPreEmitPass() {
   // converted into a local.
   addPass(createWebAssemblyFixIrreducibleControlFlow());
 
-  // Insert explicit get_local and set_local operators.
-  addPass(createWebAssemblyExplicitLocals());
-
   // Do various transformations for exception handling
   addPass(createWebAssemblyLateEHPrepare());
 
@@ -337,6 +334,9 @@ void WebAssemblyPassConfig::addPreEmitPass() {
   if (getOptLevel() != CodeGenOpt::None)
     addPass(createWebAssemblyPeephole());
 
+  // Insert explicit get_local and set_local operators.
+  addPass(createWebAssemblyExplicitLocals());
+
   // Create a mapping from LLVM CodeGen virtual registers to wasm registers.
   addPass(createWebAssemblyRegNumbering());
 }
index 9fdbd5473f5d0cfcf57be0f22619315a04918373..e30dc8836cb1f66a1009549260c3765faa247d8d 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
 
 ; Test folding constant offsets and symbols into load and store addresses under
 ; a variety of circumstances.
index 1a9b2e84aaad3d6d36fb73eae5a5d044fee27e20..2651ac0b387c2c71ab24dcd5b922b9d28ff98727 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+atomics,+sign-ext | FileCheck %s
+; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -mattr=+atomics,+sign-ext | FileCheck %s
 
 ; Test atomic RMW (read-modify-write) instructions are assembled properly.
 
index 13cf397bf776bfada0bc25e103f8703f59249c3d..fa4afc1fa5a80f84c95cb294f815f19c21d9037b 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs | FileCheck %s
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs -fast-isel | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -verify-machineinstrs | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -verify-machineinstrs -fast-isel | FileCheck %s
 
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown"
index ad494fbb83dbfefc231582e67f9c254a13174a73..dc26208994ab32dce994146f4a61cfbe3eec94aa 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-temporary-workarounds=false | FileCheck %s
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 -wasm-temporary-workarounds=false | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -wasm-temporary-workarounds=false | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -fast-isel -fast-isel-abort=1 -wasm-temporary-workarounds=false | FileCheck %s
 
 ; Test that basic call operations assemble as expected.
 
index 56ff2e0a03d02acd28d4b0df06b0d514bbf83efa..b474fe35bb4e2dd0436d61359ec8943c4cae513d 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -disable-block-placement -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 | FileCheck %s
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -tail-dup-placement=0 -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 | FileCheck -check-prefix=OPT %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -disable-block-placement -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -tail-dup-placement=0 -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 | FileCheck -check-prefix=OPT %s
 
 ; Test the CFG stackifier pass.
 
index e5664ba73a0d57d738a53503f8e8cc5d2517e9dd..2dd1d77572d691f9544e069ed7f5877d5d7c74f5 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: opt -S -lowertypetests < %s | llc -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
+; RUN: opt -S -lowertypetests < %s | llc -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 ; Tests that we correctly assign indexes for control flow integrity.
 
index 52df2fde88a118222d20d150ef9c5a2880cc714e..67f6005f626762871aa57d8f6cb97fd64c836de8 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 ; Test that basic 32-bit floating-point comparison operations assemble as
 ; expected.
index bb42e89ae7436b73be87cf4dda742045732bdd5c..d47d62ad1a3b2b7e5cdd49c060615399d5db3943 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 ; Test that basic 64-bit floating-point comparison operations assemble as
 ; expected.
index fb1fb3b61a301facdcfadc98c9e4f8c50f171bbf..0c08aec42d7215a052b560eadd8a98656756376d 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -fast-isel -fast-isel-abort=1 | FileCheck %s
 
 ; Test that basic 32-bit integer comparison operations assemble as expected.
 
index a10c3196854650f94bcfcae2bd57cdaad676ade3..19bef5685b4e4bebeb5e6fbff7980f6da482d123 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -fast-isel -fast-isel-abort=1 | FileCheck %s
 
 ; Test that basic 64-bit integer comparison operations assemble as expected.
 
index 42bd8413e651ce8d548d996e59c128be8b270b58..ce572a0dcacee976e4742b151149046c836d62e8 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=-nontrapping-fptoint | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -mattr=-nontrapping-fptoint | FileCheck %s
 
 ; Test that basic conversion operations assemble as expected using
 ; the trapping opcodes and explicit code to suppress the trapping.
index d43810f8124ab386e0d3aea07feb2f31dc2a9bc2..7cde1b4abb053a80662c586fb3cb7aa6d81a832d 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+nontrapping-fptoint | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -mattr=+nontrapping-fptoint | FileCheck %s
 
 ; Test that basic conversion operations assemble as expected.
 
index af62c753a92d42696d19662a2d5dec896567b002..06dde97d98b11317705e3117a1418b1dca875984 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 ; DAGCombiner oddly folds casts into the rhs of copysign. Test that they get
 ; unfolded.
index 6150cab4d4fd219181edf72e4ec1a7bfb69fa26a..01ef1680d536abd166049f68b1979a44244c9532 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 ; Test that integer div and rem by constant are optimized appropriately.
 
index bab8de24f73bcb35dc6ba470c4ab8d5b068c8e29..e7c0d757873c58d01ae04aec974d5b617cbaea5d 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -exception-model=wasm
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -exception-model=wasm -mattr=+exception-handling | FileCheck -allow-deprecated-dag-overlap %s
+; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -exception-model=wasm
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -exception-model=wasm -mattr=+exception-handling | FileCheck -allow-deprecated-dag-overlap %s
 
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown"
index 255802bf22dc45a269c4a70f29ece6c95f418131..087730963bd74435ff3d07dce54cf0781d0317e1 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: llc -mtriple=wasm32-unknown-unknown -run-pass wasm-explicit-locals %s -o - | FileCheck %s
+# RUN: llc -mtriple=wasm32-unknown-unknown -run-pass wasm-explicit-locals -wasm-explicit-locals-codegen-test-mode %s -o - | FileCheck %s
 
 # When a drop instruction is inserted to drop a dead register operand, the
 # original operand should be marked not dead anymore because it is now used by
index 20560437982aafa5aaba507e3cddc25508a521cf..f53b2748486cbfa0df90ba3e084f5d95364053f4 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -fast-isel | FileCheck %s
 
 ; Test that f16 is expanded.
 
index fa513fce2b73a0f42b51184505e0d79d68c47f5d..f3ea369dead24fb9d03d549eeb6d7049e4e30ad5 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 ; Test that basic 32-bit floating-point operations assemble as expected.
 
index a919bc87c84eb191a674112f7c2b5631565fc10b..b3cd39402df68be2f6d3f9ea53924434e3269ddb 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 ; Test that basic 64-bit floating-point operations assemble as expected.
 
index 76b6e1e28822d1bd27d1fe44d1956d5c60086b21..10d9712f6e42aa500cc21c28b9a97ed6e162c980 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -fast-isel -asm-verbose=false | FileCheck %s
+; RUN: llc < %s -fast-isel -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown"
index 10f1490045e9d4fe394641c9119b1e1613b5e52a..ccbfd1d55996a567cfe99c8692bafda87c4e942c 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -O0
+; RUN: llc < %s -O0 -wasm-explicit-locals-codegen-test-mode
 ; PR36564
 ; PR37546
 
index a30ea353701ac7e92418f9d74a87d5c8714ad05b..a784849daec7937be2d8552662028bad0f087159 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -O0
+; RUN: llc < %s -O0 -wasm-explicit-locals-codegen-test-mode
 ; PR36564
 ; PR37546
 
index 732601643f9338bf8dd62d4b12c7b9e795bf73d8..1ffa2d99c401c27c7c09a98b04636c414e2fea7b 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s
-; RUN: llc < %s -asm-verbose=false -fast-isel -verify-machineinstrs | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -verify-machineinstrs | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode -fast-isel -verify-machineinstrs | FileCheck %s
 
 ; Test that FastISel does not generate instructions with NoReg
 
index 36721c14999796f44c33d872cdfacfa9f5a7520e..1ab22d502a27cc1f16ea3bbb36740b0d8c94eaff 100644 (file)
@@ -1,6 +1,6 @@
 ; RUN: llc < %s -asm-verbose=false \
 ; RUN:   -fast-isel -fast-isel-abort=1 -verify-machineinstrs \
-; RUN:   -disable-wasm-explicit-locals \
+; RUN:   -wasm-register-codegen-test-mode \
 ; RUN:   | FileCheck %s
 
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
index 23447a721cef661e8bdf9a30665b8ec7c8b72a4c..439e882654933143b7252148f175ff16fdbb5d0a 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
 
 ; Test that the frem instruction works.
 
index 213e5918cfd3eddf412b1718ee874e758a436821..af6d5d70044195f055d6cb200c678f7d95d7aee7 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
 
 ; Test that basic functions assemble as expected.
 
index 5f1997b21e5570d6116fbaaf290d9b9c03120b31..56626b6fd180b4c3730de9c02c3e7ce3461da04d 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -wasm-temporary-workarounds=false | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -wasm-temporary-workarounds=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 ; Test that function pointer casts casting away varargs are replaced with
 ; wrappers.
index d3553a40b71bc39d9d5517d6ff06aa31207fbba6..2eff0d63fe86c19ac5e0ad8e0ce2518ed5d73b03 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals -enable-emscripten-cxx-exceptions -wasm-temporary-workarounds=false | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -wasm-register-codegen-test-mode -enable-emscripten-cxx-exceptions -wasm-temporary-workarounds=false | FileCheck %s
 
 ; Test that function pointer casts are replaced with wrappers.
 
index a9dd4b6227069febcace9b3933aaebe3f3320ed4..760902942c253ba8d9c6ba5ec7775f8882163c6b 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
 
 ; Test that globals assemble as expected.
 
index 29bf787863d5f502e150b8871537518c9fcf0697..4616e7f2c9314201fa5fc185f75b1779f06996a3 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 ; Test that basic 128-bit integer operations assemble as expected.
 
index a7b67387e170abd56ed5929247841cc0cef95f30..4c1c0248517afebbadcabb13c4bb9dc17287aad3 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mattr=+atomics -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -mattr=+atomics -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
 
 ; Test loads and stores with custom alignment values.
 
index f34319ed231a516466cdb4eee6ef36b8230c0b9e..14e188bc3963f4badd0f27a112f113947ca19d0d 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 ; Test that basic 32-bit integer operations assemble as expected.
 
index eb303c150ef81c6c0453019f5f1b2cd306197f72..f43aa4c550a127e40186e3d22e8d566228cb107e 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mattr=+atomics -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -mattr=+atomics -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
 
 ; Test loads and stores with custom alignment values.
 
index 915f97f4ef5e748f4983dc0002a516d4bc33b922..5edd292daaac82598cd7fc774e04f11213b13538 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 ; Test that basic 64-bit integer operations assemble as expected.
 
index 49c188ec2578af1809b39e57f11261697c916aba..f5adcb04ee64b08dbf5ab07ecfc683cfa8e74d16 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 ; Test llvm.ident.
 
index 3d11f9410a7921d045af6ea9a4724986689227a2..0930738e450a4047b9f7d276df80891a17aefe52 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 ; Test that basic immediates assemble as expected.
 
index da66be9439c2b48749dc3cda297593b4593e02b1..de8262de5d1b1ded3f859ead9a1a0d76d4956758 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc -o - %s -asm-verbose=false | FileCheck %s
+; RUN: llc -o - %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown"
 
index c8ed9620e8133137d815fc4be19d9e2da62e6466..b3e376fc9acc3ee41d35b79176ddcc6ab3a3eb67 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown"
index 7cac31a2aef5653ed733d6bf793ebf1abb76b7b4..ed080402c79d2c5aac7888de05d33f228a319b07 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs -fast-isel | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -verify-machineinstrs | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -verify-machineinstrs -fast-isel | FileCheck %s
 
 ; ModuleID = 'test/dot_s/indirect-import.c'
 source_filename = "test/dot_s/indirect-import.c"
index bee834ee8463ec16e8b5ed10f8b2cce500576cb4..ebd56ca47b04893f9d1da28c48928492b7ec390d 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -no-integrated-as
+; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -no-integrated-as
 
 ; Test basic inline assembly "m" operands, which are unsupported. Pass
 ; -no-integrated-as since these aren't actually valid assembly syntax.
index 61290c8ba4455ed61a482ded8ef537f5c89bff7a..570602a94740f8a51846f7d7a194586dfcd1e916 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -no-integrated-as | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -no-integrated-as | FileCheck %s
 
 ; Test basic inline assembly. Pass -no-integrated-as since these aren't
 ; actually valid assembly syntax.
index 2201befbe1e500b226765454c6a8e2167f3d9a86..33dbf9a9854366cb85e760f7f460bd82496716af 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-block-placement -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-block-placement -wasm-register-codegen-test-mode | FileCheck %s
 
 ; Test irreducible CFG handling.
 
index 56c2e5edc3421aa1258e254c8244456d8c817b4b..49f1d15046fc26e085bd0095e996b2e370a9f293 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
 
 ; Test various types and operators that need to be legalized.
 
index bc905e293be5fc855f789cab20c0514bac151636..8cead54ee1ebcd01726b145077cd915da9d40922 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 ; Test a subset of compiler-rt/libm libcalls expected to be emitted by the wasm backend
 
index ff69be5a70c6f71713b2e7a021b85a0dbe31d399..5d2ea521552c3ff13268576bba91b8fb9523e28f 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mattr=+atomics,+sign-ext -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -mattr=+atomics,+sign-ext -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
 
 ; Test that extending loads are assembled properly.
 
index b69046341133747972e08541904d2c4d22906ee7..7b4fc8d7c39f22d11b83fdb5157c19645f8e7cfc 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
 
 ; Test that extending loads are assembled properly.
 
index f768faaf8cea6e97105a7ceb0be7325e328613b6..018cee8c15d76e28eba689ca41c301226db6b00c 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
 
 ; Test that i1 extending loads and truncating stores are assembled properly.
 
index 62827daf882b5754a834d4e60f021bcd397bf596..30bcf8040ac5e9ac5234814a2d366cc2ab597ffc 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -fast-isel -fast-isel-abort=1 | FileCheck %s
 
 ; Test that basic loads are assembled properly.
 
index 8283b49cd584ff91e3b113b4b3a4fbdad667b6f2..b86c192af293d6b34ce84a1ea4348f6c10060eb3 100644 (file)
@@ -39,9 +39,9 @@ entry:
   %arraydecay1 = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0
   call void @longjmp(%struct.__jmp_buf_tag* %arraydecay1, i32 1) #1
   unreachable
-; SJLJ: i32.call ${{[a-zA-Z0-9]+}}=, saveSetjmp@FUNCTION
-; SJLJ: i32.call ${{[a-zA-Z0-9]+}}=, testSetjmp@FUNCTION
-; NONE: i32.call ${{[a-zA-Z0-9]+}}=, setjmp@FUNCTION
+; SJLJ: i32.call saveSetjmp@FUNCTION
+; SJLJ: i32.call testSetjmp@FUNCTION
+; NONE: i32.call setjmp@FUNCTION
 ; NONE: call longjmp@FUNCTION
 }
 
index f9b753ef65bbbe1c0dd43a01fe0fe1ec90d37ec9..22b1e1b2d8b395aa37b1562833629f50bac7ffae 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false | FileCheck --check-prefix=CHECK --check-prefix=FINI --check-prefix=NULL %s
+; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck --check-prefix=CHECK --check-prefix=FINI --check-prefix=NULL %s
 
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown"
index f6afc3e801cdf0b3dd9ae9ad8a3e93b66c3d825a..f16187361d3f53e0d8587217b41088f1419d0c1b 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -tail-dup-placement=0 | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -tail-dup-placement=0 | FileCheck %s
 
 ; Test memcpy, memmove, and memset intrinsics.
 
index ca8c2821b052611c19929b3d7836e44b6edb42d0..6a35d64b6950980f1c33d644c7d475928699cf41 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
 
 ; Test that basic memory operations assemble as expected with 32-bit addresses.
 
index 1e4033428690db2311dcb1fff2dc8f646213c96c..50f806dbb49036d6e49a067afc2c925c243ec2ad 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc -asm-verbose=false < %s | FileCheck %s
+; RUN: llc -asm-verbose=false < %s -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 ; Test that 128-bit smul.with.overflow assembles as expected.
 
index 16b4a15a44bdbed85271f48f569435df018f4eff..0ea5dff355aad5b8e3ee2fe14f76ea784db1d676 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown"
index 5ead9548f5cec72013ee053c6f09601542fb7029..f3fd6e2e491ee533b3f298d164c63ffdc15a7d01 100644 (file)
@@ -1,5 +1,5 @@
 ; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+atomics,+sign-ext | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -mattr=+atomics,+sign-ext | FileCheck %s
 
 ; Test that atomic loads are assembled properly.
 
index abad8917e9d9d50fe39a3dbf3a01c9161a6ffbdd..37eee436d9f5ceb6871f8479ebb3e46864847161 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals -fast-isel -fast-isel-abort=1 | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -wasm-register-codegen-test-mode -fast-isel -fast-isel-abort=1 | FileCheck %s
 
 ; TODO: Merge this with offset.ll when fast-isel matches better.
 
index 863549fc20fc288637a04aae7924c3c3755ac04e..d441963a0ddacb5016a4d1435168bdcb99b0e2bf 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 ; Test that constant offsets can be folded into global addresses.
 
index d2e5ca2ddd59fba13838ec24229e08ad4f26c4e3..90a2519b84896a8718e70824f30f95956cd9a052 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals -disable-wasm-fallthrough-return-opt | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -wasm-register-codegen-test-mode -disable-wasm-fallthrough-return-opt | FileCheck %s
 
 ; Test constant load and store address offsets.
 
index d01aff497ce24687dcc00ab538feefb082f0cfb7..f8319b01126ecb5012f91dc1a71c6f5788019ae4 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -verify-machineinstrs | FileCheck %s
 
 ; Test that phis are lowered.
 
index 7195cd8548235361d88d70ae1f6eeba35725f207..f36014c1395c20198e1bdc27c1232c35312f9c4f 100644 (file)
@@ -1,7 +1,11 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -verify-machineinstrs | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s --check-prefix=NOREGS
 
 ; Test the register stackifier pass.
 
+; We have two sets of tests, one with registers and implicit locals, and
+; a stack / explicit locals based version (NOREGS).
+
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown"
 
@@ -9,6 +13,8 @@ target triple = "wasm32-unknown-unknown"
 
 ; CHECK-LABEL: no0:
 ; CHECK: return $1{{$}}
+; NOREGS-LABEL: no0:
+; NOREGS: return{{$}}
 define i32 @no0(i32* %p, i32* %q) {
   %t = load i32, i32* %q
   store i32 0, i32* %p
@@ -19,6 +25,8 @@ define i32 @no0(i32* %p, i32* %q) {
 
 ; CHECK-LABEL: no1:
 ; CHECK: return $1{{$}}
+; NOREGS-LABEL: no1:
+; NOREGS: return{{$}}
 define i32 @no1(i32* %p, i32* dereferenceable(4) %q) {
   %t = load volatile i32, i32* %q, !invariant.load !0
   store volatile i32 0, i32* %p
@@ -29,6 +37,8 @@ define i32 @no1(i32* %p, i32* dereferenceable(4) %q) {
 
 ; CHECK-LABEL: yes0:
 ; CHECK: return $pop{{[0-9]+}}{{$}}
+; NOREGS-LABEL: yes0:
+; NOREGS: return{{$}}
 define i32 @yes0(i32* %p, i32* dereferenceable(4) %q) {
   %t = load i32, i32* %q, !invariant.load !0
   store i32 0, i32* %p
@@ -39,6 +49,8 @@ define i32 @yes0(i32* %p, i32* dereferenceable(4) %q) {
 
 ; CHECK-LABEL: yes1:
 ; CHECK: return $pop0{{$}}
+; NOREGS-LABEL: yes1:
+; NOREGS: return{{$}}
 define i32 @yes1(i32* %q) {
   %t = load volatile i32, i32* %q
   ret i32 %t
@@ -48,6 +60,8 @@ define i32 @yes1(i32* %q) {
 
 ; CHECK-LABEL: sink_trap:
 ; CHECK: return $pop{{[0-9]+}}{{$}}
+; NOREGS-LABEL: sink_trap:
+; NOREGS: return{{$}}
 define i32 @sink_trap(i32 %x, i32 %y, i32* %p) {
   %t = sdiv i32 %x, %y
   store volatile i32 0, i32* %p
@@ -58,6 +72,8 @@ define i32 @sink_trap(i32 %x, i32 %y, i32* %p) {
 
 ; CHECK-LABEL: sink_readnone_call:
 ; CHECK: return $pop0{{$}}
+; NOREGS-LABEL: sink_readnone_call:
+; NOREGS: return{{$}}
 declare i32 @readnone_callee() readnone nounwind
 define i32 @sink_readnone_call(i32 %x, i32 %y, i32* %p) {
   %t = call i32 @readnone_callee()
@@ -69,6 +85,8 @@ define i32 @sink_readnone_call(i32 %x, i32 %y, i32* %p) {
 
 ; CHECK-LABEL: no_sink_readonly_call:
 ; CHECK: return ${{[0-9]+}}{{$}}
+; NOREGS-LABEL: no_sink_readonly_call:
+; NOREGS: return{{$}}
 declare i32 @readonly_callee() readonly nounwind
 define i32 @no_sink_readonly_call(i32 %x, i32 %y, i32* %p) {
   %t = call i32 @readonly_callee()
@@ -105,6 +123,34 @@ define i32 @no_sink_readonly_call(i32 %x, i32 %y, i32* %p) {
 ; CHECK-NEXT: end_block{{$}}
 ; CHECK-NEXT: i32.const   $push14=, 1{{$}}
 ; CHECK-NEXT: return      $pop14{{$}}
+; NOREGS-LABEL: stack_uses:
+; NOREGS: .param i32, i32, i32, i32{{$}}
+; NOREGS-NEXT: .result i32{{$}}
+; NOREGS-NEXT: block {{$}}
+; NOREGS-NEXT: get_local 0{{$}}
+; NOREGS-NEXT: i32.const   1{{$}}
+; NOREGS-NEXT: i32.lt_s
+; NOREGS-NEXT: get_local 1{{$}}
+; NOREGS-NEXT: i32.const   2{{$}}
+; NOREGS-NEXT: i32.lt_s
+; NOREGS-NEXT: i32.xor {{$}}
+; NOREGS-NEXT: get_local 2{{$}}
+; NOREGS-NEXT: i32.const   1{{$}}
+; NOREGS-NEXT: i32.lt_s
+; NOREGS-NEXT: get_local 3{{$}}
+; NOREGS-NEXT: i32.const   2{{$}}
+; NOREGS-NEXT: i32.lt_s
+; NOREGS-NEXT: i32.xor {{$}}
+; NOREGS-NEXT: i32.xor {{$}}
+; NOREGS-NEXT: i32.const   1{{$}}
+; NOREGS-NEXT: i32.ne {{$}}
+; NOREGS-NEXT: br_if       0{{$}}
+; NOREGS-NEXT: i32.const   0{{$}}
+; NOREGS-NEXT: return{{$}}
+; NOREGS-NEXT: .LBB7_2:
+; NOREGS-NEXT: end_block{{$}}
+; NOREGS-NEXT: i32.const   1{{$}}
+; NOREGS-NEXT: return{{$}}
 define i32 @stack_uses(i32 %x, i32 %y, i32 %z, i32 %w) {
 entry:
   %c = icmp sle i32 %x, 0
@@ -137,6 +183,26 @@ false:
 ; CHECK-NEXT: .LBB8_3:
 ; CHECK-NEXT: end_block{{$}}
 ; CHECK-NEXT: return{{$}}
+; NOREGS-LABEL: multiple_uses:
+; NOREGS: .param       i32, i32, i32{{$}}
+; NOREGS: .local i32{{$}}
+; NOREGS-NEXT: block {{$}}
+; NOREGS-NEXT: get_local   2{{$}}
+; NOREGS-NEXT: i32.load    0{{$}}
+; NOREGS-NEXT: tee_local   3{{$}}
+; NOREGS-NEXT: get_local   1{{$}}
+; NOREGS-NEXT: i32.ge_u
+; NOREGS-NEXT: br_if       0{{$}}
+; NOREGS-NEXT: get_local   3{{$}}
+; NOREGS-NEXT: get_local   0{{$}}
+; NOREGS-NEXT: i32.lt_u
+; NOREGS-NEXT: br_if       0{{$}}
+; NOREGS-NEXT: get_local   2{{$}}
+; NOREGS-NEXT: get_local   3{{$}}
+; NOREGS-NEXT: i32.store   0{{$}}
+; NOREGS-NEXT: .LBB8_3:
+; NOREGS-NEXT: end_block{{$}}
+; NOREGS-NEXT: return{{$}}
 define void @multiple_uses(i32* %arg0, i32* %arg1, i32* %arg2) nounwind {
 bb:
   br label %loop
@@ -167,6 +233,11 @@ return:
 ; CHECK-NEXT: call
 ; CHECK:      store
 ; CHECK-NEXT: call
+; NOREGS:      side_effects:
+; NOREGS:      store
+; NOREGS-NEXT: call
+; NOREGS:      store
+; NOREGS-NEXT: call
 declare void @evoke_side_effects()
 define hidden void @stackify_store_across_side_effects(double* nocapture %d) {
 entry:
@@ -200,6 +271,41 @@ entry:
 ; CHECK-NEXT: i32.div_s   $push[[L13:[0-9]+]]=, $pop[[L9]], $pop[[L12]]{{$}}
 ; CHECK-NEXT: i32.div_s   $push[[L14:[0-9]+]]=, $pop[[L6]], $pop[[L13]]{{$}}
 ; CHECK-NEXT: return      $pop[[L14]]{{$}}
+; NOREGS-LABEL: div_tree:
+; NOREGS: .param i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32{{$}}
+; NOREGS-NEXT: .result     i32{{$}}
+; NOREGS-NEXT: get_local 0{{$}}
+; NOREGS-NEXT: get_local 1{{$}}
+; NOREGS-NEXT: i32.div_s{{$}}
+; NOREGS-NEXT: get_local 2{{$}}
+; NOREGS-NEXT: get_local 3{{$}}
+; NOREGS-NEXT: i32.div_s{{$}}
+; NOREGS-NEXT: i32.div_s{{$}}
+; NOREGS-NEXT: get_local 4{{$}}
+; NOREGS-NEXT: get_local 5{{$}}
+; NOREGS-NEXT: i32.div_s{{$}}
+; NOREGS-NEXT: get_local 6{{$}}
+; NOREGS-NEXT: get_local 7{{$}}
+; NOREGS-NEXT: i32.div_s{{$}}
+; NOREGS-NEXT: i32.div_s{{$}}
+; NOREGS-NEXT: i32.div_s{{$}}
+; NOREGS-NEXT: get_local 8{{$}}
+; NOREGS-NEXT: get_local 9{{$}}
+; NOREGS-NEXT: i32.div_s{{$}}
+; NOREGS-NEXT: get_local 10{{$}}
+; NOREGS-NEXT: get_local 11{{$}}
+; NOREGS-NEXT: i32.div_s{{$}}
+; NOREGS-NEXT: i32.div_s{{$}}
+; NOREGS-NEXT: get_local 12{{$}}
+; NOREGS-NEXT: get_local 13{{$}}
+; NOREGS-NEXT: i32.div_s{{$}}
+; NOREGS-NEXT: get_local 14{{$}}
+; NOREGS-NEXT: get_local 15{{$}}
+; NOREGS-NEXT: i32.div_s{{$}}
+; NOREGS-NEXT: i32.div_s{{$}}
+; NOREGS-NEXT: i32.div_s{{$}}
+; NOREGS-NEXT: i32.div_s{{$}}
+; NOREGS-NEXT: return{{$}}
 define i32 @div_tree(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p) {
 entry:
   %div = sdiv i32 %a, %b
@@ -229,6 +335,16 @@ entry:
 ; CHECK-NEXT:  call        use_a@FUNCTION, $pop[[NUM1]]{{$}}
 ; CHECK-NEXT:  call        use_b@FUNCTION, $[[NUM2]]{{$}}
 ; CHECK-NEXT:  return{{$}}
+; NOREGS-LABEL: simple_multiple_use:
+; NOREGS:  .param      i32, i32{{$}}
+; NOREGS-NEXT:  get_local 1{{$}}
+; NOREGS-NEXT:  get_local 0{{$}}
+; NOREGS-NEXT:  i32.mul
+; NOREGS-NEXT:  tee_local   1{{$}}
+; NOREGS-NEXT:  call        use_a@FUNCTION{{$}}
+; NOREGS-NEXT:  get_local   1{{$}}
+; NOREGS-NEXT:  call        use_b@FUNCTION{{$}}
+; NOREGS-NEXT:  return{{$}}
 declare void @use_a(i32)
 declare void @use_b(i32)
 define void @simple_multiple_use(i32 %x, i32 %y) {
@@ -246,6 +362,15 @@ define void @simple_multiple_use(i32 %x, i32 %y) {
 ; CHECK-NEXT:  tee_local   $push[[NUM1:[0-9]+]]=, $[[NUM2:[0-9]+]]=, $pop[[NUM0]]{{$}}
 ; CHECK-NEXT:  call        use_2@FUNCTION, $pop[[NUM1]], $[[NUM2]]{{$}}
 ; CHECK-NEXT:  return{{$}}
+; NOREGS-LABEL: multiple_uses_in_same_insn:
+; NOREGS:  .param      i32, i32{{$}}
+; NOREGS-NEXT:  get_local 1{{$}}
+; NOREGS-NEXT:  get_local 0{{$}}
+; NOREGS-NEXT:  i32.mul
+; NOREGS-NEXT:  tee_local   1{{$}}
+; NOREGS-NEXT:  get_local   1{{$}}
+; NOREGS-NEXT:  call        use_2@FUNCTION{{$}}
+; NOREGS-NEXT:  return{{$}}
 declare void @use_2(i32, i32)
 define void @multiple_uses_in_same_insn(i32 %x, i32 %y) {
   %mul = mul i32 %y, %x
@@ -264,6 +389,15 @@ define void @multiple_uses_in_same_insn(i32 %x, i32 %y) {
 ; CHECK-NEXT:  i32.call    $push3=, blue@FUNCTION{{$}}
 ; CHECK-NEXT:  i32.add     $push4=, $pop2, $pop3{{$}}
 ; CHECK-NEXT:  return      $pop4{{$}}
+; NOREGS-LABEL: commute:
+; NOREGS-NOT: param
+; NOREGS:  .result     i32{{$}}
+; NOREGS-NEXT:  i32.call    red@FUNCTION{{$}}
+; NOREGS-NEXT:  i32.call    green@FUNCTION{{$}}
+; NOREGS-NEXT:  i32.add {{$}}
+; NOREGS-NEXT:  i32.call    blue@FUNCTION{{$}}
+; NOREGS-NEXT:  i32.add {{$}}
+; NOREGS-NEXT:  return{{$}}
 declare i32 @red()
 declare i32 @green()
 declare i32 @blue()
@@ -287,6 +421,19 @@ define i32 @commute() {
 ; CHECK-NEXT: i32.sub         $push3=, $pop2, $1
 ; CHECK-NEXT: i32.div_s       $push4=, $pop3, $1
 ; CHECK-NEXT: return          $pop4
+; NOREGS-LABEL: no_stackify_past_use:
+; NOREGS:      get_local       0{{$}}
+; NOREGS-NEXT: i32.call        callee@FUNCTION
+; NOREGS-NEXT: set_local       1{{$}}
+; NOREGS-NEXT: get_local       0{{$}}
+; NOREGS-NEXT: i32.const       1
+; NOREGS-NEXT: i32.add
+; NOREGS-NEXT: i32.call        callee@FUNCTION
+; NOREGS-NEXT: get_local       1{{$}}
+; NOREGS-NEXT: i32.sub
+; NOREGS-NEXT: get_local       1{{$}}
+; NOREGS-NEXT: i32.div_s
+; NOREGS-NEXT: return
 declare i32 @callee(i32)
 define i32 @no_stackify_past_use(i32 %arg) {
   %tmp1 = call i32 @callee(i32 %arg)
@@ -309,6 +456,18 @@ define i32 @no_stackify_past_use(i32 %arg) {
 ; CHECK: i32.add         $push3=, $1, $pop2
 ; CHECK: i32.mul         $push4=, $pop[[L1]], $pop3
 ; CHECK: return          $pop4
+; NOREGS-LABEL: commute_to_fix_ordering:
+; NOREGS: get_local       0{{$}}
+; NOREGS: i32.call        callee@FUNCTION
+; NOREGS: tee_local       1
+; NOREGS: get_local       1{{$}}
+; NOREGS: get_local       0{{$}}
+; NOREGS: i32.const       1
+; NOREGS: i32.add
+; NOREGS: i32.call        callee@FUNCTION
+; NOREGS: i32.add
+; NOREGS: i32.mul
+; NOREGS: return
 define i32 @commute_to_fix_ordering(i32 %arg) {
   %tmp1 = call i32 @callee(i32 %arg)
   %tmp2 = add i32 %arg, 1
@@ -325,6 +484,10 @@ define i32 @commute_to_fix_ordering(i32 %arg) {
 ; CHECK-NEXT:   tee_local       $push[[NUM1:[0-9]+]]=, $[[NUM2:[0-9]+]]=, $pop[[NUM0]]{{$}}
 ; CHECK-NEXT:   f64.select      $push{{[0-9]+}}=, $pop{{[0-9]+}}, $pop[[NUM1]], ${{[0-9]+}}{{$}}
 ; CHECK:        $[[NUM2]]=,
+; NOREGS-LABEL: multiple_defs:
+; NOREGS:        f64.add
+; NOREGS:        tee_local
+; NOREGS:        f64.select
 define void @multiple_defs(i32 %arg, i32 %arg1, i1 %arg2, i1 %arg3, i1 %arg4) {
 bb:
   br label %bb5
@@ -367,6 +530,10 @@ exit:
 ; CHECK: i32.call $0=, red
 ; CHECK: i32.const $push0=, 0
 ; CHECK: i32.load $1=, count($pop0)
+; NOREGS-LABEL: no_stackify_call_past_load:
+; NOREGS: i32.call red
+; NOREGS: i32.const 0
+; NOREGS: i32.load count
 @count = hidden global i32 0, align 4
 define i32 @no_stackify_call_past_load() {
   %a = call i32 @red()
@@ -381,6 +548,10 @@ define i32 @no_stackify_call_past_load() {
 ; CHECK: i32.store 0($1), $0
 ; CHECK: i32.load {{.*}}, 0($2)
 ; CHECK: i32.call {{.*}}, callee@FUNCTION, $0{{$}}
+; NOREGS-LABEL: no_stackify_store_past_load
+; NOREGS: i32.store 0
+; NOREGS: i32.load 0
+; NOREGS: i32.call callee@FUNCTION{{$}}
 define i32 @no_stackify_store_past_load(i32 %a, i32* %p1, i32* %p2) {
   store i32 %a, i32* %p1
   %b = load i32, i32* %p2, align 4
@@ -394,6 +565,11 @@ define i32 @no_stackify_store_past_load(i32 %a, i32* %p1, i32* %p2) {
 ; CHECK: i32.call {{.*}}, callee@FUNCTION, $0
 ; CHECK: i32.load $push{{.*}}, 0($2)
 ; CHECK: return $pop
+; NOREGS-LABEL: store_past_invar_load
+; NOREGS: i32.store 0
+; NOREGS: i32.call callee@FUNCTION
+; NOREGS: i32.load 0
+; NOREGS: return
 define i32 @store_past_invar_load(i32 %a, i32* %p1, i32* dereferenceable(4) %p2) {
   store i32 %a, i32* %p1
   %b = load i32, i32* %p2, !invariant.load !0
@@ -404,6 +580,9 @@ define i32 @store_past_invar_load(i32 %a, i32* %p1, i32* dereferenceable(4) %p2)
 ; CHECK-LABEL: ignore_dbg_value:
 ; CHECK-NEXT: .Lfunc_begin
 ; CHECK-NEXT: unreachable
+; NOREGS-LABEL: ignore_dbg_value:
+; NOREGS-NEXT: .Lfunc_begin
+; NOREGS-NEXT: unreachable
 declare void @llvm.dbg.value(metadata, i64, metadata, metadata)
 define void @ignore_dbg_value() {
   call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !7, metadata !9), !dbg !10
@@ -415,6 +594,8 @@ define void @ignore_dbg_value() {
 
 ; CHECK-LABEL: no_stackify_past_epilogue:
 ; CHECK: return ${{[0-9]+}}{{$}}
+; NOREGS-LABEL: no_stackify_past_epilogue:
+; NOREGS: return{{$}}
 declare i32 @use_memory(i32*)
 define i32 @no_stackify_past_epilogue() {
   %x = alloca i32
@@ -429,6 +610,11 @@ define i32 @no_stackify_past_epilogue() {
 ; CHECK-NEXT:        i32.add     $push[[L4:.+]]=, $[[R0:.+]], $pop[[L5]]{{$}}
 ; CHECK-NEXT:        tee_local   $push[[L3:.+]]=, $[[R0]]=, $pop[[L4]]{{$}}
 ; CHECK-NEXT:        i32.ne      $push[[L2:.+]]=, $0, $pop[[L3]]{{$}}
+; NOREGS-LABEL: stackify_indvar:
+; NOREGS:             i32.const   1{{$}}
+; NOREGS-NEXT:        i32.add
+; NOREGS-NEXT:        tee_local   2{{$}}
+; NOREGS-NEXT:        i32.ne
 define void @stackify_indvar(i32 %tmp, i32* %v) #0 {
 bb:
   br label %bb3
@@ -451,6 +637,9 @@ bb10:                                             ; preds = %bb9, %bb
 ; CHECK-LABEL: stackpointer_dependency:
 ; CHECK:      call {{.+}}, stackpointer_callee@FUNCTION,
 ; CHECK-NEXT: set_global __stack_pointer,
+; NOREGS-LABEL: stackpointer_dependency:
+; NOREGS:      call stackpointer_callee@FUNCTION
+; NOREGS:      set_global __stack_pointer
 declare i32 @stackpointer_callee(i8* readnone, i8* readnone)
 declare i8* @llvm.frameaddress(i32)
 define i32 @stackpointer_dependency(i8* readnone) {
@@ -467,6 +656,12 @@ define i32 @stackpointer_dependency(i8* readnone) {
 ; CHECK-NEXT: i32.load  $push[[L0:.+]]=, 0($0)
 ; CHECK-NEXT: i32.load  $push[[L1:.+]]=, 0($pop[[L0]])
 ; CHECK-NEXT: i32.call_indirect $push{{.+}}=, $pop[[L3]], $1, $pop[[L1]]
+; NOREGS-LABEL: call_indirect_stackify:
+; NOREGS: i32.load  0
+; NOREGS-NEXT: tee_local 0
+; NOREGS:      i32.load  0
+; NOREGS-NEXT: i32.load  0
+; NOREGS-NEXT: i32.call_indirect
 %class.call_indirect = type { i32 (...)** }
 define i32 @call_indirect_stackify(%class.call_indirect** %objptr, i32 %arg) {
   %obj = load %class.call_indirect*, %class.call_indirect** %objptr
@@ -491,3 +686,4 @@ define i32 @call_indirect_stackify(%class.call_indirect** %objptr, i32 %arg) {
 !8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
 !9 = !DIExpression()
 !10 = !DILocation(line: 15, column: 6, scope: !5)
+
index 48459e30b7d7696b5850afc071addcf6278d54c2..742f479901bbb668274d67c48d2869e04c2245d4 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: llc < %s -asm-verbose=false | FileCheck %s
-; RUN: llc < %s -asm-verbose=false -fast-isel -fast-isel-abort=1 | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode -fast-isel -fast-isel-abort=1 | FileCheck %s
 
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown"
@@ -26,7 +26,7 @@ define i32 @return_i32_twice(i32 %a) {
 
 true:
   store i32 0, i32* null
-  ret i32 1 
+  ret i32 1
 
 false:
   store i32 2, i32* null
index 4032daf70e128b8462a1853b74fc383bb423d6e7..14939ee6336cf90b37d797cece806a4acd5caeff 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
 
 ; Test that the "returned" attribute is optimized effectively.
 
index cf3b5b96fda08bc62bf5d5fb8101cabbc6dd87c4..26a992492bee7eb9f563a4df372bfb4134595487 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -fast-isel -fast-isel-abort=1 | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -fast-isel -fast-isel-abort=1 | FileCheck %s
 
 ; Test that wasm select instruction is selected from LLVM select instruction.
 
index d32da304eb8e76ee3a588e970beddbacca78d7e5..208decc53a2d413ad07374d23c4789997193de8b 100644 (file)
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -wasm-register-codegen-test-mode | FileCheck %s
 
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown"
index 495c547e1620b94ff3f80f5aa1e9966df0d6e02c..3339576ac33e3d9bd0b54d0f1c3c39f6d44e94c8 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: llc < %s -mattr=+sign-ext -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s --check-prefix=NOSIGNEXT
+; RUN: llc < %s -mattr=+sign-ext -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s --check-prefix=NOSIGNEXT
 
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown"
index 4d0bbb522934e7f0e09c032ff35a25d5a2e5675d..76530c30582b50efbe62e95e58015930d6d48a3f 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
 
 ; Test zeroext and signext ABI keywords
 
index 8e2b4bc8a0dcf0454bd13d668bf5d7c363befd8e..4ca730d9574867fe2707aa7ed9df984725f5b217 100644 (file)
@@ -1,7 +1,7 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,SIMD128
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=-simd128 | FileCheck %s --check-prefixes CHECK,NO-SIMD128
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=-simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,NO-SIMD128
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -mattr=+simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,SIMD128
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -mattr=-simd128 | FileCheck %s --check-prefixes CHECK,NO-SIMD128
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -mattr=-simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,NO-SIMD128
 
 ; Test that basic SIMD128 arithmetic operations assemble as expected.
 
index 6f1939033a2dc66946b2ab6f7cb8798c1efdbf7d..e485c188686c7e6c2fb0265a6e2c174126a0b7dd 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown"
index 39f9e1e5bea0ddc6457b38018eefae77e57c9b4b..d281b9e863b82733b3782296dbcf3216ca191d8e 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mattr=+atomics,+sign-ext -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -mattr=+atomics,+sign-ext -asm-verbose=false -wasm-register-codegen-test-mode | FileCheck %s
 
 ; Test that truncating stores are assembled properly.
 
index 4d35f4767378a39d6cfe4e4e7210c06d7ec3f9c3..538f3021db7e5b4f4bcf63736e25b77d32831134 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -wasm-register-codegen-test-mode | FileCheck %s
 
 ; Test that truncating stores are assembled properly.
 
index 87317ee837e38debea51cd182340d6547075ae66..8e40f0c4883e7fdfd2976f74707e7a0c4fb36a9c 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -fast-isel -fast-isel-abort=1 | FileCheck %s
 
 ; Test that basic stores are assembled properly.
 
index c6354baa57a6e919b3aa6c5539eb95439cc8755b..d32d5811e6bf9d39fde77c90d558042778baac1e 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-block-placement -verify-machineinstrs | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -disable-block-placement -verify-machineinstrs | FileCheck %s
 
 ; Test switch instructions. Block placement is disabled because it reorders
 ; the blocks in a way that isn't interesting here.
index d4447feef57575b3fe1134eff211053c2139f221..5487a047e71695ff1d6750786f8b36fb76ecb49c 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -thread-model=single | FileCheck --check-prefix=SINGLE %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -thread-model=single | FileCheck --check-prefix=SINGLE %s
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown"
 
index 90eafa770026869c186daed35725edeca486ca3d..878a16e343efc6c458a9226bf4238dbebe37f748 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -wasm-register-codegen-test-mode | FileCheck %s
 ; Test that UMULO works correctly on 64-bit operands.
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown"
index 89ef73036df8288c2365b5281aeff5cd94aeda18..4bf751536d8ad2f70989bd4d1c5964e41e7791a3 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 ; Test that function pointer casts that require conversions are not converted
 ; to wrappers. In theory some conversions could be supported, but currently no
index f137e28425129eb6e6e25d24ec67ea56fcbe88a0..d44734ce372b7c1eb1111e307ab2b1064d85d13c 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
 
 ; Make sure that argument offsets are correct even if some arguments are unused.
 
index 520ae72e2eba7472b02ddb144e867590368ca0d6..e918cca3c2373066aa26b696b64c7f48d25612af 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
 
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-unknown"
@@ -138,7 +138,7 @@ define void @dynamic_alloca(i32 %alloc) {
  ; Target independent codegen bumps the stack pointer.
  ; CHECK: i32.sub
  ; Check that SP is written back to memory after decrement
- ; CHECK: set_global __stack_pointer, 
+ ; CHECK: set_global __stack_pointer,
  %r = alloca i32, i32 %alloc
  ; Target-independent codegen also calculates the store addr
  ; CHECK: call ext_func_i32@FUNCTION
index 0e26ab4959b1b47312848751a710be6a5e9d4e2a..771a019fad576145c2f12640484af30011246a6f 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -verify-machineinstrs | FileCheck %s
 
 ; Test varargs constructs.
 
index 8f0e1076865894ca8d28a282e3a1c3364b514325..3d6a03bb138d63331e2456cf5effa743e45130ce 100644 (file)
@@ -1,6 +1,6 @@
-; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s --check-prefix=TYPEINFONAME
-; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s --check-prefix=VTABLE
-; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s --check-prefix=TYPEINFO
+; RUN: llc < %s -asm-verbose=false -wasm-register-codegen-test-mode | FileCheck %s --check-prefix=TYPEINFONAME
+; RUN: llc < %s -asm-verbose=false -wasm-register-codegen-test-mode | FileCheck %s --check-prefix=VTABLE
+; RUN: llc < %s -asm-verbose=false -wasm-register-codegen-test-mode | FileCheck %s --check-prefix=TYPEINFO
 
 ; Test that simple vtables assemble as expected.
 ;
index 63c9bb183c81be5675f294f48388902e02e21c94..eb75eb3d41d7a7665a5037b2dc9b329fad55e5b5 100644 (file)
@@ -11,8 +11,7 @@
 # CHECK: i64.const -1
 0x42 0x7F
 
-# CHECK: i64.load32_u 16, :p2align=1
-# FIXME: fix p2align output in WebAssemblyInstPrinter
+# CHECK: i64.load32_u 16:p2align=1
 0x35 0x01 0x10
 
 # CHECK: block
index dbfd921ad78e35f8a1099f376f6be0093737facd..13d150ea4de54e50aff56ce301be4cc6fc3e71cf 100644 (file)
@@ -7,33 +7,33 @@ test0:
     .param      i32, i64
     .local      f32, f64  #, i8x16, i16x8, i32x4, f32x4
     # Explicit getlocal/setlocal:
-    get_local   $push0=, 2
-    set_local   2, $pop0=
-    # Implicit locals & immediates:
-    i32.const   $0=, -1
-    f64.const   $3=, 0x1.999999999999ap1
+    get_local   2
+    set_local   2
+    # Immediates:
+    i32.const   -1
+    f64.const   0x1.999999999999ap1
     # Indirect addressing:
-    get_local   $push1=, 0
-    f64.store   0($pop1), $3
+    get_local   0
+    f64.store   0
     # Loops, conditionals, binary ops, calls etc:
     block
-    i32.const   $push2=, 1
-    get_local   $push7=, 0
-    i32.ge_s    $push0=, $pop2, $pop7
-    br_if       0, $pop0        # 0: down to label0
+    i32.const   1
+    get_local   0
+    i32.ge_s
+    br_if       0        # 0: down to label0
 .LBB0_1:
     loop             # label1:
-    call        $drop=, something1@FUNCTION
-    i64.const   $push10=, 1234
-    i32.call    $push8=, something2@FUNCTION, $pop10
-    i32.const   $push11=, 0
-    call_indirect $pop11
-    i32.const   $push5=, 1
-    i32.add     $push4=, $pop8, $pop5
-    tee_local   $push3=, 0, $pop4
-    get_local   $push9=, 0
-    i32.lt_s    $push1=, $pop3, $pop9
-    br_if       0, $pop1        # 0: up to label1
+    call        something1@FUNCTION
+    i64.const   1234
+    i32.call    something2@FUNCTION
+    i32.const   0
+    call_indirect
+    i32.const   1
+    i32.add
+    tee_local   0
+    get_local   0
+    i32.lt_s
+    br_if       0        # 0: up to label1
 .LBB0_2:
     end_loop
     end_block                       # label0:
@@ -44,30 +44,30 @@ test0:
 # CHECK-LABEL: test0:
 # CHECK-NEXT:      .param      i32, i64
 # CHECK-NEXT:      .local      f32, f64
-# CHECK-NEXT:      get_local   $push0=, 2
-# CHECK-NEXT:      set_local   2, $pop0
-# CHECK-NEXT:      i32.const   $0=, -1
-# CHECK-NEXT:      f64.const   $3=, 0x1.999999999999ap1
-# CHECK-NEXT:      get_local   $push1=, 0
-# CHECK-NEXT:      f64.store   0($pop1):p2align=0, $3
+# CHECK-NEXT:      get_local   2
+# CHECK-NEXT:      set_local   2
+# CHECK-NEXT:      i32.const   -1
+# CHECK-NEXT:      f64.const   0x1.999999999999ap1
+# CHECK-NEXT:      get_local   0
+# CHECK-NEXT:      f64.store   0:p2align=0
 # CHECK-NEXT:      block
-# CHECK-NEXT:      i32.const   $push2=, 1
-# CHECK-NEXT:      get_local   $push7=, 0
-# CHECK-NEXT:      i32.ge_s    $push0=, $pop2, $pop7
-# CHECK-NEXT:      br_if 0,    $pop0        # 0: down to label0
+# CHECK-NEXT:      i32.const   1
+# CHECK-NEXT:      get_local   0
+# CHECK-NEXT:      i32.ge_s
+# CHECK-NEXT:      br_if 0            # 0: down to label0
 # CHECK-NEXT:  .LBB0_1:
 # CHECK-NEXT:      loop                    # label1:
 # CHECK-NEXT:      call        something1@FUNCTION
-# CHECK-NEXT:      i64.const   $push10=, 1234
-# CHECK-NEXT:      i32.call    $push8=, something2@FUNCTION
-# CHECK-NEXT:      i32.const   $push11=, 0
+# CHECK-NEXT:      i64.const   1234
+# CHECK-NEXT:      i32.call    something2@FUNCTION
+# CHECK-NEXT:      i32.const   0
 # CHECK-NEXT:      call_indirect
-# CHECK-NEXT:      i32.const   $push5=, 1
-# CHECK-NEXT:      i32.add     $push4=, $pop8, $pop5
-# CHECK-NEXT:      tee_local   $push3=, 0, $pop4
-# CHECK-NEXT:      get_local   $push9=, 0
-# CHECK-NEXT:      i32.lt_s    $push1=, $pop3, $pop9
-# CHECK-NEXT:      br_if 0,    $pop1        # 0: up to label1
+# CHECK-NEXT:      i32.const   1
+# CHECK-NEXT:      i32.add
+# CHECK-NEXT:      tee_local   0
+# CHECK-NEXT:      get_local   0
+# CHECK-NEXT:      i32.lt_s
+# CHECK-NEXT:      br_if 0            # 0: up to label1
 # CHECK-NEXT:  .LBB0_2:
 # CHECK-NEXT:      end_loop
 # CHECK-NEXT:      end_block                       # label0:
index 875477ce0d557211969bb5d000647e4ccca203c7..2f1c114164491c3fc5292cfb0b58754084e4b769 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc -filetype=obj %s -o - | llvm-readobj -r -expand-relocs | FileCheck %s
+; RUN: llc -filetype=obj -wasm-explicit-locals-codegen-test-mode %s -o - | llvm-readobj -r -expand-relocs | FileCheck %s
 
 target triple = "wasm32-unknown-unknown"
 
index c87700be79d7b6112a352d05703b640ff5831528..897a6e8b719a31fba3554fc6722e02065e6dfc0a 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc -filetype=obj %s -o %t.o
+; RUN: llc -filetype=obj -wasm-explicit-locals-codegen-test-mode %s -o %t.o
 ; RUN: obj2yaml %t.o | FileCheck %s
 ; RUN: llvm-objdump -t %t.o | FileCheck --check-prefix=CHECK-SYMS %s
 
@@ -47,10 +47,10 @@ entry:
 }
 
 ; CHECK:        - Type:            TYPE
-; CHECK-NEXT:     Signatures:      
+; CHECK-NEXT:     Signatures:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         ReturnType:      I32
-; CHECK-NEXT:         ParamTypes:      
+; CHECK-NEXT:         ParamTypes:
 ; CHECK-NEXT:   - Type:            IMPORT
 ; CHECK-NEXT:     Imports:
 ; CHECK-NEXT:       - Module:          env
@@ -68,13 +68,13 @@ entry:
 ; CHECK-NEXT:   - Type:            FUNCTION
 ; CHECK-NEXT:     FunctionTypes:   [ 0, 0, 0, 0, 0 ]
 ; CHECK-NEXT:   - Type:            ELEM
-; CHECK-NEXT:     Segments:        
-; CHECK-NEXT:       - Offset:          
+; CHECK-NEXT:     Segments:
+; CHECK-NEXT:       - Offset:
 ; CHECK-NEXT:           Opcode:          I32_CONST
 ; CHECK-NEXT:           Value:           1
 ; CHECK-NEXT:         Functions:       [ 0 ]
 ; CHECK-NEXT:   - Type:            CODE
-; CHECK-NEXT:     Relocations:     
+; CHECK-NEXT:     Relocations:
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_FUNCTION_INDEX_LEB
 ; CHECK-NEXT:         Index:           0
 ; CHECK-NEXT:         Offset:          0x00000009
@@ -93,40 +93,40 @@ entry:
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_TYPE_INDEX_LEB
 ; CHECK-NEXT:         Index:           0
 ; CHECK-NEXT:         Offset:          0x00000037
-; CHECK-NEXT:     Functions:       
+; CHECK-NEXT:     Functions:
 ; CHECK-NEXT:       - Index:           0
-; CHECK-NEXT:         Locals:          
+; CHECK-NEXT:         Locals:
 ; CHECK-NEXT:         Body:            41000B
 ; CHECK-NEXT:       - Index:           1
-; CHECK-NEXT:         Locals:          
+; CHECK-NEXT:         Locals:
 ; CHECK-NEXT:         Body:            1080808080000B
 ; CHECK-NEXT:       - Index:           2
-; CHECK-NEXT:         Locals:          
+; CHECK-NEXT:         Locals:
 ; CHECK-NEXT:         Body:            1080808080000B
 ; CHECK-NEXT:       - Index:           3
-; CHECK-NEXT:         Locals:          
+; CHECK-NEXT:         Locals:
 ; CHECK-NEXT:         Body:            410028028880808000118080808000000B
 ; CHECK-NEXT:       - Index:           4
-; CHECK-NEXT:         Locals:          
+; CHECK-NEXT:         Locals:
 ; CHECK-NEXT:         Body:            410028029080808000118080808000000B
 ; CHECK-NEXT:   - Type:            DATA
-; CHECK-NEXT:     Relocations:     
+; CHECK-NEXT:     Relocations:
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_I32
 ; CHECK-NEXT:         Index:           0
 ; CHECK-NEXT:         Offset:          0x0000000F
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_I32
 ; CHECK-NEXT:         Index:           3
 ; CHECK-NEXT:         Offset:          0x00000018
-; CHECK-NEXT:     Segments:        
+; CHECK-NEXT:     Segments:
 ; CHECK-NEXT:       - SectionOffset:   6
 ; CHECK-NEXT:         MemoryIndex:     0
-; CHECK-NEXT:         Offset:          
+; CHECK-NEXT:         Offset:
 ; CHECK-NEXT:           Opcode:          I32_CONST
 ; CHECK-NEXT:           Value:           0
 ; CHECK-NEXT:         Content:         '07000000'
 ; CHECK-NEXT:       - SectionOffset:   15
 ; CHECK-NEXT:         MemoryIndex:     0
-; CHECK-NEXT:         Offset:          
+; CHECK-NEXT:         Offset:
 ; CHECK-NEXT:           Opcode:          I32_CONST
 ; CHECK-NEXT:           Value:           8
 ; CHECK-NEXT:         Content:         '01000000'
@@ -139,7 +139,7 @@ entry:
 ; CHECK-NEXT:   - Type:            CUSTOM
 ; CHECK-NEXT:     Name:            linking
 ; CHECK-NEXT:     Version:         1
-; CHECK-NEXT:     SymbolTable:      
+; CHECK-NEXT:     SymbolTable:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Name:            foo
@@ -194,7 +194,7 @@ entry:
 ; CHECK-NEXT:         Flags:           [ BINDING_WEAK, VISIBILITY_HIDDEN ]
 ; CHECK-NEXT:         Segment:         0
 ; CHECK-NEXT:         Size:            4
-; CHECK-NEXT:     SegmentInfo:    
+; CHECK-NEXT:     SegmentInfo:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         Name:            .data.bar
 ; CHECK-NEXT:         Alignment:       8
index 0a6871f6f85710deebad120ad5e85d92f4c860ec..ca9581af83a01ee6a8c7fbcc9efaa74bd04126a5 100644 (file)
@@ -101,7 +101,7 @@ TEST(Disassembler, WebAssemblyTest) {
   InstSize = LLVMDisasmInstruction(DCR, BytesP, NumBytes, PC, OutString,
                                    OutStringSize);
   EXPECT_EQ(InstSize, 3U);
-  EXPECT_EQ(StringRef(OutString), "\ti64.load32_u\t16:p2align=1");
+  EXPECT_EQ(StringRef(OutString), "\ti64.load32_u\t16:p2align=1");
 
   LLVMDisasmDispose(DCR);
 }