aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/SelectionDAG
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp28
1 files changed, 26 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 8676060..cf221bb 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -16481,10 +16481,34 @@ SDValue DAGCombiner::visitTRUNCATE(SDNode *N) {
DAG, DL);
}
break;
- case ISD::AVGFLOORS:
- case ISD::AVGFLOORU:
case ISD::AVGCEILS:
case ISD::AVGCEILU:
+ // trunc (avgceilu (sext (x), sext (y))) -> avgceils(x, y)
+ // trunc (avgceils (zext (x), zext (y))) -> avgceilu(x, y)
+ if (N0.hasOneUse()) {
+ SDValue Op0 = N0.getOperand(0);
+ SDValue Op1 = N0.getOperand(1);
+ if (N0.getOpcode() == ISD::AVGCEILU) {
+ if (TLI.isOperationLegalOrCustom(ISD::AVGCEILS, VT) &&
+ Op0.getOpcode() == ISD::SIGN_EXTEND &&
+ Op1.getOpcode() == ISD::SIGN_EXTEND &&
+ Op0.getOperand(0).getValueType() == VT &&
+ Op1.getOperand(0).getValueType() == VT)
+ return DAG.getNode(ISD::AVGCEILS, DL, VT, Op0.getOperand(0),
+ Op1.getOperand(0));
+ } else {
+ if (TLI.isOperationLegalOrCustom(ISD::AVGCEILU, VT) &&
+ Op0.getOpcode() == ISD::ZERO_EXTEND &&
+ Op1.getOpcode() == ISD::ZERO_EXTEND &&
+ Op0.getOperand(0).getValueType() == VT &&
+ Op1.getOperand(0).getValueType() == VT)
+ return DAG.getNode(ISD::AVGCEILU, DL, VT, Op0.getOperand(0),
+ Op1.getOperand(0));
+ }
+ }
+ [[fallthrough]];
+ case ISD::AVGFLOORS:
+ case ISD::AVGFLOORU:
case ISD::ABDS:
case ISD::ABDU:
// (trunc (avg a, b)) -> (avg (trunc a), (trunc b))