diff options
author | Craig Topper <craig.topper@intel.com> | 2018-02-20 17:41:00 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@intel.com> | 2018-02-20 17:41:00 +0000 |
commit | 010ae8dcbbd8861f4e9f6883218b2e51c3163b9c (patch) | |
tree | 1a6402191cc334268b8f65661bff3f080b20e71f /llvm/lib | |
parent | 563c901bac5ea12b8364c2c38c2264c4c1d027ec (diff) | |
download | bcm5719-llvm-010ae8dcbbd8861f4e9f6883218b2e51c3163b9c.tar.gz bcm5719-llvm-010ae8dcbbd8861f4e9f6883218b2e51c3163b9c.zip |
[X86] Promote 16-bit cmovs to 32-bits
This allows us to avoid an opsize prefix. And forcing some move immediates to i32 avoids a length changing prefix on those instructions.
This mostly replaces the existing combine we had for zext/sext+cmov of constants. I left in a case for sign extending a 32 bit cmov of constants to 64 bits.
Differential Revision: https://reviews.llvm.org/D43327
llvm-svn: 325601
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 57 |
1 files changed, 54 insertions, 3 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index c6916fdf1a1..2a63c9a8545 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -18713,6 +18713,15 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const { } } + // Promote i16 cmovs if it won't prevent folding a load. + if (Op.getValueType() == MVT::i16 && !MayFoldLoad(Op1) && !MayFoldLoad(Op2)) { + Op1 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, Op1); + Op2 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, Op2); + SDValue Ops[] = { Op2, Op1, CC, Cond }; + SDValue Cmov = DAG.getNode(X86ISD::CMOV, DL, MVT::i32, Ops); + return DAG.getNode(ISD::TRUNCATE, DL, Op.getValueType(), Cmov); + } + // X86ISD::CMOV means set the result (which is operand 1) to the RHS if // condition is true. SDValue Ops[] = { Op2, Op1, CC, Cond }; @@ -35935,12 +35944,54 @@ static SDValue combineBT(SDNode *N, SelectionDAG &DAG, return SDValue(); } -static SDValue combineSignExtendInReg(SDNode *N, SelectionDAG &DAG, - const X86Subtarget &Subtarget) { +// Try to combine sext_in_reg of a cmov of constants by extending the constants. +static SDValue combineSextInRegCmov(SDNode *N, SelectionDAG &DAG) { EVT VT = N->getValueType(0); - if (!VT.isVector()) + + SDValue N0 = N->getOperand(0); + SDValue N1 = N->getOperand(1); + EVT ExtraVT = cast<VTSDNode>(N1)->getVT(); + + if (ExtraVT != MVT::i16) + return SDValue(); + + // Look through single use any_extends. + if (N0.getOpcode() == ISD::ANY_EXTEND && N0.hasOneUse()) + N0 = N0.getOperand(0); + + // See if we have a single use cmov. + if (N0.getOpcode() != X86ISD::CMOV || !N0.hasOneUse()) + return SDValue(); + + SDValue CMovOp0 = N0.getOperand(0); + SDValue CMovOp1 = N0.getOperand(1); + + // Make sure both operands are constants. + if (!isa<ConstantSDNode>(CMovOp0.getNode()) || + !isa<ConstantSDNode>(CMovOp1.getNode())) return SDValue(); + SDLoc DL(N); + + // If we looked through an any_extend above, add one to the constants. + if (N0.getValueType() != VT) { + CMovOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, VT, CMovOp0); + CMovOp1 = DAG.getNode(ISD::ANY_EXTEND, DL, VT, CMovOp1); + } + + CMovOp0 = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, CMovOp0, N1); + CMovOp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, CMovOp1, N1); + + return DAG.getNode(X86ISD::CMOV, DL, VT, CMovOp0, CMovOp1, + N0.getOperand(2), N0.getOperand(3)); +} + +static SDValue combineSignExtendInReg(SDNode *N, SelectionDAG &DAG, + const X86Subtarget &Subtarget) { + if (SDValue V = combineSextInRegCmov(N, DAG)) + return V; + + EVT VT = N->getValueType(0); SDValue N0 = N->getOperand(0); SDValue N1 = N->getOperand(1); EVT ExtraVT = cast<VTSDNode>(N1)->getVT(); |