summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2019-08-13 15:34:38 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2019-08-13 15:34:38 +0000
commit5af9cf042f21d6b044f8925b581a8f089d739bc5 (patch)
tree1c7016ee055287ef20d67cdbf8a5ff6d9634dfb8 /llvm/lib
parent8a033a9e3fb96b9a1099325c4cd218c1c979d9d9 (diff)
downloadbcm5719-llvm-5af9cf042f21d6b044f8925b581a8f089d739bc5.tar.gz
bcm5719-llvm-5af9cf042f21d6b044f8925b581a8f089d739bc5.zip
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
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp2
-rw-r--r--llvm/lib/CodeGen/MIRParser/MILexer.cpp1
-rw-r--r--llvm/lib/CodeGen/MIRParser/MILexer.h2
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIParser.cpp46
-rw-r--r--llvm/lib/CodeGen/MIRPrinter.cpp3
-rw-r--r--llvm/lib/CodeGen/MachineOperand.cpp18
-rw-r--r--llvm/lib/CodeGen/MachineVerifier.cpp16
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp51
-rw-r--r--llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp1
9 files changed, 94 insertions, 46 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 9b0a8abdec0..19753fbce5a 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -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;
}
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
index 4899bd3f581..ad5c617623f 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
@@ -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)
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h
index 0fe3f9f706d..200f9d026cc 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.h
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.h
@@ -117,6 +117,7 @@ struct MIToken {
kw_successors,
kw_floatpred,
kw_intpred,
+ kw_shufflemask,
kw_pre_instr_symbol,
kw_post_instr_symbol,
kw_unknown_size,
@@ -146,6 +147,7 @@ struct MIToken {
IntegerLiteral,
FloatingPointLiteral,
HexLiteral,
+ VectorLiteral,
VirtualRegister,
ConstantPoolItem,
JumpTableIndex,
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index 89eaaf6b639..a8fa2f1195d 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -451,6 +451,7 @@ public:
bool parseBlockAddressOperand(MachineOperand &Dest);
bool parseIntrinsicOperand(MachineOperand &Dest);
bool parsePredicateOperand(MachineOperand &Dest);
+ bool parseShuffleMaskOperand(MachineOperand &Dest);
bool parseTargetIndexOperand(MachineOperand &Dest);
bool parseCustomRegisterMaskOperand(MachineOperand &Dest);
bool parseLiveoutRegisterMaskOperand(MachineOperand &Dest);
@@ -2285,6 +2286,49 @@ bool MIParser::parsePredicateOperand(MachineOperand &Dest) {
return false;
}
+bool MIParser::parseShuffleMaskOperand(MachineOperand &Dest) {
+ assert(Token.is(MIToken::kw_shufflemask));
+
+ lex();
+ if (expectAndConsume(MIToken::lparen))
+ return error("expected syntax shufflemask(<integer or undef>, ...)");
+
+ SmallVector<Constant *, 32> ShufMask;
+ LLVMContext &Ctx = MF.getFunction().getContext();
+ Type *I32Ty = Type::getInt32Ty(Ctx);
+
+ bool AllZero = true;
+ bool AllUndef = true;
+
+ do {
+ if (Token.is(MIToken::kw_undef)) {
+ ShufMask.push_back(UndefValue::get(I32Ty));
+ AllZero = false;
+ } else if (Token.is(MIToken::IntegerLiteral)) {
+ AllUndef = false;
+ const APSInt &Int = Token.integerValue();
+ if (!Int.isNullValue())
+ AllZero = false;
+ ShufMask.push_back(ConstantInt::get(I32Ty, Int.getExtValue()));
+ } else
+ return error("expected integer constant");
+
+ lex();
+ } while (consumeIfPresent(MIToken::comma));
+
+ if (expectAndConsume(MIToken::rparen))
+ return error("shufflemask should be terminated by ')'.");
+
+ if (AllZero || AllUndef) {
+ VectorType *VT = VectorType::get(I32Ty, ShufMask.size());
+ Constant *C = AllZero ? Constant::getNullValue(VT) : UndefValue::get(VT);
+ Dest = MachineOperand::CreateShuffleMask(C);
+ } else
+ Dest = MachineOperand::CreateShuffleMask(ConstantVector::get(ShufMask));
+
+ return false;
+}
+
bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) {
assert(Token.is(MIToken::kw_target_index));
lex();
@@ -2432,6 +2476,8 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest,
case MIToken::kw_floatpred:
case MIToken::kw_intpred:
return parsePredicateOperand(Dest);
+ case MIToken::kw_shufflemask:
+ return parseShuffleMaskOperand(Dest);
case MIToken::Error:
return true;
case MIToken::Identifier:
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index e6010c9c0e9..539aa863e22 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -842,7 +842,8 @@ void MIPrinter::print(const MachineInstr &MI, unsigned OpIdx,
case MachineOperand::MO_CFIIndex:
case MachineOperand::MO_IntrinsicID:
case MachineOperand::MO_Predicate:
- case MachineOperand::MO_BlockAddress: {
+ case MachineOperand::MO_BlockAddress:
+ case MachineOperand::MO_ShuffleMask: {
unsigned TiedOperandIdx = 0;
if (ShouldPrintRegisterTies && Op.isReg() && Op.isTied() && !Op.isDef())
TiedOperandIdx = Op.getParent()->findTiedOperandIdx(OpIdx);
diff --git a/llvm/lib/CodeGen/MachineOperand.cpp b/llvm/lib/CodeGen/MachineOperand.cpp
index a18ee52cc55..43081ccb329 100644
--- a/llvm/lib/CodeGen/MachineOperand.cpp
+++ b/llvm/lib/CodeGen/MachineOperand.cpp
@@ -333,6 +333,8 @@ bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {
return getIntrinsicID() == Other.getIntrinsicID();
case MachineOperand::MO_Predicate:
return getPredicate() == Other.getPredicate();
+ case MachineOperand::MO_ShuffleMask:
+ return getShuffleMask() == Other.getShuffleMask();
}
llvm_unreachable("Invalid machine operand type");
}
@@ -381,6 +383,8 @@ hash_code llvm::hash_value(const MachineOperand &MO) {
return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID());
case MachineOperand::MO_Predicate:
return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate());
+ case MachineOperand::MO_ShuffleMask:
+ return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getShuffleMask());
}
llvm_unreachable("Invalid machine operand type");
}
@@ -936,6 +940,20 @@ void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
<< CmpInst::getPredicateName(Pred) << ')';
break;
}
+ case MachineOperand::MO_ShuffleMask:
+ OS << "shufflemask(";
+ const Constant* C = getShuffleMask();
+ const int NumElts = C->getType()->getVectorNumElements();
+
+ StringRef Separator;
+ for (int I = 0; I != NumElts; ++I) {
+ OS << Separator;
+ C->getAggregateElement(I)->printAsOperand(OS, false, MST);
+ Separator = ", ";
+ }
+
+ OS << ')';
+ break;
}
}
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 49f0c02e47c..ba2e72568b7 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -1387,6 +1387,22 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
report("G_SEXT_INREG size must be less than source bit width", MI);
break;
}
+ case TargetOpcode::G_SHUFFLE_VECTOR: {
+ const MachineOperand &MaskOp = MI->getOperand(3);
+ if (!MaskOp.isShuffleMask()) {
+ report("Incorrect mask operand type for G_SHUFFLE_VECTOR", MI);
+ break;
+ }
+
+ const Constant *Mask = MaskOp.getShuffleMask();
+ if (!Mask->getAggregateElement(0u)) {
+ report("Invalid shufflemask constant type", MI);
+ break;
+ }
+
+ // TODO: Verify element numbers consistent
+ break;
+ }
default:
break;
}
diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
index d19e0c1592b..f594200fe27 100644
--- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
@@ -115,8 +115,6 @@ private:
bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
- void collectShuffleMaskIndices(MachineInstr &I, MachineRegisterInfo &MRI,
- SmallVectorImpl<Optional<int>> &Idxs) const;
bool selectShuffleVector(MachineInstr &I, MachineRegisterInfo &MRI) const;
bool selectExtractElt(MachineInstr &I, MachineRegisterInfo &MRI) const;
bool selectConcatVectors(MachineInstr &I, MachineRegisterInfo &MRI) const;
@@ -3065,29 +3063,6 @@ bool AArch64InstructionSelector::selectConcatVectors(
return true;
}
-void AArch64InstructionSelector::collectShuffleMaskIndices(
- MachineInstr &I, MachineRegisterInfo &MRI,
- SmallVectorImpl<Optional<int>> &Idxs) const {
- MachineInstr *MaskDef = MRI.getVRegDef(I.getOperand(3).getReg());
- assert(
- MaskDef->getOpcode() == TargetOpcode::G_BUILD_VECTOR &&
- "G_SHUFFLE_VECTOR should have a constant mask operand as G_BUILD_VECTOR");
- // Find the constant indices.
- for (unsigned i = 1, e = MaskDef->getNumOperands(); i < e; ++i) {
- // Look through copies.
- MachineInstr *ScalarDef =
- getDefIgnoringCopies(MaskDef->getOperand(i).getReg(), MRI);
- assert(ScalarDef && "Could not find vreg def of shufflevec index op");
- if (ScalarDef->getOpcode() != TargetOpcode::G_CONSTANT) {
- // This be an undef if not a constant.
- assert(ScalarDef->getOpcode() == TargetOpcode::G_IMPLICIT_DEF);
- Idxs.push_back(None);
- } else {
- Idxs.push_back(ScalarDef->getOperand(1).getCImm()->getSExtValue());
- }
- }
-}
-
unsigned
AArch64InstructionSelector::emitConstantPoolEntry(Constant *CPVal,
MachineFunction &MF) const {
@@ -3630,16 +3605,9 @@ bool AArch64InstructionSelector::tryOptVectorDup(MachineInstr &I) const {
return false;
// The shuffle's second operand doesn't matter if the mask is all zero.
- auto *ZeroVec = getOpcodeDef(G_BUILD_VECTOR, I.getOperand(3).getReg(), MRI);
- if (!ZeroVec)
+ const Constant *Mask = I.getOperand(3).getShuffleMask();
+ if (!isa<ConstantAggregateZero>(Mask))
return false;
- int64_t Zero = 0;
- if (!mi_match(ZeroVec->getOperand(1).getReg(), MRI, m_ICst(Zero)) || Zero)
- return false;
- for (unsigned i = 1, e = ZeroVec->getNumOperands(); i < e; ++i) {
- if (ZeroVec->getOperand(i).getReg() != ZeroVec->getOperand(1).getReg())
- return false; // This wasn't an all zeros vector.
- }
// We're done, now find out what kind of splat we need.
LLT VecTy = MRI.getType(I.getOperand(0).getReg());
@@ -3687,19 +3655,14 @@ bool AArch64InstructionSelector::selectShuffleVector(
const LLT Src1Ty = MRI.getType(Src1Reg);
Register Src2Reg = I.getOperand(2).getReg();
const LLT Src2Ty = MRI.getType(Src2Reg);
+ const Constant *ShuffleMask = I.getOperand(3).getShuffleMask();
MachineBasicBlock &MBB = *I.getParent();
MachineFunction &MF = *MBB.getParent();
LLVMContext &Ctx = MF.getFunction().getContext();
- // G_SHUFFLE_VECTOR doesn't really have a strictly enforced constant mask
- // operand, it comes in as a normal vector value which we have to analyze to
- // find the mask indices. If the mask element is undef, then
- // collectShuffleMaskIndices() will add a None entry for that index into
- // the list.
- SmallVector<Optional<int>, 8> Mask;
- collectShuffleMaskIndices(I, MRI, Mask);
- assert(!Mask.empty() && "Expected to find mask indices");
+ SmallVector<int, 8> Mask;
+ ShuffleVectorInst::getShuffleMask(ShuffleMask, Mask);
// G_SHUFFLE_VECTOR is weird in that the source operands can be scalars, if
// it's originated from a <1 x T> type. Those should have been lowered into
@@ -3712,10 +3675,10 @@ bool AArch64InstructionSelector::selectShuffleVector(
unsigned BytesPerElt = DstTy.getElementType().getSizeInBits() / 8;
SmallVector<Constant *, 64> CstIdxs;
- for (auto &MaybeVal : Mask) {
+ for (int Val : Mask) {
// For now, any undef indexes we'll just assume to be 0. This should be
// optimized in future, e.g. to select DUP etc.
- int Val = MaybeVal.hasValue() ? *MaybeVal : 0;
+ Val = Val < 0 ? 0 : Val;
for (unsigned Byte = 0; Byte < BytesPerElt; ++Byte) {
unsigned Offset = Byte + Val * BytesPerElt;
CstIdxs.emplace_back(ConstantInt::get(Type::getInt8Ty(Ctx), Offset));
diff --git a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
index b32ba3eeea1..2312e6be7ea 100644
--- a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
@@ -789,6 +789,7 @@ static bool IsAnAddressOperand(const MachineOperand &MO) {
case MachineOperand::MO_Immediate:
case MachineOperand::MO_CImmediate:
case MachineOperand::MO_FPImmediate:
+ case MachineOperand::MO_ShuffleMask:
return false;
case MachineOperand::MO_MachineBasicBlock:
return true;
OpenPOWER on IntegriCloud