[PATCH] D111858: [X86] Add DAG combine for negation of CMOV absolute value pattern.
Craig Topper via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 14 18:28:29 PDT 2021
craig.topper created this revision.
craig.topper added reviewers: RKSimon, spatel, efriedma.
Herald added subscribers: pengfei, hiraditya.
craig.topper requested review of this revision.
Herald added a project: LLVM.
This patch detects the absolute value pattern on the RHS of a
subtract. If we find it we swap the CMOV true/false values and
replace the subtract with an ADD.
There may be a more generic way to do this, but I'm not sure.
Targets that don't have legal or custom ISD::ABS use a generic
expand in DAG combiner already when it sees (neg (abs(x))). I
haven't checked what happens if the neg is a more general subtract.
Fixes PR50991 for X86.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D111858
Files:
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/neg-abs.ll
Index: llvm/test/CodeGen/X86/neg-abs.ll
===================================================================
--- llvm/test/CodeGen/X86/neg-abs.ll
+++ llvm/test/CodeGen/X86/neg-abs.ll
@@ -46,9 +46,7 @@
; X64: # %bb.0:
; X64-NEXT: movl %edi, %eax
; X64-NEXT: negw %ax
-; X64-NEXT: cmovsw %di, %ax
-; X64-NEXT: negl %eax
-; X64-NEXT: # kill: def $ax killed $ax killed $eax
+; X64-NEXT: cmovnsw %di, %ax
; X64-NEXT: retq
%abs = tail call i16 @llvm.abs.i16(i16 %x, i1 true)
%neg = sub nsw i16 0, %abs
@@ -69,8 +67,7 @@
; X64: # %bb.0:
; X64-NEXT: movl %edi, %eax
; X64-NEXT: negl %eax
-; X64-NEXT: cmovsl %edi, %eax
-; X64-NEXT: negl %eax
+; X64-NEXT: cmovnsl %edi, %eax
; X64-NEXT: retq
%abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true)
%neg = sub nsw i32 0, %abs
@@ -97,8 +94,7 @@
; X64: # %bb.0:
; X64-NEXT: movq %rdi, %rax
; X64-NEXT: negq %rax
-; X64-NEXT: cmovsq %rdi, %rax
-; X64-NEXT: negq %rax
+; X64-NEXT: cmovnsq %rdi, %rax
; X64-NEXT: retq
%abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true)
%neg = sub nsw i64 0, %abs
Index: llvm/lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- llvm/lib/Target/X86/X86ISelLowering.cpp
+++ llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -51422,6 +51422,48 @@
return combineAddOrSubToADCOrSBB(N, DAG);
}
+// Try to fold (sub Y, cmovns X, -X) -> (add Y, cmovns -X, X) if the cmov
+// condition comes from the subtract node that produced -X. This matches the
+// cmov expansion for absolute value. By swapping the operands we convert abs
+// to nabs.
+static SDValue combineSubABS(SDNode *N, SelectionDAG &DAG) {
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+
+ if (N1.getOpcode() != X86ISD::CMOV || !N1.hasOneUse())
+ return SDValue();
+
+ X86::CondCode CC = (X86::CondCode)N1.getConstantOperandVal(2);
+ if (CC != X86::COND_S && CC != X86::COND_NS)
+ return SDValue();
+
+ // Condition should come from a negate operation.
+ SDValue Cond = N1.getOperand(3);
+ if (Cond.getOpcode() != X86ISD::SUB || !isNullConstant(Cond.getOperand(0)))
+ return SDValue();
+ assert(Cond.getResNo() == 1 && "Unexpected result number");
+
+ // Get the X and -X from the negate.
+ SDValue NegX = Cond.getValue(0);
+ SDValue X = Cond.getOperand(1);
+
+ SDValue FalseOp = N1.getOperand(0);
+ SDValue TrueOp = N1.getOperand(1);
+
+ // Cmov operands should be X and NegX. Order doesn't matter.
+ if (!(TrueOp == X && FalseOp == NegX) &&
+ !(TrueOp == NegX && FalseOp == X))
+ return SDValue();
+
+ // Build a new CMOV with the operands swapped.
+ SDLoc DL(N);
+ MVT VT = N->getSimpleValueType(0);
+ SDValue Cmov = DAG.getNode(X86ISD::CMOV, DL, VT,
+ TrueOp, FalseOp, N1.getOperand(2), Cond);
+ // Convert sub to add.
+ return DAG.getNode(ISD::ADD, DL, VT, N0, Cmov);
+}
+
static SDValue combineSub(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const X86Subtarget &Subtarget) {
@@ -51453,6 +51495,9 @@
return DAG.getNode(ISD::ADD, DL, VT, NewXor, NewAdd);
}
+ if (SDValue V = combineSubABS(N, DAG))
+ return V;
+
// Try to synthesize horizontal subs from subs of shuffles.
if (SDValue V = combineToHorizontalAddSub(N, DAG, Subtarget))
return V;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D111858.379896.patch
Type: text/x-patch
Size: 3416 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211015/a706de92/attachment.bin>
More information about the llvm-commits
mailing list