[PATCH] D118595: [AARCH64][DAGCombine] Add combine for negation of CSEL absolute value pattern.
Sunho Kim via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 31 04:20:27 PST 2022
sunho updated this revision to Diff 404479.
sunho added a comment.
Edit existing test
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D118595/new/
https://reviews.llvm.org/D118595
Files:
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
llvm/test/CodeGen/AArch64/neg-abs.ll
Index: llvm/test/CodeGen/AArch64/neg-abs.ll
===================================================================
--- llvm/test/CodeGen/AArch64/neg-abs.ll
+++ llvm/test/CodeGen/AArch64/neg-abs.ll
@@ -8,8 +8,7 @@
; 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 @@
; 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
Index: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -14696,6 +14696,56 @@
Dot.getOperand(2));
}
+// Try to fold (sub Y, (csel X, -X, pl)) -> (add Y, (csel -X, X, pl)) when
+// condition came from (subs X, 0). This matches the CSEL expansion of
+// abs node lowered by lowerABS. By swapping the operands, we convert
+// abs to nabs. Note that (csel X, -X, pl) will be matched
+// to csneg by the CondSelectOp pattern.
+static SDValue performCombineSubABS(SDNode *N, SelectionDAG &DAG) {
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+
+ // Is abs node has other uses, don't do the combine
+ if (N1.getOpcode() != AArch64ISD::CSEL || !N1.hasOneUse())
+ return SDValue();
+
+ ConstantSDNode *CCNode = cast<ConstantSDNode>(N1->getOperand(2));
+ AArch64CC::CondCode CC =
+ static_cast<AArch64CC::CondCode>(CCNode->getSExtValue());
+
+ if (CC != AArch64CC::PL && CC != AArch64CC::MI)
+ return SDValue();
+
+ // Condition should come from SUBS
+ SDValue Cmp = N1.getOperand(3);
+ if (Cmp.getOpcode() != AArch64ISD::SUBS || !isNullConstant(Cmp.getOperand(1)))
+ return SDValue();
+ assert(Cmp.getResNo() == 1 && "Unexpected result number");
+
+ // Get the X
+ SDValue X = Cmp.getOperand(0);
+
+ SDValue FalseOp = N1.getOperand(0);
+ SDValue TrueOp = N1.getOperand(1);
+
+ // CSEL operands should be X and NegX. Order doesn't matter.
+ auto IsNeg = [](SDValue Value, SDValue X) {
+ return Value.getOpcode() == ISD::SUB &&
+ isNullConstant(Value.getOperand(0)) && X == Value.getOperand(1);
+ };
+ if (!(IsNeg(FalseOp, X) && TrueOp == X) &&
+ !(IsNeg(TrueOp, X) && FalseOp == X))
+ return SDValue();
+
+ // Build a new CSEL with the operands swapped.
+ SDLoc DL(N);
+ MVT VT = N->getSimpleValueType(0);
+ SDValue Csel = DAG.getNode(AArch64ISD::CSEL, DL, VT, TrueOp, FalseOp,
+ N1.getOperand(2), Cmp);
+ // Convert sub to add.
+ return DAG.getNode(ISD::ADD, DL, VT, N0, Csel);
+}
+
// 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:
@@ -17617,8 +17667,12 @@
default:
LLVM_DEBUG(dbgs() << "Custom combining: skipping\n");
break;
- case ISD::ADD:
case ISD::SUB:
+ if (SDValue Val = performCombineSubABS(N, DAG)) {
+ return Val;
+ }
+ LLVM_FALLTHROUGH;
+ case ISD::ADD:
return performAddSubCombine(N, DCI, DAG);
case ISD::XOR:
return performXorCombine(N, DAG, DCI, Subtarget);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D118595.404479.patch
Type: text/x-patch
Size: 3544 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220131/ff51e914/attachment.bin>
More information about the llvm-commits
mailing list