1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-10-18 02:19:39 +00:00

Vendor import of llvm-project branch release/19.x llvmorg-19.1.1-0-gd401987fe349, a.k.a. 19.1.1 release.

This commit is contained in:
Dimitry Andric 2024-10-08 14:29:50 +02:00
parent 1de139fdd5
commit 0370629593
33 changed files with 315 additions and 77 deletions

View File

@ -680,6 +680,9 @@ class alignas(8) Decl {
/// Whether this declaration comes from explicit global module.
bool isFromExplicitGlobalModule() const;
/// Whether this declaration comes from global module.
bool isFromGlobalModule() const;
/// Whether this declaration comes from a named module.
bool isInNamedModule() const;

View File

@ -234,6 +234,12 @@ std::unique_ptr<CompilationDatabase>
std::unique_ptr<CompilationDatabase>
inferTargetAndDriverMode(std::unique_ptr<CompilationDatabase> Base);
/// Returns a wrapped CompilationDatabase that will transform argv[0] to an
/// absolute path, if it currently is a plain tool name, looking it up in
/// PATH.
std::unique_ptr<CompilationDatabase>
inferToolLocation(std::unique_ptr<CompilationDatabase> Base);
/// Returns a wrapped CompilationDatabase that will expand all rsp(response)
/// files on commandline returned by underlying database.
std::unique_ptr<CompilationDatabase>

View File

@ -1161,6 +1161,10 @@ bool Decl::isFromExplicitGlobalModule() const {
return getOwningModule() && getOwningModule()->isExplicitGlobalModule();
}
bool Decl::isFromGlobalModule() const {
return getOwningModule() && getOwningModule()->isGlobalModule();
}
bool Decl::isInNamedModule() const {
return getOwningModule() && getOwningModule()->isNamedModule();
}

View File

@ -2833,19 +2833,23 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
llvm::AtomicOrdering::SequentiallyConsistent);
return isPre ? Builder.CreateBinOp(op, old, amt) : old;
}
// Special case for atomic increment/decrement on floats
// Special case for atomic increment/decrement on floats.
// Bail out non-power-of-2-sized floating point types (e.g., x86_fp80).
if (type->isFloatingType()) {
llvm::Type *Ty = ConvertType(type);
if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
llvm::AtomicRMWInst::BinOp aop =
isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
llvm::Instruction::BinaryOps op =
isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
llvm::Value *amt = llvm::ConstantFP::get(
VMContext, llvm::APFloat(static_cast<float>(1.0)));
llvm::Value *old =
Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
llvm::AtomicRMWInst *old = Builder.CreateAtomicRMW(
aop, LV.getAddress(), amt,
llvm::AtomicOrdering::SequentiallyConsistent);
return isPre ? Builder.CreateBinOp(op, old, amt) : old;
}
}
value = EmitLoadOfLValue(LV, E->getExprLoc());
input = value;
// For every other atomic operation, we need to emit a load-op-cmpxchg loop

View File

@ -8561,6 +8561,32 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
WantDebug = !A->getOption().matches(options::OPT_g0) &&
!A->getOption().matches(options::OPT_ggdb0);
// If a -gdwarf argument appeared, remember it.
bool EmitDwarf = false;
if (const Arg *A = getDwarfNArg(Args))
EmitDwarf = checkDebugInfoOption(A, Args, D, getToolChain());
bool EmitCodeView = false;
if (const Arg *A = Args.getLastArg(options::OPT_gcodeview))
EmitCodeView = checkDebugInfoOption(A, Args, D, getToolChain());
// If the user asked for debug info but did not explicitly specify -gcodeview
// or -gdwarf, ask the toolchain for the default format.
if (!EmitCodeView && !EmitDwarf && WantDebug) {
switch (getToolChain().getDefaultDebugFormat()) {
case llvm::codegenoptions::DIF_CodeView:
EmitCodeView = true;
break;
case llvm::codegenoptions::DIF_DWARF:
EmitDwarf = true;
break;
}
}
// If the arguments don't imply DWARF, don't emit any debug info here.
if (!EmitDwarf)
WantDebug = false;
llvm::codegenoptions::DebugInfoKind DebugInfoKind =
llvm::codegenoptions::NoDebugInfo;

View File

@ -100,6 +100,13 @@ ArrayRef<FormatToken *> FormatTokenLexer::lex() {
if (Tokens.back()->NewlinesBefore > 0 || Tokens.back()->IsMultiline)
FirstInLineIndex = Tokens.size() - 1;
} while (Tokens.back()->isNot(tok::eof));
if (Style.InsertNewlineAtEOF) {
auto &TokEOF = *Tokens.back();
if (TokEOF.NewlinesBefore == 0) {
TokEOF.NewlinesBefore = 1;
TokEOF.OriginalColumn = 0;
}
}
return Tokens;
}

View File

@ -3680,11 +3680,6 @@ void TokenAnnotator::annotate(AnnotatedLine &Line) {
auto *First = Line.First;
First->SpacesRequiredBefore = 1;
First->CanBreakBefore = First->MustBreakBefore;
if (First->is(tok::eof) && First->NewlinesBefore == 0 &&
Style.InsertNewlineAtEOF) {
First->NewlinesBefore = 1;
}
}
// This function heuristically determines whether 'Current' starts the name of a

View File

@ -969,8 +969,30 @@ static const Expr *SubstituteConstraintExpressionWithoutSatisfaction(
// equivalence.
LocalInstantiationScope ScopeForParameters(S);
if (auto *FD = DeclInfo.getDecl()->getAsFunction())
for (auto *PVD : FD->parameters())
for (auto *PVD : FD->parameters()) {
if (!PVD->isParameterPack()) {
ScopeForParameters.InstantiatedLocal(PVD, PVD);
continue;
}
// This is hacky: we're mapping the parameter pack to a size-of-1 argument
// to avoid building SubstTemplateTypeParmPackTypes for
// PackExpansionTypes. The SubstTemplateTypeParmPackType node would
// otherwise reference the AssociatedDecl of the template arguments, which
// is, in this case, the template declaration.
//
// However, as we are in the process of comparing potential
// re-declarations, the canonical declaration is the declaration itself at
// this point. So if we didn't expand these packs, we would end up with an
// incorrect profile difference because we will be profiling the
// canonical types!
//
// FIXME: Improve the "no-transform" machinery in FindInstantiatedDecl so
// that we can eliminate the Scope in the cases where the declarations are
// not necessarily instantiated. It would also benefit the noexcept
// specifier comparison.
ScopeForParameters.MakeInstantiatedLocalArgPack(PVD);
ScopeForParameters.InstantiatedLocalPackArg(PVD, PVD);
}
std::optional<Sema::CXXThisScopeRAII> ThisScope;

View File

@ -9732,8 +9732,9 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// the function decl is created above).
// FIXME: We need a better way to separate C++ standard and clang modules.
bool ImplicitInlineCXX20 = !getLangOpts().CPlusPlusModules ||
NewFD->isConstexpr() || NewFD->isConsteval() ||
!NewFD->getOwningModule() ||
NewFD->isFromExplicitGlobalModule() ||
NewFD->isFromGlobalModule() ||
NewFD->getOwningModule()->isHeaderLikeModule();
bool isInline = D.getDeclSpec().isInlineSpecified();
bool isVirtual = D.getDeclSpec().isVirtualSpecified();

View File

@ -0,0 +1,71 @@
//===- GuessTargetAndModeCompilationDatabase.cpp --------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include <memory>
namespace clang {
namespace tooling {
namespace {
class LocationAdderDatabase : public CompilationDatabase {
public:
LocationAdderDatabase(std::unique_ptr<CompilationDatabase> Base)
: Base(std::move(Base)) {
assert(this->Base != nullptr);
}
std::vector<std::string> getAllFiles() const override {
return Base->getAllFiles();
}
std::vector<CompileCommand> getAllCompileCommands() const override {
return addLocation(Base->getAllCompileCommands());
}
std::vector<CompileCommand>
getCompileCommands(StringRef FilePath) const override {
return addLocation(Base->getCompileCommands(FilePath));
}
private:
std::vector<CompileCommand>
addLocation(std::vector<CompileCommand> Cmds) const {
for (auto &Cmd : Cmds) {
if (Cmd.CommandLine.empty())
continue;
std::string &Driver = Cmd.CommandLine.front();
// If the driver name already is absolute, we don't need to do anything.
if (llvm::sys::path::is_absolute(Driver))
continue;
// If the name is a relative path, like bin/clang, we assume it's
// possible to resolve it and don't do anything about it either.
if (llvm::any_of(Driver,
[](char C) { return llvm::sys::path::is_separator(C); }))
continue;
auto Absolute = llvm::sys::findProgramByName(Driver);
// If we found it in path, update the entry in Cmd.CommandLine
if (Absolute && llvm::sys::path::is_absolute(*Absolute))
Driver = std::move(*Absolute);
}
return Cmds;
}
std::unique_ptr<CompilationDatabase> Base;
};
} // namespace
std::unique_ptr<CompilationDatabase>
inferToolLocation(std::unique_ptr<CompilationDatabase> Base) {
return std::make_unique<LocationAdderDatabase>(std::move(Base));
}
} // namespace tooling
} // namespace clang

View File

@ -2014,6 +2014,18 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
return Unknown;
return esr & ESR_ELx_WNR ? Write : Read;
# elif defined(__loongarch__)
// In the musl environment, the Linux kernel uapi sigcontext.h is not
// included in signal.h. To avoid missing the SC_ADDRERR_{RD,WR} macros,
// copy them here. The LoongArch Linux kernel uapi is already stable,
// so there's no need to worry about the value changing.
# ifndef SC_ADDRERR_RD
// Address error was due to memory load
# define SC_ADDRERR_RD (1 << 30)
# endif
# ifndef SC_ADDRERR_WR
// Address error was due to memory store
# define SC_ADDRERR_WR (1 << 31)
# endif
u32 flags = ucontext->uc_mcontext.__flags;
if (flags & SC_ADDRERR_RD)
return SignalContext::Read;

View File

@ -27,7 +27,7 @@
// _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM.
// Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 17.0.1 == 17.00.01), _LIBCPP_VERSION is
// defined to XXYYZZ.
# define _LIBCPP_VERSION 190100
# define _LIBCPP_VERSION 190101
# define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y
# define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y)

View File

@ -26,7 +26,8 @@
# if __has_builtin(__builtin_verbose_trap)
// AppleClang shipped a slightly different version of __builtin_verbose_trap from the upstream
// version before upstream Clang actually got the builtin.
# if defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 17000
// TODO: Remove once AppleClang supports the two-arguments version of the builtin.
# if defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1700
# define _LIBCPP_ASSERTION_HANDLER(message) __builtin_verbose_trap(message)
# else
# define _LIBCPP_ASSERTION_HANDLER(message) __builtin_verbose_trap("libc++", message)

View File

@ -324,7 +324,7 @@ bool ICF<ELFT>::equalsConstant(const InputSection *a, const InputSection *b) {
const RelsOrRelas<ELFT> ra = a->template relsOrRelas<ELFT>();
const RelsOrRelas<ELFT> rb = b->template relsOrRelas<ELFT>();
if (ra.areRelocsCrel())
if (ra.areRelocsCrel() || rb.areRelocsCrel())
return constantEq(a, ra.crels, b, rb.crels);
return ra.areRelocsRel() || rb.areRelocsRel()
? constantEq(a, ra.rels, b, rb.rels)
@ -376,7 +376,7 @@ template <class ELFT>
bool ICF<ELFT>::equalsVariable(const InputSection *a, const InputSection *b) {
const RelsOrRelas<ELFT> ra = a->template relsOrRelas<ELFT>();
const RelsOrRelas<ELFT> rb = b->template relsOrRelas<ELFT>();
if (ra.areRelocsCrel())
if (ra.areRelocsCrel() || rb.areRelocsCrel())
return variableEq(a, ra.crels, b, rb.crels);
return ra.areRelocsRel() || rb.areRelocsRel()
? variableEq(a, ra.rels, b, rb.rels)

View File

@ -150,12 +150,12 @@ RelsOrRelas<ELFT> InputSectionBase::relsOrRelas(bool supportsCrel) const {
InputSectionBase *const &relSec = f->getSections()[relSecIdx];
// Otherwise, allocate a buffer to hold the decoded RELA relocations. When
// called for the first time, relSec is null (without --emit-relocs) or an
// InputSection with zero eqClass[0].
if (!relSec || !cast<InputSection>(relSec)->eqClass[0]) {
// InputSection with false decodedCrel.
if (!relSec || !cast<InputSection>(relSec)->decodedCrel) {
auto *sec = makeThreadLocal<InputSection>(*f, shdr, name);
f->cacheDecodedCrel(relSecIdx, sec);
sec->type = SHT_RELA;
sec->eqClass[0] = SHT_RELA;
sec->decodedCrel = true;
RelocsCrel<ELFT::Is64Bits> entries(sec->content_);
sec->size = entries.size() * sizeof(typename ELFT::Rela);

View File

@ -176,6 +176,10 @@ class InputSectionBase : public SectionBase {
mutable bool compressed = false;
// Whether this section is SHT_CREL and has been decoded to RELA by
// relsOrRelas.
bool decodedCrel = false;
// Whether the section needs to be padded with a NOP filler due to
// deleteFallThruJmpInsn.
bool nopFiller = false;

View File

@ -320,7 +320,7 @@ class AAResults {
public:
// Make these results default constructable and movable. We have to spell
// these out because MSVC won't synthesize them.
AAResults(const TargetLibraryInfo &TLI) : TLI(TLI) {}
AAResults(const TargetLibraryInfo &TLI);
AAResults(AAResults &&Arg);
~AAResults();

View File

@ -73,6 +73,8 @@ static cl::opt<bool> EnableAATrace("aa-trace", cl::Hidden, cl::init(false));
static const bool EnableAATrace = false;
#endif
AAResults::AAResults(const TargetLibraryInfo &TLI) : TLI(TLI) {}
AAResults::AAResults(AAResults &&Arg)
: TLI(Arg.TLI), AAs(std::move(Arg.AAs)), AADeps(std::move(Arg.AADeps)) {}

View File

@ -272,6 +272,7 @@ bool InitUndef::runOnMachineFunction(MachineFunction &MF) {
for (auto *DeadMI : DeadInsts)
DeadMI->eraseFromParent();
DeadInsts.clear();
NewRegs.clear();
return Changed;
}

View File

@ -191,6 +191,11 @@ namespace {
// AA - Used for DAG load/store alias analysis.
AliasAnalysis *AA;
/// This caches all chains that have already been processed in
/// DAGCombiner::getStoreMergeCandidates() and found to have no mergeable
/// stores candidates.
SmallPtrSet<SDNode *, 4> ChainsWithoutMergeableStores;
/// When an instruction is simplified, add all users of the instruction to
/// the work lists because they might get more simplified now.
void AddUsersToWorklist(SDNode *N) {
@ -776,11 +781,10 @@ namespace {
bool UseTrunc);
/// This is a helper function for mergeConsecutiveStores. Stores that
/// potentially may be merged with St are placed in StoreNodes. RootNode is
/// a chain predecessor to all store candidates.
void getStoreMergeCandidates(StoreSDNode *St,
SmallVectorImpl<MemOpLink> &StoreNodes,
SDNode *&Root);
/// potentially may be merged with St are placed in StoreNodes. On success,
/// returns a chain predecessor to all store candidates.
SDNode *getStoreMergeCandidates(StoreSDNode *St,
SmallVectorImpl<MemOpLink> &StoreNodes);
/// Helper function for mergeConsecutiveStores. Checks if candidate stores
/// have indirect dependency through their operands. RootNode is the
@ -1782,6 +1786,9 @@ void DAGCombiner::Run(CombineLevel AtLevel) {
++NodesCombined;
// Invalidate cached info.
ChainsWithoutMergeableStores.clear();
// If we get back the same node we passed in, rather than a new node or
// zero, we know that the node must have defined multiple values and
// CombineTo was used. Since CombineTo takes care of the worklist
@ -20372,15 +20379,15 @@ bool DAGCombiner::mergeStoresOfConstantsOrVecElts(
return true;
}
void DAGCombiner::getStoreMergeCandidates(
StoreSDNode *St, SmallVectorImpl<MemOpLink> &StoreNodes,
SDNode *&RootNode) {
SDNode *
DAGCombiner::getStoreMergeCandidates(StoreSDNode *St,
SmallVectorImpl<MemOpLink> &StoreNodes) {
// This holds the base pointer, index, and the offset in bytes from the base
// pointer. We must have a base and an offset. Do not handle stores to undef
// base pointers.
BaseIndexOffset BasePtr = BaseIndexOffset::match(St, DAG);
if (!BasePtr.getBase().getNode() || BasePtr.getBase().isUndef())
return;
return nullptr;
SDValue Val = peekThroughBitcasts(St->getValue());
StoreSource StoreSrc = getStoreSource(Val);
@ -20396,14 +20403,14 @@ void DAGCombiner::getStoreMergeCandidates(
LoadVT = Ld->getMemoryVT();
// Load and store should be the same type.
if (MemVT != LoadVT)
return;
return nullptr;
// Loads must only have one use.
if (!Ld->hasNUsesOfValue(1, 0))
return;
return nullptr;
// The memory operands must not be volatile/indexed/atomic.
// TODO: May be able to relax for unordered atomics (see D66309)
if (!Ld->isSimple() || Ld->isIndexed())
return;
return nullptr;
}
auto CandidateMatch = [&](StoreSDNode *Other, BaseIndexOffset &Ptr,
int64_t &Offset) -> bool {
@ -20471,6 +20478,27 @@ void DAGCombiner::getStoreMergeCandidates(
return (BasePtr.equalBaseIndex(Ptr, DAG, Offset));
};
// We are looking for a root node which is an ancestor to all mergable
// stores. We search up through a load, to our root and then down
// through all children. For instance we will find Store{1,2,3} if
// St is Store1, Store2. or Store3 where the root is not a load
// which always true for nonvolatile ops. TODO: Expand
// the search to find all valid candidates through multiple layers of loads.
//
// Root
// |-------|-------|
// Load Load Store3
// | |
// Store1 Store2
//
// FIXME: We should be able to climb and
// descend TokenFactors to find candidates as well.
SDNode *RootNode = St->getChain().getNode();
// Bail out if we already analyzed this root node and found nothing.
if (ChainsWithoutMergeableStores.contains(RootNode))
return nullptr;
// Check if the pair of StoreNode and the RootNode already bail out many
// times which is over the limit in dependence check.
auto OverLimitInDependenceCheck = [&](SDNode *StoreNode,
@ -20494,28 +20522,13 @@ void DAGCombiner::getStoreMergeCandidates(
}
};
// We looking for a root node which is an ancestor to all mergable
// stores. We search up through a load, to our root and then down
// through all children. For instance we will find Store{1,2,3} if
// St is Store1, Store2. or Store3 where the root is not a load
// which always true for nonvolatile ops. TODO: Expand
// the search to find all valid candidates through multiple layers of loads.
//
// Root
// |-------|-------|
// Load Load Store3
// | |
// Store1 Store2
//
// FIXME: We should be able to climb and
// descend TokenFactors to find candidates as well.
RootNode = St->getChain().getNode();
unsigned NumNodesExplored = 0;
const unsigned MaxSearchNodes = 1024;
if (auto *Ldn = dyn_cast<LoadSDNode>(RootNode)) {
RootNode = Ldn->getChain().getNode();
// Bail out if we already analyzed this root node and found nothing.
if (ChainsWithoutMergeableStores.contains(RootNode))
return nullptr;
for (auto I = RootNode->use_begin(), E = RootNode->use_end();
I != E && NumNodesExplored < MaxSearchNodes; ++I, ++NumNodesExplored) {
if (I.getOperandNo() == 0 && isa<LoadSDNode>(*I)) { // walk down chain
@ -20532,6 +20545,8 @@ void DAGCombiner::getStoreMergeCandidates(
I != E && NumNodesExplored < MaxSearchNodes; ++I, ++NumNodesExplored)
TryToAddCandidate(I);
}
return RootNode;
}
// We need to check that merging these stores does not cause a loop in the
@ -21162,9 +21177,8 @@ bool DAGCombiner::mergeConsecutiveStores(StoreSDNode *St) {
return false;
SmallVector<MemOpLink, 8> StoreNodes;
SDNode *RootNode;
// Find potential store merge candidates by searching through chain sub-DAG
getStoreMergeCandidates(St, StoreNodes, RootNode);
SDNode *RootNode = getStoreMergeCandidates(St, StoreNodes);
// Check if there is anything to merge.
if (StoreNodes.size() < 2)
@ -21220,6 +21234,11 @@ bool DAGCombiner::mergeConsecutiveStores(StoreSDNode *St) {
llvm_unreachable("Unhandled store source type");
}
}
// Remember if we failed to optimize, to save compile time.
if (!MadeChange)
ChainsWithoutMergeableStores.insert(RootNode);
return MadeChange;
}

View File

@ -2190,7 +2190,8 @@ void SelectionDAGLegalize::ExpandFPLibCall(SDNode* Node,
Results.push_back(Tmp.first);
Results.push_back(Tmp.second);
} else {
SDValue Tmp = ExpandLibCall(LC, Node, false).first;
bool IsSignedArgument = Node->getOpcode() == ISD::FLDEXP;
SDValue Tmp = ExpandLibCall(LC, Node, IsSignedArgument).first;
Results.push_back(Tmp);
}
}

View File

@ -3592,6 +3592,21 @@ ExecutionSession::IL_failSymbols(JITDylib &JD,
assert(MI.DefiningEDU->Symbols.count(NonOwningSymbolStringPtr(Name)) &&
"Symbol does not appear in its DefiningEDU");
MI.DefiningEDU->Symbols.erase(NonOwningSymbolStringPtr(Name));
// Remove this EDU from the dependants lists of its dependencies.
for (auto &[DepJD, DepSyms] : MI.DefiningEDU->Dependencies) {
for (auto DepSym : DepSyms) {
assert(DepJD->Symbols.count(SymbolStringPtr(DepSym)) &&
"DepSym not in DepJD");
assert(DepJD->MaterializingInfos.count(SymbolStringPtr(DepSym)) &&
"DepSym has not MaterializingInfo");
auto &SymMI = DepJD->MaterializingInfos[SymbolStringPtr(DepSym)];
assert(SymMI.DependantEDUs.count(MI.DefiningEDU.get()) &&
"DefiningEDU missing from DependantEDUs list of dependency");
SymMI.DependantEDUs.erase(MI.DefiningEDU.get());
}
}
MI.DefiningEDU = nullptr;
} else {
// Otherwise if there are any EDUs waiting on this symbol then move

View File

@ -1911,7 +1911,7 @@ bool AMDGPUDAGToDAGISel::SelectScratchSAddr(SDNode *Parent, SDValue Addr,
0);
}
Offset = CurDAG->getTargetConstant(COffsetVal, DL, MVT::i16);
Offset = CurDAG->getTargetConstant(COffsetVal, DL, MVT::i32);
return true;
}
@ -1967,7 +1967,7 @@ bool AMDGPUDAGToDAGISel::SelectScratchSVAddr(SDNode *N, SDValue Addr,
return false;
if (checkFlatScratchSVSSwizzleBug(VAddr, SAddr, SplitImmOffset))
return false;
Offset = CurDAG->getTargetConstant(SplitImmOffset, SDLoc(), MVT::i16);
Offset = CurDAG->getTargetConstant(SplitImmOffset, SDLoc(), MVT::i32);
return true;
}
}
@ -2000,7 +2000,7 @@ bool AMDGPUDAGToDAGISel::SelectScratchSVAddr(SDNode *N, SDValue Addr,
if (checkFlatScratchSVSSwizzleBug(VAddr, SAddr, ImmOffset))
return false;
SAddr = SelectSAddrFI(CurDAG, SAddr);
Offset = CurDAG->getTargetConstant(ImmOffset, SDLoc(), MVT::i16);
Offset = CurDAG->getTargetConstant(ImmOffset, SDLoc(), MVT::i32);
return true;
}

View File

@ -122,8 +122,13 @@ bool AVRDAGToDAGISel::SelectAddr(SDNode *Op, SDValue N, SDValue &Base,
// offset allowed.
MVT VT = cast<MemSDNode>(Op)->getMemoryVT().getSimpleVT();
// We only accept offsets that fit in 6 bits (unsigned).
if (isUInt<6>(RHSC) && (VT == MVT::i8 || VT == MVT::i16)) {
// We only accept offsets that fit in 6 bits (unsigned), with the exception
// of 16-bit loads - those can only go up to 62, because we desugar them
// into a pair of 8-bit loads like `ldd rx, RHSC` + `ldd ry, RHSC + 1`.
bool OkI8 = VT == MVT::i8 && RHSC <= 63;
bool OkI16 = VT == MVT::i16 && RHSC <= 62;
if (OkI8 || OkI16) {
Base = N.getOperand(0);
Disp = CurDAG->getTargetConstant(RHSC, dl, MVT::i8);

View File

@ -295,6 +295,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Custom);
setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom);
setOperationAction(ISD::BUILD_VECTOR, VT, Custom);
setOperationAction(ISD::CONCAT_VECTORS, VT, Legal);
setOperationAction(ISD::SETCC, VT, Legal);
setOperationAction(ISD::VSELECT, VT, Legal);
@ -5600,8 +5601,9 @@ bool LoongArchTargetLowering::shouldInsertFencesForAtomic(
// On LA64, atomic store operations with IntegerBitWidth of 32 and 64 do not
// require fences beacuse we can use amswap_db.[w/d].
if (isa<StoreInst>(I)) {
unsigned Size = I->getOperand(0)->getType()->getIntegerBitWidth();
Type *Ty = I->getOperand(0)->getType();
if (isa<StoreInst>(I) && Ty->isIntegerTy()) {
unsigned Size = Ty->getIntegerBitWidth();
return (Size == 8 || Size == 16);
}

View File

@ -1065,10 +1065,13 @@ def RDTIME_D : RDTIME_2R<0x00006800>;
/// Generic pattern classes
def assertsexti32 : PatFrag<(ops node:$src), (assertsext node:$src), [{
return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32);
}]>;
class PatGprGpr<SDPatternOperator OpNode, LAInst Inst>
: Pat<(OpNode GPR:$rj, GPR:$rk), (Inst GPR:$rj, GPR:$rk)>;
class PatGprGpr_32<SDPatternOperator OpNode, LAInst Inst>
: Pat<(sext_inreg (OpNode GPR:$rj, GPR:$rk), i32), (Inst GPR:$rj, GPR:$rk)>;
: Pat<(sext_inreg (OpNode (assertsexti32 GPR:$rj), (assertsexti32 GPR:$rk)), i32), (Inst GPR:$rj, GPR:$rk)>;
class PatGpr<SDPatternOperator OpNode, LAInst Inst>
: Pat<(OpNode GPR:$rj), (Inst GPR:$rj)>;

View File

@ -1789,6 +1789,12 @@ def : Pat<(v4i32 (fp_to_uint (v4f64 LASX256:$vj))),
v4f64:$vj)),
sub_128)>;
// XVPERMI_Q
foreach vt = [v32i8, v16i16, v8i32, v4i64, v8f32, v4f64] in
def : Pat<(vt (concat_vectors LSX128:$vd, LSX128:$vj)),
(XVPERMI_Q (SUBREG_TO_REG (i64 0), LSX128:$vd, sub_128),
(SUBREG_TO_REG (i64 0), LSX128:$vj, sub_128), 2)>;
} // Predicates = [HasExtLASX]
/// Intrinsic pattern

View File

@ -637,6 +637,19 @@ static bool isSignExtendedW(Register SrcReg, const LoongArchSubtarget &ST,
break;
}
return false;
// If all incoming values are sign-extended and all users only use
// the lower 32 bits, then convert them to W versions.
case LoongArch::DIV_D: {
if (!AddRegToWorkList(MI->getOperand(1).getReg()))
return false;
if (!AddRegToWorkList(MI->getOperand(2).getReg()))
return false;
if (hasAllWUsers(*MI, ST, MRI)) {
FixableDef.insert(MI);
break;
}
return false;
}
}
}
@ -651,6 +664,8 @@ static unsigned getWOp(unsigned Opcode) {
return LoongArch::ADDI_W;
case LoongArch::ADD_D:
return LoongArch::ADD_W;
case LoongArch::DIV_D:
return LoongArch::DIV_W;
case LoongArch::LD_D:
case LoongArch::LD_WU:
return LoongArch::LD_W;

View File

@ -2707,7 +2707,8 @@ bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) {
bool MaybeDirectBranchDest = true;
if (Parser.isParsingMasm()) {
if (is64BitMode() && SM.getElementSize() > 0) {
if (is64BitMode() &&
((PtrInOperand && !IndexReg) || SM.getElementSize() > 0)) {
DefaultBaseReg = X86::RIP;
}
if (IsUnconditionalBranch) {

View File

@ -3415,7 +3415,7 @@ unsigned X86TargetLowering::preferedOpcodeForCmpEqPiecesOfOperand(
// We prefer rotate for vectors of if we won't get a zext mask with SRL
// (PreferRotate will be set in the latter case).
if (PreferRotate || VT.isVector())
if (PreferRotate || !MayTransformRotate || VT.isVector())
return ShiftOpc;
// Non-vector type and we have a zext mask with SRL.

View File

@ -2625,11 +2625,11 @@ multiclass avx512_mask_mov<bits<8> opc_kk, bits<8> opc_km, bits<8> opc_mk,
def km#Suffix : I<opc_km, MRMSrcMem, (outs KRC:$dst), (ins x86memop:$src),
!strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
[(set KRC:$dst, (vvt (load addr:$src)))]>,
Sched<[WriteLoad]>;
Sched<[WriteLoad]>, NoCD8;
def mk#Suffix : I<opc_mk, MRMDestMem, (outs), (ins x86memop:$dst, KRC:$src),
!strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
[(store KRC:$src, addr:$dst)]>,
Sched<[WriteStore]>;
Sched<[WriteStore]>, NoCD8;
}
multiclass avx512_mask_mov_gpr<bits<8> opc_kr, bits<8> opc_rk,

View File

@ -1349,7 +1349,8 @@ static bool MayContainThrowingOrExitingCallAfterCB(CallBase *Begin,
// Add attributes from CB params and Fn attributes that can always be propagated
// to the corresponding argument / inner callbases.
static void AddParamAndFnBasicAttributes(const CallBase &CB,
ValueToValueMapTy &VMap) {
ValueToValueMapTy &VMap,
ClonedCodeInfo &InlinedFunctionInfo) {
auto *CalledFunction = CB.getCalledFunction();
auto &Context = CalledFunction->getContext();
@ -1380,6 +1381,11 @@ static void AddParamAndFnBasicAttributes(const CallBase &CB,
auto *NewInnerCB = dyn_cast_or_null<CallBase>(VMap.lookup(InnerCB));
if (!NewInnerCB)
continue;
// The InnerCB might have be simplified during the inlining
// process which can make propagation incorrect.
if (InlinedFunctionInfo.isSimplified(InnerCB, NewInnerCB))
continue;
AttributeList AL = NewInnerCB->getAttributes();
for (unsigned I = 0, E = InnerCB->arg_size(); I < E; ++I) {
// Check if the underlying value for the parameter is an argument.
@ -1455,7 +1461,8 @@ static AttrBuilder IdentifyValidPoisonGeneratingAttributes(CallBase &CB) {
return Valid;
}
static void AddReturnAttributes(CallBase &CB, ValueToValueMapTy &VMap) {
static void AddReturnAttributes(CallBase &CB, ValueToValueMapTy &VMap,
ClonedCodeInfo &InlinedFunctionInfo) {
AttrBuilder ValidUB = IdentifyValidUBGeneratingAttributes(CB);
AttrBuilder ValidPG = IdentifyValidPoisonGeneratingAttributes(CB);
if (!ValidUB.hasAttributes() && !ValidPG.hasAttributes())
@ -1474,6 +1481,11 @@ static void AddReturnAttributes(CallBase &CB, ValueToValueMapTy &VMap) {
auto *NewRetVal = dyn_cast_or_null<CallBase>(VMap.lookup(RetVal));
if (!NewRetVal)
continue;
// The RetVal might have be simplified during the inlining
// process which can make propagation incorrect.
if (InlinedFunctionInfo.isSimplified(RetVal, NewRetVal))
continue;
// Backward propagation of attributes to the returned value may be incorrect
// if it is control flow dependent.
// Consider:
@ -2456,11 +2468,11 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
// Clone return attributes on the callsite into the calls within the inlined
// function which feed into its return value.
AddReturnAttributes(CB, VMap);
AddReturnAttributes(CB, VMap, InlinedFunctionInfo);
// Clone attributes on the params of the callsite to calls within the
// inlined function which use the same param.
AddParamAndFnBasicAttributes(CB, VMap);
AddParamAndFnBasicAttributes(CB, VMap, InlinedFunctionInfo);
propagateMemProfMetadata(CalledFunc, CB,
InlinedFunctionInfo.ContainsMemProfMetadata, VMap);

View File

@ -859,7 +859,7 @@ static void cloneLoopBlocks(
if (LatchInst && L->contains(LatchInst))
LatchVal = VMap[LatchVal];
PHI.addIncoming(LatchVal, cast<BasicBlock>(VMap[Edge.first]));
SE.forgetValue(&PHI);
SE.forgetLcssaPhiWithNewPredecessor(L, &PHI);
}
// LastValueMap is updated with the values for the current loop