summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorStanislav Mekhanoshin <Stanislav.Mekhanoshin@amd.com>2018-06-21 16:02:05 +0000
committerStanislav Mekhanoshin <Stanislav.Mekhanoshin@amd.com>2018-06-21 16:02:05 +0000
commit22ee191c3ea92dd7054975c9e9074fbf3c3825f5 (patch)
treea6ced5032526de4ef2d8e59d379fe05ec0a49acc /llvm/lib/CodeGen
parent21a2973cc4c2d803ff680190a2ee17c15fb587dc (diff)
downloadbcm5719-llvm-22ee191c3ea92dd7054975c9e9074fbf3c3825f5.tar.gz
bcm5719-llvm-22ee191c3ea92dd7054975c9e9074fbf3c3825f5.zip
DAG combine "and|or (select c, -1, 0), x" -> "select c, x, 0|-1"
Allowed folding for "and/or" binops with non-constant operand if arguments of select are 0/-1 values. Normally this code with "and" opcode does not get to a DAG combiner and simplified yet in the InstCombine. However AMDGPU produces it during lowering and InstCombine has no chance to optimize it out. In turn the same pattern with "or" opcode can reach DAG. Differential Revision: https://reviews.llvm.org/D48301 llvm-svn: 335250
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp17
1 files changed, 14 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 22d55a1a0ef..443c9144d31 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -1901,8 +1901,19 @@ SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
return SDValue();
// Bail out if any constants are opaque because we can't constant fold those.
+ // The exception is "and" and "or" with either 0 or -1 in which case we can
+ // propagate non constant operands into select. I.e.:
+ // and (select Cond, 0, -1), X --> select Cond, 0, X
+ // or X, (select Cond, -1, 0) --> select Cond, -1, X
+ bool CanFoldNonConst = (BinOpcode == ISD::AND || BinOpcode == ISD::OR) &&
+ (isNullConstantOrNullSplatConstant(CT) ||
+ isAllOnesConstantOrAllOnesSplatConstant(CT)) &&
+ (isNullConstantOrNullSplatConstant(CF) ||
+ isAllOnesConstantOrAllOnesSplatConstant(CF));
+
SDValue CBO = BO->getOperand(SelOpNo ^ 1);
- if (!isConstantOrConstantVector(CBO, true) &&
+ if (!CanFoldNonConst &&
+ !isConstantOrConstantVector(CBO, true) &&
!isConstantFPBuildVectorOrConstantFP(CBO))
return SDValue();
@@ -1923,14 +1934,14 @@ SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
SDLoc DL(Sel);
SDValue NewCT = SelOpNo ? DAG.getNode(BinOpcode, DL, VT, CBO, CT)
: DAG.getNode(BinOpcode, DL, VT, CT, CBO);
- if (!NewCT.isUndef() &&
+ if (!CanFoldNonConst && !NewCT.isUndef() &&
!isConstantOrConstantVector(NewCT, true) &&
!isConstantFPBuildVectorOrConstantFP(NewCT))
return SDValue();
SDValue NewCF = SelOpNo ? DAG.getNode(BinOpcode, DL, VT, CBO, CF)
: DAG.getNode(BinOpcode, DL, VT, CF, CBO);
- if (!NewCF.isUndef() &&
+ if (!CanFoldNonConst && !NewCF.isUndef() &&
!isConstantOrConstantVector(NewCF, true) &&
!isConstantFPBuildVectorOrConstantFP(NewCF))
return SDValue();
OpenPOWER on IntegriCloud