[X86] Remove the separate SMUL8/UMUL8 X86ISD opcodes by merging with SMUL/UMUL. Remove the second result from X86ISD::UMUL.

All of these use custom isel so we can pretty easily detect the differences in the custom code in X86ISelDAGToDAG. The ISD opcodes just need to express the desired semantics not the details of how they would be selected by isel. So unifying them lets us remove the special casing from lowering.

llvm-svn: 350206
This commit is contained in:
Craig Topper 2019-01-02 06:40:11 +00:00
parent d4db122483
commit f7cc7e3201
3 changed files with 25 additions and 47 deletions

View File

@ -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;
}

View File

@ -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";

View File

@ -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,