[llvm] r276158 - GlobalISel: implement low-level type with just size & vector lanes.

Tim Northover via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 20 12:09:31 PDT 2016


Author: tnorthover
Date: Wed Jul 20 14:09:30 2016
New Revision: 276158

URL: http://llvm.org/viewvc/llvm-project?rev=276158&view=rev
Log:
GlobalISel: implement low-level type with just size & vector lanes.

This should be all the low-level instruction selection needs to determine how
to implement an operation, with the remaining context taken from the opcode
(e.g. G_ADD vs G_FADD) or other flags not based on type (e.g. fast-math).

Added:
    llvm/trunk/include/llvm/CodeGen/LowLevelType.h
    llvm/trunk/lib/CodeGen/LowLevelType.cpp
Modified:
    llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
    llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
    llvm/trunk/include/llvm/CodeGen/MachineInstr.h
    llvm/trunk/lib/CodeGen/CMakeLists.txt
    llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
    llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
    llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
    llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp
    llvm/trunk/lib/CodeGen/MIRParser/MILexer.h
    llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
    llvm/trunk/lib/CodeGen/MIRPrinter.cpp
    llvm/trunk/lib/CodeGen/MachineInstr.cpp
    llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp
    llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.h
    llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
    llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir
    llvm/trunk/test/CodeGen/AMDGPU/GlobalISel/amdgpu-irtranslator.ll
    llvm/trunk/test/CodeGen/MIR/X86/generic-instr-type-error.mir
    llvm/trunk/test/CodeGen/MIR/X86/generic-virtual-registers.mir

Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h Wed Jul 20 14:09:30 2016
@@ -17,6 +17,7 @@
 #include "llvm/CodeGen/GlobalISel/Types.h"
 
 #include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/LowLevelType.h"
 #include "llvm/IR/DebugLoc.h"
 
 namespace llvm {
@@ -96,7 +97,7 @@ public:
   /// \pre Ty == nullptr or isPreISelGenericOpcode(Opcode)
   ///
   /// \return The newly created instruction.
-  MachineInstr *buildInstr(unsigned Opcode, Type *Ty);
+  MachineInstr *buildInstr(unsigned Opcode, LLT Ty);
 
   /// Build and insert <empty> = \p Opcode [\p Ty] \p BB.
   ///
@@ -104,7 +105,7 @@ public:
   /// \pre Ty == nullptr or isPreISelGenericOpcode(Opcode)
   ///
   /// \return The newly created instruction.
-  MachineInstr *buildInstr(unsigned Opcode, Type *Ty, MachineBasicBlock &BB);
+  MachineInstr *buildInstr(unsigned Opcode, LLT Ty, MachineBasicBlock &BB);
 
   /// Build and insert \p Res<def> = \p Opcode [\p Ty] \p Op0, \p Op1.
   ///
@@ -112,7 +113,7 @@ public:
   /// \pre Ty == nullptr or isPreISelGenericOpcode(Opcode)
   ///
   /// \return The newly created instruction.
-  MachineInstr *buildInstr(unsigned Opcode, Type *Ty, unsigned Res,
+  MachineInstr *buildInstr(unsigned Opcode, LLT Ty, unsigned Res,
                            unsigned Op0, unsigned Op1);
 
   /// Build and insert \p Res<def> = \p Opcode \p Op0, \p Op1.

Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h Wed Jul 20 14:09:30 2016
@@ -291,9 +291,6 @@ protected:
   /// Total number of register banks.
   unsigned NumRegBanks;
 
-  /// Mapping from MVT::SimpleValueType to register banks.
-  std::unique_ptr<const RegisterBank *[]> VTToRegBank;
-
   /// Create a RegisterBankInfo that can accomodate up to \p NumRegBanks
   /// RegisterBank instances.
   ///
@@ -325,14 +322,6 @@ protected:
   /// It also adjusts the size of the register bank to reflect the maximal
   /// size of a value that can be hold into that register bank.
   ///
-  /// If \p AddTypeMapping is true, this method also records what types can
-  /// be mapped to \p ID. Although this done by default, targets may want to
-  /// disable it, espicially if a given type may be mapped on different
-  /// register bank. Indeed, in such case, this method only records the
-  /// first register bank where the type matches.
-  /// This information is only used to provide default mapping
-  /// (see getInstrMappingImpl).
-  ///
   /// \note This method does *not* add the super classes of \p RCId.
   /// The rationale is if \p ID covers the registers of \p RCId, that
   /// does not necessarily mean that \p ID covers the set of registers
@@ -343,8 +332,7 @@ protected:
   ///
   /// \todo TableGen should just generate the BitSet vector for us.
   void addRegBankCoverage(unsigned ID, unsigned RCId,
-                          const TargetRegisterInfo &TRI,
-                          bool AddTypeMapping = true);
+                          const TargetRegisterInfo &TRI);
 
   /// Get the register bank identified by \p ID.
   RegisterBank &getRegBank(unsigned ID) {
@@ -352,36 +340,6 @@ protected:
     return RegBanks[ID];
   }
 
-  /// Get the register bank that has been recorded to cover \p SVT.
-  const RegisterBank *getRegBankForType(MVT::SimpleValueType SVT) const {
-    if (!VTToRegBank)
-      return nullptr;
-    assert(SVT < MVT::SimpleValueType::LAST_VALUETYPE && "Out-of-bound access");
-    return VTToRegBank.get()[SVT];
-  }
-
-  /// Record \p RegBank as the register bank that covers \p SVT.
-  /// If a record was already set for \p SVT, the mapping is not
-  /// updated, unless \p Force == true
-  ///
-  /// \post if getRegBankForType(SVT)\@pre == nullptr then
-  ///                       getRegBankForType(SVT) == &RegBank
-  /// \post if Force == true then getRegBankForType(SVT) == &RegBank
-  void recordRegBankForType(const RegisterBank &RegBank,
-                            MVT::SimpleValueType SVT, bool Force = false) {
-    if (!VTToRegBank) {
-      VTToRegBank.reset(
-          new const RegisterBank *[MVT::SimpleValueType::LAST_VALUETYPE]);
-      std::fill(&VTToRegBank[0],
-                &VTToRegBank[MVT::SimpleValueType::LAST_VALUETYPE], nullptr);
-    }
-    assert(SVT < MVT::SimpleValueType::LAST_VALUETYPE && "Out-of-bound access");
-    // If we want to override the mapping or the mapping does not exits yet,
-    // set the register bank for SVT.
-    if (Force || !getRegBankForType(SVT))
-      VTToRegBank.get()[SVT] = &RegBank;
-  }
-
   /// Try to get the mapping of \p MI.
   /// See getInstrMapping for more details on what a mapping represents.
   ///

Added: llvm/trunk/include/llvm/CodeGen/LowLevelType.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LowLevelType.h?rev=276158&view=auto
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/LowLevelType.h (added)
+++ llvm/trunk/include/llvm/CodeGen/LowLevelType.h Wed Jul 20 14:09:30 2016
@@ -0,0 +1,187 @@
+//== llvm/CodeGen/GlobalISel/LowLevelType.h -------------------- -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// Implement a low-level type suitable for MachineInstr level instruction
+/// selection.
+///
+/// For a type attached to a MachineInstr, we only care about 2 details: total
+/// size and the number of vector lanes (if any). Accordingly, there are 3
+/// possible valid type-kinds:
+///
+///    * `unsized` for labels etc
+///    * `sN` for scalars and aggregates
+///    * `<N x sM>` for vectors, which must have at least 2 elements.
+///
+/// Other information required for correct selection is expected to be carried
+/// by the opcode, or non-type flags. For example the distinction between G_ADD
+/// and G_FADD for int/float or fast-math flags.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_GLOBALISEL_LOWLEVELTYPE_H
+#define LLVM_CODEGEN_GLOBALISEL_LOWLEVELTYPE_H
+
+#include <cassert>
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/CodeGen/ValueTypes.h"
+
+namespace llvm {
+
+class LLVMContext;
+class Type;
+class raw_ostream;
+
+class LLT {
+public:
+  enum TypeKind : uint16_t {
+    Invalid,
+    Scalar,
+    Vector,
+    Unsized,
+  };
+
+  /// \brief get a low-level scalar or aggregate "bag of bits".
+  static LLT scalar(unsigned SizeInBits) {
+    return LLT{Scalar, 1, SizeInBits};
+  }
+
+  /// \brief get a low-level vector of some number of elements and element
+  /// width. \p NumElements must be at least 2.
+  static LLT vector(uint16_t NumElements, unsigned ScalarSizeInBits) {
+    assert(NumElements > 1 && "invalid number of vector elements");
+    return LLT{Vector, NumElements, ScalarSizeInBits};
+  }
+
+  /// \brief get a low-level vector of some number of elements and element
+  /// type
+  static LLT vector(uint16_t NumElements, LLT ScalarTy) {
+    assert(NumElements > 1 && "invalid number of vector elements");
+    assert(ScalarTy.isScalar() && "invalid vector element type");
+    return LLT{Vector, NumElements, ScalarTy.getSizeInBits()};
+  }
+
+  /// \brief get an unsized but valid low-level type (e.g. for a label).
+  static LLT unsized() {
+    return LLT{Unsized, 1, 0};
+  }
+
+  explicit LLT(TypeKind Kind, uint16_t NumElements, unsigned ScalarSizeInBits)
+    : ScalarSize(ScalarSizeInBits), NumElements(NumElements), Kind(Kind) {
+    assert((Kind != Vector || NumElements > 1) &&
+           "invalid number of vector elements");
+  }
+
+  explicit LLT() : ScalarSize(0), NumElements(0), Kind(Invalid) {}
+
+  /// \brief construct a low-level type based on an LLVM type.
+  explicit LLT(const Type &Ty);
+
+  bool isValid() const { return Kind != Invalid; }
+
+  bool isScalar() const { return Kind == Scalar; }
+
+  bool isVector() const { return Kind == Vector; }
+
+  bool isSized() const { return Kind == Scalar || Kind == Vector; }
+
+  /// \brief Returns the number of elements in a vector LLT. Must only be called
+  /// on vector types.
+  uint16_t getNumElements() const {
+    assert(isVector() && "cannot get number of elements on scalar/aggregate");
+    return NumElements;
+  }
+
+  /// \brief Returns the total size of the type. Must only be called on sized
+  /// types.
+  unsigned getSizeInBits() const {
+    assert(isSized() && "attempt to get size of unsized type");
+    return ScalarSize * NumElements;
+  }
+
+  unsigned getScalarSizeInBits() const {
+    assert(isSized() && "cannot get size of this type");
+    return ScalarSize;
+  }
+
+  /// \brief Returns the vector's element type. Only valid for vector types.
+  LLT getElementType() const {
+    assert(isVector() && "cannot get element type of scalar/aggregate");
+    return scalar(ScalarSize);
+  }
+
+  /// \brief get a low-level type with half the size of the original, by halving
+  /// the size of the scalar type involved. For example `s32` will become
+  /// `s16`, `<2 x s32>` will become `<2 x s16>`.
+  LLT halfScalarSize() const {
+    assert(isSized() && "cannot change size of this type");
+    return LLT{Kind, NumElements, ScalarSize / 2};
+  }
+
+  /// \brief get a low-level type with twice the size of the original, by
+  /// doubling the size of the scalar type involved. For example `s32` will
+  /// become `s64`, `<2 x s32>` will become `<2 x s64>`.
+  LLT doubleScalarSize() const {
+    assert(isSized() && "cannot change size of this type");
+    return LLT{Kind, NumElements, ScalarSize * 2};
+  }
+
+  /// \brief get a low-level type with half the size of the original, by halving
+  /// the number of vector elements of the scalar type involved. The source must
+  /// be a vector type with an even number of elements. For example `<4 x
+  /// s32>` will become `<2 x s32>`, `<2 x s32>` will become `s32`.
+  LLT halfElements() const {
+    assert(isVector() && NumElements % 2 == 0 && "cannot half odd vector");
+    if (NumElements == 2)
+      return scalar(ScalarSize);
+
+    return LLT{Vector, static_cast<uint16_t>(NumElements / 2), ScalarSize};
+  }
+
+  /// \brief get a low-level type with twice the size of the original, by
+  /// doubling the number of vector elements of the scalar type involved. The
+  /// source must be a vector type. For example `<2 x s32>` will become `<4 x
+  /// s32>`. Doubling the number of elements in sN produces <2 x sN>.
+  LLT doubleElements() const {
+    return LLT{Vector, static_cast<uint16_t>(NumElements * 2), ScalarSize};
+  }
+
+  void print(raw_ostream &OS) const;
+
+  bool operator ==(const LLT &RHS) const {
+    return Kind == RHS.Kind && ScalarSize == RHS.ScalarSize &&
+           NumElements == RHS.NumElements;
+  }
+
+  friend struct DenseMapInfo<LLT>;
+private:
+  unsigned ScalarSize;
+  uint16_t NumElements;
+  TypeKind Kind;
+};
+
+template<> struct DenseMapInfo<LLT> {
+  static inline LLT getEmptyKey() {
+    return LLT{LLT::Invalid, 0, -1u};
+  }
+  static inline LLT getTombstoneKey() {
+    return LLT{LLT::Invalid, 0, -2u};
+  }
+  static inline unsigned getHashValue(const LLT &Ty) {
+    uint64_t Val = ((uint64_t)Ty.ScalarSize << 32) |
+                   ((uint64_t)Ty.NumElements << 16) | (uint64_t)Ty.Kind;
+    return DenseMapInfo<uint64_t>::getHashValue(Val);
+  }
+  static bool isEqual(const LLT &LHS, const LLT &RHS) {
+    return LHS == RHS;
+  }
+};
+
+}
+
+#endif

Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineInstr.h?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineInstr.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineInstr.h Wed Jul 20 14:09:30 2016
@@ -23,6 +23,9 @@
 #include "llvm/ADT/iterator_range.h"
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/CodeGen/MachineOperand.h"
+#ifdef LLVM_BUILD_GLOBAL_ISEL
+#include "llvm/CodeGen/LowLevelType.h"
+#endif
 #include "llvm/IR/DebugLoc.h"
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/MC/MCInstrDesc.h"
@@ -39,9 +42,6 @@ class DIExpression;
 class TargetInstrInfo;
 class TargetRegisterClass;
 class TargetRegisterInfo;
-#ifdef LLVM_BUILD_GLOBAL_ISEL
-class Type;
-#endif
 class MachineFunction;
 class MachineMemOperand;
 
@@ -108,9 +108,9 @@ private:
 
 #ifdef LLVM_BUILD_GLOBAL_ISEL
   /// Type of the instruction in case of a generic opcode.
-  /// \invariant This must be nullptr is getOpcode() is not
+  /// \invariant This must be LLT{} if getOpcode() is not
   /// in the range of generic opcodes.
-  Type *Ty;
+  LLT Ty;
 #endif
 
   MachineInstr(const MachineInstr&) = delete;
@@ -189,8 +189,8 @@ public:
 
   /// Set the type of the instruction.
   /// \pre getOpcode() is in the range of the generic opcodes.
-  void setType(Type *Ty);
-  Type *getType() const;
+  void setType(LLT Ty);
+  LLT getType() const;
 
   /// Return true if MI is in a bundle (but not the first MI in a bundle).
   ///

Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CMakeLists.txt (original)
+++ llvm/trunk/lib/CodeGen/CMakeLists.txt Wed Jul 20 14:09:30 2016
@@ -48,6 +48,7 @@ add_llvm_library(LLVMCodeGen
   LiveVariables.cpp
   LLVMTargetMachine.cpp
   LocalStackSlotAllocation.cpp
+  LowLevelType.cpp
   LowerEmuTLS.cpp
   MachineBasicBlock.cpp
   MachineBlockFrequencyInfo.cpp

Modified: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp Wed Jul 20 14:09:30 2016
@@ -69,7 +69,7 @@ bool IRTranslator::translateBinaryOp(uns
   unsigned Op0 = getOrCreateVReg(*Inst.getOperand(0));
   unsigned Op1 = getOrCreateVReg(*Inst.getOperand(1));
   unsigned Res = getOrCreateVReg(Inst);
-  MIRBuilder.buildInstr(Opcode, Inst.getType(), Res, Op0, Op1);
+  MIRBuilder.buildInstr(Opcode, LLT{*Inst.getType()}, Res, Op0, Op1);
   return true;
 }
 
@@ -88,7 +88,7 @@ bool IRTranslator::translateBr(const Ins
   if (BrInst.isUnconditional()) {
     const BasicBlock &BrTgt = *cast<BasicBlock>(BrInst.getOperand(0));
     MachineBasicBlock &TgtBB = getOrCreateBB(BrTgt);
-    MIRBuilder.buildInstr(TargetOpcode::G_BR, BrTgt.getType(), TgtBB);
+    MIRBuilder.buildInstr(TargetOpcode::G_BR, LLT{*BrTgt.getType()}, TgtBB);
   } else {
     assert(0 && "Not yet implemented");
   }

Modified: llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp Wed Jul 20 14:09:30 2016
@@ -56,9 +56,9 @@ MachineBasicBlock::iterator MachineIRBui
 //------------------------------------------------------------------------------
 // Build instruction variants.
 //------------------------------------------------------------------------------
-MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, Type *Ty) {
+MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, LLT Ty) {
   MachineInstr *NewMI = BuildMI(getMF(), DL, getTII().get(Opcode));
-  if (Ty) {
+  if (Ty.isValid()) {
     assert(isPreISelGenericOpcode(Opcode) &&
            "Only generic instruction can have a type");
     NewMI->setType(Ty);
@@ -71,10 +71,10 @@ MachineInstr *MachineIRBuilder::buildIns
 
 MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, unsigned Res,
                                            unsigned Op0, unsigned Op1) {
-  return buildInstr(Opcode, nullptr, Res, Op0, Op1);
+  return buildInstr(Opcode, LLT{}, Res, Op0, Op1);
 }
 
-MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, Type *Ty,
+MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, LLT Ty,
                                            unsigned Res, unsigned Op0,
                                            unsigned Op1) {
   MachineInstr *NewMI = buildInstr(Opcode, Ty);
@@ -87,16 +87,16 @@ MachineInstr *MachineIRBuilder::buildIns
 
 MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, unsigned Res,
                                            unsigned Op0) {
-  MachineInstr *NewMI = buildInstr(Opcode, nullptr);
+  MachineInstr *NewMI = buildInstr(Opcode, LLT{});
   MachineInstrBuilder(getMF(), NewMI).addReg(Res, RegState::Define).addReg(Op0);
   return NewMI;
 }
 
 MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode) {
-  return buildInstr(Opcode, nullptr);
+  return buildInstr(Opcode, LLT{});
 }
 
-MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, Type *Ty,
+MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, LLT Ty,
                                            MachineBasicBlock &BB) {
   MachineInstr *NewMI = buildInstr(Opcode, Ty);
   MachineInstrBuilder(getMF(), NewMI).addMBB(&BB);

Modified: llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp Wed Jul 20 14:09:30 2016
@@ -65,8 +65,7 @@ void RegisterBankInfo::createRegisterBan
 }
 
 void RegisterBankInfo::addRegBankCoverage(unsigned ID, unsigned RCId,
-                                          const TargetRegisterInfo &TRI,
-                                          bool AddTypeMapping) {
+                                          const TargetRegisterInfo &TRI) {
   RegisterBank &RB = getRegBank(ID);
   unsigned NbOfRegClasses = TRI.getNumRegClasses();
 
@@ -98,13 +97,6 @@ void RegisterBankInfo::addRegBankCoverag
     // Remember the biggest size in bits.
     MaxSize = std::max(MaxSize, CurRC.getSize() * 8);
 
-    // If we have been asked to record the type supported by this
-    // register bank, do it now.
-    if (AddTypeMapping)
-      for (MVT::SimpleValueType SVT :
-           make_range(CurRC.vt_begin(), CurRC.vt_end()))
-        recordRegBankForType(getRegBank(ID), SVT);
-
     // Walk through all sub register classes and push them into the worklist.
     bool First = true;
     for (BitMaskClassIterator It(CurRC.getSubClassMask(), TRI); It.isValid();
@@ -240,30 +232,18 @@ RegisterBankInfo::getInstrMappingImpl(co
       // the register bank from the encoding constraints.
       CurRegBank = getRegBankFromConstraints(MI, OpIdx, TII, TRI);
       if (!CurRegBank) {
-        // Check if we can deduce the register bank from the type of
-        // the instruction.
-        Type *MITy = MI.getType();
-        if (MITy)
-          CurRegBank = getRegBankForType(
-              MVT::getVT(MITy, /*HandleUnknown*/ true).SimpleTy);
-        if (!CurRegBank)
-          // Use the current assigned register bank.
-          // That may not make much sense though.
-          CurRegBank = AltRegBank;
-        if (!CurRegBank) {
-          // All our attempts failed, give up.
-          CompleteMapping = false;
-
-          if (!isCopyLike)
-            // MI does not carry enough information to guess the mapping.
-            return InstructionMapping();
-
-          // For copies, we want to keep interating to find a register
-          // bank for the other operands if we did not find one yet.
-          if (RegBank)
-            break;
-          continue;
-        }
+        // All our attempts failed, give up.
+        CompleteMapping = false;
+
+        if (!isCopyLike)
+          // MI does not carry enough information to guess the mapping.
+          return InstructionMapping();
+
+        // For copies, we want to keep interating to find a register
+        // bank for the other operands if we did not find one yet.
+        if (RegBank)
+          break;
+        continue;
       }
     }
     RegBank = CurRegBank;

Added: llvm/trunk/lib/CodeGen/LowLevelType.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LowLevelType.cpp?rev=276158&view=auto
==============================================================================
--- llvm/trunk/lib/CodeGen/LowLevelType.cpp (added)
+++ llvm/trunk/lib/CodeGen/LowLevelType.cpp Wed Jul 20 14:09:30 2016
@@ -0,0 +1,46 @@
+//===-- llvm/CodeGen/GlobalISel/LowLevelType.cpp --------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file This file implements the more header-heavy bits of the LLT class to
+/// avoid polluting users' namespaces.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/LowLevelType.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+LLT::LLT(const Type &Ty) {
+  if (auto VTy = dyn_cast<VectorType>(&Ty)) {
+    ScalarSize = VTy->getElementType()->getPrimitiveSizeInBits();
+    NumElements = VTy->getNumElements();
+    Kind = NumElements == 1 ? Scalar : Vector;
+  } else if (Ty.isSized()) {
+    // Aggregates are no different from real scalars as far as GlobalISel is
+    // concerned.
+    Kind = Scalar;
+    ScalarSize = Ty.getPrimitiveSizeInBits();
+    NumElements = 1;
+  } else {
+    Kind = Unsized;
+    ScalarSize = NumElements = 0;
+  }
+}
+
+void LLT::print(raw_ostream &OS) const {
+  if (isVector())
+    OS << "<" << NumElements << " x s" << ScalarSize << ">";
+  else if (isSized())
+    OS << "s" << ScalarSize;
+  else if (isValid())
+    OS << "unsized";
+  else
+    llvm_unreachable("trying to print an invalid type");
+}

Modified: llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp Wed Jul 20 14:09:30 2016
@@ -173,14 +173,16 @@ static Cursor lexName(Cursor C, MIToken
   return C;
 }
 
-static Cursor maybeLexIntegerType(Cursor C, MIToken &Token) {
-  if (C.peek() != 'i' || !isdigit(C.peek(1)))
+static Cursor maybeLexIntegerOrScalarType(Cursor C, MIToken &Token) {
+  if ((C.peek() != 'i' && C.peek() != 's') || !isdigit(C.peek(1)))
     return None;
+  char Kind = C.peek();
   auto Range = C;
   C.advance(); // Skip 'i'
   while (isdigit(C.peek()))
     C.advance();
-  Token.reset(MIToken::IntegerType, Range.upto(C));
+  Token.reset(Kind == 'i' ? MIToken::IntegerType : MIToken::ScalarType,
+              Range.upto(C));
   return C;
 }
 
@@ -566,7 +568,7 @@ StringRef llvm::lexMIToken(StringRef Sou
     return C.remaining();
   }
 
-  if (Cursor R = maybeLexIntegerType(C, Token))
+  if (Cursor R = maybeLexIntegerOrScalarType(C, Token))
     return R.remaining();
   if (Cursor R = maybeLexMachineBasicBlock(C, Token, ErrorCallback))
     return R.remaining();

Modified: llvm/trunk/lib/CodeGen/MIRParser/MILexer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MILexer.h?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MILexer.h (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.h Wed Jul 20 14:09:30 2016
@@ -102,6 +102,7 @@ struct MIToken {
     NamedRegister,
     MachineBasicBlockLabel,
     MachineBasicBlock,
+    ScalarType,
     StackObject,
     FixedStackObject,
     NamedGlobalValue,

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp Wed Jul 20 14:09:30 2016
@@ -130,10 +130,8 @@ public:
   bool parseIRConstant(StringRef::iterator Loc, StringRef Source,
                        const Constant *&C);
   bool parseIRConstant(StringRef::iterator Loc, const Constant *&C);
-  bool parseIRType(StringRef::iterator Loc, StringRef Source, unsigned &Read,
-                   Type *&Ty);
-  // \p MustBeSized defines whether or not \p Ty must be sized.
-  bool parseIRType(StringRef::iterator Loc, Type *&Ty, bool MustBeSized = true);
+  bool parseLowLevelType(StringRef::iterator Loc, LLT &Ty,
+                         bool MustBeSized = true);
   bool parseTypedImmediateOperand(MachineOperand &Dest);
   bool parseFPImmediateOperand(MachineOperand &Dest);
   bool parseMBBReference(MachineBasicBlock *&MBB);
@@ -597,11 +595,11 @@ bool MIParser::parse(MachineInstr *&MI)
   if (Token.isError() || parseInstruction(OpCode, Flags))
     return true;
 
-  Type *Ty = nullptr;
+  LLT Ty{};
   if (isPreISelGenericOpcode(OpCode)) {
     // For generic opcode, a type is mandatory.
     auto Loc = Token.location();
-    if (parseIRType(Loc, Ty))
+    if (parseLowLevelType(Loc, Ty))
       return true;
   }
 
@@ -660,7 +658,7 @@ bool MIParser::parse(MachineInstr *&MI)
   // TODO: Check for extraneous machine operands.
   MI = MF.CreateMachineInstr(MCID, DebugLocation, /*NoImplicit=*/true);
   MI->setFlags(Flags);
-  if (Ty)
+  if (Ty.isValid())
     MI->setType(Ty);
   for (const auto &Operand : Operands)
     MI->addOperand(MF, Operand.Operand);
@@ -1028,35 +1026,44 @@ bool MIParser::parseIRConstant(StringRef
   return false;
 }
 
-bool MIParser::parseIRType(StringRef::iterator Loc, StringRef StringValue,
-                           unsigned &Read, Type *&Ty) {
-  auto Source = StringValue.str(); // The source has to be null terminated.
-  SMDiagnostic Err;
-  Ty = parseTypeAtBeginning(Source.c_str(), Read, Err,
-                            *MF.getFunction()->getParent(), &PFS.IRSlots);
-  if (!Ty)
-    return error(Loc + Err.getColumnNo(), Err.getMessage());
-  return false;
-}
+bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty,
+                                 bool MustBeSized) {
+  if (Token.is(MIToken::Identifier) && Token.stringValue() == "unsized") {
+    if (MustBeSized)
+      return error(Loc, "expected sN or <N x sM> for sized GlobalISel type");
+    lex();
+    Ty = LLT::unsized();
+    return false;
+  } else if (Token.is(MIToken::ScalarType)) {
+    Ty = LLT::scalar(APSInt(Token.range().drop_front()).getZExtValue());
+    lex();
+    return false;
+  }
+
+  // Now we're looking for a vector.
+  if (Token.isNot(MIToken::less))
+    return error(Loc, "expected unsized, sN or <N x sM> for GlobalISel type");
+  lex();
+
+  if (Token.isNot(MIToken::IntegerLiteral))
+    return error(Loc, "expected <N x sM> for vctor type");
+  uint64_t NumElements = Token.integerValue().getZExtValue();
+  lex();
+
+  if (Token.isNot(MIToken::Identifier) || Token.stringValue() != "x")
+    return error(Loc, "expected '<N x sM>' for vector type");
+  lex();
+
+  if (Token.isNot(MIToken::ScalarType))
+    return error(Loc, "expected '<N x sM>' for vector type");
+  uint64_t ScalarSize = APSInt(Token.range().drop_front()).getZExtValue();
+  lex();
+
+  if (Token.isNot(MIToken::greater))
+    return error(Loc, "expected '<N x sM>' for vector type");
+  lex();
 
-bool MIParser::parseIRType(StringRef::iterator Loc, Type *&Ty,
-                           bool MustBeSized) {
-  // At this point we enter in the IR world, i.e., to get the correct type,
-  // we need to hand off the whole string, not just the current token.
-  // E.g., <4 x i64> would give '<' as a token and there is not much
-  // the IR parser can do with that.
-  unsigned Read = 0;
-  if (parseIRType(Loc, StringRef(Loc), Read, Ty))
-    return true;
-  // The type must be sized, otherwise there is not much the backend
-  // can do with it.
-  if (MustBeSized && !Ty->isSized())
-    return error("expected a sized type");
-  // The next token is Read characters from the Loc.
-  // However, the current location is not Loc, but Loc + the length of Token.
-  // Therefore, subtract the length of Token (range().end() - Loc) to the
-  // number of characters to skip before the next token.
-  lex(Read - (Token.range().end() - Loc));
+  Ty = LLT::vector(NumElements, ScalarSize);
   return false;
 }
 

Modified: llvm/trunk/lib/CodeGen/MIRPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRPrinter.cpp?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRPrinter.cpp Wed Jul 20 14:09:30 2016
@@ -565,9 +565,9 @@ void MIPrinter::print(const MachineInstr
     OS << "frame-setup ";
   OS << TII->getName(MI.getOpcode());
   if (isPreISelGenericOpcode(MI.getOpcode())) {
-    assert(MI.getType() && "Generic instructions must have a type");
+    assert(MI.getType().isValid() && "Generic instructions must have a type");
     OS << ' ';
-    MI.getType()->print(OS, /*IsForDebug*/ false, /*NoDetails*/ true);
+    MI.getType().print(OS);
   }
   if (I < E)
     OS << ' ';

Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Wed Jul 20 14:09:30 2016
@@ -656,7 +656,7 @@ MachineInstr::MachineInstr(MachineFuncti
       debugLoc(std::move(dl))
 #ifdef LLVM_BUILD_GLOBAL_ISEL
       ,
-      Ty(nullptr)
+      Ty(LLT{})
 #endif
 {
   assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
@@ -680,7 +680,7 @@ MachineInstr::MachineInstr(MachineFuncti
       MemRefs(MI.MemRefs), debugLoc(MI.getDebugLoc())
 #ifdef LLVM_BUILD_GLOBAL_ISEL
       ,
-      Ty(nullptr)
+      Ty(LLT{})
 #endif
 {
   assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
@@ -710,18 +710,18 @@ MachineRegisterInfo *MachineInstr::getRe
 // The proper implementation is WIP and is tracked here:
 // PR26576.
 #ifndef LLVM_BUILD_GLOBAL_ISEL
-void MachineInstr::setType(Type *Ty) {}
+void MachineInstr::setType(LLT Ty) {}
 
-Type *MachineInstr::getType() const { return nullptr; }
+LLT MachineInstr::getType() const { return LLT{}; }
 
 #else
-void MachineInstr::setType(Type *Ty) {
-  assert((!Ty || isPreISelGenericOpcode(getOpcode())) &&
+void MachineInstr::setType(LLT Ty) {
+  assert((!Ty.isValid() || isPreISelGenericOpcode(getOpcode())) &&
          "Non generic instructions are not supposed to be typed");
   this->Ty = Ty;
 }
 
-Type *MachineInstr::getType() const { return Ty; }
+LLT MachineInstr::getType() const { return Ty; }
 #endif // LLVM_BUILD_GLOBAL_ISEL
 
 /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in
@@ -1724,9 +1724,9 @@ void MachineInstr::print(raw_ostream &OS
   else
     OS << "UNKNOWN";
 
-  if (getType()) {
+  if (getType().isValid()) {
     OS << ' ';
-    getType()->print(OS, /*IsForDebug*/ false, /*NoDetails*/ true);
+    getType().print(OS);
     OS << ' ';
   }
 

Modified: llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp Wed Jul 20 14:09:30 2016
@@ -155,6 +155,7 @@ AArch64RegisterBankInfo::getInstrAlterna
 void AArch64RegisterBankInfo::applyMappingImpl(
     const OperandsMapper &OpdMapper) const {
   switch (OpdMapper.getMI().getOpcode()) {
+  case TargetOpcode::G_ADD:
   case TargetOpcode::G_OR: {
     // Those ID must match getInstrAlternativeMappings.
     assert((OpdMapper.getInstrMapping().getID() == 1 ||
@@ -166,3 +167,27 @@ void AArch64RegisterBankInfo::applyMappi
     llvm_unreachable("Don't know how to handle that operation");
   }
 }
+
+RegisterBankInfo::InstructionMapping
+AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
+  RegisterBankInfo::InstructionMapping Mapping = getInstrMappingImpl(MI);
+  if (Mapping.isValid())
+    return Mapping;
+
+  // As a top-level guess, vectors go in FPRs, scalars in GPRs. Obviously this
+  // won't work for normal floating-point types (or NZCV). When such
+  // instructions exist we'll need to look at the MI's opcode.
+  LLT Ty = MI.getType();
+  unsigned BankID;
+  if (Ty.isVector())
+    BankID = AArch64::FPRRegBankID;
+  else
+    BankID = AArch64::GPRRegBankID;
+
+  Mapping = InstructionMapping{1, 1, MI.getNumOperands()};
+  int Size = Ty.isSized() ? Ty.getSizeInBits() : 0;
+  for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx)
+    Mapping.setOperandMapping(Idx, Size, getRegBank(BankID));
+
+  return Mapping;
+}

Modified: llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.h?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.h (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.h Wed Jul 20 14:09:30 2016
@@ -64,6 +64,8 @@ public:
   /// Alternative in the sense different from getInstrMapping.
   InstructionMappings
   getInstrAlternativeMappings(const MachineInstr &MI) const override;
+
+  InstructionMapping getInstrMapping(const MachineInstr &MI) const override;
 };
 } // End llvm namespace.
 #endif

Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll Wed Jul 20 14:09:30 2016
@@ -9,7 +9,7 @@ target triple = "aarch64-apple-ios"
 ; CHECK: name: addi64
 ; CHECK: [[ARG1:%[0-9]+]](64) = COPY %x0
 ; CHECK-NEXT: [[ARG2:%[0-9]+]](64) = COPY %x1
-; CHECK-NEXT: [[RES:%[0-9]+]](64) = G_ADD i64 [[ARG1]], [[ARG2]]
+; CHECK-NEXT: [[RES:%[0-9]+]](64) = G_ADD s64 [[ARG1]], [[ARG2]]
 ; CHECK-NEXT: %x0 = COPY [[RES]]
 ; CHECK-NEXT: RET_ReallyLR implicit %x0 
 define i64 @addi64(i64 %arg1, i64 %arg2) {
@@ -28,7 +28,7 @@ define i64 @addi64(i64 %arg1, i64 %arg2)
 ; CHECK-NEXT: successors: %[[END:[0-9a-zA-Z._-]+]]({{0x[a-f0-9]+ / 0x[a-f0-9]+}} = 100.00%)
 ;
 ; Check that we emit the correct branch.
-; CHECK: G_BR label %[[END]]
+; CHECK: G_BR unsized %[[END]]
 ;
 ; Check that end contains the return instruction.
 ; CHECK: [[END]]:
@@ -43,7 +43,7 @@ end:
 ; CHECK: name: ori64
 ; CHECK: [[ARG1:%[0-9]+]](64) = COPY %x0
 ; CHECK-NEXT: [[ARG2:%[0-9]+]](64) = COPY %x1
-; CHECK-NEXT: [[RES:%[0-9]+]](64) = G_OR i64 [[ARG1]], [[ARG2]]
+; CHECK-NEXT: [[RES:%[0-9]+]](64) = G_OR s64 [[ARG1]], [[ARG2]]
 ; CHECK-NEXT: %x0 = COPY [[RES]]
 ; CHECK-NEXT: RET_ReallyLR implicit %x0
 define i64 @ori64(i64 %arg1, i64 %arg2) {
@@ -54,7 +54,7 @@ define i64 @ori64(i64 %arg1, i64 %arg2)
 ; CHECK: name: ori32
 ; CHECK: [[ARG1:%[0-9]+]](32) = COPY %w0
 ; CHECK-NEXT: [[ARG2:%[0-9]+]](32) = COPY %w1
-; CHECK-NEXT: [[RES:%[0-9]+]](32) = G_OR i32 [[ARG1]], [[ARG2]]
+; CHECK-NEXT: [[RES:%[0-9]+]](32) = G_OR s32 [[ARG1]], [[ARG2]]
 ; CHECK-NEXT: %w0 = COPY [[RES]]
 ; CHECK-NEXT: RET_ReallyLR implicit %w0
 define i32 @ori32(i32 %arg1, i32 %arg2) {

Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir Wed Jul 20 14:09:30 2016
@@ -68,8 +68,8 @@ registers:
 body: |
   bb.0.entry:
     liveins: %x0
-    ; CHECK:      %0(32) = G_ADD i32 %x0
-    %0(32) = G_ADD i32 %x0, %x0
+    ; CHECK:      %0(32) = G_ADD s32 %w0
+    %0(32) = G_ADD s32 %w0, %w0
 ...
 
 ---
@@ -85,8 +85,8 @@ registers:
 body: |
   bb.0.entry:
     liveins: %d0
-    ; CHECK:      %0(32) = G_ADD <2 x i32> %d0
-    %0(32) = G_ADD <2 x i32> %d0, %d0
+    ; CHECK:      %0(64) = G_ADD <2 x s32> %d0
+    %0(64) = G_ADD <2 x s32> %d0, %d0
 ...
 
 ---
@@ -107,9 +107,9 @@ body: |
     liveins: %s0, %x0
     ; CHECK:           %0(32) = COPY %s0
     ; CHECK-NEXT:      %2(32) = COPY %0
-    ; CHECK-NEXT:      %1(32) = G_ADD i32 %2, %x0
+    ; CHECK-NEXT:      %1(32) = G_ADD s32 %2, %w0
     %0(32) = COPY %s0
-    %1(32) = G_ADD i32 %0, %x0
+    %1(32) = G_ADD s32 %0, %w0
 ...
 
 # Check that we repair the assignment for %0 differently for both uses.
@@ -129,9 +129,9 @@ body: |
     ; CHECK:           %0(32) = COPY %s0
     ; CHECK-NEXT:      %2(32) = COPY %0
     ; CHECK-NEXT:      %3(32) = COPY %0
-    ; CHECK-NEXT:      %1(32) = G_ADD i32 %2, %3
+    ; CHECK-NEXT:      %1(32) = G_ADD s32 %2, %3
     %0(32) = COPY %s0
-    %1(32) = G_ADD i32 %0, %0
+    %1(32) = G_ADD s32 %0, %0
 ...
 
 ---
@@ -152,10 +152,10 @@ body: |
   bb.0.entry:
     liveins: %w0
     ; CHECK:           %0(32) = COPY %w0
-    ; CHECK-NEXT:      %2(32) = G_ADD i32 %0, %w0
+    ; CHECK-NEXT:      %2(32) = G_ADD s32 %0, %w0
     ; CHECK-NEXT:      %1(32) = COPY %2
     %0(32) = COPY %w0
-    %1(32) = G_ADD i32 %0, %w0
+    %1(32) = G_ADD s32 %0, %w0
 ...
 
 ---
@@ -187,7 +187,7 @@ body: |
   
   bb.1.then:
     successors: %bb.2.end
-    %3(32) = G_ADD i32 %0, %0
+    %3(32) = G_ADD s32 %0, %0
   
   bb.2.end:
     %4(32) = PHI %0, %bb.0.entry, %3, %bb.1.then
@@ -211,9 +211,9 @@ body: |
     liveins: %w0, %s0
     ; CHECK:           %0(32) = COPY %w0
     ; CHECK-NEXT:      %2(32) = COPY %s0
-    ; CHECK-NEXT:      %1(32) = G_ADD i32 %0, %2
+    ; CHECK-NEXT:      %1(32) = G_ADD s32 %0, %2
     %0(32) = COPY %w0
-    %1(32) = G_ADD i32 %0, %s0
+    %1(32) = G_ADD s32 %0, %s0
 ...
 
 ---
@@ -229,10 +229,10 @@ body: |
   bb.0.entry:
     liveins: %w0
     ; CHECK:           %0(32) = COPY %w0
-    ; CHECK-NEXT:      %1(32) = G_ADD i32 %0, %0
+    ; CHECK-NEXT:      %1(32) = G_ADD s32 %0, %0
     ; CHECK-NEXT:      %s0 = COPY %1
     %0(32) = COPY %w0
-    %s0 = G_ADD i32 %0, %0
+    %s0 = G_ADD s32 %0, %0
 ...
 
 ---
@@ -271,13 +271,13 @@ body: |
     ; FAST-NEXT: %3(64) = COPY %0
     ; FAST-NEXT: %4(64) = COPY %1
     ; The mapping of G_OR is on FPR.
-    ; FAST-NEXT: %2(64) = G_OR <2 x i32> %3, %4
+    ; FAST-NEXT: %2(64) = G_OR <2 x s32> %3, %4
 
     ; Greedy mode remapped the instruction on the GPR bank.
-    ; GREEDY-NEXT: %2(64) = G_OR <2 x i32> %0, %1
+    ; GREEDY-NEXT: %2(64) = G_OR <2 x s32> %0, %1
     %0(64) = COPY %x0
     %1(64) = COPY %x1
-    %2(64) = G_OR <2 x i32> %0, %1
+    %2(64) = G_OR <2 x s32> %0, %1
 ...
 
 ---
@@ -317,13 +317,13 @@ body: |
     ; FAST-NEXT: %3(64) = COPY %0
     ; FAST-NEXT: %4(64) = COPY %1
     ; The mapping of G_OR is on FPR.
-    ; FAST-NEXT: %2(64) = G_OR <2 x i32> %3, %4
+    ; FAST-NEXT: %2(64) = G_OR <2 x s32> %3, %4
 
     ; Greedy mode remapped the instruction on the GPR bank.
-    ; GREEDY-NEXT: %3(64) = G_OR <2 x i32> %0, %1
+    ; GREEDY-NEXT: %3(64) = G_OR <2 x s32> %0, %1
     ; We need to keep %2 into FPR because we do not know anything about it.
     ; GREEDY-NEXT: %2(64) = COPY %3
     %0(64) = COPY %x0
     %1(64) = COPY %x1
-    %2(64) = G_OR <2 x i32> %0, %1
+    %2(64) = G_OR <2 x s32> %0, %1
 ...

Modified: llvm/trunk/test/CodeGen/AMDGPU/GlobalISel/amdgpu-irtranslator.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AMDGPU/GlobalISel/amdgpu-irtranslator.ll?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AMDGPU/GlobalISel/amdgpu-irtranslator.ll (original)
+++ llvm/trunk/test/CodeGen/AMDGPU/GlobalISel/amdgpu-irtranslator.ll Wed Jul 20 14:09:30 2016
@@ -5,7 +5,7 @@
 
 ; Tests for add.
 ; CHECK: name: addi32
-; CHECK: G_ADD i32
+; CHECK: G_ADD s32
 define i32 @addi32(i32 %arg1, i32 %arg2) {
   %res = add i32 %arg1, %arg2
   ret i32 %res

Modified: llvm/trunk/test/CodeGen/MIR/X86/generic-instr-type-error.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/generic-instr-type-error.mir?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/generic-instr-type-error.mir (original)
+++ llvm/trunk/test/CodeGen/MIR/X86/generic-instr-type-error.mir Wed Jul 20 14:09:30 2016
@@ -10,6 +10,6 @@ registers:
 body: |
   bb.0.entry:
     liveins: %edi
-    ; CHECK: [[@LINE+1]]:16: expected a sized type
-    %0 = G_ADD %opaque %edi, %edi
+    ; CHECK: [[@LINE+1]]:16: expected sN or <N x sM> for sized GlobalISel type
+    %0 = G_ADD unsized %edi, %edi
 ...

Modified: llvm/trunk/test/CodeGen/MIR/X86/generic-virtual-registers.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/generic-virtual-registers.mir?rev=276158&r1=276157&r2=276158&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/generic-virtual-registers.mir (original)
+++ llvm/trunk/test/CodeGen/MIR/X86/generic-virtual-registers.mir Wed Jul 20 14:09:30 2016
@@ -33,16 +33,16 @@ registers:
 body: |
   bb.0.entry:
     liveins: %edi
-    ; CHECK:      %0(32) = G_ADD i32 %edi
-    %0(32) = G_ADD i32 %edi, %edi
-    ; CHECK:      %1(64) = G_ADD <2 x i32> %edi
-    %1(64) = G_ADD <2 x i32> %edi, %edi
-    ; CHECK:      %2(64) = G_ADD <2 x i32> %edi
-    %2(64) = G_ADD %type_alias %edi, %edi
+    ; CHECK:      %0(32) = G_ADD s32 %edi
+    %0(32) = G_ADD s32 %edi, %edi
+    ; CHECK:      %1(64) = G_ADD <2 x s32> %edi
+    %1(64) = G_ADD <2 x s32> %edi, %edi
+    ; CHECK:      %2(64) = G_ADD s64 %edi
+    %2(64) = G_ADD s64 %edi, %edi
     ; G_ADD is actually not a valid operand for structure type,
     ; but that is the only one we have for now for testing.
-    ; CHECK:      %3(64) = G_ADD { i32, i32 } %edi
-    %3(64) = G_ADD {i32, i32} %edi, %edi
-    ; CHECK:      %4(48) = G_ADD %structure_alias %edi
-    %4(48) = G_ADD %structure_alias %edi, %edi
+    ; CHECK:      %3(64) = G_ADD s64 %edi
+    %3(64) = G_ADD s64 %edi, %edi
+    ; CHECK:      %4(48) = G_ADD s48 %edi
+    %4(48) = G_ADD s48 %edi, %edi
 ...




More information about the llvm-commits mailing list