forked from OSchip/llvm-project
Fixed DAGCombine optimizations which generate select_cc for targets
that do not support it (X86 does not lower select_cc). PR: 13428 Together with Michael Kuperstein <michael.m.kuperstein@intel.com> llvm-svn: 160619
This commit is contained in:
parent
87f5dc53b2
commit
9056076cab
|
@ -6002,29 +6002,36 @@ SDValue DAGCombiner::visitSINT_TO_FP(SDNode *N) {
|
||||||
return DAG.getNode(ISD::UINT_TO_FP, N->getDebugLoc(), VT, N0);
|
return DAG.getNode(ISD::UINT_TO_FP, N->getDebugLoc(), VT, N0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fold (sint_to_fp (setcc x, y, cc)) -> (select_cc x, y, -1.0, 0.0,, cc)
|
// The next optimizations are desireable only if SELECT_CC can be lowered.
|
||||||
if (N0.getOpcode() == ISD::SETCC && N0.getValueType() == MVT::i1 &&
|
// Check against MVT::Other for SELECT_CC, which is a workaround for targets
|
||||||
!VT.isVector() &&
|
// having to say they don't support SELECT_CC on every type the DAG knows
|
||||||
(!LegalOperations ||
|
// about, since there is no way to mark an opcode illegal at all value types
|
||||||
TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) {
|
// (See also visitSELECT)
|
||||||
SDValue Ops[] =
|
if (TLI.isOperationLegalOrCustom(ISD::SELECT_CC, MVT::Other)) {
|
||||||
{ N0.getOperand(0), N0.getOperand(1),
|
// fold (sint_to_fp (setcc x, y, cc)) -> (select_cc x, y, -1.0, 0.0,, cc)
|
||||||
DAG.getConstantFP(-1.0, VT) , DAG.getConstantFP(0.0, VT),
|
if (N0.getOpcode() == ISD::SETCC && N0.getValueType() == MVT::i1 &&
|
||||||
N0.getOperand(2) };
|
!VT.isVector() &&
|
||||||
return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT, Ops, 5);
|
(!LegalOperations ||
|
||||||
}
|
TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) {
|
||||||
|
SDValue Ops[] =
|
||||||
|
{ N0.getOperand(0), N0.getOperand(1),
|
||||||
|
DAG.getConstantFP(-1.0, VT) , DAG.getConstantFP(0.0, VT),
|
||||||
|
N0.getOperand(2) };
|
||||||
|
return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT, Ops, 5);
|
||||||
|
}
|
||||||
|
|
||||||
// fold (sint_to_fp (zext (setcc x, y, cc))) ->
|
// fold (sint_to_fp (zext (setcc x, y, cc))) ->
|
||||||
// (select_cc x, y, 1.0, 0.0,, cc)
|
// (select_cc x, y, 1.0, 0.0,, cc)
|
||||||
if (N0.getOpcode() == ISD::ZERO_EXTEND &&
|
if (N0.getOpcode() == ISD::ZERO_EXTEND &&
|
||||||
N0.getOperand(0).getOpcode() == ISD::SETCC &&!VT.isVector() &&
|
N0.getOperand(0).getOpcode() == ISD::SETCC &&!VT.isVector() &&
|
||||||
(!LegalOperations ||
|
(!LegalOperations ||
|
||||||
TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) {
|
TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) {
|
||||||
SDValue Ops[] =
|
SDValue Ops[] =
|
||||||
{ N0.getOperand(0).getOperand(0), N0.getOperand(0).getOperand(1),
|
{ N0.getOperand(0).getOperand(0), N0.getOperand(0).getOperand(1),
|
||||||
DAG.getConstantFP(1.0, VT) , DAG.getConstantFP(0.0, VT),
|
DAG.getConstantFP(1.0, VT) , DAG.getConstantFP(0.0, VT),
|
||||||
N0.getOperand(0).getOperand(2) };
|
N0.getOperand(0).getOperand(2) };
|
||||||
return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT, Ops, 5);
|
return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT, Ops, 5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SDValue();
|
return SDValue();
|
||||||
|
@ -6052,17 +6059,24 @@ SDValue DAGCombiner::visitUINT_TO_FP(SDNode *N) {
|
||||||
return DAG.getNode(ISD::SINT_TO_FP, N->getDebugLoc(), VT, N0);
|
return DAG.getNode(ISD::SINT_TO_FP, N->getDebugLoc(), VT, N0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fold (uint_to_fp (setcc x, y, cc)) -> (select_cc x, y, -1.0, 0.0,, cc)
|
// The next optimizations are desireable only if SELECT_CC can be lowered.
|
||||||
if (N0.getOpcode() == ISD::SETCC && !VT.isVector() &&
|
// Check against MVT::Other for SELECT_CC, which is a workaround for targets
|
||||||
(!LegalOperations ||
|
// having to say they don't support SELECT_CC on every type the DAG knows
|
||||||
TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) {
|
// about, since there is no way to mark an opcode illegal at all value types
|
||||||
SDValue Ops[] =
|
// (See also visitSELECT)
|
||||||
{ N0.getOperand(0), N0.getOperand(1),
|
if (TLI.isOperationLegalOrCustom(ISD::SELECT_CC, MVT::Other)) {
|
||||||
DAG.getConstantFP(1.0, VT), DAG.getConstantFP(0.0, VT),
|
// fold (uint_to_fp (setcc x, y, cc)) -> (select_cc x, y, -1.0, 0.0,, cc)
|
||||||
N0.getOperand(2) };
|
|
||||||
return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT, Ops, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (N0.getOpcode() == ISD::SETCC && !VT.isVector() &&
|
||||||
|
(!LegalOperations ||
|
||||||
|
TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) {
|
||||||
|
SDValue Ops[] =
|
||||||
|
{ N0.getOperand(0), N0.getOperand(1),
|
||||||
|
DAG.getConstantFP(1.0, VT), DAG.getConstantFP(0.0, VT),
|
||||||
|
N0.getOperand(2) };
|
||||||
|
return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT, Ops, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return SDValue();
|
return SDValue();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
; RUN: llc < %s -march=x86-64 -mcpu=corei7
|
||||||
|
|
||||||
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||||
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
||||||
|
; PR 13428
|
||||||
|
|
||||||
|
declare void @use(double)
|
||||||
|
|
||||||
|
define void @test() {
|
||||||
|
entry:
|
||||||
|
call void @use(double 1.000000e+00)
|
||||||
|
%A = icmp eq i64 undef, 2
|
||||||
|
%B = zext i1 %A to i32
|
||||||
|
%C = sitofp i32 %B to double
|
||||||
|
call void @use(double %C)
|
||||||
|
call void @use(double 0.000000e+00)
|
||||||
|
unreachable
|
||||||
|
}
|
Loading…
Reference in New Issue