diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index 7e171d770331..f6de519a1c87 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -3411,24 +3411,11 @@ void X86DAGToDAGISel::Select(SDNode *Node) { getI8Imm(ShlVal, dl)); return; } - case X86ISD::UMUL8: - case X86ISD::SMUL8: { - SDValue N0 = Node->getOperand(0); - SDValue N1 = Node->getOperand(1); - - unsigned Opc = (Opcode == X86ISD::SMUL8 ? X86::IMUL8r : X86::MUL8r); - - SDValue InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::AL, - N0, SDValue()).getValue(1); - - SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32); - SDValue Ops[] = {N1, InFlag}; - SDNode *CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops); - - ReplaceNode(Node, CNode); - return; - } - + case X86ISD::SMUL: + // i16/i32/i64 are handled with isel patterns. + if (NVT != MVT::i8) + break; + LLVM_FALLTHROUGH; case X86ISD::UMUL: { SDValue N0 = Node->getOperand(0); SDValue N1 = Node->getOperand(1); @@ -3436,7 +3423,10 @@ void X86DAGToDAGISel::Select(SDNode *Node) { unsigned LoReg, Opc; switch (NVT.SimpleTy) { default: llvm_unreachable("Unsupported VT!"); - // MVT::i8 is handled by X86ISD::UMUL8. + case MVT::i8: + LoReg = X86::AL; + Opc = Opcode == X86ISD::SMUL ? X86::IMUL8r : X86::MUL8r; + break; case MVT::i16: LoReg = X86::AX; Opc = X86::MUL16r; break; case MVT::i32: LoReg = X86::EAX; Opc = X86::MUL32r; break; case MVT::i64: LoReg = X86::RAX; Opc = X86::MUL64r; break; @@ -3445,11 +3435,19 @@ void X86DAGToDAGISel::Select(SDNode *Node) { SDValue InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg, N0, SDValue()).getValue(1); - SDVTList VTs = CurDAG->getVTList(NVT, NVT, MVT::i32); + // i16/i32/i64 use an instruction that produces a low and high result even + // though only the low result is used. + SDVTList VTs; + if (NVT == MVT::i8) + VTs = CurDAG->getVTList(NVT, MVT::i32); + else + VTs = CurDAG->getVTList(NVT, NVT, MVT::i32); + SDValue Ops[] = {N1, InFlag}; SDNode *CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops); - - ReplaceNode(Node, CNode); + ReplaceUses(SDValue(Node, 0), SDValue(CNode, 0)); + ReplaceUses(SDValue(Node, 1), SDValue(CNode, NVT == MVT::i8 ? 1 : 2)); + CurDAG->RemoveDeadNode(Node); return; } diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 2023e38d480b..6515ea4c9821 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -19633,23 +19633,14 @@ getX86XALUOOp(X86::CondCode &Cond, SDValue Op, SelectionDAG &DAG) { Cond = X86::COND_B; break; case ISD::SMULO: - BaseOp = Op.getValueType() == MVT::i8 ? X86ISD::SMUL8 : X86ISD::SMUL; + BaseOp = X86ISD::SMUL; Cond = X86::COND_O; break; - case ISD::UMULO: { // i64, i8 = umulo lhs, rhs --> i64, i64, i32 umul lhs,rhs - if (Op.getValueType() == MVT::i8) { - BaseOp = X86ISD::UMUL8; - Cond = X86::COND_O; - break; - } - SDVTList VTs = DAG.getVTList(Op.getValueType(), Op.getValueType(), - MVT::i32); - Value = DAG.getNode(X86ISD::UMUL, DL, VTs, LHS, RHS); - Overflow = Value.getValue(2); + case ISD::UMULO: + BaseOp = X86ISD::UMUL; Cond = X86::COND_O; break; } - } if (BaseOp) { // Also sets EFLAGS. @@ -19683,14 +19674,11 @@ static bool isX86LogicalCmp(SDValue Op) { return true; if (Op.getResNo() == 1 && (Opc == X86ISD::ADD || Opc == X86ISD::SUB || Opc == X86ISD::ADC || - Opc == X86ISD::SBB || Opc == X86ISD::SMUL || + Opc == X86ISD::SBB || Opc == X86ISD::SMUL || Opc == X86ISD::UMUL || Opc == X86ISD::INC || Opc == X86ISD::DEC || Opc == X86ISD::OR || Opc == X86ISD::XOR || Opc == X86ISD::AND)) return true; - if (Op.getResNo() == 2 && Opc == X86ISD::UMUL) - return true; - return false; } @@ -27085,8 +27073,6 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const { case X86ISD::SBB: return "X86ISD::SBB"; case X86ISD::SMUL: return "X86ISD::SMUL"; case X86ISD::UMUL: return "X86ISD::UMUL"; - case X86ISD::SMUL8: return "X86ISD::SMUL8"; - case X86ISD::UMUL8: return "X86ISD::UMUL8"; case X86ISD::INC: return "X86ISD::INC"; case X86ISD::DEC: return "X86ISD::DEC"; case X86ISD::OR: return "X86ISD::OR"; diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index ad37576288f5..58c0f958d3c2 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -336,7 +336,7 @@ namespace llvm { CMPM_RND, // Arithmetic operations with FLAGS results. - ADD, SUB, ADC, SBB, SMUL, + ADD, SUB, ADC, SBB, SMUL, UMUL, INC, DEC, OR, XOR, AND, // Bit field extract. @@ -345,12 +345,6 @@ namespace llvm { // Zero High Bits Starting with Specified Bit Position. BZHI, - // LOW, HI, FLAGS = umul LHS, RHS. - UMUL, - - // 8-bit SMUL/UMUL - AX, FLAGS = smul8/umul8 AL, RHS. - SMUL8, UMUL8, - // X86-specific multiply by immediate. MUL_IMM,