Villmow, Micah
2012-Apr-19 22:07 UTC
[LLVMdev] Tablegen to match a literal in an instruction
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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120419/2292b1cd/attachment.html>
Owen Anderson
2012-Apr-19 22:34 UTC
[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> 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 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/20120419/7839630b/attachment.html>
Villmow, Micah
2012-Apr-19 23:05 UTC
[LLVMdev] Tablegen to match a literal in an instruction
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] 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/20120419/7908c279/attachment.html>