forked from OSchip/llvm-project
DAGCombiner: Optimize SELECTs first before turning them into SELECT_CC
This is part of http://reviews.llvm.org/D11616 - I just decided to split this up into a separate commit. llvm-svn: 245349
This commit is contained in:
parent
edaba3b7c3
commit
2e920bd04f
|
@ -4955,38 +4955,6 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
|
|||
if (SimplifySelectOps(N, N1, N2))
|
||||
return SDValue(N, 0); // Don't revisit N.
|
||||
|
||||
// fold selects based on a setcc into other things, such as min/max/abs
|
||||
if (N0.getOpcode() == ISD::SETCC) {
|
||||
// select x, y (fcmp lt x, y) -> fminnum x, y
|
||||
// select x, y (fcmp gt x, y) -> fmaxnum x, y
|
||||
//
|
||||
// This is OK if we don't care about what happens if either operand is a
|
||||
// NaN.
|
||||
//
|
||||
|
||||
// FIXME: Instead of testing for UnsafeFPMath, this should be checking for
|
||||
// no signed zeros as well as no nans.
|
||||
const TargetOptions &Options = DAG.getTarget().Options;
|
||||
if (Options.UnsafeFPMath &&
|
||||
VT.isFloatingPoint() && N0.hasOneUse() &&
|
||||
DAG.isKnownNeverNaN(N1) && DAG.isKnownNeverNaN(N2)) {
|
||||
ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(2))->get();
|
||||
|
||||
if (SDValue FMinMax = combineMinNumMaxNum(SDLoc(N), VT, N0.getOperand(0),
|
||||
N0.getOperand(1), N1, N2, CC,
|
||||
TLI, DAG))
|
||||
return FMinMax;
|
||||
}
|
||||
|
||||
if ((!LegalOperations &&
|
||||
TLI.isOperationLegalOrCustom(ISD::SELECT_CC, VT)) ||
|
||||
TLI.isOperationLegal(ISD::SELECT_CC, VT))
|
||||
return DAG.getNode(ISD::SELECT_CC, SDLoc(N), VT,
|
||||
N0.getOperand(0), N0.getOperand(1),
|
||||
N1, N2, N0.getOperand(2));
|
||||
return SimplifySelect(SDLoc(N), N0, N1, N2);
|
||||
}
|
||||
|
||||
if (VT0 == MVT::i1) {
|
||||
if (TLI.shouldNormalizeToSelectSequence(*DAG.getContext(), VT)) {
|
||||
// select (and Cond0, Cond1), X, Y
|
||||
|
@ -5050,6 +5018,38 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
|
|||
}
|
||||
}
|
||||
|
||||
// fold selects based on a setcc into other things, such as min/max/abs
|
||||
if (N0.getOpcode() == ISD::SETCC) {
|
||||
// select x, y (fcmp lt x, y) -> fminnum x, y
|
||||
// select x, y (fcmp gt x, y) -> fmaxnum x, y
|
||||
//
|
||||
// This is OK if we don't care about what happens if either operand is a
|
||||
// NaN.
|
||||
//
|
||||
|
||||
// FIXME: Instead of testing for UnsafeFPMath, this should be checking for
|
||||
// no signed zeros as well as no nans.
|
||||
const TargetOptions &Options = DAG.getTarget().Options;
|
||||
if (Options.UnsafeFPMath &&
|
||||
VT.isFloatingPoint() && N0.hasOneUse() &&
|
||||
DAG.isKnownNeverNaN(N1) && DAG.isKnownNeverNaN(N2)) {
|
||||
ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(2))->get();
|
||||
|
||||
if (SDValue FMinMax = combineMinNumMaxNum(SDLoc(N), VT, N0.getOperand(0),
|
||||
N0.getOperand(1), N1, N2, CC,
|
||||
TLI, DAG))
|
||||
return FMinMax;
|
||||
}
|
||||
|
||||
if ((!LegalOperations &&
|
||||
TLI.isOperationLegalOrCustom(ISD::SELECT_CC, VT)) ||
|
||||
TLI.isOperationLegal(ISD::SELECT_CC, VT))
|
||||
return DAG.getNode(ISD::SELECT_CC, SDLoc(N), VT,
|
||||
N0.getOperand(0), N0.getOperand(1),
|
||||
N1, N2, N0.getOperand(2));
|
||||
return SimplifySelect(SDLoc(N), N0, N1, N2);
|
||||
}
|
||||
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
; RUN: llc -o - %s | FileCheck %s
|
||||
target triple = "arm64--"
|
||||
|
||||
; Ensure that we transform select(C0, x, select(C1, x, y)) towards
|
||||
; select(C0 | C1, x, y) so we can use CMP;CCMP for the implementation.
|
||||
; CHECK-LABEL: test0:
|
||||
; CHECK: cmp w0, #7
|
||||
; CHECK: ccmp w1, #0, #0, ne
|
||||
; CHECK: csel w0, w1, w2, gt
|
||||
; CHECK: ret
|
||||
define i32 @test0(i32 %v0, i32 %v1, i32 %v2) {
|
||||
%cmp1 = icmp eq i32 %v0, 7
|
||||
%cmp2 = icmp sgt i32 %v1, 0
|
||||
%sel0 = select i1 %cmp1, i32 %v1, i32 %v2
|
||||
%sel1 = select i1 %cmp2, i32 %v1, i32 %sel0
|
||||
ret i32 %sel1
|
||||
}
|
Loading…
Reference in New Issue