[llvm] r245349 - DAGCombiner: Optimize SELECTs first before turning them into SELECT_CC
Matthias Braun via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 18 13:48:29 PDT 2015
Author: matze
Date: Tue Aug 18 15:48:29 2015
New Revision: 245349
URL: http://llvm.org/viewvc/llvm-project?rev=245349&view=rev
Log:
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.
Added:
llvm/trunk/test/CodeGen/AArch64/dag-combine-select.ll
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=245349&r1=245348&r2=245349&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Aug 18 15:48:29 2015
@@ -4955,38 +4955,6 @@ SDValue DAGCombiner::visitSELECT(SDNode
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
}
}
+ // 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();
}
Added: llvm/trunk/test/CodeGen/AArch64/dag-combine-select.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/dag-combine-select.ll?rev=245349&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/dag-combine-select.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/dag-combine-select.ll Tue Aug 18 15:48:29 2015
@@ -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
+}
More information about the llvm-commits
mailing list