DAGCombiner question

I have a target for which UDIV/SDIV is legal, UMOD/SMOD requires an
instruction prefix to a divide instruction, and UDIVMOD/SDIVMOD is the same as
UMOD/SMOD.

In DAGCombiner::useDivRem there is this code:

    // If div is legal, it's better to do the normal expansion
    unsigned OtherOpcode = 0;
    if ((Opcode == ISD::SDIV) || (Opcode == ISD::UDIV)) {
      OtherOpcode = isSigned ? ISD::SREM : ISD::UREM;
      if (TLI.isOperationLegalOrCustom(Opcode, VT))
        return SDValue();
    } else {
      OtherOpcode = isSigned ? ISD::SDIV : ISD::UDIV;
      if (TLI.isOperationLegalOrCustom(OtherOpcode, VT))
        return SDValue();
    }

This prevents generation of UDIVMOD/SDIVMOD because UDIV/SDIV is legal.
Why is this check made? An what does "it's better to do the normal expansion"
mean?

Thanks,
brian

Unless I’m mistaken, the code at the bottom of useDivRem will always create a DIVREM node regardless of whether both results are needed. That’s different then what the comment above the function says. All those checks are trying to prevent it from doing that when it would be a bad idea. I think the code might assume that either DIV/REM is supported or DIVREM is supported but not both.

I think the normal expansion it refers to is to use REM if only remainder is needed. Or DIV if only quotient is needed. Or if both results are needed use a div and a mul+sub to calculate the remainder from the quotient.

One thought I had is that you might lie to lowering and DAG combine and say that you only support DIVREM. Then during isel select your DIV or MOD instruction if only one of the results of the DIVREM is used. You can’t do that with an isel pattern though and would need to implement custom code in your ISelDAGToDAG file.

Thanks. I had tried the trick of saying I only support DIVREM. And then I tried doing a custom emitter for them after matching the pattern. But I couldn't figure out how, in a customer emitter, to check if a MachineInstr Operand is subsequently used:
static MachineBasicBlock *emitDIVREM(MachineInstr &MI,
                                        MachineBasicBlock *BB, unsigned inst) {
   unsigned DIV = MI.getOperand(0).getReg();
   unsigned REM = MI.getOperand(1).getReg(); <== how to test if this is used?

So what you are saying is that's too late, and I must have the code in the ISelDAGToDAG phase where I can check for REM usage?

brian

You should be able do it in the custom emitter. I think you can ask MachineRegisterInfo if the virtual register has any uses.

You should be able do it in the custom emitter. I think you can ask MachineRegisterInfo if the virtual register has any uses.

Yes, that does work. Thanks.
The problem with the custom emitter approach is that one ends up with
a lot of BuildMI calls that, in a sense, replace what could be done with normal patterns.

What I really need, I think, is to be able to put a predicate on the *result* register of a pattern that checks if the result is used. If it isn't used then the pattern doesn't match. E.g.:
  [(set GRegs:$div, UsedGRegs:$rem, (sdivrem GRegs:$lhs, GRegs:$rhs))]>;
where UsedGRegs is a predicate that is true if it is a GRegs and it is subsequently used.

I supposed no one else has even needed that so either tablegen doesn't deal with it or I can't find an example of how to do it.

Thanks again, brian