Use of custom operations after DAG legalization

I've been working on a backend for a 16-bit microcontroller and I've just updated my base from LLVM 3.4 to LLVM 3.5.0. This threw up a regression failure in my test suite, and having tracked down the cause, I'm now confused about the DAG legalization and optimization process which I thought I understood. I'd be really grateful for advice on whether I've misunderstood how legalization works.

The target doesn't support MUL but does support i8 and i16 UMUL_LOHI and SMUL_LOHI. I custom lower i16 MUL because it's possible to use i8 UMUL_LOHI if the operands meet certain criteria. If this isn't possible, my custom-lowering returns SDValue() and so falls back onto the default expansion, which is to generate i16 SMUL_LOHI and use only the low result. This worked fine when I was using 3.4 but in 3.5.0, the DAG Combiner replaces a SMUL_LOHI whose high result is unused with a MUL. I traced this to r199678 in which the DAG Combiner was changed specifically to allow this replacement when MUL is either Legal or Custom. In 3.4, it was only permitted if MUL was Legal. For my target, the 3.5.0 behaviour isn't acceptable because the subsequent instruction selection will fail as i16 MUL isn't legal. I could work around this by not falling back onto the default expansion for i16 MUL, and instead lowering to a target-specific SMUL_LOHI but I'd rather not duplicate the existing expansion code if possible.

This got me wondering why it's ever permitted for the DAG Combiner, when running post-legalization, to combine to an operation that requires custom lowering. I'd believed that after legalization, all operations were Legal and that none were permitted to be Custom. I see several places in DAGCombine where nodes are combined, post-legalization, to Legal or Custom operations but I can also see other places where only Legal operations are permitted. Is this intentional?

I've hit numerous similar issues with SelectionDAG. They're all difficult to debug because the typical behaviour is an infinite loop, where the back end replaces something generic with something that works for the architecture and then SelectionDAG decides to replace this with the original generic thing. One example is that our architecture supported unaligned loads and stores with some pointer types, but not others.


I'm glad I'm not the only one having issues in this area.

Is anyone able to offer an opinion or answer to the original question, namely: is it permitted for the DAG Combiner to introduce anything other then legal operations when it is running post-legalization?

It seems counter-intuitive to me that illegal operations are be introduced at this stage. However, I see that some backends use Custom to permit a custom-lowering of an operation that is actually natively supported, an example being Mips i32 SELECT.

Steve Montgomery