Unsigned int multiplication using UMUL_LOHI


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.
    // See if multiply or divide can be lowered using two-result
    // 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),

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.


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.