diff options
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64ISelLowering.cpp')
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 60 |
1 files changed, 46 insertions, 14 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 2b6ea86..1f5ff4e 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -11390,13 +11390,18 @@ SDValue AArch64TargetLowering::LowerSELECT_CC( // select_cc lhs, rhs, sub(rhs, lhs), sub(lhs, rhs), cc -> // select_cc lhs, rhs, neg(sub(lhs, rhs)), sub(lhs, rhs), cc // The second forms can be matched into subs+cneg. + // NOTE: Drop poison generating flags from the negated operand to avoid + // inadvertently propagating poison after the canonicalisation. if (TVal.getOpcode() == ISD::SUB && FVal.getOpcode() == ISD::SUB) { if (TVal.getOperand(0) == LHS && TVal.getOperand(1) == RHS && - FVal.getOperand(0) == RHS && FVal.getOperand(1) == LHS) + FVal.getOperand(0) == RHS && FVal.getOperand(1) == LHS) { + TVal->dropFlags(SDNodeFlags::PoisonGeneratingFlags); FVal = DAG.getNegative(TVal, DL, TVal.getValueType()); - else if (TVal.getOperand(0) == RHS && TVal.getOperand(1) == LHS && - FVal.getOperand(0) == LHS && FVal.getOperand(1) == RHS) + } else if (TVal.getOperand(0) == RHS && TVal.getOperand(1) == LHS && + FVal.getOperand(0) == LHS && FVal.getOperand(1) == RHS) { + FVal->dropFlags(SDNodeFlags::PoisonGeneratingFlags); TVal = DAG.getNegative(FVal, DL, FVal.getValueType()); + } } unsigned Opcode = AArch64ISD::CSEL; @@ -13477,7 +13482,7 @@ static bool isEXTMask(ArrayRef<int> M, EVT VT, bool &ReverseEXT, // Look for the first non-undef element. const int *FirstRealElt = find_if(M, [](int Elt) { return Elt >= 0; }); - // Benefit form APInt to handle overflow when calculating expected element. + // Benefit from APInt to handle overflow when calculating expected element. unsigned NumElts = VT.getVectorNumElements(); unsigned MaskBits = APInt(32, NumElts * 2).logBase2(); APInt ExpectedElt = APInt(MaskBits, *FirstRealElt + 1, /*isSigned=*/false, @@ -13485,7 +13490,7 @@ static bool isEXTMask(ArrayRef<int> M, EVT VT, bool &ReverseEXT, // The following shuffle indices must be the successive elements after the // first real element. bool FoundWrongElt = std::any_of(FirstRealElt + 1, M.end(), [&](int Elt) { - return Elt != ExpectedElt++ && Elt != -1; + return Elt != ExpectedElt++ && Elt >= 0; }); if (FoundWrongElt) return false; @@ -15772,6 +15777,7 @@ bool AArch64TargetLowering::isShuffleMaskLegal(ArrayRef<int> M, EVT VT) const { isREVMask(M, EltSize, NumElts, 32) || isREVMask(M, EltSize, NumElts, 16) || isEXTMask(M, VT, DummyBool, DummyUnsigned) || + isSingletonEXTMask(M, VT, DummyUnsigned) || isTRNMask(M, NumElts, DummyUnsigned) || isUZPMask(M, NumElts, DummyUnsigned) || isZIPMask(M, NumElts, DummyUnsigned) || @@ -16284,9 +16290,8 @@ AArch64TargetLowering::LowerWindowsDYNAMIC_STACKALLOC(SDValue Op, Chain = SP.getValue(1); SP = DAG.getNode(ISD::SUB, DL, MVT::i64, SP, Size); if (Align) - SP = - DAG.getNode(ISD::AND, DL, VT, SP.getValue(0), - DAG.getSignedConstant(-(uint64_t)Align->value(), DL, VT)); + SP = DAG.getNode(ISD::AND, DL, VT, SP.getValue(0), + DAG.getSignedConstant(-Align->value(), DL, VT)); Chain = DAG.getCopyToReg(Chain, DL, AArch64::SP, SP); SDValue Ops[2] = {SP, Chain}; return DAG.getMergeValues(Ops, DL); @@ -16323,7 +16328,7 @@ AArch64TargetLowering::LowerWindowsDYNAMIC_STACKALLOC(SDValue Op, SP = DAG.getNode(ISD::SUB, DL, MVT::i64, SP, Size); if (Align) SP = DAG.getNode(ISD::AND, DL, VT, SP.getValue(0), - DAG.getSignedConstant(-(uint64_t)Align->value(), DL, VT)); + DAG.getSignedConstant(-Align->value(), DL, VT)); Chain = DAG.getCopyToReg(Chain, DL, AArch64::SP, SP); Chain = DAG.getCALLSEQ_END(Chain, 0, 0, SDValue(), DL); @@ -16351,7 +16356,7 @@ AArch64TargetLowering::LowerInlineDYNAMIC_STACKALLOC(SDValue Op, SP = DAG.getNode(ISD::SUB, DL, MVT::i64, SP, Size); if (Align) SP = DAG.getNode(ISD::AND, DL, VT, SP.getValue(0), - DAG.getSignedConstant(-(uint64_t)Align->value(), DL, VT)); + DAG.getSignedConstant(-Align->value(), DL, VT)); // Set the real SP to the new value with a probing loop. Chain = DAG.getNode(AArch64ISD::PROBED_ALLOCA, DL, MVT::Other, Chain, SP); @@ -25450,6 +25455,29 @@ static SDValue performCSELCombine(SDNode *N, } } + // CSEL a, b, cc, SUBS(SUB(x,y), 0) -> CSEL a, b, cc, SUBS(x,y) if cc doesn't + // use overflow flags, to avoid the comparison with zero. In case of success, + // this also replaces the original SUB(x,y) with the newly created SUBS(x,y). + // NOTE: Perhaps in the future use performFlagSettingCombine to replace SUB + // nodes with their SUBS equivalent as is already done for other flag-setting + // operators, in which case doing the replacement here becomes redundant. + if (Cond.getOpcode() == AArch64ISD::SUBS && Cond->hasNUsesOfValue(1, 1) && + isNullConstant(Cond.getOperand(1))) { + SDValue Sub = Cond.getOperand(0); + AArch64CC::CondCode CC = + static_cast<AArch64CC::CondCode>(N->getConstantOperandVal(2)); + if (Sub.getOpcode() == ISD::SUB && + (CC == AArch64CC::EQ || CC == AArch64CC::NE || CC == AArch64CC::MI || + CC == AArch64CC::PL)) { + SDLoc DL(N); + SDValue Subs = DAG.getNode(AArch64ISD::SUBS, DL, Cond->getVTList(), + Sub.getOperand(0), Sub.getOperand(1)); + DCI.CombineTo(Sub.getNode(), Subs); + DCI.CombineTo(Cond.getNode(), Subs, Subs.getValue(1)); + return SDValue(N, 0); + } + } + // CSEL (LASTB P, Z), X, NE(ANY P) -> CLASTB P, X, Z if (SDValue CondLast = foldCSELofLASTB(N, DAG)) return CondLast; @@ -28609,14 +28637,16 @@ Value *AArch64TargetLowering::getIRStackGuard(IRBuilderBase &IRB) const { void AArch64TargetLowering::insertSSPDeclarations(Module &M) const { // MSVC CRT provides functionalities for stack protection. - if (Subtarget->getTargetTriple().isWindowsMSVCEnvironment()) { + RTLIB::LibcallImpl SecurityCheckCookieLibcall = + getLibcallImpl(RTLIB::SECURITY_CHECK_COOKIE); + if (SecurityCheckCookieLibcall != RTLIB::Unsupported) { // MSVC CRT has a global variable holding security cookie. M.getOrInsertGlobal("__security_cookie", PointerType::getUnqual(M.getContext())); // MSVC CRT has a function to validate security cookie. FunctionCallee SecurityCheckCookie = - M.getOrInsertFunction(Subtarget->getSecurityCheckCookieName(), + M.getOrInsertFunction(getLibcallImplName(SecurityCheckCookieLibcall), Type::getVoidTy(M.getContext()), PointerType::getUnqual(M.getContext())); if (Function *F = dyn_cast<Function>(SecurityCheckCookie.getCallee())) { @@ -28637,8 +28667,10 @@ Value *AArch64TargetLowering::getSDagStackGuard(const Module &M) const { Function *AArch64TargetLowering::getSSPStackGuardCheck(const Module &M) const { // MSVC CRT has a function to validate security cookie. - if (Subtarget->getTargetTriple().isWindowsMSVCEnvironment()) - return M.getFunction(Subtarget->getSecurityCheckCookieName()); + RTLIB::LibcallImpl SecurityCheckCookieLibcall = + getLibcallImpl(RTLIB::SECURITY_CHECK_COOKIE); + if (SecurityCheckCookieLibcall != RTLIB::Unsupported) + return M.getFunction(getLibcallImplName(SecurityCheckCookieLibcall)); return TargetLowering::getSSPStackGuardCheck(M); } |