[LLVMdev] Tablegen to match a literal in an instruction

Villmow, Micah Micah.Villmow at amd.com
Thu Apr 19 17:16:28 PDT 2012


Thanks for the tip, didn't think to look at the AND node as a culprit because we have a similar pattern on a different internal backend and its matching fine.

Micah


From: Owen Anderson [mailto:resistor at mac.com]
Sent: Thursday, April 19, 2012 4:31 PM
To: Villmow, Micah
Cc: LLVM Developers Mailing List
Subject: Re: [LLVMdev] Tablegen to match a literal in an instruction

Right, it's failing when it tries to materialize a move of a constant into a register.  But it's only trying to do that because it previously failed to fold the constant into the AND.  What you need to do is step through the path it takes when matching the AND node, and try to figure out why it ends up selecting the register-register version rather than the register-immediate version.  Fortunately, the debug output from llc will contain a complete trace of what happened, so you just need to line it up with GenDAGISel.inc and determine which step did the wrong thing.

At a guess, I'd say you probably have a type declared wrong somewhere.

--Owen

On Apr 19, 2012, at 4:05 PM, "Villmow, Micah" <Micah.Villmow at amd.com<mailto:Micah.Villmow at amd.com>> wrote:


I'm not at the machine that has the changes, but it was failing at index 0.

Micah

From: Owen Anderson [mailto:resistor at mac.com<http://mac.com>]
Sent: Thursday, April 19, 2012 3:35 PM
To: Villmow, Micah
Cc: LLVM Developers Mailing List
Subject: Re: [LLVMdev] Tablegen to match a literal in an instruction

Micah,

I don't see anything wrong with this offhand.  Have you tried getting the debug output from llc -debug, and matching it up with the state machine in your DAGISel.inc to see at what step the auto-generated matcher is failing to match your and-with-immediate?

-Owen

On Apr 19, 2012, at 3:07 PM, "Villmow, Micah" <Micah.Villmow at amd.com<mailto:Micah.Villmow at amd.com>> wrote:



I am trying to make some modifications to our code generator that will produce better code, but require adding new patterns.

What I am trying to do is take a register/register pattern and change it to a register/immediate.
So for example, I have this pattern:
class ILFormat<ILOpCode op, dag outs, dag ins, string asmstr, list<dag> pattern>
: Instruction {
     let Namespace = "AMDIL";
     dag OutOperandList = outs;
     dag InOperandList = ins;
     ILOpCode operation = op;
     let Pattern = pattern;
     let AsmString = !strconcat(asmstr, "\n");
     bit hasIEEEFlag = 0;
     bit hasZeroOpFlag = 0;
}
class BinaryOp<ILOpCode op, SDNode OpNode, RegisterClass dReg,
      RegisterClass sReg0, RegisterClass sReg1>
      : ILFormat<op, (outs dReg:$dst), (ins sReg0:$src0, sReg1:$src1),
      !strconcat(op.Text, " $dst, $src0, $src1"),
      [(set dReg:$dst, (OpNode sReg0:$src0, sReg1:$src1))]>;
multiclass BinaryOpMCInt<ILOpCode OpCode, SDNode OpNode> {
  def _i8    : BinaryOp<OpCode, OpNode, GPRI8, GPRI8, GPRI8>;

  def _i16    : BinaryOp<OpCode, OpNode, GPRI16, GPRI16, GPRI16>;
  def _i32    : BinaryOp<OpCode, OpNode, GPRI32, GPRI32, GPRI32>;
  def _i64    : BinaryOp<OpCode, OpNode, GPRI64, GPRI64, GPRI64>;
}
defm AND        : BinaryOpMCInt<IL_OP_AND, and>;

I want to turn this into a register/immediate pattern by changing it to:
class ILFormat<dag outs, dag ins, string asmstr, list<dag> pattern>
: Instruction {
     let Namespace = "AMDIL";
     dag OutOperandList = outs;
     dag InOperandList = ins;
     let Pattern = pattern;
     let AsmString = !strconcat(asmstr, "\n");
}
multiclass BinaryOp<SDNode OpNode, RegisterClass dReg,
      RegisterClass sReg0, RegisterClass sReg1, Operand lit>
{
def _rr: ILFormat<op, (outs dReg:$dst), (ins sReg0:$src0, sReg1:$src1),
      !strconcat(op.Text, " $dst, $src0, $src1"),
      [(set dReg:$dst, (OpNode sReg0:$src0, sReg1:$src1))]>;
def _ri : ILFormat<op, (outs dReg:$dst), (ins sReg0:$src0, lit:$src1),
      "and  $dst, $src0, $src1"),
      [(set dReg:$dst, (OpNode sReg0:$src0, imm:$src1))]>;

}
multiclass BinaryOpMCInt<SDNode OpNode> {
  defm _i32  : BinaryOp<OpNode, GPRI32, GPRI32, GPRI32, i32imm>;
}
defm AND        : BinaryOpMCInt<and>;


When I run on a simple program which just ands a value and writes to memory, I get this error:
LLVM ERROR: Cannot select: 0x99555d0: i32 = Constant<2> [ORD=7] [ID=8]

Where 0x99555d0 is only used as the second operand of the 'and' node.

So, how can I figure out what I'm doing wrong? Does anyone see anything majorly wrong here?

Thanks,
Micah
_______________________________________________
LLVM Developers mailing list
LLVMdev at cs.uiuc.edu<mailto:LLVMdev at cs.uiuc.edu>         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120420/a55f3796/attachment.html>


More information about the llvm-dev mailing list