ISel fails in my back-end to perform instruction selection and I think
it is a bug in ISel.
My target is a CISC architecture. For example it can add two values
and store the result indirectly in memory: ADD (A0), R0, R1
add the
values in register R0
and R1
and stores the result in memory
pointed to by register A0
. Maybe, I should add here that every
instruction has two PredicateOperand
s and one OptionalDefOperand
for conditional execution support.
I have defined an instruction for operations like ADD
with this
addressing modes described above and it works as expected. I have
verified that.
But ISel fails for the operation ADDC
and ADDE
in optimization
level O0
for the described addressing mode (STORE
). I was worried
that this is a fast-isel
problem.
The SelectionDAG for ISel looks like:
Optimized legalized selection DAG: %bb.2 'test_main:for.body'
SelectionDAG has 45 nodes:
t0: ch = EntryToken
...
t55: i32 = TARGETISD::convertBitAddressToByteAddress t54
t28: i32,glue = adde t46, t44, t27:1
t35: ch = store<(store (s32) into %ir.res, align 8)> t14, t28, t34, undef:i32
t38: ch = store<(store (s32) into %ir.res + 4, basealign 8)> t14, t27, t37, undef:i32
t31: ch = TokenFactor t35, t38
t17: ch = br t31, BasicBlock:ch<for.inc 0x7f9f29889780>
This is ok, but in ISel:
ISEL: Starting selection on root node: t35: ch = store<(store (s32) into %ir.res, align 8)> t14, t28, t33, undef:i32
ISEL: Starting pattern match
Initial Opcode index to 5
...
Morphed node: t35: ch,glue = ADDE_x<Mem:(store (s32) into %ir.res, align 8)> t44, t28, t46, t33, Register:i32 $noreg, Register:i32 $noreg, t14, t27:1
ISEL: Match complete!
This is completely wrong:
- operation
ADDE
operandst44
andt46
are swapped, which is
basically ok, becauseADDE
is commutative, but might give a hint - operand
t28
is the node with operationADDE
itself which is
done by the instructionADDE_x
; this is a wrong/illegal operand,
a second match on operationADDE
is kept alive - operands
t33, Register:i32 $noreg, Register:i32 $noreg
are
wrong, the three operands that I add (see comment above) areRegister:i32 $noreg, TargetConstant:i32<0>, Register:i32 $noreg
- the morphed node has 8 operands but should have 7, this raises an
abort
In general the morphed node should have the operands t46, t44, Register:i32 $noreg, TargetConstant:i32<0>, Register:i32 $noreg, t14, t27:1
.
All other matches seem to be correct, except an additional illegal
match on an ADDC
operation, which has no glue
edge. But no other
match has a chain
and a glue
edge.
Any hints how I can track this down? I went through all my uses of
getMachineNode
and BuildMI
, but I can’t find any interference with
the morphed node.