More Back-End Porting Troubles

Hi LLVM-Folks,

as mentioned in an earlier post
(http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-July/051677.html) I
am currently working on a Back-End for the TriCore processor.
Currently, I am struggling as LLVM could not select zext and load, for
instance, so some of the testcases in test/CodeGen/Generic are not
successfully compiled by my back-end.
Furthermore, I am completely puzzled by the error messages generated.
The testcase 'test/CodeGen/Generic/pr12507.ll' for instance yields:

LLVM ERROR: Cannot select: 0x229dbd0: i64,ch = load 0x226ee70,
0x229d8d0, 0x229d9d0<LD4[FixedStack-1](align=8), zext from i32>
[ID=14]
  0x229d8d0: i64 = FrameIndex<-1> [ORD=1] [ID=3]
  0x229d9d0: i64 = undef [ORD=1] [ID=4]

What exactly does this mean? OK, it means that some load instruction
could not be selected. But why? Is the instruction not supported as it
is (I doubt this as there are such instructions defined according with
appropriate patterns)? Is the addressing mode node supported (how
could I derive this information)? Is there a way how I can extract
that information from these error messages in an "easy" manner?

My other problem is the zext instruction from i32 to i64. In
principle, this is very easy on the TriCore. Zext the argument in the
lower part of the 64bit register pair and write 0 to higher part.
Finally, these parts are glued together using ISD::BUILD_PAIR.
However, when I try to insert such nodes into the DAG within
TriCoreTargetLowering, I run into an assertion:

llc: /home/scheler/git/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp:704:
void llvm::InstrEmitter::EmitMachineNode(llvm::SDNode*, bool, bool,
llvm::DenseMap<llvm::SDValue, unsigned int>&): Assertion
`NumMIOperands >= II.getNumOperands() && NumMIOperands <=
II.getNumOperands()+II.getNumImplicitDefs() && "#operands for dag node
doesn't match .td file!"' failed.

Currently, I am not even able to find out which instruction is messed
up here (dumping the node via the dump-Method yields "<<Unknown
Machine Node #65434>>"). Can I use "machine nodes" and "normal nodes"
when lowering a specific instruction within the TargetLowering?

Any hints are highly welcome!

Ciao, Fabian

If you run llc with -debug-only=isel, it will dump the decision process
for the lowering of each instruction. The index numbers in that dump
refer to predicates in TriCoreGenDAGISel.inc. This should help you
figure out why it isn't being selected.

-Tom

From: llvmdev-bounces@cs.uiuc.edu [mailto:llvmdev-bounces@cs.uiuc.edu]
On Behalf Of Fabian Scheler
Sent: Wednesday, August 15, 2012 9:12 AM
To: LLVM Developers Mailing List
Subject: [LLVMdev] More Back-End Porting Troubles

Hi LLVM-Folks,

as mentioned in an earlier post
(http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-July/051677.html) I
am currently working on a Back-End for the TriCore processor.
Currently, I am struggling as LLVM could not select zext and load, for
instance, so some of the testcases in test/CodeGen/Generic are not
successfully compiled by my back-end.
Furthermore, I am completely puzzled by the error messages generated.
The testcase 'test/CodeGen/Generic/pr12507.ll' for instance yields:

LLVM ERROR: Cannot select: 0x229dbd0: i64,ch = load 0x226ee70,
0x229d8d0, 0x229d9d0<LD4[FixedStack-1](align=8), zext from i32>
[ID=14]
  0x229d8d0: i64 = FrameIndex<-1> [ORD=1] [ID=3]
  0x229d9d0: i64 = undef [ORD=1] [ID=4]

[Villmow, Micah] This is a zero extending load and not just a normal load. Do you handle the pattern fragment zextload in your tablegen?
You can try to do setLoadExtAction(ISD::ZEXTLOAD, MVT::i64, Expand); in your ISelLowering constructor if you don't support this natively.

What exactly does this mean? OK, it means that some load instruction
could not be selected. But why? Is the instruction not supported as it
is (I doubt this as there are such instructions defined according with
appropriate patterns)? Is the addressing mode node supported (how
could I derive this information)? Is there a way how I can extract
that information from these error messages in an "easy" manner?

My other problem is the zext instruction from i32 to i64. In
principle, this is very easy on the TriCore. Zext the argument in the
lower part of the 64bit register pair and write 0 to higher part.
Finally, these parts are glued together using ISD::BUILD_PAIR.
However, when I try to insert such nodes into the DAG within
TriCoreTargetLowering, I run into an assertion:

llc:
/home/scheler/git/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp:704:
void llvm::InstrEmitter::EmitMachineNode(llvm::SDNode*, bool, bool,
llvm::DenseMap<llvm::SDValue, unsigned int>&): Assertion
`NumMIOperands >= II.getNumOperands() && NumMIOperands <=
II.getNumOperands()+II.getNumImplicitDefs() && "#operands for dag node
doesn't match .td file!"' failed.

Currently, I am not even able to find out which instruction is messed
up here (dumping the node via the dump-Method yields "<<Unknown
Machine Node #65434>>"). Can I use "machine nodes" and "normal nodes"
when lowering a specific instruction within the TargetLowering?

[Villmow, Micah] Have you tried using a tablegen pattern here? I find it is easier for simple conversions like this than using C++ code.
For example our backend does this with:
def uitoli64rr:Pat < (i64 (zext GPRI32:$src)), (LCREATEi64rr GPRI32:$src, (LOADCONSTi32 0)) >;
Where LCREATE is a machine instruction that does similar to ISD::BUILD_PAIR from two i32's and outputs a i64.

Hi LLVM-Folks,

Currently, I am not even able to find out which instruction is messed
up here (dumping the node via the dump-Method yields “<<Unknown
Machine Node #65434>>”). Can I use “machine nodes” and “normal nodes”
when lowering a specific instruction within the TargetLowering?

Usually, when I see this type of error in the X86 target, I use the following function to narrow down the search:

/// getTargetNodeName - This method returns the name of a target specific
/// DAG node.
virtual const char *getTargetNodeName(unsigned Opcode) const;

If I’m not mistaken, the normal dump method returns names for ISD Opcodes and not for target specific opcodes, in my case X86ISD Opcodes.

If you do dump(CurDAG) then it will resolve machine nodes for you. See llvm/include/llvm/CodeGen/SelectionDAGNodes.h

Hi,

first of all: thanks for your kind, very helpful and unbelievable fast response!

as mentioned in an earlier post
(http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-July/051677.html) I
am currently working on a Back-End for the TriCore processor.
Currently, I am struggling as LLVM could not select zext and load, for
instance, so some of the testcases in test/CodeGen/Generic are not
successfully compiled by my back-end.
Furthermore, I am completely puzzled by the error messages generated.
The testcase 'test/CodeGen/Generic/pr12507.ll' for instance yields:

LLVM ERROR: Cannot select: 0x229dbd0: i64,ch = load 0x226ee70,
0x229d8d0, 0x229d9d0<LD4[FixedStack-1](align=8), zext from i32>
[ID=14]
  0x229d8d0: i64 = FrameIndex<-1> [ORD=1] [ID=3]
  0x229d9d0: i64 = undef [ORD=1] [ID=4]

[Villmow, Micah] This is a zero extending load and not just a normal load. Do you handle the pattern fragment zextload in your tablegen?
You can try to do setLoadExtAction(ISD::ZEXTLOAD, MVT::i64, Expand); in your ISelLowering constructor if you don't support this natively.

This really brought me forward as I just missed setLoadExtAction & Co
up to now, I just was aware of setOperationAction.

What exactly does this mean? OK, it means that some load instruction
could not be selected. But why? Is the instruction not supported as it
is (I doubt this as there are such instructions defined according with
appropriate patterns)? Is the addressing mode node supported (how
could I derive this information)? Is there a way how I can extract
that information from these error messages in an "easy" manner?

My other problem is the zext instruction from i32 to i64. In
principle, this is very easy on the TriCore. Zext the argument in the
lower part of the 64bit register pair and write 0 to higher part.
Finally, these parts are glued together using ISD::BUILD_PAIR.
However, when I try to insert such nodes into the DAG within
TriCoreTargetLowering, I run into an assertion:

llc:
/home/scheler/git/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp:704:
void llvm::InstrEmitter::EmitMachineNode(llvm::SDNode*, bool, bool,
llvm::DenseMap<llvm::SDValue, unsigned int>&): Assertion
`NumMIOperands >= II.getNumOperands() && NumMIOperands <=
II.getNumOperands()+II.getNumImplicitDefs() && "#operands for dag node
doesn't match .td file!"' failed.

Currently, I am not even able to find out which instruction is messed
up here (dumping the node via the dump-Method yields "<<Unknown
Machine Node #65434>>"). Can I use "machine nodes" and "normal nodes"
when lowering a specific instruction within the TargetLowering?

If you do dump(CurDAG) then it will resolve machine nodes for you.
See llvm/include /llvm/CodeGen/SelectionDAGNodes.h

By using dump(CurDAG) I was finally able to find out the problematic
instruction. It was defined in TriCoreInstrInfo.td but did not have an
associated pattern (the pattern is empty ''). Furthermore, this
instruction was not used anywhere else in the TriCore back-end, so I
commented it out. This resulted in the same assertion being triggered
and again no pattern was associated with the problematic instruction.
After commenting out enough of these instructions the assertion was
not triggered any more, this is the current state.

Is '' supposed to be a catch-all-pattern or a pattern that never
matches? Is this a problem that results from the back-end
implementation or is it a general problem (there are more back-ends
having ''-patterns).

[Villmow, Micah] Have you tried using a tablegen pattern here? I find it is easier for simple conversions like this than using C++ code.
For example our backend does this with:
def uitoli64rr:Pat < (i64 (zext GPRI32:$src)), (LCREATEi64rr GPRI32:$src, (LOADCONSTi32 0)) >;
Where LCREATE is a machine instruction that does similar to ISD::BUILD_PAIR from two i32's and outputs a i64.

I already tried to use a pattern, but for some reason I messed it up.
Giving it another try now, I finally succeeded :slight_smile: And yes, it is much
easier than doing it in C++.

Ciao, Fabian

From: Fabian Scheler [mailto:fabian.scheler@gmail.com]
Sent: Thursday, August 16, 2012 4:58 AM
To: LLVM Developers Mailing List; Villmow, Micah
Cc: Stellard, Thomas; cameron.mcinally@nyu.edu
Subject: Re: [LLVMdev] More Back-End Porting Troubles

Hi,

first of all: thanks for your kind, very helpful and unbelievable fast
response!

[Villmow, Micah] No problem, glad I could help.

>> as mentioned in an earlier post
>> (http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-July/051677.html) I
>> am currently working on a Back-End for the TriCore processor.
>> Currently, I am struggling as LLVM could not select zext and load,
>> for instance, so some of the testcases in test/CodeGen/Generic are
>> not successfully compiled by my back-end.
>> Furthermore, I am completely puzzled by the error messages generated.
>> The testcase 'test/CodeGen/Generic/pr12507.ll' for instance yields:
>>
>> LLVM ERROR: Cannot select: 0x229dbd0: i64,ch = load 0x226ee70,
>> 0x229d8d0, 0x229d9d0<LD4[FixedStack-1](align=8), zext from i32>
>> [ID=14]
>> 0x229d8d0: i64 = FrameIndex<-1> [ORD=1] [ID=3]
>> 0x229d9d0: i64 = undef [ORD=1] [ID=4]
> [Villmow, Micah] This is a zero extending load and not just a normal
load. Do you handle the pattern fragment zextload in your tablegen?
> You can try to do setLoadExtAction(ISD::ZEXTLOAD, MVT::i64, Expand);
in your ISelLowering constructor if you don't support this natively.
>

This really brought me forward as I just missed setLoadExtAction & Co up
to now, I just was aware of setOperationAction.

[Villmow, Micah] Yep, this is relatively new.

>> What exactly does this mean? OK, it means that some load instruction
>> could not be selected. But why? Is the instruction not supported as
>> it is (I doubt this as there are such instructions defined according
>> with appropriate patterns)? Is the addressing mode node supported
>> (how could I derive this information)? Is there a way how I can
>> extract that information from these error messages in an "easy"
manner?
>>
>> My other problem is the zext instruction from i32 to i64. In
>> principle, this is very easy on the TriCore. Zext the argument in the
>> lower part of the 64bit register pair and write 0 to higher part.
>> Finally, these parts are glued together using ISD::BUILD_PAIR.
>> However, when I try to insert such nodes into the DAG within
>> TriCoreTargetLowering, I run into an assertion:
>>
>> llc:
>> /home/scheler/git/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp:704:
>> void llvm::InstrEmitter::EmitMachineNode(llvm::SDNode*, bool, bool,
>> llvm::DenseMap<llvm::SDValue, unsigned int>&): Assertion
>> `NumMIOperands >= II.getNumOperands() && NumMIOperands <=
>> II.getNumOperands()+II.getNumImplicitDefs() && "#operands for dag
>> node doesn't match .td file!"' failed.
>>
>> Currently, I am not even able to find out which instruction is messed
>> up here (dumping the node via the dump-Method yields "<<Unknown
>> Machine Node #65434>>"). Can I use "machine nodes" and "normal nodes"
>> when lowering a specific instruction within the TargetLowering?
>
> If you do dump(CurDAG) then it will resolve machine nodes for you.
> See llvm/include /llvm/CodeGen/SelectionDAGNodes.h
>

By using dump(CurDAG) I was finally able to find out the problematic
instruction. It was defined in TriCoreInstrInfo.td but did not have an
associated pattern (the pattern is empty ''). Furthermore, this
instruction was not used anywhere else in the TriCore back-end, so I
commented it out. This resulted in the same assertion being triggered
and again no pattern was associated with the problematic instruction.
After commenting out enough of these instructions the assertion was not
triggered any more, this is the current state.

Is '' supposed to be a catch-all-pattern or a pattern that never
matches? Is this a problem that results from the back-end implementation
or is it a general problem (there are more back-ends having ''-
patterns).

[Villmow, Micah] This just means that there is no pattern so the only way to generate this instruction is by manually generating it. We use this quite extensively in the AMDIL backend for memory operations and flow control. We generate pseudo-instructions that are selected at ISel time and then run custom passes that transform them into the real HW instructions. Since they aren't selected at ISel time, they have no pattern.

By using dump(CurDAG) I was finally able to find out the problematic
instruction. It was defined in TriCoreInstrInfo.td but did not have an
associated pattern (the pattern is empty ''). Furthermore, this
instruction was not used anywhere else in the TriCore back-end, so I
commented it out. This resulted in the same assertion being triggered
and again no pattern was associated with the problematic instruction.
After commenting out enough of these instructions the assertion was not
triggered any more, this is the current state.

Is '' supposed to be a catch-all-pattern or a pattern that never
matches? Is this a problem that results from the back-end implementation
or is it a general problem (there are more back-ends having ''-
patterns).

[Villmow, Micah] This just means that there is no pattern so the only way to generate this instruction is by manually generating it. We use this quite extensively in the AMDIL backend for memory operations and flow control. We generate pseudo-instructions that are selected at ISel time and then run custom passes that transform them into the real HW instructions. Since they aren't selected at ISel time, they have no pattern.

OK, so these patterns work as I expected :slight_smile: The astonishing thing
here is: I don't find a single place where such an SDNode is created
manually. And after commenting out these instructions from the
tablegen file everything seems to be fine, but if those
instruction-nodes were created manually, I should not be able to
compile the back-end, right?

Ciao, Fabian