// We need to make sure that when we import an INSERT_SUBREG as a
// subinstruction that it ends up being constrained to the correct super
// register and subregister classes.
- if (Target.getInstruction(Dst->getOperator()).TheDef->getName() ==
- "INSERT_SUBREG") {
+ auto OpName = Target.getInstruction(Dst->getOperator()).TheDef->getName();
+ if (OpName == "INSERT_SUBREG") {
auto SubClass = inferRegClassFromPattern(Dst->getChild(1));
if (!SubClass)
return failedImport(
// Similar to INSERT_SUBREG, we also have to handle SUBREG_TO_REG as a
// subinstruction.
- if (Target.getInstruction(Dst->getOperator()).TheDef->getName() ==
- "SUBREG_TO_REG") {
- auto SubClass = inferRegClassFromPattern(Dst->getChild(1));
- if (!SubClass)
- return failedImport(
+ if (OpName == "SUBREG_TO_REG") {
+ auto SubClass = inferRegClassFromPattern(Dst->getChild(1));
+ if (!SubClass)
+ return failedImport(
"Cannot infer register class from SUBREG_TO_REG child #1");
- auto SuperClass = inferSuperRegisterClass(Dst->getExtType(0),
- Dst->getChild(2));
- if (!SuperClass)
- return failedImport(
+ auto SuperClass = inferSuperRegisterClass(Dst->getExtType(0),
+ Dst->getChild(2));
+ if (!SuperClass)
+ return failedImport(
"Cannot infer register class for SUBREG_TO_REG operand #0");
- M.insertAction<ConstrainOperandToRegClassAction>(
+ M.insertAction<ConstrainOperandToRegClassAction>(
InsertPt, DstMIBuilder.getInsnID(), 0, **SuperClass);
- M.insertAction<ConstrainOperandToRegClassAction>(
+ M.insertAction<ConstrainOperandToRegClassAction>(
InsertPt, DstMIBuilder.getInsnID(), 2, **SubClass);
- return InsertPtOrError.get();
-}
+ return InsertPtOrError.get();
+ }
M.insertAction<ConstrainOperandsToDefinitionAction>(InsertPt,
DstMIBuilder.getInsnID());
// Handle any special-case instructions which we can safely infer register
// classes from.
StringRef InstName = Inst.TheDef->getName();
- if (InstName == "COPY_TO_REGCLASS") {
+ bool IsRegSequence = InstName == "REG_SEQUENCE";
+ if (IsRegSequence || InstName == "COPY_TO_REGCLASS") {
// If we have a COPY_TO_REGCLASS, then we need to handle it specially. It
// has the desired register class as the first child.
- TreePatternNode *RCChild = N->getChild(1);
+ TreePatternNode *RCChild = N->getChild(IsRegSequence ? 0 : 1);
if (!RCChild->isLeaf())
return None;
return getRegClassFromLeaf(RCChild);
return failedImport("Pattern operator isn't an instruction");
auto &DstI = Target.getInstruction(DstOp);
+ StringRef DstIName = DstI.TheDef->getName();
+
if (DstI.Operands.NumDefs != Src->getExtTypes().size())
return failedImport("Src pattern results and dst MI defs are different (" +
to_string(Src->getExtTypes().size()) + " def(s) vs " +
const auto &DstIOperand = DstI.Operands[OpIdx];
Record *DstIOpRec = DstIOperand.Rec;
- if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
+ if (DstIName == "COPY_TO_REGCLASS") {
DstIOpRec = getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
if (DstIOpRec == nullptr)
return failedImport(
"COPY_TO_REGCLASS operand #1 isn't a register class");
- } else if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
+ } else if (DstIName == "REG_SEQUENCE") {
+ DstIOpRec = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
+ if (DstIOpRec == nullptr)
+ return failedImport("REG_SEQUENCE operand #0 isn't a register class");
+ } else if (DstIName == "EXTRACT_SUBREG") {
if (!Dst->getChild(0)->isLeaf())
return failedImport("EXTRACT_SUBREG operand #0 isn't a leaf");
if (DstIOpRec == nullptr)
return failedImport("EXTRACT_SUBREG operand #0 isn't a register class");
- } else if (DstI.TheDef->getName() == "INSERT_SUBREG") {
+ } else if (DstIName == "INSERT_SUBREG") {
auto MaybeSuperClass = inferSuperRegisterClassForNode(
VTy, Dst->getChild(0), Dst->getChild(2));
if (!MaybeSuperClass)
OM.addPredicate<RegisterBankOperandMatcher>(**MaybeSuperClass);
++OpIdx;
continue;
- } else if (DstI.TheDef->getName() == "SUBREG_TO_REG") {
+ } else if (DstIName == "SUBREG_TO_REG") {
auto MaybeRegClass = inferSuperRegisterClass(VTy, Dst->getChild(2));
if (!MaybeRegClass)
return failedImport(
// Constrain the registers to classes. This is normally derived from the
// emitted instruction but a few instructions require special handling.
- if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
+ if (DstIName == "COPY_TO_REGCLASS") {
// COPY_TO_REGCLASS does not provide operand constraints itself but the
// result is constrained to the class given by the second child.
Record *DstIOpRec =
return std::move(M);
}
- if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
+ if (DstIName == "EXTRACT_SUBREG") {
// EXTRACT_SUBREG selects into a subregister COPY but unlike most
// instructions, the result register class is controlled by the
// subregisters of the operand. As a result, we must constrain the result
return std::move(M);
}
- if (DstI.TheDef->getName() == "INSERT_SUBREG") {
+ if (DstIName == "INSERT_SUBREG") {
assert(Src->getExtTypes().size() == 1 &&
"Expected Src of INSERT_SUBREG to have one result type");
// We need to constrain the destination, a super regsister source, and a
return std::move(M);
}
- if (DstI.TheDef->getName() == "SUBREG_TO_REG") {
+ if (DstIName == "SUBREG_TO_REG") {
// We need to constrain the destination and subregister source.
assert(Src->getExtTypes().size() == 1 &&
"Expected Src of SUBREG_TO_REG to have one result type");