diff options
author | zhongyunde <zhongyunde@huawei.com> | 2022-10-30 02:03:44 +0800 |
---|---|---|
committer | zhongyunde <zhongyunde@huawei.com> | 2022-10-30 02:04:02 +0800 |
commit | 63a46385f2c6dd39cf68d9811548c53e8d460cd9 (patch) | |
tree | 2cb1e0f46a288a4fa3216df670c9a0669b3ee52b /llvm/lib | |
parent | c4a8f9abac2b2a6925ab99384f10ae3f5c2fd85f (diff) | |
download | llvm-63a46385f2c6dd39cf68d9811548c53e8d460cd9.zip llvm-63a46385f2c6dd39cf68d9811548c53e8d460cd9.tar.gz llvm-63a46385f2c6dd39cf68d9811548c53e8d460cd9.tar.bz2 |
Recommit [AArch64] Optimize memcmp when the result is tested for [in]equality with 0
Fixes 1st issue of https://github.com/llvm/llvm-project/issues/58061
Fixes the crash of https://github.com/llvm/llvm-project/issues/58675
Reviewed By: dmgreen, efriedma
Differential Revision: https://reviews.llvm.org/D136244
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 3194f54..a97a24c 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -19490,6 +19490,35 @@ static SDValue performSETCCCombine(SDNode *N, } } + // Try to express conjunction "cmp 0 (or (xor A0 A1) (xor B0 B1))" as: + // cmp A0, A0; ccmp A0, B1, 0, eq; cmp inv(Cond) flag + if (!DCI.isBeforeLegalize() && VT.isScalarInteger() && + (Cond == ISD::SETEQ || Cond == ISD::SETNE) && isNullConstant(RHS) && + LHS->getOpcode() == ISD::OR && + (LHS.getOperand(0)->getOpcode() == ISD::XOR && + LHS.getOperand(1)->getOpcode() == ISD::XOR) && + LHS.hasOneUse() && LHS.getOperand(0)->hasOneUse() && + LHS.getOperand(1)->hasOneUse()) { + SDValue XOR0 = LHS.getOperand(0); + SDValue XOR1 = LHS.getOperand(1); + SDValue CCVal = DAG.getConstant(AArch64CC::EQ, DL, MVT_CC); + EVT TstVT = LHS->getValueType(0); + SDValue Cmp = + DAG.getNode(AArch64ISD::SUBS, DL, DAG.getVTList(TstVT, MVT::i32), + XOR0.getOperand(0), XOR0.getOperand(1)); + SDValue Overflow = Cmp.getValue(1); + SDValue NZCVOp = DAG.getConstant(0, DL, MVT::i32); + SDValue CCmp = DAG.getNode(AArch64ISD::CCMP, DL, MVT_CC, XOR1.getOperand(0), + XOR1.getOperand(1), NZCVOp, CCVal, Overflow); + // Invert CSEL's operands. + SDValue TVal = DAG.getConstant(1, DL, VT); + SDValue FVal = DAG.getConstant(0, DL, VT); + AArch64CC::CondCode CC = changeIntCCToAArch64CC(Cond); + AArch64CC::CondCode InvCC = AArch64CC::getInvertedCondCode(CC); + return DAG.getNode(AArch64ISD::CSEL, DL, VT, FVal, TVal, + DAG.getConstant(InvCC, DL, MVT::i32), CCmp); + } + return SDValue(); } |