forked from OSchip/llvm-project
[X86] Don't zero_extend cmov up to i64, stop at i32.
Zero extend from i32 to i64 is free. So extend from i16 to i32, and then use a free zero extend to finish. llvm-svn: 325317
This commit is contained in:
parent
6de1e858a1
commit
5d9e301042
|
@ -36028,7 +36028,7 @@ static SDValue getDivRem8(SDNode *N, SelectionDAG &DAG) {
|
||||||
// promotion).
|
// promotion).
|
||||||
static SDValue combineToExtendCMOV(SDNode *Extend, SelectionDAG &DAG) {
|
static SDValue combineToExtendCMOV(SDNode *Extend, SelectionDAG &DAG) {
|
||||||
SDValue CMovN = Extend->getOperand(0);
|
SDValue CMovN = Extend->getOperand(0);
|
||||||
if (CMovN.getOpcode() != X86ISD::CMOV)
|
if (CMovN.getOpcode() != X86ISD::CMOV || !CMovN.hasOneUse())
|
||||||
return SDValue();
|
return SDValue();
|
||||||
|
|
||||||
EVT TargetVT = Extend->getValueType(0);
|
EVT TargetVT = Extend->getValueType(0);
|
||||||
|
@ -36039,20 +36039,35 @@ static SDValue combineToExtendCMOV(SDNode *Extend, SelectionDAG &DAG) {
|
||||||
SDValue CMovOp0 = CMovN.getOperand(0);
|
SDValue CMovOp0 = CMovN.getOperand(0);
|
||||||
SDValue CMovOp1 = CMovN.getOperand(1);
|
SDValue CMovOp1 = CMovN.getOperand(1);
|
||||||
|
|
||||||
bool DoPromoteCMOV =
|
if (!isa<ConstantSDNode>(CMovOp0.getNode()) ||
|
||||||
(VT == MVT::i16 && (TargetVT == MVT::i32 || TargetVT == MVT::i64)) &&
|
!isa<ConstantSDNode>(CMovOp0.getNode()))
|
||||||
CMovN.hasOneUse() &&
|
|
||||||
(isa<ConstantSDNode>(CMovOp0.getNode()) &&
|
|
||||||
isa<ConstantSDNode>(CMovOp1.getNode()));
|
|
||||||
|
|
||||||
if (!DoPromoteCMOV)
|
|
||||||
return SDValue();
|
return SDValue();
|
||||||
|
|
||||||
CMovOp0 = DAG.getNode(ExtendOpcode, DL, TargetVT, CMovOp0);
|
// Only extend to i32 or i64.
|
||||||
CMovOp1 = DAG.getNode(ExtendOpcode, DL, TargetVT, CMovOp1);
|
if (TargetVT != MVT::i32 && TargetVT != MVT::i64)
|
||||||
|
return SDValue();
|
||||||
|
|
||||||
return DAG.getNode(X86ISD::CMOV, DL, TargetVT, CMovOp0, CMovOp1,
|
// Only extend from i16.
|
||||||
CMovN.getOperand(2), CMovN.getOperand(3));
|
if (VT != MVT::i16)
|
||||||
|
return SDValue();
|
||||||
|
|
||||||
|
// If this a zero extend to i64, we should only extend to i32 and use a free
|
||||||
|
// zero extend to finish.
|
||||||
|
EVT ExtendVT = TargetVT;
|
||||||
|
if (TargetVT == MVT::i64 && ExtendOpcode == ISD::ZERO_EXTEND)
|
||||||
|
ExtendVT = MVT::i32;
|
||||||
|
|
||||||
|
CMovOp0 = DAG.getNode(ExtendOpcode, DL, ExtendVT, CMovOp0);
|
||||||
|
CMovOp1 = DAG.getNode(ExtendOpcode, DL, ExtendVT, CMovOp1);
|
||||||
|
|
||||||
|
SDValue Res = DAG.getNode(X86ISD::CMOV, DL, ExtendVT, CMovOp0, CMovOp1,
|
||||||
|
CMovN.getOperand(2), CMovN.getOperand(3));
|
||||||
|
|
||||||
|
// Finish extending if needed.
|
||||||
|
if (ExtendVT != TargetVT)
|
||||||
|
Res = DAG.getNode(ISD::ZERO_EXTEND, DL, TargetVT, Res);
|
||||||
|
|
||||||
|
return Res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert (vXiY *ext(vXi1 bitcast(iX))) to extend_in_reg(broadcast(iX)).
|
// Convert (vXiY *ext(vXi1 bitcast(iX))) to extend_in_reg(broadcast(iX)).
|
||||||
|
|
|
@ -115,7 +115,7 @@ define i64 @cmov_zpromotion_16_to_64(i1 %c) {
|
||||||
; CMOV-NEXT: testb $1, %dil
|
; CMOV-NEXT: testb $1, %dil
|
||||||
; CMOV-NEXT: movl $12414, %ecx # imm = 0x307E
|
; CMOV-NEXT: movl $12414, %ecx # imm = 0x307E
|
||||||
; CMOV-NEXT: movl $65535, %eax # imm = 0xFFFF
|
; CMOV-NEXT: movl $65535, %eax # imm = 0xFFFF
|
||||||
; CMOV-NEXT: cmovneq %rcx, %rax
|
; CMOV-NEXT: cmovnel %ecx, %eax
|
||||||
; CMOV-NEXT: retq
|
; CMOV-NEXT: retq
|
||||||
;
|
;
|
||||||
; NO_CMOV-LABEL: cmov_zpromotion_16_to_64:
|
; NO_CMOV-LABEL: cmov_zpromotion_16_to_64:
|
||||||
|
|
Loading…
Reference in New Issue