Javier Martinez
2009-Dec-09 02:23 UTC
[LLVMdev] Unsigned int multiplication using UMUL_LOHI
Hello, I'm having trouble getting LLVM to use UMUL_LOHI instead of MUL for unsigned integers. In the TargetLowering constructor I have: setOperationAction(ISD::MUL, MVT::i32, Expand); setOperationAction(ISD::SMUL_LOHI, MVT::i32, Legal); setOperationAction(ISD::UMUL_LOHI, MVT::i32, Legal); The problem seems to be with the code in LegalizeOp() in LegalizeDAG.cpp. Here's a snipet of the relevant section. [Snipet] // See if multiply or divide can be lowered using two-result operations. // We just need the low half of the multiply; try both the signed // and unsigned forms. If the target supports both SMUL_LOHI and // UMUL_LOHI, form a preference by checking which forms of plain // MULH it supports. bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, VT); bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, VT); bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, VT); bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, VT); unsigned OpToUse = 0; if (HasSMUL_LOHI && !HasMULHS) { OpToUse = ISD::SMUL_LOHI; } else if (HasUMUL_LOHI && !HasMULHU) { OpToUse = ISD::UMUL_LOHI; } else if (HasSMUL_LOHI) { OpToUse = ISD::SMUL_LOHI; } else if (HasUMUL_LOHI) { OpToUse = ISD::UMUL_LOHI; } if (OpToUse) { Results.push_back(DAG.getNode(OpToUse, dl, VTs, Node->getOperand(0), Node->getOperand(1))); break; } [/Snipet] For my target HasSMUL_LOHI and HasUMUL_LOHI are both true while HasMULHS and HasMULHU are both false (default). Under this conditions it doesn't matter if the multiplication is done on integers or unsigned integers at the end of the code snipet OpToUse will be ISD::SMUL_LOHI. Is there a way of fixing this? Thanks, Javier
On Tue, Dec 8, 2009 at 6:23 PM, Javier Martinez <javier at jmartinez.org> wrote:> For my target HasSMUL_LOHI and HasUMUL_LOHI are both true while HasMULHS > and HasMULHU are both false (default). Under this conditions it doesn't > matter if the multiplication is done on integers or unsigned integers at > the end of the code snipet OpToUse will be ISD::SMUL_LOHI. Is there a way > of fixing this?What exactly needs to be fixed? x86, for example, is precisely the same as your target in this respect. -Eli
Javier Martinez
2009-Dec-09 17:43 UTC
[LLVMdev] Unsigned int multiplication using UMUL_LOHI
Thanks Eli. I didn't know that the operand sign didn't affect the operation as I've never done multiplication at the bit level. Javier On Tue, 8 Dec 2009 20:16:23 -0800, Eli Friedman <eli.friedman at gmail.com> wrote:> On Tue, Dec 8, 2009 at 7:16 PM, Javier Martinez <javier at jmartinez.org> > wrote: >> Eli, >> >> I think it is an error for LLVM to select ISD::SMUL_LOHI for UNSIGNED >> integers; isn't it? > > The LLVM mul instruction isn't fundamentally signed or unsigned. For a > 64 * 64 -> 64 multiply, it's perfectly legitimate to use 32 * 32 -> 64 > signed multiply as one of the components. > > -Eli