cmn a, b means a - (-b) - which under two's complement arithmetic
is exactly equivalent to a + b. so Y == -Y is just match the cmn Y, Y
Details
Details
- Reviewers
paulwalker-arm david-arm spatel
Diff Detail
Diff Detail
Unit Tests
Unit Tests
Event Timeline
Comment Actions
We should probably view this as a missed canonicalization in IR first:
https://alive2.llvm.org/ce/z/D2Aph4 (that should also work with eq predicates)
The IR with and removes a use of the input variable, so it's better for analysis.
If the codegen here is still considered better, then add a transform from the new canonical form to the cmn form.
Comment Actions
Yes, Agree your idea, thanks @spatel. I also realize that the cmn directive may not exist on all backends? so this is not appropriate.
I try to add a patten match in performSETCCCombine , but then it go Into an infinite, so I'm trying to add a codegen pattern for this issue.
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -20436,6 +20436,20 @@ static SDValue performSETCCCombine(SDNode *N, } } + // setcc (shl x, 1), 0, ne ==> setcc (sub 0, x), x, ne for CMN + if (Cond == ISD::SETNE && isNullConstant(RHS) && + LHS->getOpcode() == ISD::SHL && isa<ConstantSDNode>(LHS->getOperand(1)) && + LHS->getConstantOperandVal(1) == 1 && LHS->hasOneUse()) { + EVT TstVT = LHS->getValueType(0); + if (TstVT.isScalarInteger() && TstVT.getFixedSizeInBits() <= 64) { + // this pattern will get better opt in emitComparison + SDValue ValX = LHS->getOperand(0); + SDValue TST = DAG.getNode(ISD::SUB, DL, TstVT, DAG.getConstant(0, DL, TstVT), + ValX); + return DAG.getNode(ISD::SETCC, DL, VT, TST, ValX, N->getOperand(2)); + } + }