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
On 5/7/21 5:40 PM, Craig Topper wrote:> 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.
>
> ~Craig
>
>
> On Fri, May 7, 2021 at 2:01 PM Bagel via llvm-dev <llvm-dev at
lists.llvm.org
> <mailto:llvm-dev at lists.llvm.org>> wrote:
>
> 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
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
> <https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev>
>