Vendor import of llvm-project branch release/17.x llvmorg-17.0.0-rc4-10-g0176e8729ea4.

This commit is contained in:
Dimitry Andric 2023-09-11 15:44:52 +02:00
parent c938c0a643
commit 8092e001bc
21 changed files with 297 additions and 54 deletions

View file

@ -14,20 +14,21 @@
#ifndef LLVM_CLANG_AST_EXPRCONCEPTS_H
#define LLVM_CLANG_AST_EXPRCONCEPTS_H
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConcept.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TrailingObjects.h"
#include <utility>
#include <string>
#include <utility>
namespace clang {
class ASTStmtReader;
@ -467,6 +468,13 @@ public:
}
};
using EntityPrinter = llvm::function_ref<void(llvm::raw_ostream &)>;
/// \brief create a Requirement::SubstitutionDiagnostic with only a
/// SubstitutedEntity and DiagLoc using Sema's allocator.
Requirement::SubstitutionDiagnostic *
createSubstDiagAt(Sema &S, SourceLocation Location, EntityPrinter Printer);
} // namespace concepts
/// C++2a [expr.prim.req]:

View file

@ -2386,7 +2386,7 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
// functions. If the current target's C++ ABI requires this and this is a
// member function, set its alignment accordingly.
if (getTarget().getCXXABI().areMemberFunctionsAligned()) {
if (F->getPointerAlignment(getDataLayout()) < 2 && isa<CXXMethodDecl>(D))
if (isa<CXXMethodDecl>(D) && F->getPointerAlignment(getDataLayout()) < 2)
F->setAlignment(std::max(llvm::Align(2), F->getAlign().valueOrOne()));
}

View file

@ -4936,6 +4936,12 @@ void Driver::BuildJobs(Compilation &C) const {
(void)C.getArgs().hasArg(options::OPT_driver_mode);
(void)C.getArgs().hasArg(options::OPT_rsp_quoting);
bool HasAssembleJob = llvm::any_of(C.getJobs(), [](auto &J) {
// Match ClangAs and other derived assemblers of Tool. ClangAs uses a
// longer ShortName "clang integrated assembler" while other assemblers just
// use "assembler".
return strstr(J.getCreator().getShortName(), "assembler");
});
for (Arg *A : C.getArgs()) {
// FIXME: It would be nice to be able to send the argument to the
// DiagnosticsEngine, so that extra values, position, and so on could be
@ -4965,7 +4971,7 @@ void Driver::BuildJobs(Compilation &C) const {
// already been warned about.
if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
if (A->getOption().hasFlag(options::TargetSpecific) &&
!A->isIgnoredTargetSpecific()) {
!A->isIgnoredTargetSpecific() && !HasAssembleJob) {
Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getSpelling() << getTargetTriple();
} else {

View file

@ -30,6 +30,7 @@ void aix::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
const Driver &D = getToolChain().getDriver();
ArgStringList CmdArgs;
const bool IsArch32Bit = getToolChain().getTriple().isArch32Bit();
@ -38,6 +39,11 @@ void aix::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
if (!IsArch32Bit && !IsArch64Bit)
llvm_unreachable("Unsupported bit width value.");
if (Arg *A = C.getArgs().getLastArg(options::OPT_G)) {
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getSpelling() << D.getTargetTriple();
}
// Specify the mode in which the as(1) command operates.
if (IsArch32Bit) {
CmdArgs.push_back("-a32");

View file

@ -118,13 +118,7 @@ std::string x86::getX86TargetCPU(const Driver &D, const ArgList &Args,
void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args,
std::vector<StringRef> &Features, bool ForAS) {
if (ForAS) {
// Some target-specific options are only handled in AddX86TargetArgs, which
// is not called by ClangAs::ConstructJob. Claim them here.
Args.claimAllArgs(options::OPT_mfpmath_EQ);
}
std::vector<StringRef> &Features) {
// Claim and report unsupported -mabi=. Note: we don't support "sysv_abi" or
// "ms_abi" as default function attributes.
if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mabi_EQ)) {

View file

@ -26,7 +26,7 @@ std::string getX86TargetCPU(const Driver &D, const llvm::opt::ArgList &Args,
void getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args,
std::vector<llvm::StringRef> &Features, bool ForAS);
std::vector<llvm::StringRef> &Features);
} // end namespace x86
} // end namespace target

View file

@ -528,7 +528,7 @@ void tools::getTargetFeatures(const Driver &D, const llvm::Triple &Triple,
break;
case llvm::Triple::x86:
case llvm::Triple::x86_64:
x86::getX86TargetFeatures(D, Triple, Args, Features, ForAS);
x86::getX86TargetFeatures(D, Triple, Args, Features);
break;
case llvm::Triple::hexagon:
hexagon::getHexagonTargetFeatures(D, Triple, Args, Features);

View file

@ -15,6 +15,7 @@
#include "clang/Basic/FileEntry.h"
#include "clang/Basic/LangStandard.h"
#include "clang/Basic/Sarif.h"
#include "clang/Basic/Stack.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
@ -1150,6 +1151,10 @@ void ASTFrontendAction::ExecuteAction() {
CompilerInstance &CI = getCompilerInstance();
if (!CI.hasPreprocessor())
return;
// This is a fallback: If the client forgets to invoke this, we mark the
// current stack as the bottom. Though not optimal, this could help prevent
// stack overflow during deep recursion.
clang::noteBottomOfStack();
// FIXME: Move the truncation aspect of this into Sema, we delayed this till
// here so the source manager would be initialized.

View file

@ -19,6 +19,7 @@
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprConcepts.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
@ -9072,16 +9073,24 @@ Sema::BuildExprRequirement(
MultiLevelTemplateArgumentList MLTAL(Param, TAL.asArray(),
/*Final=*/false);
MLTAL.addOuterRetainedLevels(TPL->getDepth());
Expr *IDC = Param->getTypeConstraint()->getImmediatelyDeclaredConstraint();
const TypeConstraint *TC = Param->getTypeConstraint();
assert(TC && "Type Constraint cannot be null here");
auto *IDC = TC->getImmediatelyDeclaredConstraint();
assert(IDC && "ImmediatelyDeclaredConstraint can't be null here.");
ExprResult Constraint = SubstExpr(IDC, MLTAL);
if (Constraint.isInvalid()) {
Status = concepts::ExprRequirement::SS_ExprSubstitutionFailure;
} else {
SubstitutedConstraintExpr =
cast<ConceptSpecializationExpr>(Constraint.get());
if (!SubstitutedConstraintExpr->isSatisfied())
Status = concepts::ExprRequirement::SS_ConstraintsNotSatisfied;
return new (Context) concepts::ExprRequirement(
concepts::createSubstDiagAt(*this, IDC->getExprLoc(),
[&](llvm::raw_ostream &OS) {
IDC->printPretty(OS, /*Helper=*/nullptr,
getPrintingPolicy());
}),
IsSimple, NoexceptLoc, ReturnTypeRequirement);
}
SubstitutedConstraintExpr =
cast<ConceptSpecializationExpr>(Constraint.get());
if (!SubstitutedConstraintExpr->isSatisfied())
Status = concepts::ExprRequirement::SS_ConstraintsNotSatisfied;
}
return new (Context) concepts::ExprRequirement(E, IsSimple, NoexceptLoc,
ReturnTypeRequirement, Status,

View file

@ -2276,9 +2276,9 @@ QualType TemplateInstantiator::TransformSubstTemplateTypeParmPackType(
getPackIndex(Pack), Arg, TL.getNameLoc());
}
template<typename EntityPrinter>
static concepts::Requirement::SubstitutionDiagnostic *
createSubstDiag(Sema &S, TemplateDeductionInfo &Info, EntityPrinter Printer) {
createSubstDiag(Sema &S, TemplateDeductionInfo &Info,
concepts::EntityPrinter Printer) {
SmallString<128> Message;
SourceLocation ErrorLoc;
if (Info.hasSFINAEDiagnostic()) {
@ -2302,6 +2302,19 @@ createSubstDiag(Sema &S, TemplateDeductionInfo &Info, EntityPrinter Printer) {
StringRef(MessageBuf, Message.size())};
}
concepts::Requirement::SubstitutionDiagnostic *
concepts::createSubstDiagAt(Sema &S, SourceLocation Location,
EntityPrinter Printer) {
SmallString<128> Entity;
llvm::raw_svector_ostream OS(Entity);
Printer(OS);
char *EntityBuf = new (S.Context) char[Entity.size()];
llvm::copy(Entity, EntityBuf);
return new (S.Context) concepts::Requirement::SubstitutionDiagnostic{
/*SubstitutedEntity=*/StringRef(EntityBuf, Entity.size()),
/*DiagLoc=*/Location, /*DiagMessage=*/StringRef()};
}
ExprResult TemplateInstantiator::TransformRequiresTypeParams(
SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,

View file

@ -3773,6 +3773,33 @@ SYMBOL(viewable_range, std::ranges::, <ranges>)
SYMBOL(wistream_view, std::ranges::, <ranges>)
SYMBOL(zip_transform_view, std::ranges::, <ranges>)
SYMBOL(zip_view, std::ranges::, <ranges>)
SYMBOL(all, std::ranges::views::, <ranges>)
SYMBOL(all_t, std::ranges::views::, <ranges>)
SYMBOL(as_const, std::ranges::views::, <ranges>)
SYMBOL(as_rvalue, std::ranges::views::, <ranges>)
SYMBOL(common, std::ranges::views::, <ranges>)
SYMBOL(counted, std::ranges::views::, <ranges>)
SYMBOL(drop, std::ranges::views::, <ranges>)
SYMBOL(drop_while, std::ranges::views::, <ranges>)
SYMBOL(elements, std::ranges::views::, <ranges>)
SYMBOL(empty, std::ranges::views::, <ranges>)
SYMBOL(filter, std::ranges::views::, <ranges>)
SYMBOL(iota, std::ranges::views::, <ranges>)
SYMBOL(istream, std::ranges::views::, <ranges>)
SYMBOL(istream, std::ranges::views::, <iosfwd>)
SYMBOL(join, std::ranges::views::, <ranges>)
SYMBOL(join_with, std::ranges::views::, <ranges>)
SYMBOL(keys, std::ranges::views::, <ranges>)
SYMBOL(lazy_split, std::ranges::views::, <ranges>)
SYMBOL(reverse, std::ranges::views::, <ranges>)
SYMBOL(single, std::ranges::views::, <ranges>)
SYMBOL(split, std::ranges::views::, <ranges>)
SYMBOL(take, std::ranges::views::, <ranges>)
SYMBOL(take_while, std::ranges::views::, <ranges>)
SYMBOL(transform, std::ranges::views::, <ranges>)
SYMBOL(values, std::ranges::views::, <ranges>)
SYMBOL(zip, std::ranges::views::, <ranges>)
SYMBOL(zip_transform, std::ranges::views::, <ranges>)
SYMBOL(ECMAScript, std::regex_constants::, <regex>)
SYMBOL(awk, std::regex_constants::, <regex>)
SYMBOL(basic, std::regex_constants::, <regex>)
@ -3817,3 +3844,30 @@ SYMBOL(get_id, std::this_thread::, <thread>)
SYMBOL(sleep_for, std::this_thread::, <thread>)
SYMBOL(sleep_until, std::this_thread::, <thread>)
SYMBOL(yield, std::this_thread::, <thread>)
SYMBOL(all, std::views::, <ranges>)
SYMBOL(all_t, std::views::, <ranges>)
SYMBOL(as_const, std::views::, <ranges>)
SYMBOL(as_rvalue, std::views::, <ranges>)
SYMBOL(common, std::views::, <ranges>)
SYMBOL(counted, std::views::, <ranges>)
SYMBOL(drop, std::views::, <ranges>)
SYMBOL(drop_while, std::views::, <ranges>)
SYMBOL(elements, std::views::, <ranges>)
SYMBOL(empty, std::views::, <ranges>)
SYMBOL(filter, std::views::, <ranges>)
SYMBOL(iota, std::views::, <ranges>)
SYMBOL(istream, std::views::, <ranges>)
SYMBOL(istream, std::views::, <iosfwd>)
SYMBOL(join, std::views::, <ranges>)
SYMBOL(join_with, std::views::, <ranges>)
SYMBOL(keys, std::views::, <ranges>)
SYMBOL(lazy_split, std::views::, <ranges>)
SYMBOL(reverse, std::views::, <ranges>)
SYMBOL(single, std::views::, <ranges>)
SYMBOL(split, std::views::, <ranges>)
SYMBOL(take, std::views::, <ranges>)
SYMBOL(take_while, std::views::, <ranges>)
SYMBOL(transform, std::views::, <ranges>)
SYMBOL(values, std::views::, <ranges>)
SYMBOL(zip, std::views::, <ranges>)
SYMBOL(zip_transform, std::views::, <ranges>)

View file

@ -7,7 +7,7 @@
// Out-of-line LSE atomics helpers. Ported from libgcc library.
// N = {1, 2, 4, 8}
// M = {1, 2, 4, 8, 16}
// ORDER = {'relax', 'acq', 'rel', 'acq_rel'}
// ORDER = {'relax', 'acq', 'rel', 'acq_rel', 'sync'}
// Routines implemented:
//
// iM __aarch64_casM_ORDER(iM expected, iM desired, iM *ptr)
@ -35,8 +35,8 @@ HIDDEN(___aarch64_have_lse_atomics)
#endif
// Generate mnemonics for
// L_cas: SIZE: 1,2,4,8,16 MODEL: 1,2,3,4
// L_swp L_ldadd L_ldclr L_ldeor L_ldset: SIZE: 1,2,4,8 MODEL: 1,2,3,4
// L_cas: SIZE: 1,2,4,8,16 MODEL: 1,2,3,4,5
// L_swp L_ldadd L_ldclr L_ldeor L_ldset: SIZE: 1,2,4,8 MODEL: 1,2,3,4,5
#if SIZE == 1
#define S b
@ -64,24 +64,44 @@ HIDDEN(___aarch64_have_lse_atomics)
#define L
#define M 0x000000
#define N 0x000000
#define BARRIER
#elif MODEL == 2
#define SUFF _acq
#define A a
#define L
#define M 0x400000
#define N 0x800000
#define BARRIER
#elif MODEL == 3
#define SUFF _rel
#define A
#define L l
#define M 0x008000
#define N 0x400000
#define BARRIER
#elif MODEL == 4
#define SUFF _acq_rel
#define A a
#define L l
#define M 0x408000
#define N 0xc00000
#define BARRIER
#elif MODEL == 5
#define SUFF _sync
#ifdef L_swp
// swp has _acq semantics.
#define A a
#define L
#define M 0x400000
#define N 0x800000
#else
// All other _sync functions have _seq semantics.
#define A a
#define L l
#define M 0x408000
#define N 0xc00000
#endif
#define BARRIER dmb ish
#else
#error
#endif // MODEL
@ -96,7 +116,12 @@ HIDDEN(___aarch64_have_lse_atomics)
#endif
#define NAME(BASE) GLUE4(__aarch64_, BASE, SIZE, SUFF)
#if MODEL == 5
// Drop A for _sync functions.
#define LDXR GLUE3(ld, xr, S)
#else
#define LDXR GLUE4(ld, A, xr, S)
#endif
#define STXR GLUE4(st, L, xr, S)
// Define temporary registers.
@ -136,9 +161,15 @@ DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(NAME(cas))
STXR w(tmp1), s(1), [x2]
cbnz w(tmp1), 0b
1:
BARRIER
ret
#else
#if MODEL == 5
// Drop A for _sync functions.
#define LDXP GLUE2(ld, xp)
#else
#define LDXP GLUE3(ld, A, xp)
#endif
#define STXP GLUE3(st, L, xp)
#ifdef HAS_ASM_LSE
#define CASP GLUE3(casp, A, L) x0, x1, x2, x3, [x4]
@ -159,6 +190,7 @@ DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(NAME(cas))
STXP w(tmp2), x2, x3, [x4]
cbnz w(tmp2), 0b
1:
BARRIER
ret
#endif
END_COMPILERRT_OUTLINE_FUNCTION(NAME(cas))
@ -180,6 +212,7 @@ DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(NAME(swp))
LDXR s(0), [x1]
STXR w(tmp1), s(tmp0), [x1]
cbnz w(tmp1), 0b
BARRIER
ret
END_COMPILERRT_OUTLINE_FUNCTION(NAME(swp))
#endif // L_swp
@ -224,6 +257,7 @@ DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(NAME(LDNM))
OP s(tmp1), s(0), s(tmp0)
STXR w(tmp2), s(tmp1), [x1]
cbnz w(tmp2), 0b
BARRIER
ret
END_COMPILERRT_OUTLINE_FUNCTION(NAME(LDNM))
#endif // L_ldadd L_ldclr L_ldeor L_ldset

View file

@ -340,11 +340,19 @@ static void scanf_common(void *ctx, int n_inputs, bool allowGnuMalloc,
size = 0;
}
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, argp, size);
// For %ms/%mc, write the allocated output buffer as well.
// For %mc/%mC/%ms/%m[/%mS, write the allocated output buffer as well.
if (dir.allocate) {
char *buf = *(char **)argp;
if (buf)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1);
if (char *buf = *(char **)argp) {
if (dir.convSpecifier == 'c')
size = 1;
else if (dir.convSpecifier == 'C')
size = sizeof(wchar_t);
else if (dir.convSpecifier == 'S')
size = (internal_wcslen((wchar_t *)buf) + 1) * sizeof(wchar_t);
else // 's' or '['
size = internal_strlen(buf) + 1;
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, size);
}
}
}
}

View file

@ -208,19 +208,16 @@
// HARDENING {
// TODO(hardening): remove this in LLVM 18.
// This is for backward compatibility -- make enabling `_LIBCPP_ENABLE_ASSERTIONS` (which predates hardening modes)
// equivalent to setting the hardened mode.
# ifdef _LIBCPP_ENABLE_ASSERTIONS
# warning "_LIBCPP_ENABLE_ASSERTIONS is deprecated, please use _LIBCPP_ENABLE_HARDENED_MODE instead."
# if _LIBCPP_ENABLE_ASSERTIONS != 0 && _LIBCPP_ENABLE_ASSERTIONS != 1
# error "_LIBCPP_ENABLE_ASSERTIONS must be set to 0 or 1"
# endif
# if _LIBCPP_ENABLE_ASSERTIONS
# define _LIBCPP_ENABLE_HARDENED_MODE 1
# endif
# ifndef _LIBCPP_ENABLE_ASSERTIONS
# define _LIBCPP_ENABLE_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS_DEFAULT
# endif
# if _LIBCPP_ENABLE_ASSERTIONS != 0 && _LIBCPP_ENABLE_ASSERTIONS != 1
# error "_LIBCPP_ENABLE_ASSERTIONS must be set to 0 or 1"
# endif
// NOTE: These modes are experimental and are not stable yet in LLVM 17. Please refrain from using them and use the
// documented libc++ "safe" mode instead.
//
// Enables the hardened mode which consists of all checks intended to be used in production. Hardened mode prioritizes
// security-critical checks that can be done with relatively little overhead in constant time. Mutually exclusive with
// `_LIBCPP_ENABLE_DEBUG_MODE`.
@ -275,6 +272,11 @@
# error "Only one of _LIBCPP_ENABLE_HARDENED_MODE and _LIBCPP_ENABLE_DEBUG_MODE can be enabled."
# endif
# if _LIBCPP_ENABLE_ASSERTIONS && (_LIBCPP_ENABLE_HARDENED_MODE || _LIBCPP_ENABLE_DEBUG_MODE)
# error \
"_LIBCPP_ENABLE_ASSERTIONS is mutually exclusive with _LIBCPP_ENABLE_HARDENED_MODE and _LIBCPP_ENABLE_DEBUG_MODE."
# endif
// Hardened mode checks.
// clang-format off
@ -303,6 +305,18 @@
# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message)
// Safe mode checks.
# elif _LIBCPP_ENABLE_ASSERTIONS
// All checks enabled.
# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message)
// Disable all checks if hardening is not enabled.
# else

View file

@ -115,6 +115,9 @@ public:
/// PredBB to OldSucc to be from PredBB to NewSucc instead.
void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc);
/// Remove information related to this value from the cache.
void forgetValue(Value *V);
/// Inform the analysis cache that we have erased a block.
void eraseBlock(BasicBlock *BB);

View file

@ -465,6 +465,10 @@ public:
F.print(OS, &Writer);
}
/// This is part of the update interface to remove information related to this
/// value from the cache.
void forgetValue(Value *V) { TheCache.eraseValue(V); }
/// This is part of the update interface to inform the cache
/// that a block has been deleted.
void eraseBlock(BasicBlock *BB) {
@ -1969,6 +1973,11 @@ void LazyValueInfo::threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc,
}
}
void LazyValueInfo::forgetValue(Value *V) {
if (PImpl)
getImpl(PImpl, AC, nullptr).forgetValue(V);
}
void LazyValueInfo::eraseBlock(BasicBlock *BB) {
if (PImpl) {
getImpl(PImpl, AC, BB->getModule()).eraseBlock(BB);

View file

@ -6833,7 +6833,7 @@ const ConstantRange &ScalarEvolution::getRangeRef(
if (llvm::isKnownNonZero(V, DL))
MinVal = Align;
ConservativeResult = ConservativeResult.intersectWith(
{MinVal, MaxVal + 1}, RangeType);
ConstantRange::getNonEmpty(MinVal, MaxVal + 1), RangeType);
}
}

View file

@ -1424,7 +1424,17 @@ bool ComplexDeinterleavingGraph::identifyNodes(Instruction *RootI) {
// CompositeNode we should choose only one either Real or Imag instruction to
// use as an anchor for generating complex instruction.
auto It = RootToNode.find(RootI);
if (It != RootToNode.end() && It->second->Real == RootI) {
if (It != RootToNode.end()) {
auto RootNode = It->second;
assert(RootNode->Operation ==
ComplexDeinterleavingOperation::ReductionOperation);
// Find out which part, Real or Imag, comes later, and only if we come to
// the latest part, add it to OrderedRoots.
auto *R = cast<Instruction>(RootNode->Real);
auto *I = cast<Instruction>(RootNode->Imag);
auto *ReplacementAnchor = R->comesBefore(I) ? I : R;
if (ReplacementAnchor != RootI)
return false;
OrderedRoots.push_back(RootI);
return true;
}

View file

@ -13840,7 +13840,17 @@ bool AArch64TargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
case Intrinsic::aarch64_neon_ld4:
case Intrinsic::aarch64_neon_ld1x2:
case Intrinsic::aarch64_neon_ld1x3:
case Intrinsic::aarch64_neon_ld1x4:
case Intrinsic::aarch64_neon_ld1x4: {
Info.opc = ISD::INTRINSIC_W_CHAIN;
uint64_t NumElts = DL.getTypeSizeInBits(I.getType()) / 64;
Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
Info.ptrVal = I.getArgOperand(I.arg_size() - 1);
Info.offset = 0;
Info.align.reset();
// volatile loads with NEON intrinsics not supported
Info.flags = MachineMemOperand::MOLoad;
return true;
}
case Intrinsic::aarch64_neon_ld2lane:
case Intrinsic::aarch64_neon_ld3lane:
case Intrinsic::aarch64_neon_ld4lane:
@ -13848,9 +13858,13 @@ bool AArch64TargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
case Intrinsic::aarch64_neon_ld3r:
case Intrinsic::aarch64_neon_ld4r: {
Info.opc = ISD::INTRINSIC_W_CHAIN;
// Conservatively set memVT to the entire set of vectors loaded.
uint64_t NumElts = DL.getTypeSizeInBits(I.getType()) / 64;
Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
// ldx return struct with the same vec type
Type *RetTy = I.getType();
auto *StructTy = cast<StructType>(RetTy);
unsigned NumElts = StructTy->getNumElements();
Type *VecTy = StructTy->getElementType(0);
MVT EleVT = MVT::getVT(VecTy).getVectorElementType();
Info.memVT = EVT::getVectorVT(I.getType()->getContext(), EleVT, NumElts);
Info.ptrVal = I.getArgOperand(I.arg_size() - 1);
Info.offset = 0;
Info.align.reset();
@ -13863,12 +13877,8 @@ bool AArch64TargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
case Intrinsic::aarch64_neon_st4:
case Intrinsic::aarch64_neon_st1x2:
case Intrinsic::aarch64_neon_st1x3:
case Intrinsic::aarch64_neon_st1x4:
case Intrinsic::aarch64_neon_st2lane:
case Intrinsic::aarch64_neon_st3lane:
case Intrinsic::aarch64_neon_st4lane: {
case Intrinsic::aarch64_neon_st1x4: {
Info.opc = ISD::INTRINSIC_VOID;
// Conservatively set memVT to the entire set of vectors stored.
unsigned NumElts = 0;
for (const Value *Arg : I.args()) {
Type *ArgTy = Arg->getType();
@ -13884,6 +13894,30 @@ bool AArch64TargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
Info.flags = MachineMemOperand::MOStore;
return true;
}
case Intrinsic::aarch64_neon_st2lane:
case Intrinsic::aarch64_neon_st3lane:
case Intrinsic::aarch64_neon_st4lane: {
Info.opc = ISD::INTRINSIC_VOID;
unsigned NumElts = 0;
// all the vector type is same
Type *VecTy = I.getArgOperand(0)->getType();
MVT EleVT = MVT::getVT(VecTy).getVectorElementType();
for (const Value *Arg : I.args()) {
Type *ArgTy = Arg->getType();
if (!ArgTy->isVectorTy())
break;
NumElts += 1;
}
Info.memVT = EVT::getVectorVT(I.getType()->getContext(), EleVT, NumElts);
Info.ptrVal = I.getArgOperand(I.arg_size() - 1);
Info.offset = 0;
Info.align.reset();
// volatile stores with NEON intrinsics not supported
Info.flags = MachineMemOperand::MOStore;
return true;
}
case Intrinsic::aarch64_ldaxr:
case Intrinsic::aarch64_ldxr: {
Type *ValTy = I.getParamElementType(0);

View file

@ -1269,6 +1269,7 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
if (IsLoadCSE) {
LoadInst *NLoadI = cast<LoadInst>(AvailableVal);
combineMetadataForCSE(NLoadI, LoadI, false);
LVI->forgetValue(NLoadI);
};
// If the returned value is the load itself, replace with poison. This can
@ -1461,6 +1462,7 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
for (LoadInst *PredLoadI : CSELoads) {
combineMetadataForCSE(PredLoadI, LoadI, true);
LVI->forgetValue(PredLoadI);
}
LoadI->replaceAllUsesWith(PN);

View file

@ -3781,10 +3781,44 @@ void InnerLoopVectorizer::fixCrossIterationPHIs(VPTransformState &State) {
// the incoming edges.
VPBasicBlock *Header =
State.Plan->getVectorLoopRegion()->getEntryBasicBlock();
// Gather all VPReductionPHIRecipe and sort them so that Intermediate stores
// sank outside of the loop would keep the same order as they had in the
// original loop.
SmallVector<VPReductionPHIRecipe *> ReductionPHIList;
for (VPRecipeBase &R : Header->phis()) {
if (auto *ReductionPhi = dyn_cast<VPReductionPHIRecipe>(&R))
fixReduction(ReductionPhi, State);
else if (auto *FOR = dyn_cast<VPFirstOrderRecurrencePHIRecipe>(&R))
ReductionPHIList.emplace_back(ReductionPhi);
}
stable_sort(ReductionPHIList, [this](const VPReductionPHIRecipe *R1,
const VPReductionPHIRecipe *R2) {
auto *IS1 = R1->getRecurrenceDescriptor().IntermediateStore;
auto *IS2 = R2->getRecurrenceDescriptor().IntermediateStore;
// If neither of the recipes has an intermediate store, keep the order the
// same.
if (!IS1 && !IS2)
return false;
// If only one of the recipes has an intermediate store, then move it
// towards the beginning of the list.
if (IS1 && !IS2)
return true;
if (!IS1 && IS2)
return false;
// If both recipes have an intermediate store, then the recipe with the
// later store should be processed earlier. So it should go to the beginning
// of the list.
return DT->dominates(IS2, IS1);
});
for (VPReductionPHIRecipe *ReductionPhi : ReductionPHIList)
fixReduction(ReductionPhi, State);
for (VPRecipeBase &R : Header->phis()) {
if (auto *FOR = dyn_cast<VPFirstOrderRecurrencePHIRecipe>(&R))
fixFixedOrderRecurrence(FOR, State);
}
}