Skip to content

Commit ad6bb86

Browse files
author
Michael Berg
committed
adding more fmf propagation for selects plus updated tests
llvm-svn: 363484
1 parent 744870f commit ad6bb86

File tree

4 files changed

+116
-21
lines changed

4 files changed

+116
-21
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,7 +2091,9 @@ SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
20912091
!isConstantFPBuildVectorOrConstantFP(NewCF))
20922092
return SDValue();
20932093

2094-
return DAG.getSelect(DL, VT, Sel.getOperand(0), NewCT, NewCF);
2094+
SDValue SelectOp = DAG.getSelect(DL, VT, Sel.getOperand(0), NewCT, NewCF);
2095+
SelectOp->setFlags(BO->getFlags());
2096+
return SelectOp;
20952097
}
20962098

20972099
static SDValue foldAddSubBoolOfMaskedVal(SDNode *N, SelectionDAG &DAG) {
@@ -7997,6 +7999,7 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
79977999
EVT VT = N->getValueType(0);
79988000
EVT VT0 = N0.getValueType();
79998001
SDLoc DL(N);
8002+
SDNodeFlags Flags = N->getFlags();
80008003

80018004
if (SDValue V = DAG.simplifySelect(N0, N1, N2))
80028005
return V;
@@ -8047,10 +8050,10 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
80478050
SDValue Cond0 = N0->getOperand(0);
80488051
SDValue Cond1 = N0->getOperand(1);
80498052
SDValue InnerSelect =
8050-
DAG.getNode(ISD::SELECT, DL, N1.getValueType(), Cond1, N1, N2);
8053+
DAG.getNode(ISD::SELECT, DL, N1.getValueType(), Cond1, N1, N2, Flags);
80518054
if (normalizeToSequence || !InnerSelect.use_empty())
80528055
return DAG.getNode(ISD::SELECT, DL, N1.getValueType(), Cond0,
8053-
InnerSelect, N2);
8056+
InnerSelect, N2, Flags);
80548057
// Cleanup on failure.
80558058
if (InnerSelect.use_empty())
80568059
recursivelyDeleteUnusedNodes(InnerSelect.getNode());
@@ -8059,11 +8062,11 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
80598062
if (N0->getOpcode() == ISD::OR && N0->hasOneUse()) {
80608063
SDValue Cond0 = N0->getOperand(0);
80618064
SDValue Cond1 = N0->getOperand(1);
8062-
SDValue InnerSelect =
8063-
DAG.getNode(ISD::SELECT, DL, N1.getValueType(), Cond1, N1, N2);
8065+
SDValue InnerSelect = DAG.getNode(ISD::SELECT, DL, N1.getValueType(),
8066+
Cond1, N1, N2, Flags);
80648067
if (normalizeToSequence || !InnerSelect.use_empty())
80658068
return DAG.getNode(ISD::SELECT, DL, N1.getValueType(), Cond0, N1,
8066-
InnerSelect);
8069+
InnerSelect, Flags);
80678070
// Cleanup on failure.
80688071
if (InnerSelect.use_empty())
80698072
recursivelyDeleteUnusedNodes(InnerSelect.getNode());
@@ -8078,12 +8081,14 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
80788081
// Create the actual and node if we can generate good code for it.
80798082
if (!normalizeToSequence) {
80808083
SDValue And = DAG.getNode(ISD::AND, DL, N0.getValueType(), N0, N1_0);
8081-
return DAG.getNode(ISD::SELECT, DL, N1.getValueType(), And, N1_1, N2);
8084+
return DAG.getNode(ISD::SELECT, DL, N1.getValueType(), And, N1_1,
8085+
N2, Flags);
80828086
}
80838087
// Otherwise see if we can optimize the "and" to a better pattern.
8084-
if (SDValue Combined = visitANDLike(N0, N1_0, N))
8088+
if (SDValue Combined = visitANDLike(N0, N1_0, N)) {
80858089
return DAG.getNode(ISD::SELECT, DL, N1.getValueType(), Combined, N1_1,
8086-
N2);
8090+
N2, Flags);
8091+
}
80878092
}
80888093
}
80898094
// select Cond0, X, (select Cond1, X, Y) -> select (or Cond0, Cond1), X, Y
@@ -8095,19 +8100,23 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
80958100
// Create the actual or node if we can generate good code for it.
80968101
if (!normalizeToSequence) {
80978102
SDValue Or = DAG.getNode(ISD::OR, DL, N0.getValueType(), N0, N2_0);
8098-
return DAG.getNode(ISD::SELECT, DL, N1.getValueType(), Or, N1, N2_2);
8103+
return DAG.getNode(ISD::SELECT, DL, N1.getValueType(), Or, N1,
8104+
N2_2, Flags);
80998105
}
81008106
// Otherwise see if we can optimize to a better pattern.
81018107
if (SDValue Combined = visitORLike(N0, N2_0, N))
81028108
return DAG.getNode(ISD::SELECT, DL, N1.getValueType(), Combined, N1,
8103-
N2_2);
8109+
N2_2, Flags);
81048110
}
81058111
}
81068112
}
81078113

81088114
// select (not Cond), N1, N2 -> select Cond, N2, N1
8109-
if (SDValue F = extractBooleanFlip(N0, TLI))
8110-
return DAG.getSelect(DL, VT, F, N2, N1);
8115+
if (SDValue F = extractBooleanFlip(N0, TLI)) {
8116+
SDValue SelectOp = DAG.getSelect(DL, VT, F, N2, N1);
8117+
SelectOp->setFlags(Flags);
8118+
return SelectOp;
8119+
}
81118120

81128121
// Fold selects based on a setcc into other things, such as min/max/abs.
81138122
if (N0.getOpcode() == ISD::SETCC) {
@@ -8157,7 +8166,7 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
81578166
TLI.isOperationLegalOrCustom(ISD::SELECT_CC, VT))) {
81588167
// Any flags available in a select/setcc fold will be on the setcc as they
81598168
// migrated from fcmp
8160-
const SDNodeFlags Flags = N0.getNode()->getFlags();
8169+
Flags = N0.getNode()->getFlags();
81618170
SDValue SelectNode = DAG.getNode(ISD::SELECT_CC, DL, VT, Cond0, Cond1, N1,
81628171
N2, N0.getOperand(2));
81638172
SelectNode->setFlags(Flags);
@@ -8743,9 +8752,11 @@ SDValue DAGCombiner::visitSELECT_CC(SDNode *N) {
87438752
return N2;
87448753
} else if (SCC.getOpcode() == ISD::SETCC) {
87458754
// Fold to a simpler select_cc
8746-
return DAG.getNode(ISD::SELECT_CC, SDLoc(N), N2.getValueType(),
8747-
SCC.getOperand(0), SCC.getOperand(1), N2, N3,
8748-
SCC.getOperand(2));
8755+
SDValue SelectOp = DAG.getNode(
8756+
ISD::SELECT_CC, SDLoc(N), N2.getValueType(), SCC.getOperand(0),
8757+
SCC.getOperand(1), N2, N3, SCC.getOperand(2));
8758+
SelectOp->setFlags(SCC->getFlags());
8759+
return SelectOp;
87498760
}
87508761
}
87518762

@@ -19412,13 +19423,16 @@ SDValue DAGCombiner::SimplifySelect(const SDLoc &DL, SDValue N0, SDValue N1,
1941219423
// Check to see if we got a select_cc back (to turn into setcc/select).
1941319424
// Otherwise, just return whatever node we got back, like fabs.
1941419425
if (SCC.getOpcode() == ISD::SELECT_CC) {
19426+
const SDNodeFlags Flags = N0.getNode()->getFlags();
1941519427
SDValue SETCC = DAG.getNode(ISD::SETCC, SDLoc(N0),
1941619428
N0.getValueType(),
1941719429
SCC.getOperand(0), SCC.getOperand(1),
19418-
SCC.getOperand(4));
19430+
SCC.getOperand(4), Flags);
1941919431
AddToWorklist(SETCC.getNode());
19420-
return DAG.getSelect(SDLoc(SCC), SCC.getValueType(), SETCC,
19421-
SCC.getOperand(2), SCC.getOperand(3));
19432+
SDValue SelectNode = DAG.getSelect(SDLoc(SCC), SCC.getValueType(), SETCC,
19433+
SCC.getOperand(2), SCC.getOperand(3));
19434+
SelectNode->setFlags(Flags);
19435+
return SelectNode;
1942219436
}
1942319437

1942419438
return SCC;

llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3591,6 +3591,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
35913591
// Use the new condition code and swap true and false
35923592
Legalized = true;
35933593
Tmp1 = DAG.getSelectCC(dl, Tmp1, Tmp2, Tmp4, Tmp3, InvCC);
3594+
Tmp1->setFlags(Node->getFlags());
35943595
} else {
35953596
// If The inverse is not legal, then try to swap the arguments using
35963597
// the inverse condition code.
@@ -3600,6 +3601,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
36003601
// lhs and rhs.
36013602
Legalized = true;
36023603
Tmp1 = DAG.getSelectCC(dl, Tmp2, Tmp1, Tmp4, Tmp3, SwapInvCC);
3604+
Tmp1->setFlags(Node->getFlags());
36033605
}
36043606
}
36053607

@@ -3626,6 +3628,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
36263628
Tmp1 = DAG.getNode(ISD::SELECT_CC, dl, Node->getValueType(0), Tmp1,
36273629
Tmp2, Tmp3, Tmp4, CC);
36283630
}
3631+
Tmp1->setFlags(Node->getFlags());
36293632
}
36303633
Results.push_back(Tmp1);
36313634
break;
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
; RUN: llc < %s -mtriple=arm64-- | FileCheck %s
2+
3+
; This test provides fmf coverage for DAG combining of selects
4+
5+
; CHECK-LABEL: select_select_fold_select_and
6+
; CHECK: fminnm s1, s1, s2
7+
; CHECK-NEXT: fmaxnm s2, s0, s3
8+
; CHECK-NEXT: fmov
9+
; CHECK-NEXT: fccmp s1, s0, #4, lt
10+
; CHECK-NEXT: fcsel s2, s2, s0, gt
11+
12+
; select Cond0, (select Cond1, X, Y), Y -> select (and Cond0, Cond1), X, Y
13+
define float @select_select_fold_select_and(float %w, float %x, float %y, float %z) {
14+
%tmp21 = fcmp fast olt float %x, %y
15+
%tmp22 = select fast i1 %tmp21, float %x, float %y
16+
%tmp24 = fcmp fast ogt float %tmp22, %w
17+
%tmp78 = fcmp fast ogt float %w, %z
18+
%select0 = select fast i1 %tmp78, float %w, float %z
19+
%select1 = select fast i1 %tmp21, float %select0, float %w
20+
%select2 = select fast i1 %tmp24, float %select1, float %w
21+
%tmp82 = fadd fast float %w, 5.000000e-01
22+
%tmp102 = fadd fast float %tmp82, %select2
23+
%cmp.i155.i.i = fcmp fast ogt float %tmp102, %tmp82
24+
br i1 %cmp.i155.i.i, label %if.then.i157.i.i, label %if.end.i159.i.i
25+
26+
if.then.i157.i.i: ; preds = %0
27+
%add.i156.i.i = fadd fast float %select2, 1.000000e+00
28+
br label %exit
29+
30+
if.end.i159.i.i: ; preds = %0
31+
%sub.i158.i.i = fadd fast float %w, 0xBFD99999A0000000
32+
%sub15.i.i.i = fadd fast float %z, 0xBFD6666660000000
33+
%tmp191 = fcmp fast ogt float %tmp82, 0.000000e+00
34+
%select3 = select fast i1 %tmp191, float %sub.i158.i.i, float %sub15.i.i.i
35+
br label %exit
36+
37+
exit: ; preds = %if.end.i159.i.i, %if.then.i157.i.i
38+
%phi1 = phi float [ %add.i156.i.i, %if.then.i157.i.i ], [ %select3, %if.end.i159.i.i ]
39+
ret float %phi1
40+
}
41+
42+
; CHECK-LABEL: select_select_fold_select_or
43+
; CHECK: fcmp s1, s2
44+
; CHECK-NEXT: fminnm s1, s1, s2
45+
; CHECK-NEXT: fmaxnm s2, s0, s3
46+
; CHECK-NEXT: fmov
47+
; CHECK-NEXT: fccmp s1, s0, #0, ge
48+
; CHECK-NEXT: fcsel s2, s0, s2, gt
49+
50+
; select Cond0, X, (select Cond1, X, Y) -> select (or Cond0, Cond1), X, Y
51+
define float @select_select_fold_select_or(float %w, float %x, float %y, float %z) {
52+
%tmp21 = fcmp fast olt float %x, %y
53+
%tmp22 = select fast i1 %tmp21, float %x, float %y
54+
%tmp24 = fcmp fast ogt float %tmp22, %w
55+
%tmp78 = fcmp fast ogt float %w, %z
56+
%select0 = select fast i1 %tmp78, float %w, float %z
57+
%select1 = select fast i1 %tmp21, float %w, float %select0
58+
%select2 = select fast i1 %tmp24, float %w, float %select1
59+
%tmp82 = fadd fast float %w, 5.000000e-01
60+
%tmp102 = fadd fast float %tmp82, %select2
61+
%cmp.i155.i.i = fcmp fast ogt float %tmp102, %tmp82
62+
br i1 %cmp.i155.i.i, label %if.then.i157.i.i, label %if.end.i159.i.i
63+
64+
if.then.i157.i.i: ; preds = %0
65+
%add.i156.i.i = fadd fast float %select2, 1.000000e+00
66+
br label %exit
67+
68+
if.end.i159.i.i: ; preds = %0
69+
%sub.i158.i.i = fadd fast float %w, 0xBFD99999A0000000
70+
%sub15.i.i.i = fadd fast float %z, 0xBFD6666660000000
71+
%tmp191 = fcmp fast ogt float %tmp82, 0.000000e+00
72+
%select3 = select fast i1 %tmp191, float %sub.i158.i.i, float %sub15.i.i.i
73+
br label %exit
74+
75+
exit: ; preds = %if.end.i159.i.i, %if.then.i157.i.i
76+
%phi1 = phi float [ %add.i156.i.i, %if.then.i157.i.i ], [ %select3, %if.end.i159.i.i ]
77+
ret float %phi1
78+
}

llvm/test/CodeGen/X86/fdiv-combine.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ define float @div_select_constant_fold(i1 zeroext %arg) {
108108
; CHECK-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
109109
; CHECK-NEXT: retq
110110
%tmp = select i1 %arg, float 5.000000e+00, float 6.000000e+00
111-
%B2 = fdiv float %tmp, 1.000000e+00
111+
%B2 = fdiv nnan float %tmp, 2.000000e+00
112112
ret float %B2
113113
}
114114

0 commit comments

Comments
 (0)