Commit 5af9cf04 authored by Matt Arsenault's avatar Matt Arsenault
Browse files

GlobalISel: Change representation of shuffle masks

Currently shufflemasks get emitted as any other constant, and you end
up with a bunch of virtual registers of G_CONSTANT with a
G_BUILD_VECTOR. The AArch64 selector then asserts on anything that
doesn't fit this pattern. This isn't an ideal representation, and
should avoid legalization and have fewer opportunities for a
representational error.

Rather than invent a new shuffle mask operand type, similar to what
ShuffleVectorSDNode does, just track the original IR Constant mask
operand. I don't completely like the idea of adding another link to
the IR, but MIR is already quite dependent on IR constants already,
and this will allow sharing the shuffle mask utility functions with
the IR.

llvm-svn: 368704
parent 8a033a9e
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -250,6 +250,11 @@ public:
    return *this;
  }

  const MachineInstrBuilder &addShuffleMask(const Constant *Val) const {
    MI->addOperand(*MF, MachineOperand::CreateShuffleMask(Val));
    return *this;
  }

  const MachineInstrBuilder &addSym(MCSymbol *Sym,
                                    unsigned char TargetFlags = 0) const {
    MI->addOperand(*MF, MachineOperand::CreateMCSymbol(Sym, TargetFlags));
+16 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
namespace llvm {

class BlockAddress;
class Constant;
class ConstantFP;
class ConstantInt;
class GlobalValue;
@@ -68,7 +69,8 @@ public:
    MO_CFIIndex,          ///< MCCFIInstruction index.
    MO_IntrinsicID,       ///< Intrinsic ID for ISel
    MO_Predicate,         ///< Generic predicate for ISel
    MO_Last = MO_Predicate,
    MO_ShuffleMask,       ///< Other IR Constant for ISel (shuffle masks)
    MO_Last = MO_ShuffleMask
  };

private:
@@ -172,6 +174,7 @@ private:
    unsigned CFIIndex;       // For MO_CFI.
    Intrinsic::ID IntrinsicID; // For MO_IntrinsicID.
    unsigned Pred;           // For MO_Predicate
    const Constant *ShuffleMask; // For MO_ShuffleMask

    struct {                  // For MO_Register.
      // Register number is in SmallContents.RegNo.
@@ -341,6 +344,7 @@ public:
  bool isCFIIndex() const { return OpKind == MO_CFIIndex; }
  bool isIntrinsicID() const { return OpKind == MO_IntrinsicID; }
  bool isPredicate() const { return OpKind == MO_Predicate; }
  bool isShuffleMask() const { return OpKind == MO_ShuffleMask; }
  //===--------------------------------------------------------------------===//
  // Accessors for Register Operands
  //===--------------------------------------------------------------------===//
@@ -579,6 +583,11 @@ public:
    return Contents.Pred;
  }

  const Constant *getShuffleMask() const {
    assert(isShuffleMask() && "Wrong MachineOperand accessor");
    return Contents.ShuffleMask;
  }

  /// Return the offset from the symbol in this operand. This always returns 0
  /// for ExternalSymbol operands.
  int64_t getOffset() const {
@@ -902,6 +911,12 @@ public:
    return Op;
  }

  static MachineOperand CreateShuffleMask(const Constant *C) {
    MachineOperand Op(MachineOperand::MO_ShuffleMask);
    Op.Contents.ShuffleMask = C;
    return Op;
  }

  friend class MachineInstr;
  friend class MachineRegisterInfo;

+4 −1
Original line number Diff line number Diff line
@@ -967,9 +967,12 @@ def G_EXTRACT_VECTOR_ELT : GenericInstruction {
}

// Generic shufflevector.
//
// The mask operand should be an IR Constant which exactly matches the
// corresponding mask for the IR shufflevector instruction.
def G_SHUFFLE_VECTOR: GenericInstruction {
  let OutOperandList = (outs type0:$dst);
  let InOperandList = (ins type1:$v1, type1:$v2, type2:$mask);
  let InOperandList = (ins type1:$v1, type1:$v2, unknown:$mask);
  let hasSideEffects = 0;
}

+1 −1
Original line number Diff line number Diff line
@@ -1902,7 +1902,7 @@ bool IRTranslator::translateShuffleVector(const User &U,
      .addDef(getOrCreateVReg(U))
      .addUse(getOrCreateVReg(*U.getOperand(0)))
      .addUse(getOrCreateVReg(*U.getOperand(1)))
      .addUse(getOrCreateVReg(*U.getOperand(2)));
      .addShuffleMask(cast<Constant>(U.getOperand(2)));
  return true;
}

+1 −0
Original line number Diff line number Diff line
@@ -249,6 +249,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
      .Case("successors", MIToken::kw_successors)
      .Case("floatpred", MIToken::kw_floatpred)
      .Case("intpred", MIToken::kw_intpred)
      .Case("shufflemask", MIToken::kw_shufflemask)
      .Case("pre-instr-symbol", MIToken::kw_pre_instr_symbol)
      .Case("post-instr-symbol", MIToken::kw_post_instr_symbol)
      .Case("unknown-size", MIToken::kw_unknown_size)
Loading