forked from OSchip/llvm-project
[X86] X86ISelLowering::combineSextInRegCmov(): also handle i8 CMOV's
Summary: As noted by @andreadb in https://reviews.llvm.org/D59035#inline-525780 If we have `sext (trunc (cmov C0, C1) to i8)`, we can instead do `cmov (sext (trunc C0 to i8)), (sext (trunc C1 to i8))` Reviewers: craig.topper, andreadb, RKSimon Reviewed By: craig.topper Subscribers: llvm-commits, andreadb Tags: #llvm Differential Revision: https://reviews.llvm.org/D59412 llvm-svn: 356301
This commit is contained in:
parent
b6e376ddfa
commit
9f37790608
|
@ -39937,18 +39937,24 @@ static SDValue combineBT(SDNode *N, SelectionDAG &DAG,
|
|||
|
||||
// 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);
|
||||
assert(N->getOpcode() == ISD::SIGN_EXTEND_INREG);
|
||||
|
||||
EVT DstVT = N->getValueType(0);
|
||||
|
||||
SDValue N0 = N->getOperand(0);
|
||||
SDValue N1 = N->getOperand(1);
|
||||
EVT ExtraVT = cast<VTSDNode>(N1)->getVT();
|
||||
|
||||
if (ExtraVT != MVT::i16)
|
||||
if (ExtraVT != MVT::i8 && ExtraVT != MVT::i16)
|
||||
return SDValue();
|
||||
|
||||
// Look through single use any_extends.
|
||||
if (N0.getOpcode() == ISD::ANY_EXTEND && N0.hasOneUse())
|
||||
// Look through single use any_extends / truncs.
|
||||
SDValue IntermediateBitwidthOp;
|
||||
if ((N0.getOpcode() == ISD::ANY_EXTEND || N0.getOpcode() == ISD::TRUNCATE) &&
|
||||
N0.hasOneUse()) {
|
||||
IntermediateBitwidthOp = N0;
|
||||
N0 = N0.getOperand(0);
|
||||
}
|
||||
|
||||
// See if we have a single use cmov.
|
||||
if (N0.getOpcode() != X86ISD::CMOV || !N0.hasOneUse())
|
||||
|
@ -39964,21 +39970,37 @@ static SDValue combineSextInRegCmov(SDNode *N, SelectionDAG &DAG) {
|
|||
|
||||
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);
|
||||
// If we looked through an any_extend/trunc above, add one to the constants.
|
||||
if (IntermediateBitwidthOp) {
|
||||
unsigned IntermediateOpc = IntermediateBitwidthOp.getOpcode();
|
||||
CMovOp0 = DAG.getNode(IntermediateOpc, DL, DstVT, CMovOp0);
|
||||
CMovOp1 = DAG.getNode(IntermediateOpc, DL, DstVT, CMovOp1);
|
||||
}
|
||||
|
||||
CMovOp0 = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, CMovOp0, N1);
|
||||
CMovOp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, CMovOp1, N1);
|
||||
CMovOp0 = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, DstVT, CMovOp0, N1);
|
||||
CMovOp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, DstVT, CMovOp1, N1);
|
||||
|
||||
return DAG.getNode(X86ISD::CMOV, DL, VT, CMovOp0, CMovOp1,
|
||||
N0.getOperand(2), N0.getOperand(3));
|
||||
EVT CMovVT = DstVT;
|
||||
// We do not want i16 CMOV's. Promote to i32 and truncate afterwards.
|
||||
if (DstVT == MVT::i16) {
|
||||
CMovVT = MVT::i32;
|
||||
CMovOp0 = DAG.getNode(ISD::ZERO_EXTEND, DL, CMovVT, CMovOp0);
|
||||
CMovOp1 = DAG.getNode(ISD::ZERO_EXTEND, DL, CMovVT, CMovOp1);
|
||||
}
|
||||
|
||||
SDValue CMov = DAG.getNode(X86ISD::CMOV, DL, CMovVT, CMovOp0, CMovOp1,
|
||||
N0.getOperand(2), N0.getOperand(3));
|
||||
|
||||
if (CMovVT != DstVT)
|
||||
CMov = DAG.getNode(ISD::TRUNCATE, DL, DstVT, CMov);
|
||||
|
||||
return CMov;
|
||||
}
|
||||
|
||||
static SDValue combineSignExtendInReg(SDNode *N, SelectionDAG &DAG,
|
||||
const X86Subtarget &Subtarget) {
|
||||
assert(N->getOpcode() == ISD::SIGN_EXTEND_INREG);
|
||||
|
||||
if (SDValue V = combineSextInRegCmov(N, DAG))
|
||||
return V;
|
||||
|
||||
|
|
|
@ -152,10 +152,9 @@ define i16 @cmov_spromotion_8_to_16(i1 %c) {
|
|||
; CMOV-LABEL: cmov_spromotion_8_to_16:
|
||||
; CMOV: # %bb.0:
|
||||
; CMOV-NEXT: testb $1, %dil
|
||||
; CMOV-NEXT: movl $117, %eax
|
||||
; CMOV-NEXT: movl $237, %ecx
|
||||
; CMOV-NEXT: cmovnel %eax, %ecx
|
||||
; CMOV-NEXT: movsbl %cl, %eax
|
||||
; CMOV-NEXT: movl $117, %ecx
|
||||
; CMOV-NEXT: movl $65517, %eax # imm = 0xFFED
|
||||
; CMOV-NEXT: cmovnel %ecx, %eax
|
||||
; CMOV-NEXT: # kill: def $ax killed $ax killed $eax
|
||||
; CMOV-NEXT: retq
|
||||
;
|
||||
|
@ -179,10 +178,9 @@ define i32 @cmov_spromotion_8_to_32(i1 %c) {
|
|||
; CMOV-LABEL: cmov_spromotion_8_to_32:
|
||||
; CMOV: # %bb.0:
|
||||
; CMOV-NEXT: testb $1, %dil
|
||||
; CMOV-NEXT: movl $126, %eax
|
||||
; CMOV-NEXT: movl $255, %ecx
|
||||
; CMOV-NEXT: cmovnel %eax, %ecx
|
||||
; CMOV-NEXT: movsbl %cl, %eax
|
||||
; CMOV-NEXT: movl $126, %ecx
|
||||
; CMOV-NEXT: movl $-1, %eax
|
||||
; CMOV-NEXT: cmovnel %ecx, %eax
|
||||
; CMOV-NEXT: retq
|
||||
;
|
||||
; NO_CMOV-LABEL: cmov_spromotion_8_to_32:
|
||||
|
@ -204,10 +202,9 @@ define i64 @cmov_spromotion_8_to_64(i1 %c) {
|
|||
; CMOV-LABEL: cmov_spromotion_8_to_64:
|
||||
; CMOV: # %bb.0:
|
||||
; CMOV-NEXT: testb $1, %dil
|
||||
; CMOV-NEXT: movl $126, %eax
|
||||
; CMOV-NEXT: movl $255, %ecx
|
||||
; CMOV-NEXT: cmovnel %eax, %ecx
|
||||
; CMOV-NEXT: movsbq %cl, %rax
|
||||
; CMOV-NEXT: movl $126, %ecx
|
||||
; CMOV-NEXT: movq $-1, %rax
|
||||
; CMOV-NEXT: cmovneq %rcx, %rax
|
||||
; CMOV-NEXT: retq
|
||||
;
|
||||
; NO_CMOV-LABEL: cmov_spromotion_8_to_64:
|
||||
|
|
Loading…
Reference in New Issue