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);
|
||||
}
|
||||
|
||||
// fold (sint_to_fp (setcc x, y, cc)) -> (select_cc x, y, -1.0, 0.0,, cc)
|
||||
if (N0.getOpcode() == ISD::SETCC && N0.getValueType() == MVT::i1 &&
|
||||
!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);
|
||||
}
|
||||
// The next optimizations are desireable only if SELECT_CC can be lowered.
|
||||
// Check against MVT::Other for SELECT_CC, which is a workaround for targets
|
||||
// having to say they don't support SELECT_CC on every type the DAG knows
|
||||
// about, since there is no way to mark an opcode illegal at all value types
|
||||
// (See also visitSELECT)
|
||||
if (TLI.isOperationLegalOrCustom(ISD::SELECT_CC, MVT::Other)) {
|
||||
// fold (sint_to_fp (setcc x, y, cc)) -> (select_cc x, y, -1.0, 0.0,, cc)
|
||||
if (N0.getOpcode() == ISD::SETCC && N0.getValueType() == MVT::i1 &&
|
||||
!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);
|
||||
}
|
||||
|
||||
// fold (sint_to_fp (zext (setcc x, y, cc))) ->
|
||||
// (select_cc x, y, 1.0, 0.0,, cc)
|
||||
if (N0.getOpcode() == ISD::ZERO_EXTEND &&
|
||||
N0.getOperand(0).getOpcode() == ISD::SETCC &&!VT.isVector() &&
|
||||
(!LegalOperations ||
|
||||
TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) {
|
||||
SDValue Ops[] =
|
||||
{ N0.getOperand(0).getOperand(0), N0.getOperand(0).getOperand(1),
|
||||
DAG.getConstantFP(1.0, VT) , DAG.getConstantFP(0.0, VT),
|
||||
N0.getOperand(0).getOperand(2) };
|
||||
return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT, Ops, 5);
|
||||
// fold (sint_to_fp (zext (setcc x, y, cc))) ->
|
||||
// (select_cc x, y, 1.0, 0.0,, cc)
|
||||
if (N0.getOpcode() == ISD::ZERO_EXTEND &&
|
||||
N0.getOperand(0).getOpcode() == ISD::SETCC &&!VT.isVector() &&
|
||||
(!LegalOperations ||
|
||||
TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) {
|
||||
SDValue Ops[] =
|
||||
{ N0.getOperand(0).getOperand(0), N0.getOperand(0).getOperand(1),
|
||||
DAG.getConstantFP(1.0, VT) , DAG.getConstantFP(0.0, VT),
|
||||
N0.getOperand(0).getOperand(2) };
|
||||
return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT, Ops, 5);
|
||||
}
|
||||
}
|
||||
|
||||
return SDValue();
|
||||
|
@ -6052,17 +6059,24 @@ SDValue DAGCombiner::visitUINT_TO_FP(SDNode *N) {
|
|||
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)
|
||||
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);
|
||||
}
|
||||
// The next optimizations are desireable only if SELECT_CC can be lowered.
|
||||
// Check against MVT::Other for SELECT_CC, which is a workaround for targets
|
||||
// having to say they don't support SELECT_CC on every type the DAG knows
|
||||
// about, since there is no way to mark an opcode illegal at all value types
|
||||
// (See also visitSELECT)
|
||||
if (TLI.isOperationLegalOrCustom(ISD::SELECT_CC, MVT::Other)) {
|
||||
// fold (uint_to_fp (setcc x, y, cc)) -> (select_cc x, y, -1.0, 0.0,, cc)
|
||||
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -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