[llvm] d6a9eec - [AARCH64][DAGCombine] Add combine for negation of CSEL absolute value pattern.
David Green via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 22 01:59:41 PST 2022
Author: Sunho Kim
Date: 2022-02-22T09:59:36Z
New Revision: d6a9eec2382559aeae3bb87761afa1b6d351e9a5
URL: https://github.com/llvm/llvm-project/commit/d6a9eec2382559aeae3bb87761afa1b6d351e9a5
DIFF: https://github.com/llvm/llvm-project/commit/d6a9eec2382559aeae3bb87761afa1b6d351e9a5.diff
LOG: [AARCH64][DAGCombine] Add combine for negation of CSEL absolute value pattern.
This folds a negation through a csel, which can come up during the
lowering of negative abs.
Fixes https://github.com/llvm/llvm-project/issues/51558.
Differential Revision: https://reviews.llvm.org/D112204
Added:
Modified:
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
llvm/test/CodeGen/AArch64/neg-abs.ll
llvm/test/CodeGen/AArch64/neg-selects.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 30d30e88f2740..5678029be376e 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -14893,6 +14893,49 @@ static SDValue performAddDotCombine(SDNode *N, SelectionDAG &DAG) {
Dot.getOperand(2));
}
+static bool isNegatedInteger(SDValue Op) {
+ return Op.getOpcode() == ISD::SUB && isNullConstant(Op.getOperand(0));
+}
+
+static SDValue getNegatedInteger(SDValue Op, SelectionDAG &DAG) {
+ SDLoc DL(Op);
+ EVT VT = Op.getValueType();
+ SDValue Zero = DAG.getConstant(0, DL, VT);
+ return DAG.getNode(ISD::SUB, DL, VT, Zero, Op);
+}
+
+// Try to fold
+//
+// (neg (csel X, Y)) -> (csel (neg X), (neg Y))
+//
+// The folding helps csel to be matched with csneg without generating
+// redundant neg instruction, which includes negation of the csel expansion
+// of abs node lowered by lowerABS.
+static SDValue performNegCSelCombine(SDNode *N, SelectionDAG &DAG) {
+ if (!isNegatedInteger(SDValue(N, 0)))
+ return SDValue();
+
+ SDValue CSel = N->getOperand(1);
+ if (CSel.getOpcode() != AArch64ISD::CSEL || !CSel->hasOneUse())
+ return SDValue();
+
+ SDValue N0 = CSel.getOperand(0);
+ SDValue N1 = CSel.getOperand(1);
+
+ // If both of them is not negations, it's not worth the folding as it
+ // introduces two additional negations while reducing one negation.
+ if (!isNegatedInteger(N0) && !isNegatedInteger(N1))
+ return SDValue();
+
+ SDValue N0N = getNegatedInteger(N0, DAG);
+ SDValue N1N = getNegatedInteger(N1, DAG);
+
+ SDLoc DL(N);
+ EVT VT = CSel.getValueType();
+ return DAG.getNode(AArch64ISD::CSEL, DL, VT, N0N, N1N, CSel.getOperand(2),
+ CSel.getOperand(3));
+}
+
// The basic add/sub long vector instructions have variants with "2" on the end
// which act on the high-half of their inputs. They are normally matched by
// patterns like:
@@ -14956,6 +14999,8 @@ static SDValue performAddSubCombine(SDNode *N,
return Val;
if (SDValue Val = performAddCSelIntoCSinc(N, DAG))
return Val;
+ if (SDValue Val = performNegCSelCombine(N, DAG))
+ return Val;
return performAddSubLongCombine(N, DCI, DAG);
}
diff --git a/llvm/test/CodeGen/AArch64/neg-abs.ll b/llvm/test/CodeGen/AArch64/neg-abs.ll
index 71a320e98398a..7f691c9b694c4 100644
--- a/llvm/test/CodeGen/AArch64/neg-abs.ll
+++ b/llvm/test/CodeGen/AArch64/neg-abs.ll
@@ -8,8 +8,7 @@ define i64 @neg_abs64(i64 %x) {
; CHECK-LABEL: neg_abs64:
; CHECK: // %bb.0:
; CHECK-NEXT: cmp x0, #0
-; CHECK-NEXT: cneg x8, x0, mi
-; CHECK-NEXT: neg x0, x8
+; CHECK-NEXT: cneg x0, x0, pl
; CHECK-NEXT: ret
%abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true)
%neg = sub nsw i64 0, %abs
@@ -22,8 +21,7 @@ define i32 @neg_abs32(i32 %x) {
; CHECK-LABEL: neg_abs32:
; CHECK: // %bb.0:
; CHECK-NEXT: cmp w0, #0
-; CHECK-NEXT: cneg w8, w0, mi
-; CHECK-NEXT: neg w0, w8
+; CHECK-NEXT: cneg w0, w0, pl
; CHECK-NEXT: ret
%abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true)
%neg = sub nsw i32 0, %abs
diff --git a/llvm/test/CodeGen/AArch64/neg-selects.ll b/llvm/test/CodeGen/AArch64/neg-selects.ll
index e0f0efdcc2d3f..114300a79b909 100644
--- a/llvm/test/CodeGen/AArch64/neg-selects.ll
+++ b/llvm/test/CodeGen/AArch64/neg-selects.ll
@@ -31,8 +31,7 @@ define i32 @neg_select_nega(i32 %a, i32 %b, i1 %bb) {
; CHECK-LABEL: neg_select_nega:
; CHECK: // %bb.0:
; CHECK-NEXT: tst w2, #0x1
-; CHECK-NEXT: csneg w8, w1, w0, eq
-; CHECK-NEXT: neg w0, w8
+; CHECK-NEXT: csneg w0, w0, w1, ne
; CHECK-NEXT: ret
%nega = sub i32 0, %a
%sel = select i1 %bb, i32 %nega, i32 %b
@@ -44,8 +43,7 @@ define i32 @neg_select_negb(i32 %a, i32 %b, i1 %bb) {
; CHECK-LABEL: neg_select_negb:
; CHECK: // %bb.0:
; CHECK-NEXT: tst w2, #0x1
-; CHECK-NEXT: csneg w8, w0, w1, ne
-; CHECK-NEXT: neg w0, w8
+; CHECK-NEXT: csneg w0, w1, w0, eq
; CHECK-NEXT: ret
%negb = sub i32 0, %b
%sel = select i1 %bb, i32 %a, i32 %negb
More information about the llvm-commits
mailing list