--- /dev/null
+// RUN: llvm-tblgen -gen-dag-isel -I %p/../../include %s -o %t
+// RUN: FileCheck --check-prefix=ADD %s < %t
+// RUN: FileCheck --check-prefix=ADDINT %s < %t
+// RUN: FileCheck --check-prefix=SUB %s < %t
+// RUN: FileCheck --check-prefix=MULINT %s < %t
+
+include "llvm/Target/Target.td"
+
+def TestInstrInfo : InstrInfo;
+def TestTarget : Target {
+ let InstructionSet = TestInstrInfo;
+}
+
+class TestEncoding : Instruction {
+ field bits<32> Inst;
+}
+
+class TestReg<int index> : Register<"R"#index, []> {
+ let HWEncoding{15-4} = 0;
+ let HWEncoding{3-0} = !cast<bits<4>>(index);
+}
+foreach i = 0-15 in
+ def "R"#i : TestReg<i>;
+
+def Reg : RegisterClass<"TestTarget", [i32], 32, (sequence "R%d", 0, 15)>;
+
+def IntOperand: Operand<i32>;
+def OptionalIntOperand: OperandWithDefaultOps<i32, (ops (i32 0))>;
+
+class RRI<string Mnemonic, bits<4> Opcode> : TestEncoding {
+ dag OutOperandList = (outs Reg:$dest);
+ dag InOperandList = (ins Reg:$src1, Reg:$src2, OptionalIntOperand:$imm);
+ string AsmString = Mnemonic # " $dest1, $src1, $src2, #$imm";
+ string AsmVariantName = "";
+ field bits<4> dest;
+ field bits<4> src1;
+ field bits<4> src2;
+ field bits<16> imm;
+ let Inst{31-28} = Opcode;
+ let Inst{27-24} = dest;
+ let Inst{23-20} = src1;
+ let Inst{19-16} = src2;
+ let Inst{15-0} = imm;
+}
+
+def AddRRI : RRI<"add", 0b0001>;
+
+// I define one of these intrinsics with IntrNoMem and the other
+// without it, so that they'll match different top-level DAG opcodes
+// (INTRINSIC_WO_CHAIN and INTRINSIC_W_CHAIN), which makes the
+// FileCheck-herding easier, because every case I want to detect
+// should show up as a separate top-level switch element.
+def int_addplus1 : Intrinsic<
+ [llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mul3 : Intrinsic<
+ [llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty]>;
+
+def AddPat : Pat<(add i32:$x, i32:$y),
+ (AddRRI Reg:$x, Reg:$y)>;
+def Add1Pat : Pat<(int_addplus1 i32:$x, i32:$y),
+ (AddRRI Reg:$x, Reg:$y, (i32 1))>;
+
+def SubRRI : RRI<"sub", 0b0010> {
+ let Pattern = [(set Reg:$dest, (sub Reg:$src1, Reg:$src2))];
+}
+
+def MulRRI : RRI<"mul", 0b0011> {
+ let Pattern = [(set Reg:$dest, (int_mul3 Reg:$src1, Reg:$src2, i32:$imm))];
+}
+
+def MulIRR : RRI<"mul2", 0b0100> {
+ let InOperandList = (ins OptionalIntOperand:$imm, Reg:$src1, Reg:$src2);
+}
+def MulIRRPat : Pat<(mul i32:$x, i32:$y), (MulIRR Reg:$x, Reg:$y)>;
+
+// ADD: SwitchOpcode{{.*}}TARGET_VAL(ISD::ADD)
+// ADD-NEXT: OPC_RecordChild0
+// ADD-NEXT: OPC_RecordChild1
+// ADD-NEXT: OPC_EmitInteger, MVT::i32, 0
+// ADD-NEXT: OPC_MorphNodeTo1, TARGET_VAL(::AddRRI)
+
+// ADDINT: SwitchOpcode{{.*}}TARGET_VAL(ISD::INTRINSIC_WO_CHAIN)
+// ADDINT-NEXT: OPC_CheckChild0Integer
+// ADDINT-NEXT: OPC_RecordChild1
+// ADDINT-NEXT: OPC_RecordChild2
+// ADDINT-NEXT: OPC_EmitInteger, MVT::i32, 1
+// ADDINT-NEXT: OPC_MorphNodeTo1, TARGET_VAL(::AddRRI)
+
+// SUB: SwitchOpcode{{.*}}TARGET_VAL(ISD::SUB)
+// SUB-NEXT: OPC_RecordChild0
+// SUB-NEXT: OPC_RecordChild1
+// SUB-NEXT: OPC_EmitInteger, MVT::i32, 0
+// SUB-NEXT: OPC_MorphNodeTo1, TARGET_VAL(::SubRRI)
+
+// MULINT: SwitchOpcode{{.*}}TARGET_VAL(ISD::INTRINSIC_W_CHAIN)
+// MULINT-NEXT: OPC_RecordNode
+// MULINT-NEXT: OPC_CheckChild1Integer
+// MULINT-NEXT: OPC_RecordChild2
+// MULINT-NEXT: OPC_RecordChild3
+// MULINT-NEXT: OPC_RecordChild4
+// MULINT-NEXT: OPC_EmitMergeInputChains
+// MULINT-NEXT: OPC_MorphNodeTo1, TARGET_VAL(::MulRRI)
+
+// MUL: SwitchOpcode{{.*}}TARGET_VAL(ISD::MUL)
+// MUL-NEXT: OPC_EmitInteger, MVT::i32, 0
+// MUL-NEXT: OPC_RecordChild0
+// MUL-NEXT: OPC_RecordChild1
+// MUL-NEXT: OPC_MorphNodeTo1, TARGET_VAL(::MulRRI)
}
}
+ // If one or more operands with a default value appear at the end of the
+ // formal operand list for an instruction, we allow them to be overridden
+ // by optional operands provided in the pattern.
+ //
+ // But if an operand B without a default appears at any point after an
+ // operand A with a default, then we don't allow A to be overridden,
+ // because there would be no way to specify whether the next operand in
+ // the pattern was intended to override A or skip it.
+ unsigned NonOverridableOperands = Inst.getNumOperands();
+ while (NonOverridableOperands > 0 &&
+ CDP.operandHasDefault(Inst.getOperand(NonOverridableOperands-1)))
+ --NonOverridableOperands;
+
unsigned ChildNo = 0;
for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i) {
Record *OperandNode = Inst.getOperand(i);
- // If the instruction expects a predicate or optional def operand, we
- // codegen this by setting the operand to it's default value if it has a
- // non-empty DefaultOps field.
- if (OperandNode->isSubClassOf("OperandWithDefaultOps") &&
- !CDP.getDefaultOperand(OperandNode).DefaultOps.empty())
+ // If the operand has a default value, do we use it? We must use the
+ // default if we've run out of children of the pattern DAG to consume,
+ // or if the operand is followed by a non-defaulted one.
+ if (CDP.operandHasDefault(OperandNode) &&
+ (i < NonOverridableOperands || ChildNo >= getNumChildren()))
continue;
- // Verify that we didn't run out of provided operands.
+ // If we have run out of child nodes and there _isn't_ a default
+ // value we can use for the next operand, give an error.
if (ChildNo >= getNumChildren()) {
emitTooFewOperandsError(TP, getOperator()->getName(), getNumChildren());
return false;
// 'execute always' values. Match up the node operands to the instruction
// operands to do this.
unsigned ChildNo = 0;
+
+ // Similarly to the code in TreePatternNode::ApplyTypeConstraints, count the
+ // number of operands at the end of the list which have default values.
+ // Those can come from the pattern if it provides enough arguments, or be
+ // filled in with the default if the pattern hasn't provided them. But any
+ // operand with a default value _before_ the last mandatory one will be
+ // filled in with their defaults unconditionally.
+ unsigned NonOverridableOperands = NumFixedOperands;
+ while (NonOverridableOperands > NumResults &&
+ CGP.operandHasDefault(II.Operands[NonOverridableOperands-1].Rec))
+ --NonOverridableOperands;
+
for (unsigned InstOpNo = NumResults, e = NumFixedOperands;
InstOpNo != e; ++InstOpNo) {
// Determine what to emit for this operand.
Record *OperandNode = II.Operands[InstOpNo].Rec;
- if (OperandNode->isSubClassOf("OperandWithDefaultOps") &&
- !CGP.getDefaultOperand(OperandNode).DefaultOps.empty()) {
- // This is a predicate or optional def operand; emit the
- // 'default ops' operands.
+ if (CGP.operandHasDefault(OperandNode) &&
+ (InstOpNo < NonOverridableOperands || ChildNo >= N->getNumChildren())) {
+ // This is a predicate or optional def operand which the pattern has not
+ // overridden, or which we aren't letting it override; emit the 'default
+ // ops' operands.
const DAGDefaultOperand &DefaultOp
= CGP.getDefaultOperand(OperandNode);
for (unsigned i = 0, e = DefaultOp.DefaultOps.size(); i != e; ++i)