summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorStanislav Mekhanoshin <Stanislav.Mekhanoshin@amd.com>2018-06-20 20:24:20 +0000
committerStanislav Mekhanoshin <Stanislav.Mekhanoshin@amd.com>2018-06-20 20:24:20 +0000
commit20279dc0258b39d8bbe10261ba2e4442fbd0e0ae (patch)
tree58937a37ab5c2deb5190ce7866a11edab55bd97d /llvm/lib/CodeGen
parent7d796ececd6323756d5b4f61ec27072e1c1deda5 (diff)
downloadbcm5719-llvm-20279dc0258b39d8bbe10261ba2e4442fbd0e0ae.tar.gz
bcm5719-llvm-20279dc0258b39d8bbe10261ba2e4442fbd0e0ae.zip
Allow binop C1, (select cc, CF, CT) -> select folding
Previously this folding was done only if select is a first operand. However, for non-commutative operations constant may go before select. Differential Revision: https://reviews.llvm.org/D48223 llvm-svn: 335167
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp38
1 files changed, 28 insertions, 10 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index ee767c0fd03..b29006c9967 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -1877,16 +1877,16 @@ SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
BinOpcode == ISD::FDIV || BinOpcode == ISD::FREM) &&
"Unexpected binary operator");
- // Bail out if any constants are opaque because we can't constant fold those.
- SDValue C1 = BO->getOperand(1);
- if (!isConstantOrConstantVector(C1, true) &&
- !isConstantFPBuildVectorOrConstantFP(C1))
- return SDValue();
-
// Don't do this unless the old select is going away. We want to eliminate the
// binary operator, not replace a binop with a select.
// TODO: Handle ISD::SELECT_CC.
+ unsigned SelOpNo = 0;
SDValue Sel = BO->getOperand(0);
+ if (Sel.getOpcode() != ISD::SELECT || !Sel.hasOneUse()) {
+ SelOpNo = 1;
+ Sel = BO->getOperand(1);
+ }
+
if (Sel.getOpcode() != ISD::SELECT || !Sel.hasOneUse())
return SDValue();
@@ -1900,18 +1900,36 @@ SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
!isConstantFPBuildVectorOrConstantFP(CF))
return SDValue();
+ // Bail out if any constants are opaque because we can't constant fold those.
+ SDValue CBO = BO->getOperand(SelOpNo ^ 1);
+ if (!isConstantOrConstantVector(CBO, true) &&
+ !isConstantFPBuildVectorOrConstantFP(CBO))
+ return SDValue();
+
+ EVT VT = Sel.getValueType();
+
+ // In case of shift value and shift amount may have different VT. For instance
+ // on x86 shift amount is i8 regardles of LHS type. Bail out if we have
+ // swapped operands and value types do not match. NB: x86 is fine if operands
+ // are not swapped with shift amount VT being not bigger than shifted value.
+ // TODO: that is possible to check for a shift operation, correct VTs and
+ // still perform optimization on x86 if needed.
+ if (SelOpNo && VT != CBO.getValueType())
+ return SDValue();
+
// We have a select-of-constants followed by a binary operator with a
// constant. Eliminate the binop by pulling the constant math into the select.
- // Example: add (select Cond, CT, CF), C1 --> select Cond, CT + C1, CF + C1
- EVT VT = Sel.getValueType();
+ // Example: add (select Cond, CT, CF), CBO --> select Cond, CT + CBO, CF + CBO
SDLoc DL(Sel);
- SDValue NewCT = DAG.getNode(BinOpcode, DL, VT, CT, C1);
+ SDValue NewCT = SelOpNo ? DAG.getNode(BinOpcode, DL, VT, CBO, CT)
+ : DAG.getNode(BinOpcode, DL, VT, CT, CBO);
if (!NewCT.isUndef() &&
!isConstantOrConstantVector(NewCT, true) &&
!isConstantFPBuildVectorOrConstantFP(NewCT))
return SDValue();
- SDValue NewCF = DAG.getNode(BinOpcode, DL, VT, CF, C1);
+ SDValue NewCF = SelOpNo ? DAG.getNode(BinOpcode, DL, VT, CBO, CF)
+ : DAG.getNode(BinOpcode, DL, VT, CF, CBO);
if (!NewCF.isUndef() &&
!isConstantOrConstantVector(NewCF, true) &&
!isConstantFPBuildVectorOrConstantFP(NewCF))
OpenPOWER on IntegriCloud