[isel] OPC_EmitMergeInputChains failure on intrinsic lowering.

Hi,

I’m still missing something on the operations used by the DAG Pattern ISel state machine, in particular operations like ‘OPC_EmitMergeInputChains’.

I’ve define an architecture specific intrinsic mapping to the target NOP operation, like this:

def : Pat<(int_clp_nop), (NOP)>;

In many ‘contexts’, it works perfectly. But prior to ‘TokenFactor’ it fails as in following example:

Total amount of phi nodes to update: 2

Node 0 : (0x31d8508, 2147483651)

Node 1 : (0x31d8568, 2147483652)

Initial selection DAG: BB#1 ‘_start:while.body’

SelectionDAG has 24 nodes:

t0: ch = EntryToken

t4: i32,ch = CopyFromReg t0, Register:i32 %vreg1

t12: i32,ch = CopyFromReg t0, Register:i32 %vreg0

t13: i32 = add t12, t4

t15: ch = CopyToReg t0, Register:i32 %vreg2, t13

t5: ch = llvm.clp.writeapb.i32 t0, TargetConstant:i16<398>, Constant:i32<24574>, t4

t7: ch = llvm.clp.nop t5, TargetConstant:i16<390>

t8: ch = llvm.clp.nop t7, TargetConstant:i16<390>

t9: ch = llvm.clp.nop t8, TargetConstant:i16<390>

t10: ch = llvm.clp.nop t9, TargetConstant:i16<390>

t20: ch = TokenFactor t15, t10

t18: i1 = setcc t13, Constant:i32<100>, setlt:ch

t21: ch = brcond t20, t18, BasicBlock:ch<while.body 0x31d8458>

t23: ch = br t21, BasicBlock:ch<while.end 0x31d85c8>

Selecting: t20: ch = TokenFactor t15, t10

Selecting: t10: ch = llvm.clp.nop t9, TargetConstant:i16<390>

ISEL: Starting pattern match on root node: t10: ch = llvm.clp.nop t9, TargetConstant:i16<390>

Initial Opcode index to 5

Skipped scope entry (due to false predicate) at index 8, continuing at 44

Skipped scope entry (due to false predicate) at index 45, continuing at 68

Skipped scope entry (due to false predicate) at index 69, continuing at 92

Skipped scope entry (due to false predicate) at index 93, continuing at 116

Match failed at index 120

Continuing at 127

Match failed at index 128

LLVM ERROR: Cannot select: intrinsic %llvm.clp.nop

Hi Dominique,

TokenFactors are merge points for multiple chains. A chain is an artificial dependency that is used to maintain (linear) ordering between operations. A TokenFactor takes several input chains, and ensures that the output chain is preceded by each of the inputs (so it allows non-linear ordering).

The most common cause of failure during instruction selection in MergeInputChains is that the chains form a loop. The DAG after instruction selection is still a DAG (except that all nodes are now machine nodes), and it will still have chains in it. When instructions are selected, old chains can be replaced with new chains, and somewhere in that process a mistake can cause a loop to be formed.

It is also a fairly tedious issue to debug. You can try to dump the DAG right before the OPC_EmitMergeInputChains is executed (in SelectCodeCommon, in SelectionDAGISel.cpp) to see if the problem is evident. Then you can work backwards to see where the problem first shows up.

-Krzysztof