aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-31 21:43:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-12-22 09:58:09 +0000
commit955767994abe78af298b6a46c248f93fb89c6fe3 (patch)
tree1f73042933f0109b107c93ef91fd709b39dc8dd6
parente55e5e640b052220b1cd9f86f9729662df5b1e02 (diff)
downloadsrc-955767994abe78af298b6a46c248f93fb89c6fe3.tar.gz
src-955767994abe78af298b6a46c248f93fb89c6fe3.zip
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
release/11.x llvmorg-11-init-20933-g3c1fca803bc. (cherry picked from commit 590d96feea75246dee213cb528930df8f6234b87)
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/Options.td4
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/SemaInternal.h5
-rw-r--r--contrib/llvm-project/clang/lib/AST/ExprConstant.cpp3
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp21
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h15
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp3
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp57
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp36
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/RISCV.cpp93
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp6
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp5
-rw-r--r--contrib/llvm-project/clang/lib/Driver/Types.cpp2
-rw-r--r--contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp7
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp25
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp18
-rw-r--r--contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp103
-rw-r--r--contrib/llvm-project/lld/COFF/SymbolTable.cpp60
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp22
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IRBuilder.h28
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/RISCVTargetParser.def13
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/TargetParser.h26
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h6
-rw-r--r--contrib/llvm-project/llvm/lib/Analysis/AssumeBundleQueries.cpp13
-rw-r--r--contrib/llvm-project/llvm/lib/Analysis/ConstantFolding.cpp8
-rw-r--r--contrib/llvm-project/llvm/lib/Analysis/InstructionSimplify.cpp16
-rw-r--r--contrib/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp5
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp161
-rw-r--r--contrib/llvm-project/llvm/lib/IR/ConstantFold.cpp24
-rw-r--r--contrib/llvm-project/llvm/lib/IR/IRBuilder.cpp77
-rw-r--r--contrib/llvm-project/llvm/lib/IR/Verifier.cpp23
-rw-r--r--contrib/llvm-project/llvm/lib/MC/MCParser/MasmParser.cpp3
-rw-r--r--contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp26
-rw-r--r--contrib/llvm-project/llvm/lib/Support/TargetParser.cpp64
-rw-r--r--contrib/llvm-project/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp7
-rw-r--r--contrib/llvm-project/llvm/lib/Target/PowerPC/PPCISelLowering.cpp36
-rw-r--r--contrib/llvm-project/llvm/lib/Target/PowerPC/PPCInstr64Bit.td9
-rw-r--r--contrib/llvm-project/llvm/lib/Target/PowerPC/PPCInstrInfo.td9
-rw-r--r--contrib/llvm-project/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp37
-rw-r--r--contrib/llvm-project/llvm/lib/Target/RISCV/RISCV.td10
-rw-r--r--contrib/llvm-project/llvm/lib/Target/X86/AsmParser/X86Operand.h18
-rw-r--r--contrib/llvm-project/llvm/lib/Target/X86/X86ISelLowering.cpp72
-rw-r--r--contrib/llvm-project/llvm/lib/Target/X86/X86InstrInfo.td9
-rw-r--r--contrib/llvm-project/llvm/lib/Target/X86/X86InstrSystem.td16
-rw-r--r--contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp3
-rw-r--r--contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp15
-rw-r--r--contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineInternal.h2
-rw-r--r--contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp4
-rw-r--r--contrib/llvm-project/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp121
-rw-r--r--contrib/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.cpp3
49 files changed, 757 insertions, 592 deletions
diff --git a/contrib/llvm-project/clang/include/clang/Driver/Options.td b/contrib/llvm-project/clang/include/clang/Driver/Options.td
index f4556c15d744..b20b8a288221 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/Options.td
+++ b/contrib/llvm-project/clang/include/clang/Driver/Options.td
@@ -1440,6 +1440,10 @@ def fpch_instantiate_templates:
def fno_pch_instantiate_templates:
Flag <["-"], "fno-pch-instantiate-templates">,
Group<f_Group>, Flags<[CC1Option]>;
+defm pch_codegen: OptInFFlag<"pch-codegen", "Generate ", "Do not generate ",
+ "code for uses of this PCH that assumes an explicit object file will be built for the PCH">;
+defm pch_debuginfo: OptInFFlag<"pch-debuginfo", "Generate ", "Do not generate ",
+ "debug info for types in an object file built from this PCH and do not generate them elsewhere">;
def fmodules : Flag <["-"], "fmodules">, Group<f_Group>,
Flags<[DriverOption, CC1Option]>,
diff --git a/contrib/llvm-project/clang/include/clang/Sema/SemaInternal.h b/contrib/llvm-project/clang/include/clang/Sema/SemaInternal.h
index cdaf7b70a92f..842eec099540 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/SemaInternal.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/SemaInternal.h
@@ -168,6 +168,11 @@ public:
return TC;
}
+ /// In the case of deeply invalid expressions, `getNextCorrection()` will
+ /// never be called since the transform never makes progress. If we don't
+ /// detect this we risk trying to correct typos forever.
+ bool hasMadeAnyCorrectionProgress() const { return CurrentTCIndex != 0; }
+
/// Reset the consumer's position in the stream of viable corrections
/// (i.e. getNextCorrection() will return each of the previously returned
/// corrections in order before returning any new corrections).
diff --git a/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp b/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp
index d20c2382b6ac..41a4ae4b91c8 100644
--- a/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp
+++ b/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp
@@ -9930,8 +9930,7 @@ namespace {
const ConstantArrayType *CAT =
Info.Ctx.getAsConstantArrayType(E->getType());
if (!CAT) {
- if (const IncompleteArrayType *IAT =
- Info.Ctx.getAsIncompleteArrayType(E->getType())) {
+ if (E->getType()->isIncompleteArrayType()) {
// We can be asked to zero-initialize a flexible array member; this
// is represented as an ImplicitValueInitExpr of incomplete array
// type. In this case, the array has zero elements.
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp
index 4a13913a1556..6154c0f99002 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp
@@ -13,6 +13,7 @@
#include "RISCV.h"
#include "clang/Basic/MacroBuilder.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/TargetParser.h"
using namespace clang;
using namespace clang::targets;
@@ -172,3 +173,23 @@ bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
return true;
}
+
+bool RISCV32TargetInfo::isValidCPUName(StringRef Name) const {
+ return llvm::RISCV::checkCPUKind(llvm::RISCV::parseCPUKind(Name),
+ /*Is64Bit=*/false);
+}
+
+void RISCV32TargetInfo::fillValidCPUList(
+ SmallVectorImpl<StringRef> &Values) const {
+ llvm::RISCV::fillValidCPUArchList(Values, false);
+}
+
+bool RISCV64TargetInfo::isValidCPUName(StringRef Name) const {
+ return llvm::RISCV::checkCPUKind(llvm::RISCV::parseCPUKind(Name),
+ /*Is64Bit=*/true);
+}
+
+void RISCV64TargetInfo::fillValidCPUList(
+ SmallVectorImpl<StringRef> &Values) const {
+ llvm::RISCV::fillValidCPUArchList(Values, true);
+}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h
index 73652b409e9c..6db526da4c59 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h
@@ -24,7 +24,7 @@ namespace targets {
// RISC-V Target
class RISCVTargetInfo : public TargetInfo {
protected:
- std::string ABI;
+ std::string ABI, CPU;
bool HasM;
bool HasA;
bool HasF;
@@ -44,6 +44,13 @@ public:
WIntType = UnsignedInt;
}
+ bool setCPU(const std::string &Name) override {
+ if (!isValidCPUName(Name))
+ return false;
+ CPU = Name;
+ return true;
+ }
+
StringRef getABI() const override { return ABI; }
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
@@ -97,6 +104,9 @@ public:
return false;
}
+ bool isValidCPUName(StringRef Name) const override;
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
+
void setMaxAtomicWidth() override {
MaxAtomicPromoteWidth = 128;
@@ -121,6 +131,9 @@ public:
return false;
}
+ bool isValidCPUName(StringRef Name) const override;
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
+
void setMaxAtomicWidth() override {
MaxAtomicPromoteWidth = 128;
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 43cbe9c720ea..a7e1fe8560b6 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -886,8 +886,11 @@ void ReductionCodeGen::emitInitialization(
SharedType, SharedAddresses[N].first.getBaseInfo(),
CGF.CGM.getTBAAInfoForSubobject(SharedAddresses[N].first, SharedType));
if (CGF.getContext().getAsArrayType(PrivateVD->getType())) {
+ if (DRD && DRD->getInitializer())
+ (void)DefaultInit(CGF);
emitAggregateInitialization(CGF, N, PrivateAddr, SharedLVal, DRD);
} else if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {
+ (void)DefaultInit(CGF);
emitInitWithReductionInitializer(CGF, DRD, ClausesData[N].ReductionOp,
PrivateAddr, SharedLVal.getAddress(CGF),
SharedLVal.getType());
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
index cbd443134e7a..ac6ec742335c 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
@@ -4770,6 +4770,7 @@ Address CGOpenMPRuntimeNVPTX::getAddressOfLocalVariable(CodeGenFunction &CGF,
const VarDecl *VD) {
if (VD && VD->hasAttr<OMPAllocateDeclAttr>()) {
const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
+ auto AS = LangAS::Default;
switch (A->getAllocatorType()) {
// Use the default allocator here as by default local vars are
// threadlocal.
@@ -4783,42 +4784,30 @@ Address CGOpenMPRuntimeNVPTX::getAddressOfLocalVariable(CodeGenFunction &CGF,
case OMPAllocateDeclAttr::OMPUserDefinedMemAlloc:
// TODO: implement aupport for user-defined allocators.
return Address::invalid();
- case OMPAllocateDeclAttr::OMPConstMemAlloc: {
- llvm::Type *VarTy = CGF.ConvertTypeForMem(VD->getType());
- auto *GV = new llvm::GlobalVariable(
- CGM.getModule(), VarTy, /*isConstant=*/false,
- llvm::GlobalValue::InternalLinkage,
- llvm::Constant::getNullValue(VarTy), VD->getName(),
- /*InsertBefore=*/nullptr, llvm::GlobalValue::NotThreadLocal,
- CGM.getContext().getTargetAddressSpace(LangAS::cuda_constant));
- CharUnits Align = CGM.getContext().getDeclAlign(VD);
- GV->setAlignment(Align.getAsAlign());
- return Address(GV, Align);
- }
- case OMPAllocateDeclAttr::OMPPTeamMemAlloc: {
- llvm::Type *VarTy = CGF.ConvertTypeForMem(VD->getType());
- auto *GV = new llvm::GlobalVariable(
- CGM.getModule(), VarTy, /*isConstant=*/false,
- llvm::GlobalValue::InternalLinkage,
- llvm::Constant::getNullValue(VarTy), VD->getName(),
- /*InsertBefore=*/nullptr, llvm::GlobalValue::NotThreadLocal,
- CGM.getContext().getTargetAddressSpace(LangAS::cuda_shared));
- CharUnits Align = CGM.getContext().getDeclAlign(VD);
- GV->setAlignment(Align.getAsAlign());
- return Address(GV, Align);
- }
+ case OMPAllocateDeclAttr::OMPConstMemAlloc:
+ AS = LangAS::cuda_constant;
+ break;
+ case OMPAllocateDeclAttr::OMPPTeamMemAlloc:
+ AS = LangAS::cuda_shared;
+ break;
case OMPAllocateDeclAttr::OMPLargeCapMemAlloc:
- case OMPAllocateDeclAttr::OMPCGroupMemAlloc: {
- llvm::Type *VarTy = CGF.ConvertTypeForMem(VD->getType());
- auto *GV = new llvm::GlobalVariable(
- CGM.getModule(), VarTy, /*isConstant=*/false,
- llvm::GlobalValue::InternalLinkage,
- llvm::Constant::getNullValue(VarTy), VD->getName());
- CharUnits Align = CGM.getContext().getDeclAlign(VD);
- GV->setAlignment(Align.getAsAlign());
- return Address(GV, Align);
- }
+ case OMPAllocateDeclAttr::OMPCGroupMemAlloc:
+ break;
}
+ llvm::Type *VarTy = CGF.ConvertTypeForMem(VD->getType());
+ auto *GV = new llvm::GlobalVariable(
+ CGM.getModule(), VarTy, /*isConstant=*/false,
+ llvm::GlobalValue::InternalLinkage, llvm::Constant::getNullValue(VarTy),
+ VD->getName(),
+ /*InsertBefore=*/nullptr, llvm::GlobalValue::NotThreadLocal,
+ CGM.getContext().getTargetAddressSpace(AS));
+ CharUnits Align = CGM.getContext().getDeclAlign(VD);
+ GV->setAlignment(Align.getAsAlign());
+ return Address(
+ CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
+ GV, VarTy->getPointerTo(CGM.getContext().getTargetAddressSpace(
+ VD->getType().getAddressSpace()))),
+ Align);
}
if (getDataSharingMode(CGM) != CGOpenMPRuntimeNVPTX::Generic)
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp
index 4a7c84562dee..8ce488f35dd3 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -2154,39 +2154,13 @@ void CodeGenFunction::emitAlignmentAssumption(llvm::Value *PtrValue,
SourceLocation AssumptionLoc,
llvm::Value *Alignment,
llvm::Value *OffsetValue) {
- if (Alignment->getType() != IntPtrTy)
- Alignment =
- Builder.CreateIntCast(Alignment, IntPtrTy, false, "casted.align");
- if (OffsetValue && OffsetValue->getType() != IntPtrTy)
- OffsetValue =
- Builder.CreateIntCast(OffsetValue, IntPtrTy, true, "casted.offset");
- llvm::Value *TheCheck = nullptr;
+ llvm::Value *TheCheck;
+ llvm::Instruction *Assumption = Builder.CreateAlignmentAssumption(
+ CGM.getDataLayout(), PtrValue, Alignment, OffsetValue, &TheCheck);
if (SanOpts.has(SanitizerKind::Alignment)) {
- llvm::Value *PtrIntValue =
- Builder.CreatePtrToInt(PtrValue, IntPtrTy, "ptrint");
-
- if (OffsetValue) {
- bool IsOffsetZero = false;
- if (const auto *CI = dyn_cast<llvm::ConstantInt>(OffsetValue))
- IsOffsetZero = CI->isZero();
-
- if (!IsOffsetZero)
- PtrIntValue = Builder.CreateSub(PtrIntValue, OffsetValue, "offsetptr");
- }
-
- llvm::Value *Zero = llvm::ConstantInt::get(IntPtrTy, 0);
- llvm::Value *Mask =
- Builder.CreateSub(Alignment, llvm::ConstantInt::get(IntPtrTy, 1));
- llvm::Value *MaskedPtr = Builder.CreateAnd(PtrIntValue, Mask, "maskedptr");
- TheCheck = Builder.CreateICmpEQ(MaskedPtr, Zero, "maskcond");
+ emitAlignmentAssumptionCheck(PtrValue, Ty, Loc, AssumptionLoc, Alignment,
+ OffsetValue, TheCheck, Assumption);
}
- llvm::Instruction *Assumption = Builder.CreateAlignmentAssumption(
- CGM.getDataLayout(), PtrValue, Alignment, OffsetValue);
-
- if (!SanOpts.has(SanitizerKind::Alignment))
- return;
- emitAlignmentAssumptionCheck(PtrValue, Ty, Loc, AssumptionLoc, Alignment,
- OffsetValue, TheCheck, Assumption);
}
void CodeGenFunction::emitAlignmentAssumption(llvm::Value *PtrValue,
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index 80d12e5aa8da..be3f0a07b576 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -446,6 +446,19 @@ static bool getArchFeatures(const Driver &D, StringRef MArch,
return true;
}
+// Get features except standard extension feature
+void getRISCFeaturesFromMcpu(const Driver &D, const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args,
+ const llvm::opt::Arg *A, StringRef Mcpu,
+ std::vector<StringRef> &Features) {
+ bool Is64Bit = (Triple.getArch() == llvm::Triple::riscv64);
+ llvm::RISCV::CPUKind CPUKind = llvm::RISCV::parseCPUKind(Mcpu);
+ if (!llvm::RISCV::checkCPUKind(CPUKind, Is64Bit) ||
+ !llvm::RISCV::getCPUFeaturesExceptStdExt(CPUKind, Features)) {
+ D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
+ }
+}
+
void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args,
std::vector<StringRef> &Features) {
@@ -454,6 +467,11 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
if (!getArchFeatures(D, MArch, Features, Args))
return;
+ // If users give march and mcpu, get std extension feature from MArch
+ // and other features (ex. mirco architecture feature) from mcpu
+ if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
+ getRISCFeaturesFromMcpu(D, Triple, Args, A, A->getValue(), Features);
+
// Handle features corresponding to "-ffixed-X" options
if (Args.hasArg(options::OPT_ffixed_x1))
Features.push_back("+reserve-x1");
@@ -543,11 +561,9 @@ StringRef riscv::getRISCVABI(const ArgList &Args, const llvm::Triple &Triple) {
// GCC's logic around choosing a default `-mabi=` is complex. If GCC is not
// configured using `--with-abi=`, then the logic for the default choice is
- // defined in config.gcc. This function is based on the logic in GCC 9.2.0. We
- // deviate from GCC's default only on baremetal targets (UnknownOS) where
- // neither `-march` nor `-mabi` is specified.
+ // defined in config.gcc. This function is based on the logic in GCC 9.2.0.
//
- // The logic uses the following, in order:
+ // The logic used in GCC 9.2.0 is the following, in order:
// 1. Explicit choices using `--with-abi=`
// 2. A default based on `--with-arch=`, if provided
// 3. A default based on the target triple's arch
@@ -556,38 +572,40 @@ StringRef riscv::getRISCVABI(const ArgList &Args, const llvm::Triple &Triple) {
//
// Clang does not have `--with-arch=` or `--with-abi=`, so we use `-march=`
// and `-mabi=` respectively instead.
+ //
+ // In order to make chosing logic more clear, Clang uses the following logic,
+ // in order:
+ // 1. Explicit choices using `-mabi=`
+ // 2. A default based on the architecture as determined by getRISCVArch
+ // 3. Choose a default based on the triple
// 1. If `-mabi=` is specified, use it.
if (const Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
return A->getValue();
- // 2. Choose a default based on `-march=`
+ // 2. Choose a default based on the target architecture.
//
// rv32g | rv32*d -> ilp32d
// rv32e -> ilp32e
// rv32* -> ilp32
// rv64g | rv64*d -> lp64d
// rv64* -> lp64
- if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
- StringRef MArch = A->getValue();
-
- if (MArch.startswith_lower("rv32")) {
- // FIXME: parse `March` to find `D` extension properly
- if (MArch.substr(4).contains_lower("d") ||
- MArch.startswith_lower("rv32g"))
- return "ilp32d";
- else if (MArch.startswith_lower("rv32e"))
- return "ilp32e";
- else
- return "ilp32";
- } else if (MArch.startswith_lower("rv64")) {
- // FIXME: parse `March` to find `D` extension properly
- if (MArch.substr(4).contains_lower("d") ||
- MArch.startswith_lower("rv64g"))
- return "lp64d";
- else
- return "lp64";
- }
+ StringRef MArch = getRISCVArch(Args, Triple);
+
+ if (MArch.startswith_lower("rv32")) {
+ // FIXME: parse `March` to find `D` extension properly
+ if (MArch.substr(4).contains_lower("d") || MArch.startswith_lower("rv32g"))
+ return "ilp32d";
+ else if (MArch.startswith_lower("rv32e"))
+ return "ilp32e";
+ else
+ return "ilp32";
+ } else if (MArch.startswith_lower("rv64")) {
+ // FIXME: parse `March` to find `D` extension properly
+ if (MArch.substr(4).contains_lower("d") || MArch.startswith_lower("rv64g"))
+ return "lp64d";
+ else
+ return "lp64";
}
// 3. Choose a default based on the triple
@@ -617,10 +635,11 @@ StringRef riscv::getRISCVArch(const llvm::opt::ArgList &Args,
// GCC's logic around choosing a default `-march=` is complex. If GCC is not
// configured using `--with-arch=`, then the logic for the default choice is
// defined in config.gcc. This function is based on the logic in GCC 9.2.0. We
- // deviate from GCC's default only on baremetal targets (UnknownOS) where
- // neither `-march` nor `-mabi` is specified.
+ // deviate from GCC's default on additional `-mcpu` option (GCC does not
+ // support `-mcpu`) and baremetal targets (UnknownOS) where neither `-march`
+ // nor `-mabi` is specified.
//
- // The logic uses the following, in order:
+ // The logic used in GCC 9.2.0 is the following, in order:
// 1. Explicit choices using `--with-arch=`
// 2. A default based on `--with-abi=`, if provided
// 3. A default based on the target triple's arch
@@ -630,6 +649,12 @@ StringRef riscv::getRISCVArch(const llvm::opt::ArgList &Args,
// Clang does not have `--with-arch=` or `--with-abi=`, so we use `-march=`
// and `-mabi=` respectively instead.
//
+ // Clang uses the following logic, in order:
+ // 1. Explicit choices using `-march=`
+ // 2. Based on `-mcpu` if the target CPU has a default ISA string
+ // 3. A default based on `-mabi`, if provided
+ // 4. A default based on the target triple's arch
+ //
// Clang does not yet support MULTILIB_REUSE, so we use `rv{XLEN}imafdc`
// instead of `rv{XLEN}gc` though they are (currently) equivalent.
@@ -637,7 +662,15 @@ StringRef riscv::getRISCVArch(const llvm::opt::ArgList &Args,
if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
return A->getValue();
- // 2. Choose a default based on `-mabi=`
+ // 2. Get march (isa string) based on `-mcpu=`
+ if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
+ StringRef MArch = llvm::RISCV::getMArchFromMcpu(A->getValue());
+ // Bypass if target cpu's default march is empty.
+ if (MArch != "")
+ return MArch;
+ }
+
+ // 3. Choose a default based on `-mabi=`
//
// ilp32e -> rv32e
// ilp32 | ilp32f | ilp32d -> rv32imafdc
@@ -653,7 +686,7 @@ StringRef riscv::getRISCVArch(const llvm::opt::ArgList &Args,
return "rv64imafdc";
}
- // 3. Choose a default based on the triple
+ // 4. Choose a default based on the triple
//
// We deviate from GCC's defaults here:
// - On `riscv{XLEN}-unknown-elf` we default to `rv{XLEN}imac`
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp
index 9d6333bb5f1d..25fc837e803b 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5627,6 +5627,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasFlag(options::OPT_fpch_instantiate_templates,
options::OPT_fno_pch_instantiate_templates, false))
CmdArgs.push_back("-fpch-instantiate-templates");
+ if (Args.hasFlag(options::OPT_fpch_codegen, options::OPT_fno_pch_codegen,
+ false))
+ CmdArgs.push_back("-fmodules-codegen");
+ if (Args.hasFlag(options::OPT_fpch_debuginfo, options::OPT_fno_pch_debuginfo,
+ false))
+ CmdArgs.push_back("-fmodules-debuginfo");
Args.AddLastArg(CmdArgs, options::OPT_fexperimental_new_pass_manager,
options::OPT_fno_experimental_new_pass_manager);
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 1cac5a0822a4..6b6e276b8ce7 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -333,6 +333,11 @@ std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T,
return TargetCPUName;
}
+ case llvm::Triple::riscv32:
+ case llvm::Triple::riscv64:
+ if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
+ return A->getValue();
+ return "";
case llvm::Triple::bpfel:
case llvm::Triple::bpfeb:
diff --git a/contrib/llvm-project/clang/lib/Driver/Types.cpp b/contrib/llvm-project/clang/lib/Driver/Types.cpp
index 399e26d8d64a..2050dffa6fa0 100644
--- a/contrib/llvm-project/clang/lib/Driver/Types.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/Types.cpp
@@ -141,7 +141,7 @@ bool types::isAcceptedByClang(ID Id) {
case TY_CXXHeader: case TY_PP_CXXHeader:
case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
case TY_CXXModule: case TY_PP_CXXModule:
- case TY_AST: case TY_ModuleFile:
+ case TY_AST: case TY_ModuleFile: case TY_PCH:
case TY_LLVM_IR: case TY_LLVM_BC:
return true;
}
diff --git a/contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp b/contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp
index 75d7cf5d26d3..73114c6d76cb 100644
--- a/contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2022,8 +2022,9 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
// FIXME: Supporting '<lang>-header-cpp-output' would be useful.
bool Preprocessed = XValue.consume_back("-cpp-output");
bool ModuleMap = XValue.consume_back("-module-map");
- IsHeaderFile =
- !Preprocessed && !ModuleMap && XValue.consume_back("-header");
+ IsHeaderFile = !Preprocessed && !ModuleMap &&
+ XValue != "precompiled-header" &&
+ XValue.consume_back("-header");
// Principal languages.
DashX = llvm::StringSwitch<InputKind>(XValue)
@@ -2050,7 +2051,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
DashX = llvm::StringSwitch<InputKind>(XValue)
.Case("cpp-output", InputKind(Language::C).getPreprocessed())
.Case("assembler-with-cpp", Language::Asm)
- .Cases("ast", "pcm",
+ .Cases("ast", "pcm", "precompiled-header",
InputKind(Language::Unknown, InputKind::Precompiled))
.Case("ir", Language::LLVM_IR)
.Default(Language::Unknown);
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp b/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp
index d885920b6c14..77bd1ab360b2 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp
@@ -7977,19 +7977,26 @@ class TransformTypos : public TreeTransform<TransformTypos> {
}
}
- /// If corrections for the first TypoExpr have been exhausted for a
- /// given combination of the other TypoExprs, retry those corrections against
- /// the next combination of substitutions for the other TypoExprs by advancing
- /// to the next potential correction of the second TypoExpr. For the second
- /// and subsequent TypoExprs, if its stream of corrections has been exhausted,
- /// the stream is reset and the next TypoExpr's stream is advanced by one (a
- /// TypoExpr's correction stream is advanced by removing the TypoExpr from the
- /// TransformCache). Returns true if there is still any untried combinations
- /// of corrections.
+ /// Try to advance the typo correction state of the first unfinished TypoExpr.
+ /// We allow advancement of the correction stream by removing it from the
+ /// TransformCache which allows `TransformTypoExpr` to advance during the
+ /// next transformation attempt.
+ ///
+ /// Any substitution attempts for the previous TypoExprs (which must have been
+ /// finished) will need to be retried since it's possible that they will now
+ /// be invalid given the latest advancement.
+ ///
+ /// We need to be sure that we're making progress - it's possible that the
+ /// tree is so malformed that the transform never makes it to the
+ /// `TransformTypoExpr`.
+ ///
+ /// Returns true if there are any untried correction combinations.
bool CheckAndAdvanceTypoExprCorrectionStreams() {
for (auto TE : TypoExprs) {
auto &State = SemaRef.getTypoExprState(TE);
TransformCache.erase(TE);
+ if (!State.Consumer->hasMadeAnyCorrectionProgress())
+ return false;
if (!State.Consumer->finished())
return true;
State.Consumer->resetCorrectionStream();
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp b/contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp
index 920463da4027..8bf605e5e76b 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp
@@ -15153,6 +15153,7 @@ static bool actOnOMPReductionKindClause(
auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
if (DRD->getInitializer()) {
+ S.ActOnUninitializedDecl(PrivateVD);
Init = DRDRef;
RHSVD->setInit(DRDRef);
RHSVD->setInitStyle(VarDecl::CallInit);
@@ -15259,10 +15260,19 @@ static bool actOnOMPReductionKindClause(
llvm_unreachable("Unexpected reduction operation");
}
}
- if (Init && DeclareReductionRef.isUnset())
+ if (Init && DeclareReductionRef.isUnset()) {
S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
- else if (!Init)
+ // Store initializer for single element in private copy. Will be used
+ // during codegen.
+ PrivateVD->setInit(RHSVD->getInit());
+ PrivateVD->setInitStyle(RHSVD->getInitStyle());
+ } else if (!Init) {
S.ActOnUninitializedDecl(RHSVD);
+ // Store initializer for single element in private copy. Will be used
+ // during codegen.
+ PrivateVD->setInit(RHSVD->getInit());
+ PrivateVD->setInitStyle(RHSVD->getInitStyle());
+ }
if (RHSVD->isInvalidDecl())
continue;
if (!RHSVD->hasInit() &&
@@ -15276,10 +15286,6 @@ static bool actOnOMPReductionKindClause(
<< D;
continue;
}
- // Store initializer for single element in private copy. Will be used during
- // codegen.
- PrivateVD->setInit(RHSVD->getInit());
- PrivateVD->setInitStyle(RHSVD->getInitStyle());
DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
ExprResult ReductionOp;
if (DeclareReductionRef.isUsable()) {
diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp
index 949beac1c551..3354546c2a10 100644
--- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp
+++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp
@@ -439,65 +439,61 @@ void RestoreStack(int tid, const u64 epoch, VarSizeStackTrace *stk,
ExtractTagFromStack(stk, tag);
}
-static bool HandleRacyStacks(ThreadState *thr, VarSizeStackTrace traces[2],
- uptr addr_min, uptr addr_max) {
- bool equal_stack = false;
- RacyStacks hash;
- bool equal_address = false;
- RacyAddress ra0 = {addr_min, addr_max};
- {
- ReadLock lock(&ctx->racy_mtx);
- if (flags()->suppress_equal_stacks) {
- hash.hash[0] = md5_hash(traces[0].trace, traces[0].size * sizeof(uptr));
- hash.hash[1] = md5_hash(traces[1].trace, traces[1].size * sizeof(uptr));
- for (uptr i = 0; i < ctx->racy_stacks.Size(); i++) {
- if (hash == ctx->racy_stacks[i]) {
- VPrintf(2,
- "ThreadSanitizer: suppressing report as doubled (stack)\n");
- equal_stack = true;
- break;
- }
- }
- }
- if (flags()->suppress_equal_addresses) {
- for (uptr i = 0; i < ctx->racy_addresses.Size(); i++) {
- RacyAddress ra2 = ctx->racy_addresses[i];
- uptr maxbeg = max(ra0.addr_min, ra2.addr_min);
- uptr minend = min(ra0.addr_max, ra2.addr_max);
- if (maxbeg < minend) {
- VPrintf(2, "ThreadSanitizer: suppressing report as doubled (addr)\n");
- equal_address = true;
- break;
- }
- }
+static bool FindRacyStacks(const RacyStacks &hash) {
+ for (uptr i = 0; i < ctx->racy_stacks.Size(); i++) {
+ if (hash == ctx->racy_stacks[i]) {
+ VPrintf(2, "ThreadSanitizer: suppressing report as doubled (stack)\n");
+ return true;
}
}
- if (!equal_stack && !equal_address)
+ return false;
+}
+
+static bool HandleRacyStacks(ThreadState *thr, VarSizeStackTrace traces[2]) {
+ if (!flags()->suppress_equal_stacks)
return false;
- if (!equal_stack) {
- Lock lock(&ctx->racy_mtx);
- ctx->racy_stacks.PushBack(hash);
- }
- if (!equal_address) {
- Lock lock(&ctx->racy_mtx);
- ctx->racy_addresses.PushBack(ra0);
+ RacyStacks hash;
+ hash.hash[0] = md5_hash(traces[0].trace, traces[0].size * sizeof(uptr));
+ hash.hash[1] = md5_hash(traces[1].trace, traces[1].size * sizeof(uptr));
+ {
+ ReadLock lock(&ctx->racy_mtx);
+ if (FindRacyStacks(hash))
+ return true;
}
- return true;
+ Lock lock(&ctx->racy_mtx);
+ if (FindRacyStacks(hash))
+ return true;
+ ctx->racy_stacks.PushBack(hash);
+ return false;
}
-static void AddRacyStacks(ThreadState *thr, VarSizeStackTrace traces[2],
- uptr addr_min, uptr addr_max) {
- Lock lock(&ctx->racy_mtx);
- if (flags()->suppress_equal_stacks) {
- RacyStacks hash;
- hash.hash[0] = md5_hash(traces[0].trace, traces[0].size * sizeof(uptr));
- hash.hash[1] = md5_hash(traces[1].trace, traces[1].size * sizeof(uptr));
- ctx->racy_stacks.PushBack(hash);
+static bool FindRacyAddress(const RacyAddress &ra0) {
+ for (uptr i = 0; i < ctx->racy_addresses.Size(); i++) {
+ RacyAddress ra2 = ctx->racy_addresses[i];
+ uptr maxbeg = max(ra0.addr_min, ra2.addr_min);
+ uptr minend = min(ra0.addr_max, ra2.addr_max);
+ if (maxbeg < minend) {
+ VPrintf(2, "ThreadSanitizer: suppressing report as doubled (addr)\n");
+ return true;
+ }
}
- if (flags()->suppress_equal_addresses) {
- RacyAddress ra0 = {addr_min, addr_max};
- ctx->racy_addresses.PushBack(ra0);
+ return false;
+}
+
+static bool HandleRacyAddress(ThreadState *thr, uptr addr_min, uptr addr_max) {
+ if (!flags()->suppress_equal_addresses)
+ return false;
+ RacyAddress ra0 = {addr_min, addr_max};
+ {
+ ReadLock lock(&ctx->racy_mtx);
+ if (FindRacyAddress(ra0))
+ return true;
}
+ Lock lock(&ctx->racy_mtx);
+ if (FindRacyAddress(ra0))
+ return true;
+ ctx->racy_addresses.PushBack(ra0);
+ return false;
}
bool OutputReport(ThreadState *thr, const ScopedReport &srep) {
@@ -618,6 +614,8 @@ void ReportRace(ThreadState *thr) {
if (IsExpectedReport(addr_min, addr_max - addr_min))
return;
}
+ if (HandleRacyAddress(thr, addr_min, addr_max))
+ return;
ReportType typ = ReportTypeRace;
if (thr->is_vptr_access && freed)
@@ -668,7 +666,7 @@ void ReportRace(ThreadState *thr) {
if (IsFiredSuppression(ctx, typ, traces[1]))
return;
- if (HandleRacyStacks(thr, traces, addr_min, addr_max))
+ if (HandleRacyStacks(thr, traces))
return;
// If any of the accesses has a tag, treat this as an "external" race.
@@ -711,7 +709,6 @@ void ReportRace(ThreadState *thr) {
if (!OutputReport(thr, rep))
return;
- AddRacyStacks(thr, traces, addr_min, addr_max);
}
void PrintCurrentStack(ThreadState *thr, uptr pc) {
diff --git a/contrib/llvm-project/lld/COFF/SymbolTable.cpp b/contrib/llvm-project/lld/COFF/SymbolTable.cpp
index d4d2a159a639..173e32f628ef 100644
--- a/contrib/llvm-project/lld/COFF/SymbolTable.cpp
+++ b/contrib/llvm-project/lld/COFF/SymbolTable.cpp
@@ -136,12 +136,16 @@ getFileLine(const SectionChunk *c, uint32_t addr) {
// of all references to that symbol from that file. If no debug information is
// available, returns just the name of the file, else one string per actual
// reference as described in the debug info.
-std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex) {
+// Returns up to maxStrings string descriptions, along with the total number of
+// locations found.
+static std::pair<std::vector<std::string>, size_t>
+getSymbolLocations(ObjFile *file, uint32_t symIndex, size_t maxStrings) {
struct Location {
Symbol *sym;
std::pair<StringRef, uint32_t> fileLine;
};
std::vector<Location> locations;
+ size_t numLocations = 0;
for (Chunk *c : file->getChunks()) {
auto *sc = dyn_cast<SectionChunk>(c);
@@ -150,6 +154,10 @@ std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex) {
for (const coff_relocation &r : sc->getRelocs()) {
if (r.SymbolTableIndex != symIndex)
continue;
+ numLocations++;
+ if (locations.size() >= maxStrings)
+ continue;
+
Optional<std::pair<StringRef, uint32_t>> fileLine =
getFileLine(sc, r.VirtualAddress);
Symbol *sym = getSymbol(sc, r.VirtualAddress);
@@ -160,8 +168,12 @@ std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex) {
}
}
- if (locations.empty())
- return std::vector<std::string>({"\n>>> referenced by " + toString(file)});
+ if (maxStrings == 0)
+ return std::make_pair(std::vector<std::string>(), numLocations);
+
+ if (numLocations == 0)
+ return std::make_pair(
+ std::vector<std::string>{"\n>>> referenced by " + toString(file)}, 1);
std::vector<std::string> symbolLocations(locations.size());
size_t i = 0;
@@ -175,17 +187,26 @@ std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex) {
if (loc.sym)
os << ":(" << toString(*loc.sym) << ')';
}
- return symbolLocations;
+ return std::make_pair(symbolLocations, numLocations);
+}
+
+std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex) {
+ return getSymbolLocations(file, symIndex, SIZE_MAX).first;
}
-std::vector<std::string> getSymbolLocations(InputFile *file,
- uint32_t symIndex) {
+static std::pair<std::vector<std::string>, size_t>
+getSymbolLocations(InputFile *file, uint32_t symIndex, size_t maxStrings) {
if (auto *o = dyn_cast<ObjFile>(file))
- return getSymbolLocations(o, symIndex);
- if (auto *b = dyn_cast<BitcodeFile>(file))
- return getSymbolLocations(b);
+ return getSymbolLocations(o, symIndex, maxStrings);
+ if (auto *b = dyn_cast<BitcodeFile>(file)) {
+ std::vector<std::string> symbolLocations = getSymbolLocations(b);
+ size_t numLocations = symbolLocations.size();
+ if (symbolLocations.size() > maxStrings)
+ symbolLocations.resize(maxStrings);
+ return std::make_pair(symbolLocations, numLocations);
+ }
llvm_unreachable("unsupported file type passed to getSymbolLocations");
- return {};
+ return std::make_pair(std::vector<std::string>(), (size_t)0);
}
// For an undefined symbol, stores all files referencing it and the index of
@@ -205,20 +226,21 @@ static void reportUndefinedSymbol(const UndefinedDiag &undefDiag) {
os << "undefined symbol: " << toString(*undefDiag.sym);
const size_t maxUndefReferences = 3;
- size_t i = 0, numRefs = 0;
+ size_t numDisplayedRefs = 0, numRefs = 0;
for (const UndefinedDiag::File &ref : undefDiag.files) {
- std::vector<std::string> symbolLocations =
- getSymbolLocations(ref.file, ref.symIndex);
- numRefs += symbolLocations.size();
+ std::vector<std::string> symbolLocations;
+ size_t totalLocations = 0;
+ std::tie(symbolLocations, totalLocations) = getSymbolLocations(
+ ref.file, ref.symIndex, maxUndefReferences - numDisplayedRefs);
+
+ numRefs += totalLocations;
+ numDisplayedRefs += symbolLocations.size();
for (const std::string &s : symbolLocations) {
- if (i >= maxUndefReferences)
- break;
os << s;
- i++;
}
}
- if (i < numRefs)
- os << "\n>>> referenced " << numRefs - i << " more times";
+ if (numDisplayedRefs < numRefs)
+ os << "\n>>> referenced " << numRefs - numDisplayedRefs << " more times";
errorOrWarn(os.str());
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 9f64e5255fd5..0b7e31ae2d1d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1036,18 +1036,20 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) {
// FIXME: Rather than parsing the whole line table and then copying it over
// into LLDB, we should explore using a callback to populate the line table
// while we parse to reduce memory usage.
- std::unique_ptr<LineSequence> sequence =
- LineTable::CreateLineSequenceContainer();
std::vector<std::unique_ptr<LineSequence>> sequences;
- for (auto &row : line_table->Rows) {
- LineTable::AppendLineEntryToSequence(
- sequence.get(), row.Address.Address, row.Line, row.Column, row.File,
- row.IsStmt, row.BasicBlock, row.PrologueEnd, row.EpilogueBegin,
- row.EndSequence);
- if (row.EndSequence) {
- sequences.push_back(std::move(sequence));
- sequence = LineTable::CreateLineSequenceContainer();
+ // The Sequences view contains only valid line sequences. Don't iterate over
+ // the Rows directly.
+ for (const llvm::DWARFDebugLine::Sequence &seq : line_table->Sequences) {
+ std::unique_ptr<LineSequence> sequence =
+ LineTable::CreateLineSequenceContainer();
+ for (unsigned idx = seq.FirstRowIndex; idx < seq.LastRowIndex; ++idx) {
+ const llvm::DWARFDebugLine::Row &row = line_table->Rows[idx];
+ LineTable::AppendLineEntryToSequence(
+ sequence.get(), row.Address.Address, row.Line, row.Column, row.File,
+ row.IsStmt, row.BasicBlock, row.PrologueEnd, row.EpilogueBegin,
+ row.EndSequence);
}
+ sequences.push_back(std::move(sequence));
}
std::unique_ptr<LineTable> line_table_up =
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IRBuilder.h b/contrib/llvm-project/llvm/include/llvm/IR/IRBuilder.h
index 4552ca016bd7..ffec4ff64ca6 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/IRBuilder.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IRBuilder.h
@@ -782,11 +782,7 @@ public:
/// Create an assume intrinsic call that allows the optimizer to
/// assume that the provided condition will be true.
- ///
- /// The optional argument \p OpBundles specifies operand bundles that are
- /// added to the call instruction.
- CallInst *CreateAssumption(Value *Cond,
- ArrayRef<OperandBundleDef> OpBundles = llvm::None);
+ CallInst *CreateAssumption(Value *Cond);
/// Create a call to the experimental.gc.statepoint intrinsic to
/// start a new statepoint sequence.
@@ -2506,11 +2502,13 @@ public:
private:
/// Helper function that creates an assume intrinsic call that
- /// represents an alignment assumption on the provided pointer \p PtrValue
- /// with offset \p OffsetValue and alignment value \p AlignValue.
+ /// represents an alignment assumption on the provided Ptr, Mask, Type
+ /// and Offset. It may be sometimes useful to do some other logic
+ /// based on this alignment check, thus it can be stored into 'TheCheck'.
CallInst *CreateAlignmentAssumptionHelper(const DataLayout &DL,
- Value *PtrValue, Value *AlignValue,
- Value *OffsetValue);
+ Value *PtrValue, Value *Mask,
+ Type *IntPtrTy, Value *OffsetValue,
+ Value **TheCheck);
public:
/// Create an assume intrinsic call that represents an alignment
@@ -2519,9 +2517,13 @@ public:
/// An optional offset can be provided, and if it is provided, the offset
/// must be subtracted from the provided pointer to get the pointer with the
/// specified alignment.
+ ///
+ /// It may be sometimes useful to do some other logic
+ /// based on this alignment check, thus it can be stored into 'TheCheck'.
CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue,
unsigned Alignment,
- Value *OffsetValue = nullptr);
+ Value *OffsetValue = nullptr,
+ Value **TheCheck = nullptr);
/// Create an assume intrinsic call that represents an alignment
/// assumption on the provided pointer.
@@ -2530,11 +2532,15 @@ public:
/// must be subtracted from the provided pointer to get the pointer with the
/// specified alignment.
///
+ /// It may be sometimes useful to do some other logic
+ /// based on this alignment check, thus it can be stored into 'TheCheck'.
+ ///
/// This overload handles the condition where the Alignment is dependent
/// on an existing value rather than a static value.
CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue,
Value *Alignment,
- Value *OffsetValue = nullptr);
+ Value *OffsetValue = nullptr,
+ Value **TheCheck = nullptr);
};
/// This provides a uniform API for creating instructions and inserting
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/RISCVTargetParser.def b/contrib/llvm-project/llvm/include/llvm/Support/RISCVTargetParser.def
new file mode 100644
index 000000000000..28de6cd40132
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Support/RISCVTargetParser.def
@@ -0,0 +1,13 @@
+#ifndef PROC
+#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH)
+#endif
+
+PROC(INVALID, {"invalid"}, FK_INVALID, {""})
+PROC(GENERIC_RV32, {"generic-rv32"}, FK_NONE, {""})
+PROC(GENERIC_RV64, {"generic-rv64"}, FK_64BIT, {""})
+PROC(ROCKET_RV32, {"rocket-rv32"}, FK_NONE, {""})
+PROC(ROCKET_RV64, {"rocket-rv64"}, FK_64BIT, {""})
+PROC(SIFIVE_E31, {"sifive-e31"}, FK_NONE, {"rv32imac"})
+PROC(SIFIVE_U54, {"sifive-u54"}, FK_64BIT, {"rv64gc"})
+
+#undef PROC
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/TargetParser.h b/contrib/llvm-project/llvm/include/llvm/Support/TargetParser.h
index a0bd88c153b6..f521d8f836b4 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/TargetParser.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/TargetParser.h
@@ -130,6 +130,32 @@ IsaVersion getIsaVersion(StringRef GPU);
} // namespace AMDGPU
+namespace RISCV {
+
+enum CPUKind : unsigned {
+#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) CK_##ENUM,
+#include "RISCVTargetParser.def"
+};
+
+enum FeatureKind : unsigned {
+ FK_INVALID = 0,
+ FK_NONE = 1,
+ FK_STDEXTM = 1 << 2,
+ FK_STDEXTA = 1 << 3,
+ FK_STDEXTF = 1 << 4,
+ FK_STDEXTD = 1 << 5,
+ FK_STDEXTC = 1 << 6,
+ FK_64BIT = 1 << 7,
+};
+
+bool checkCPUKind(CPUKind Kind, bool IsRV64);
+CPUKind parseCPUKind(StringRef CPU);
+StringRef getMArchFromMcpu(StringRef CPU);
+void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64);
+bool getCPUFeaturesExceptStdExt(CPUKind Kind, std::vector<StringRef> &Features);
+
+} // namespace RISCV
+
} // namespace llvm
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h
index 10b6e1c6a21b..be119b8ab855 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h
@@ -37,9 +37,9 @@ struct AlignmentFromAssumptionsPass
ScalarEvolution *SE = nullptr;
DominatorTree *DT = nullptr;
- bool extractAlignmentInfo(CallInst *I, unsigned Idx, Value *&AAPtr,
- const SCEV *&AlignSCEV, const SCEV *&OffSCEV);
- bool processAssumption(CallInst *I, unsigned Idx);
+ bool extractAlignmentInfo(CallInst *I, Value *&AAPtr, const SCEV *&AlignSCEV,
+ const SCEV *&OffSCEV);
+ bool processAssumption(CallInst *I);
};
}
diff --git a/contrib/llvm-project/llvm/lib/Analysis/AssumeBundleQueries.cpp b/contrib/llvm-project/llvm/lib/Analysis/AssumeBundleQueries.cpp
index 05fe05a0bd85..972d0d3ea7f2 100644
--- a/contrib/llvm-project/llvm/lib/Analysis/AssumeBundleQueries.cpp
+++ b/contrib/llvm-project/llvm/lib/Analysis/AssumeBundleQueries.cpp
@@ -108,17 +108,10 @@ llvm::getKnowledgeFromBundle(CallInst &Assume,
Result.AttrKind = Attribute::getAttrKindFromName(BOI.Tag->getKey());
if (bundleHasArgument(BOI, ABA_WasOn))
Result.WasOn = getValueFromBundleOpInfo(Assume, BOI, ABA_WasOn);
- auto GetArgOr1 = [&](unsigned Idx) -> unsigned {
- if (auto *ConstInt = dyn_cast<ConstantInt>(
- getValueFromBundleOpInfo(Assume, BOI, ABA_Argument + Idx)))
- return ConstInt->getZExtValue();
- return 1;
- };
if (BOI.End - BOI.Begin > ABA_Argument)
- Result.ArgValue = GetArgOr1(0);
- if (Result.AttrKind == Attribute::Alignment)
- if (BOI.End - BOI.Begin > ABA_Argument + 1)
- Result.ArgValue = MinAlign(Result.ArgValue, GetArgOr1(1));
+ Result.ArgValue =
+ cast<ConstantInt>(getValueFromBundleOpInfo(Assume, BOI, ABA_Argument))
+ ->getZExtValue();
return Result;
}
diff --git a/contrib/llvm-project/llvm/lib/Analysis/ConstantFolding.cpp b/contrib/llvm-project/llvm/lib/Analysis/ConstantFolding.cpp
index 8c66decaaf58..6feffcbb98e1 100644
--- a/contrib/llvm-project/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/contrib/llvm-project/llvm/lib/Analysis/ConstantFolding.cpp
@@ -342,8 +342,12 @@ Constant *llvm::ConstantFoldLoadThroughBitcast(Constant *C, Type *DestTy,
// pointers legally).
if (C->isNullValue() && !DestTy->isX86_MMXTy())
return Constant::getNullValue(DestTy);
- if (C->isAllOnesValue() && !DestTy->isX86_MMXTy() &&
- !DestTy->isPtrOrPtrVectorTy()) // Don't get ones for ptr types!
+ if (C->isAllOnesValue() &&
+ (DestTy->isIntegerTy() || DestTy->isFloatingPointTy() ||
+ DestTy->isVectorTy()) &&
+ !DestTy->isX86_MMXTy() && !DestTy->isPtrOrPtrVectorTy())
+ // Get ones when the input is trivial, but
+ // only for supported types inside getAllOnesValue.
return Constant::getAllOnesValue(DestTy);
// If the type sizes are the same and a cast is legal, just directly
diff --git a/contrib/llvm-project/llvm/lib/Analysis/InstructionSimplify.cpp b/contrib/llvm-project/llvm/lib/Analysis/InstructionSimplify.cpp
index 0975a65d183e..d3bdf9d6aafd 100644
--- a/contrib/llvm-project/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/contrib/llvm-project/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4118,15 +4118,9 @@ static Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
if (TrueVal == FalseVal)
return TrueVal;
- // If the true or false value is undef, we can fold to the other value as
- // long as the other value isn't poison.
- // select ?, undef, X -> X
- if (isa<UndefValue>(TrueVal) &&
- isGuaranteedNotToBeUndefOrPoison(FalseVal, Q.CxtI, Q.DT))
+ if (isa<UndefValue>(TrueVal)) // select ?, undef, X -> X
return FalseVal;
- // select ?, X, undef -> X
- if (isa<UndefValue>(FalseVal) &&
- isGuaranteedNotToBeUndefOrPoison(TrueVal, Q.CxtI, Q.DT))
+ if (isa<UndefValue>(FalseVal)) // select ?, X, undef -> X
return TrueVal;
// Deal with partial undef vector constants: select ?, VecC, VecC' --> VecC''
@@ -4146,11 +4140,9 @@ static Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
// one element is undef, choose the defined element as the safe result.
if (TEltC == FEltC)
NewC.push_back(TEltC);
- else if (isa<UndefValue>(TEltC) &&
- isGuaranteedNotToBeUndefOrPoison(FEltC))
+ else if (isa<UndefValue>(TEltC))
NewC.push_back(FEltC);
- else if (isa<UndefValue>(FEltC) &&
- isGuaranteedNotToBeUndefOrPoison(TEltC))
+ else if (isa<UndefValue>(FEltC))
NewC.push_back(TEltC);
else
break;
diff --git a/contrib/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp b/contrib/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp
index 48c686b73260..3c96b3f20461 100644
--- a/contrib/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/contrib/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -3317,10 +3317,7 @@ ScalarEvolution::getGEPExpr(GEPOperator *GEP,
}
// Add the total offset from all the GEP indices to the base.
- auto *GEPExpr = getAddExpr(BaseExpr, TotalOffset, Wrap);
- assert(BaseExpr->getType() == GEPExpr->getType() &&
- "GEP should not change type mid-flight.");
- return GEPExpr;
+ return getAddExpr(BaseExpr, TotalOffset, Wrap);
}
std::tuple<SCEV *, FoldingSetNodeID, void *>
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/contrib/llvm-project/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
index de336abe607a..615ff4b8789c 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
@@ -70,7 +70,6 @@ STATISTIC(NumTwoAddressInstrs, "Number of two-address instructions");
STATISTIC(NumCommuted , "Number of instructions commuted to coalesce");
STATISTIC(NumAggrCommuted , "Number of instructions aggressively commuted");
STATISTIC(NumConvertedTo3Addr, "Number of instructions promoted to 3-address");
-STATISTIC(Num3AddrSunk, "Number of 3-address instructions sunk");
STATISTIC(NumReSchedUps, "Number of instructions re-scheduled up");
STATISTIC(NumReSchedDowns, "Number of instructions re-scheduled down");
@@ -109,10 +108,6 @@ class TwoAddressInstructionPass : public MachineFunctionPass {
// Set of already processed instructions in the current block.
SmallPtrSet<MachineInstr*, 8> Processed;
- // Set of instructions converted to three-address by target and then sunk
- // down current basic block.
- SmallPtrSet<MachineInstr*, 8> SunkInstrs;
-
// A map from virtual registers to physical registers which are likely targets
// to be coalesced to due to copies from physical registers to virtual
// registers. e.g. v1024 = move r0.
@@ -123,9 +118,6 @@ class TwoAddressInstructionPass : public MachineFunctionPass {
// registers. e.g. r1 = move v1024.
DenseMap<unsigned, unsigned> DstRegMap;
- bool sink3AddrInstruction(MachineInstr *MI, unsigned Reg,
- MachineBasicBlock::iterator OldPos);
-
bool isRevCopyChain(unsigned FromReg, unsigned ToReg, int Maxlen);
bool noUseAfterLastDef(unsigned Reg, unsigned Dist, unsigned &LastDef);
@@ -209,136 +201,6 @@ INITIALIZE_PASS_END(TwoAddressInstructionPass, DEBUG_TYPE,
static bool isPlainlyKilled(MachineInstr *MI, unsigned Reg, LiveIntervals *LIS);
-/// A two-address instruction has been converted to a three-address instruction
-/// to avoid clobbering a register. Try to sink it past the instruction that
-/// would kill the above mentioned register to reduce register pressure.
-bool TwoAddressInstructionPass::
-sink3AddrInstruction(MachineInstr *MI, unsigned SavedReg,
- MachineBasicBlock::iterator OldPos) {
- // FIXME: Shouldn't we be trying to do this before we three-addressify the
- // instruction? After this transformation is done, we no longer need
- // the instruction to be in three-address form.
-
- // Check if it's safe to move this instruction.
- bool SeenStore = true; // Be conservative.
- if (!MI->isSafeToMove(AA, SeenStore))
- return false;
-
- unsigned DefReg = 0;
- SmallSet<unsigned, 4> UseRegs;
-
- for (const MachineOperand &MO : MI->operands()) {
- if (!MO.isReg())
- continue;
- Register MOReg = MO.getReg();
- if (!MOReg)
- continue;
- if (MO.isUse() && MOReg != SavedReg)
- UseRegs.insert(MO.getReg());
- if (!MO.isDef())
- continue;
- if (MO.isImplicit())
- // Don't try to move it if it implicitly defines a register.
- return false;
- if (DefReg)
- // For now, don't move any instructions that define multiple registers.
- return false;
- DefReg = MO.getReg();
- }
-
- // Find the instruction that kills SavedReg.
- MachineInstr *KillMI = nullptr;
- if (LIS) {
- LiveInterval &LI = LIS->getInterval(SavedReg);
- assert(LI.end() != LI.begin() &&
- "Reg should not have empty live interval.");
-
- SlotIndex MBBEndIdx = LIS->getMBBEndIdx(MBB).getPrevSlot();
- LiveInterval::const_iterator I = LI.find(MBBEndIdx);
- if (I != LI.end() && I->start < MBBEndIdx)
- return false;
-
- --I;
- KillMI = LIS->getInstructionFromIndex(I->end);
- }
- if (!KillMI) {
- for (MachineOperand &UseMO : MRI->use_nodbg_operands(SavedReg)) {
- if (!UseMO.isKill())
- continue;
- KillMI = UseMO.getParent();
- break;
- }
- }
-
- // If we find the instruction that kills SavedReg, and it is in an
- // appropriate location, we can try to sink the current instruction
- // past it.
- if (!KillMI || KillMI->getParent() != MBB || KillMI == MI ||
- MachineBasicBlock::iterator(KillMI) == OldPos || KillMI->isTerminator())
- return false;
-
- // If any of the definitions are used by another instruction between the
- // position and the kill use, then it's not safe to sink it.
- //
- // FIXME: This can be sped up if there is an easy way to query whether an
- // instruction is before or after another instruction. Then we can use
- // MachineRegisterInfo def / use instead.
- MachineOperand *KillMO = nullptr;
- MachineBasicBlock::iterator KillPos = KillMI;
- ++KillPos;
-
- unsigned NumVisited = 0;
- for (MachineInstr &OtherMI : make_range(std::next(OldPos), KillPos)) {
- // Debug instructions cannot be counted against the limit.
- if (OtherMI.isDebugInstr())
- continue;
- if (NumVisited > 30) // FIXME: Arbitrary limit to reduce compile time cost.
- return false;
- ++NumVisited;
- for (unsigned i = 0, e = OtherMI.getNumOperands(); i != e; ++i) {
- MachineOperand &MO = OtherMI.getOperand(i);
- if (!MO.isReg())
- continue;
- Register MOReg = MO.getReg();
- if (!MOReg)
- continue;
- if (DefReg == MOReg)
- return false;
-
- if (MO.isKill() || (LIS && isPlainlyKilled(&OtherMI, MOReg, LIS))) {
- if (&OtherMI == KillMI && MOReg == SavedReg)
- // Save the operand that kills the register. We want to unset the kill
- // marker if we can sink MI past it.
- KillMO = &MO;
- else if (UseRegs.count(MOReg))
- // One of the uses is killed before the destination.
- return false;
- }
- }
- }
- assert(KillMO && "Didn't find kill");
-
- if (!LIS) {
- // Update kill and LV information.
- KillMO->setIsKill(false);
- KillMO = MI->findRegisterUseOperand(SavedReg, false, TRI);
- KillMO->setIsKill(true);
-
- if (LV)
- LV->replaceKillInstruction(SavedReg, *KillMI, *MI);
- }
-
- // Move instruction to its destination.
- MBB->remove(MI);
- MBB->insert(KillPos, MI);
-
- if (LIS)
- LIS->handleMove(*MI);
-
- ++Num3AddrSunk;
- return true;
-}
-
/// Return the MachineInstr* if it is the single def of the Reg in current BB.
static MachineInstr *getSingleDef(unsigned Reg, MachineBasicBlock *BB,
const MachineRegisterInfo *MRI) {
@@ -740,26 +602,15 @@ TwoAddressInstructionPass::convertInstTo3Addr(MachineBasicBlock::iterator &mi,
LLVM_DEBUG(dbgs() << "2addr: CONVERTING 2-ADDR: " << *mi);
LLVM_DEBUG(dbgs() << "2addr: TO 3-ADDR: " << *NewMI);
- bool Sunk = false;
if (LIS)
LIS->ReplaceMachineInstrInMaps(*mi, *NewMI);
- if (NewMI->findRegisterUseOperand(RegB, false, TRI))
- // FIXME: Temporary workaround. If the new instruction doesn't
- // uses RegB, convertToThreeAddress must have created more
- // then one instruction.
- Sunk = sink3AddrInstruction(NewMI, RegB, mi);
-
MBB->erase(mi); // Nuke the old inst.
- if (!Sunk) {
- DistanceMap.insert(std::make_pair(NewMI, Dist));
- mi = NewMI;
- nmi = std::next(mi);
- }
- else
- SunkInstrs.insert(NewMI);
+ DistanceMap.insert(std::make_pair(NewMI, Dist));
+ mi = NewMI;
+ nmi = std::next(mi);
// Update source and destination register maps.
SrcRegMap.erase(RegA);
@@ -1700,13 +1551,11 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &Func) {
SrcRegMap.clear();
DstRegMap.clear();
Processed.clear();
- SunkInstrs.clear();
for (MachineBasicBlock::iterator mi = MBB->begin(), me = MBB->end();
mi != me; ) {
MachineBasicBlock::iterator nmi = std::next(mi);
- // Don't revisit an instruction previously converted by target. It may
- // contain undef register operands (%noreg), which are not handled.
- if (mi->isDebugInstr() || SunkInstrs.count(&*mi)) {
+ // Skip debug instructions.
+ if (mi->isDebugInstr()) {
mi = nmi;
continue;
}
diff --git a/contrib/llvm-project/llvm/lib/IR/ConstantFold.cpp b/contrib/llvm-project/llvm/lib/IR/ConstantFold.cpp
index f02246cda7fc..f3c3e9ad9f69 100644
--- a/contrib/llvm-project/llvm/lib/IR/ConstantFold.cpp
+++ b/contrib/llvm-project/llvm/lib/IR/ConstantFold.cpp
@@ -779,30 +779,10 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond,
if (isa<UndefValue>(V1)) return V1;
return V2;
}
-
+ if (isa<UndefValue>(V1)) return V2;
+ if (isa<UndefValue>(V2)) return V1;
if (V1 == V2) return V1;
- // If the true or false value is undef, we can fold to the other value as
- // long as the other value isn't poison.
- auto NotPoison = [](Constant *C) {
- // TODO: We can analyze ConstExpr by opcode to determine if there is any
- // possibility of poison.
- if (isa<ConstantExpr>(C))
- return false;
-
- if (isa<ConstantInt>(C) || isa<GlobalVariable>(C) || isa<ConstantFP>(C) ||
- isa<ConstantPointerNull>(C) || isa<Function>(C))
- return true;
-
- if (C->getType()->isVectorTy())
- return !C->containsUndefElement() && !C->containsConstantExpression();
-
- // TODO: Recursively analyze aggregates or other constants.
- return false;
- };
- if (isa<UndefValue>(V1) && NotPoison(V2)) return V2;
- if (isa<UndefValue>(V2) && NotPoison(V1)) return V1;
-
if (ConstantExpr *TrueVal = dyn_cast<ConstantExpr>(V1)) {
if (TrueVal->getOpcode() == Instruction::Select)
if (TrueVal->getOperand(0) == Cond)
diff --git a/contrib/llvm-project/llvm/lib/IR/IRBuilder.cpp b/contrib/llvm-project/llvm/lib/IR/IRBuilder.cpp
index b87dfe1c8df6..1fffce015f70 100644
--- a/contrib/llvm-project/llvm/lib/IR/IRBuilder.cpp
+++ b/contrib/llvm-project/llvm/lib/IR/IRBuilder.cpp
@@ -71,9 +71,8 @@ Value *IRBuilderBase::getCastedInt8PtrValue(Value *Ptr) {
static CallInst *createCallHelper(Function *Callee, ArrayRef<Value *> Ops,
IRBuilderBase *Builder,
const Twine &Name = "",
- Instruction *FMFSource = nullptr,
- ArrayRef<OperandBundleDef> OpBundles = {}) {
- CallInst *CI = Builder->CreateCall(Callee, Ops, OpBundles, Name);
+ Instruction *FMFSource = nullptr) {
+ CallInst *CI = Builder->CreateCall(Callee, Ops, Name);
if (FMFSource)
CI->copyFastMathFlags(FMFSource);
return CI;
@@ -450,16 +449,14 @@ CallInst *IRBuilderBase::CreateInvariantStart(Value *Ptr, ConstantInt *Size) {
return createCallHelper(TheFn, Ops, this);
}
-CallInst *
-IRBuilderBase::CreateAssumption(Value *Cond,
- ArrayRef<OperandBundleDef> OpBundles) {
+CallInst *IRBuilderBase::CreateAssumption(Value *Cond) {
assert(Cond->getType() == getInt1Ty() &&
"an assumption condition must be of type i1");
Value *Ops[] = { Cond };
Module *M = BB->getParent()->getParent();
Function *FnAssume = Intrinsic::getDeclaration(M, Intrinsic::assume);
- return createCallHelper(FnAssume, Ops, this, "", nullptr, OpBundles);
+ return createCallHelper(FnAssume, Ops, this);
}
/// Create a call to a Masked Load intrinsic.
@@ -1110,37 +1107,63 @@ Value *IRBuilderBase::CreatePreserveStructAccessIndex(
return Fn;
}
-CallInst *IRBuilderBase::CreateAlignmentAssumptionHelper(const DataLayout &DL,
- Value *PtrValue,
- Value *AlignValue,
- Value *OffsetValue) {
- SmallVector<Value *, 4> Vals({PtrValue, AlignValue});
- if (OffsetValue)
- Vals.push_back(OffsetValue);
- OperandBundleDefT<Value *> AlignOpB("align", Vals);
- return CreateAssumption(ConstantInt::getTrue(getContext()), {AlignOpB});
+CallInst *IRBuilderBase::CreateAlignmentAssumptionHelper(
+ const DataLayout &DL, Value *PtrValue, Value *Mask, Type *IntPtrTy,
+ Value *OffsetValue, Value **TheCheck) {
+ Value *PtrIntValue = CreatePtrToInt(PtrValue, IntPtrTy, "ptrint");
+
+ if (OffsetValue) {
+ bool IsOffsetZero = false;
+ if (const auto *CI = dyn_cast<ConstantInt>(OffsetValue))
+ IsOffsetZero = CI->isZero();
+
+ if (!IsOffsetZero) {
+ if (OffsetValue->getType() != IntPtrTy)
+ OffsetValue = CreateIntCast(OffsetValue, IntPtrTy, /*isSigned*/ true,
+ "offsetcast");
+ PtrIntValue = CreateSub(PtrIntValue, OffsetValue, "offsetptr");
+ }
+ }
+
+ Value *Zero = ConstantInt::get(IntPtrTy, 0);
+ Value *MaskedPtr = CreateAnd(PtrIntValue, Mask, "maskedptr");
+ Value *InvCond = CreateICmpEQ(MaskedPtr, Zero, "maskcond");
+ if (TheCheck)
+ *TheCheck = InvCond;
+
+ return CreateAssumption(InvCond);
}
-CallInst *IRBuilderBase::CreateAlignmentAssumption(const DataLayout &DL,
- Value *PtrValue,
- unsigned Alignment,
- Value *OffsetValue) {
+CallInst *IRBuilderBase::CreateAlignmentAssumption(
+ const DataLayout &DL, Value *PtrValue, unsigned Alignment,
+ Value *OffsetValue, Value **TheCheck) {
assert(isa<PointerType>(PtrValue->getType()) &&
"trying to create an alignment assumption on a non-pointer?");
assert(Alignment != 0 && "Invalid Alignment");
auto *PtrTy = cast<PointerType>(PtrValue->getType());
Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace());
- Value *AlignValue = ConstantInt::get(IntPtrTy, Alignment);
- return CreateAlignmentAssumptionHelper(DL, PtrValue, AlignValue, OffsetValue);
+
+ Value *Mask = ConstantInt::get(IntPtrTy, Alignment - 1);
+ return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy,
+ OffsetValue, TheCheck);
}
-CallInst *IRBuilderBase::CreateAlignmentAssumption(const DataLayout &DL,
- Value *PtrValue,
- Value *Alignment,
- Value *OffsetValue) {
+CallInst *IRBuilderBase::CreateAlignmentAssumption(
+ const DataLayout &DL, Value *PtrValue, Value *Alignment,
+ Value *OffsetValue, Value **TheCheck) {
assert(isa<PointerType>(PtrValue->getType()) &&
"trying to create an alignment assumption on a non-pointer?");
- return CreateAlignmentAssumptionHelper(DL, PtrValue, Alignment, OffsetValue);
+ auto *PtrTy = cast<PointerType>(PtrValue->getType());
+ Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace());
+
+ if (Alignment->getType() != IntPtrTy)
+ Alignment = CreateIntCast(Alignment, IntPtrTy, /*isSigned*/ false,
+ "alignmentcast");
+
+ Value *Mask = CreateSub(Alignment, ConstantInt::get(IntPtrTy, 1), "mask");
+
+ return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy,
+ OffsetValue, TheCheck);
}
IRBuilderDefaultInserter::~IRBuilderDefaultInserter() {}
diff --git a/contrib/llvm-project/llvm/lib/IR/Verifier.cpp b/contrib/llvm-project/llvm/lib/IR/Verifier.cpp
index 6df1072925f9..c518ae87ea9b 100644
--- a/contrib/llvm-project/llvm/lib/IR/Verifier.cpp
+++ b/contrib/llvm-project/llvm/lib/IR/Verifier.cpp
@@ -4449,32 +4449,21 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
Assert(Elem.Tag->getKey() == "ignore" ||
Attribute::isExistingAttribute(Elem.Tag->getKey()),
"tags must be valid attribute names");
+ Assert(Elem.End - Elem.Begin <= 2, "to many arguments");
Attribute::AttrKind Kind =
Attribute::getAttrKindFromName(Elem.Tag->getKey());
- unsigned ArgCount = Elem.End - Elem.Begin;
- if (Kind == Attribute::Alignment) {
- Assert(ArgCount <= 3 && ArgCount >= 2,
- "alignment assumptions should have 2 or 3 arguments");
- Assert(Call.getOperand(Elem.Begin)->getType()->isPointerTy(),
- "first argument should be a pointer");
- Assert(Call.getOperand(Elem.Begin + 1)->getType()->isIntegerTy(),
- "second argument should be an integer");
- if (ArgCount == 3)
- Assert(Call.getOperand(Elem.Begin + 2)->getType()->isIntegerTy(),
- "third argument should be an integer if present");
- return;
- }
- Assert(ArgCount <= 2, "to many arguments");
if (Kind == Attribute::None)
break;
if (Attribute::doesAttrKindHaveArgument(Kind)) {
- Assert(ArgCount == 2, "this attribute should have 2 arguments");
+ Assert(Elem.End - Elem.Begin == 2,
+ "this attribute should have 2 arguments");
Assert(isa<ConstantInt>(Call.getOperand(Elem.Begin + 1)),
"the second argument should be a constant integral value");
} else if (isFuncOnlyAttr(Kind)) {
- Assert((ArgCount) == 0, "this attribute has no argument");
+ Assert((Elem.End - Elem.Begin) == 0, "this attribute has no argument");
} else if (!isFuncOrArgAttr(Kind)) {
- Assert((ArgCount) == 1, "this attribute should have one argument");
+ Assert((Elem.End - Elem.Begin) == 1,
+ "this attribute should have one argument");
}
}
break;
diff --git a/contrib/llvm-project/llvm/lib/MC/MCParser/MasmParser.cpp b/contrib/llvm-project/llvm/lib/MC/MCParser/MasmParser.cpp
index 58c22b2ccef2..e2aaeaae03b0 100644
--- a/contrib/llvm-project/llvm/lib/MC/MCParser/MasmParser.cpp
+++ b/contrib/llvm-project/llvm/lib/MC/MCParser/MasmParser.cpp
@@ -812,9 +812,6 @@ private:
const StructInitializer &Initializer);
// User-defined types (structs, unions):
- bool emitStructValue(const StructInfo &Structure,
- const StructInitializer &Initializer,
- size_t InitialOffset = 0, size_t InitialField = 0);
bool emitStructValues(const StructInfo &Structure);
bool addStructField(StringRef Name, const StructInfo &Structure);
bool parseDirectiveStructValue(const StructInfo &Structure,
diff --git a/contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp b/contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp
index 3f3f79b0f4ff..ad7a50d13bb7 100644
--- a/contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp
@@ -62,6 +62,8 @@ static bool supportsAArch64(uint64_t Type) {
switch (Type) {
case ELF::R_AARCH64_ABS32:
case ELF::R_AARCH64_ABS64:
+ case ELF::R_AARCH64_PREL32:
+ case ELF::R_AARCH64_PREL64:
return true;
default:
return false;
@@ -74,6 +76,10 @@ static uint64_t resolveAArch64(RelocationRef R, uint64_t S, uint64_t A) {
return (S + getELFAddend(R)) & 0xFFFFFFFF;
case ELF::R_AARCH64_ABS64:
return S + getELFAddend(R);
+ case ELF::R_AARCH64_PREL32:
+ return (S + getELFAddend(R) - R.getOffset()) & 0xFFFFFFFF;
+ case ELF::R_AARCH64_PREL64:
+ return S + getELFAddend(R) - R.getOffset();
default:
llvm_unreachable("Invalid relocation type");
}
@@ -152,6 +158,8 @@ static bool supportsPPC64(uint64_t Type) {
switch (Type) {
case ELF::R_PPC64_ADDR32:
case ELF::R_PPC64_ADDR64:
+ case ELF::R_PPC64_REL32:
+ case ELF::R_PPC64_REL64:
return true;
default:
return false;
@@ -164,6 +172,10 @@ static uint64_t resolvePPC64(RelocationRef R, uint64_t S, uint64_t A) {
return (S + getELFAddend(R)) & 0xFFFFFFFF;
case ELF::R_PPC64_ADDR64:
return S + getELFAddend(R);
+ case ELF::R_PPC64_REL32:
+ return (S + getELFAddend(R) - R.getOffset()) & 0xFFFFFFFF;
+ case ELF::R_PPC64_REL64:
+ return S + getELFAddend(R) - R.getOffset();
default:
llvm_unreachable("Invalid relocation type");
}
@@ -259,12 +271,22 @@ static uint64_t resolveX86(RelocationRef R, uint64_t S, uint64_t A) {
}
static bool supportsPPC32(uint64_t Type) {
- return Type == ELF::R_PPC_ADDR32;
+ switch (Type) {
+ case ELF::R_PPC_ADDR32:
+ case ELF::R_PPC_REL32:
+ return true;
+ default:
+ return false;
+ }
}
static uint64_t resolvePPC32(RelocationRef R, uint64_t S, uint64_t A) {
- if (R.getType() == ELF::R_PPC_ADDR32)
+ switch (R.getType()) {
+ case ELF::R_PPC_ADDR32:
return (S + getELFAddend(R)) & 0xFFFFFFFF;
+ case ELF::R_PPC_REL32:
+ return (S + getELFAddend(R) - R.getOffset()) & 0xFFFFFFFF;
+ }
llvm_unreachable("Invalid relocation type");
}
diff --git a/contrib/llvm-project/llvm/lib/Support/TargetParser.cpp b/contrib/llvm-project/llvm/lib/Support/TargetParser.cpp
index be9b541237c7..031384ebaa91 100644
--- a/contrib/llvm-project/llvm/lib/Support/TargetParser.cpp
+++ b/contrib/llvm-project/llvm/lib/Support/TargetParser.cpp
@@ -11,11 +11,12 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/TargetParser.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/Support/ARMBuildAttributes.h"
using namespace llvm;
using namespace AMDGPU;
@@ -208,3 +209,64 @@ AMDGPU::IsaVersion AMDGPU::getIsaVersion(StringRef GPU) {
default: return {0, 0, 0};
}
}
+
+namespace llvm {
+namespace RISCV {
+
+struct CPUInfo {
+ StringLiteral Name;
+ CPUKind Kind;
+ unsigned Features;
+ StringLiteral DefaultMarch;
+ bool is64Bit() const { return (Features & FK_64BIT); }
+};
+
+constexpr CPUInfo RISCVCPUInfo[] = {
+#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) \
+ {NAME, CK_##ENUM, FEATURES, DEFAULT_MARCH},
+#include "llvm/Support/RISCVTargetParser.def"
+};
+
+bool checkCPUKind(CPUKind Kind, bool IsRV64) {
+ if (Kind == CK_INVALID)
+ return false;
+ return RISCVCPUInfo[static_cast<unsigned>(Kind)].is64Bit() == IsRV64;
+}
+
+CPUKind parseCPUKind(StringRef CPU) {
+ return llvm::StringSwitch<CPUKind>(CPU)
+#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) .Case(NAME, CK_##ENUM)
+#include "llvm/Support/RISCVTargetParser.def"
+ .Default(CK_INVALID);
+}
+
+StringRef getMArchFromMcpu(StringRef CPU) {
+ CPUKind Kind = parseCPUKind(CPU);
+ return RISCVCPUInfo[static_cast<unsigned>(Kind)].DefaultMarch;
+}
+
+void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) {
+ for (const auto &C : RISCVCPUInfo) {
+ if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit())
+ Values.emplace_back(C.Name);
+ }
+}
+
+// Get all features except standard extension feature
+bool getCPUFeaturesExceptStdExt(CPUKind Kind,
+ std::vector<StringRef> &Features) {
+ unsigned CPUFeatures = RISCVCPUInfo[static_cast<unsigned>(Kind)].Features;
+
+ if (CPUFeatures == FK_INVALID)
+ return false;
+
+ if (CPUFeatures & FK_64BIT)
+ Features.push_back("+64bit");
+ else
+ Features.push_back("-64bit");
+
+ return true;
+}
+
+} // namespace RISCV
+} // namespace llvm
diff --git a/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp b/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
index bd9174c1973d..2ee394e9259d 100644
--- a/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
@@ -1466,11 +1466,10 @@ void PPCFrameLowering::inlineStackProbe(MachineFunction &MF,
.addImm(0)
.addImm(32 - Log2(MaxAlign))
.addImm(31);
- BuildMI(PrologMBB, {MI}, DL, TII.get(isPPC64 ? PPC::STDUX : PPC::STWUX),
+ BuildMI(PrologMBB, {MI}, DL, TII.get(isPPC64 ? PPC::SUBFC8 : PPC::SUBFC),
SPReg)
- .addReg(FPReg)
- .addReg(SPReg)
- .addReg(ScratchReg);
+ .addReg(ScratchReg)
+ .addReg(SPReg);
}
// Probe residual part.
if (NegResidualSize) {
diff --git a/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 88c535f21a2d..1b016b6e3745 100644
--- a/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -11950,18 +11950,34 @@ PPCTargetLowering::emitProbedAlloca(MachineInstr &MI,
Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
Register FinalStackPtr = MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
Register FramePointer = MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
-
- // Get the canonical FinalStackPtr like what
- // PPCRegisterInfo::lowerDynamicAlloc does.
- BuildMI(*MBB, {MI}, DL,
- TII->get(isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64
- : PPC::PREPARE_PROBED_ALLOCA_32),
- FramePointer)
- .addDef(FinalStackPtr)
+ Register ActualNegSizeReg = MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
+
+ // Since value of NegSizeReg might be realigned in prologepilog, insert a
+ // PREPARE_PROBED_ALLOCA pseudo instruction to get actual FramePointer and
+ // NegSize.
+ unsigned ProbeOpc;
+ if (!MRI.hasOneNonDBGUse(NegSizeReg))
+ ProbeOpc =
+ isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
+ else
+ // By introducing PREPARE_PROBED_ALLOCA_NEGSIZE_OPT, ActualNegSizeReg
+ // and NegSizeReg will be allocated in the same phyreg to avoid
+ // redundant copy when NegSizeReg has only one use which is current MI and
+ // will be replaced by PREPARE_PROBED_ALLOCA then.
+ ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
+ : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
+ BuildMI(*MBB, {MI}, DL, TII->get(ProbeOpc), FramePointer)
+ .addDef(ActualNegSizeReg)
.addReg(NegSizeReg)
.add(MI.getOperand(2))
.add(MI.getOperand(3));
+ // Calculate final stack pointer, which equals to SP + ActualNegSize.
+ BuildMI(*MBB, {MI}, DL, TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4),
+ FinalStackPtr)
+ .addReg(SPReg)
+ .addReg(ActualNegSizeReg);
+
// Materialize a scratch register for update.
int64_t NegProbeSize = -(int64_t)ProbeSize;
assert(isInt<32>(NegProbeSize) && "Unhandled probe size!");
@@ -11982,7 +11998,7 @@ PPCTargetLowering::emitProbedAlloca(MachineInstr &MI,
// Probing leading residual part.
Register Div = MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
BuildMI(*MBB, {MI}, DL, TII->get(isPPC64 ? PPC::DIVD : PPC::DIVW), Div)
- .addReg(NegSizeReg)
+ .addReg(ActualNegSizeReg)
.addReg(ScratchReg);
Register Mul = MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
BuildMI(*MBB, {MI}, DL, TII->get(isPPC64 ? PPC::MULLD : PPC::MULLW), Mul)
@@ -11991,7 +12007,7 @@ PPCTargetLowering::emitProbedAlloca(MachineInstr &MI,
Register NegMod = MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
BuildMI(*MBB, {MI}, DL, TII->get(isPPC64 ? PPC::SUBF8 : PPC::SUBF), NegMod)
.addReg(Mul)
- .addReg(NegSizeReg);
+ .addReg(ActualNegSizeReg);
BuildMI(*MBB, {MI}, DL, TII->get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
.addReg(FramePointer)
.addReg(SPReg)
diff --git a/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
index 1c457d4170d5..6956c40a70be 100644
--- a/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -431,9 +431,14 @@ def PROBED_ALLOCA_64 : PPCCustomInserterPseudo<(outs g8rc:$result),
(ins g8rc:$negsize, memri:$fpsi), "#PROBED_ALLOCA_64",
[(set i64:$result,
(PPCprobedalloca i64:$negsize, iaddr:$fpsi))]>;
-def PREPARE_PROBED_ALLOCA_64 : PPCEmitTimePseudo<(outs g8rc:$fp,
- g8rc:$sp),
+def PREPARE_PROBED_ALLOCA_64 : PPCEmitTimePseudo<(outs
+ g8rc:$fp, g8rc:$actual_negsize),
(ins g8rc:$negsize, memri:$fpsi), "#PREPARE_PROBED_ALLOCA_64", []>;
+def PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64 : PPCEmitTimePseudo<(outs
+ g8rc:$fp, g8rc:$actual_negsize),
+ (ins g8rc:$negsize, memri:$fpsi),
+ "#PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64", []>,
+ RegConstraint<"$actual_negsize = $negsize">;
def PROBED_STACKALLOC_64 : PPCEmitTimePseudo<(outs g8rc:$scratch, g8rc:$temp),
(ins i64imm:$stacksize),
"#PROBED_STACKALLOC_64", []>;
diff --git a/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index 673ab63039cf..fedbf592af39 100644
--- a/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -1406,9 +1406,14 @@ def PROBED_ALLOCA_32 : PPCCustomInserterPseudo<(outs gprc:$result),
(ins gprc:$negsize, memri:$fpsi), "#PROBED_ALLOCA_32",
[(set i32:$result,
(PPCprobedalloca i32:$negsize, iaddr:$fpsi))]>;
-def PREPARE_PROBED_ALLOCA_32 : PPCEmitTimePseudo<(outs gprc:$fp,
- gprc:$sp),
+def PREPARE_PROBED_ALLOCA_32 : PPCEmitTimePseudo<(outs
+ gprc:$fp, gprc:$actual_negsize),
(ins gprc:$negsize, memri:$fpsi), "#PREPARE_PROBED_ALLOCA_32", []>;
+def PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32 : PPCEmitTimePseudo<(outs
+ gprc:$fp, gprc:$actual_negsize),
+ (ins gprc:$negsize, memri:$fpsi),
+ "#PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32", []>,
+ RegConstraint<"$actual_negsize = $negsize">;
def PROBED_STACKALLOC_32 : PPCEmitTimePseudo<(outs gprc:$scratch, gprc:$temp),
(ins i64imm:$stacksize),
"#PROBED_STACKALLOC_32", []>;
diff --git a/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
index 35f5e1fbebcd..ed8948a63972 100644
--- a/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -624,21 +624,30 @@ void PPCRegisterInfo::lowerPrepareProbedAlloca(
bool LP64 = TM.isPPC64();
DebugLoc dl = MI.getDebugLoc();
Register FramePointer = MI.getOperand(0).getReg();
- Register FinalStackPtr = MI.getOperand(1).getReg();
+ const Register ActualNegSizeReg = MI.getOperand(1).getReg();
bool KillNegSizeReg = MI.getOperand(2).isKill();
Register NegSizeReg = MI.getOperand(2).getReg();
- prepareDynamicAlloca(II, NegSizeReg, KillNegSizeReg, FramePointer);
- if (LP64) {
- BuildMI(MBB, II, dl, TII.get(PPC::ADD8), FinalStackPtr)
- .addReg(PPC::X1)
- .addReg(NegSizeReg, getKillRegState(KillNegSizeReg));
-
- } else {
- BuildMI(MBB, II, dl, TII.get(PPC::ADD4), FinalStackPtr)
- .addReg(PPC::R1)
- .addReg(NegSizeReg, getKillRegState(KillNegSizeReg));
+ const MCInstrDesc &CopyInst = TII.get(LP64 ? PPC::OR8 : PPC::OR);
+ // RegAllocator might allocate FramePointer and NegSizeReg in the same phyreg.
+ if (FramePointer == NegSizeReg) {
+ assert(KillNegSizeReg && "FramePointer is a def and NegSizeReg is an use, "
+ "NegSizeReg should be killed");
+ // FramePointer is clobbered earlier than the use of NegSizeReg in
+ // prepareDynamicAlloca, save NegSizeReg in ActualNegSizeReg to avoid
+ // misuse.
+ BuildMI(MBB, II, dl, CopyInst, ActualNegSizeReg)
+ .addReg(NegSizeReg)
+ .addReg(NegSizeReg);
+ NegSizeReg = ActualNegSizeReg;
+ KillNegSizeReg = false;
}
-
+ prepareDynamicAlloca(II, NegSizeReg, KillNegSizeReg, FramePointer);
+ // NegSizeReg might be updated in prepareDynamicAlloca if MaxAlign >
+ // TargetAlign.
+ if (NegSizeReg != ActualNegSizeReg)
+ BuildMI(MBB, II, dl, CopyInst, ActualNegSizeReg)
+ .addReg(NegSizeReg)
+ .addReg(NegSizeReg);
MBB.erase(II);
}
@@ -1084,7 +1093,9 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
if (FPSI && FrameIndex == FPSI &&
(OpC == PPC::PREPARE_PROBED_ALLOCA_64 ||
- OpC == PPC::PREPARE_PROBED_ALLOCA_32)) {
+ OpC == PPC::PREPARE_PROBED_ALLOCA_32 ||
+ OpC == PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64 ||
+ OpC == PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32)) {
lowerPrepareProbedAlloca(II);
return;
}
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCV.td b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCV.td
index f0583f691936..57e7c41c4271 100644
--- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCV.td
+++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCV.td
@@ -215,6 +215,16 @@ def : ProcessorModel<"rocket-rv32", Rocket32Model, []>;
def : ProcessorModel<"rocket-rv64", Rocket64Model, [Feature64Bit]>;
+def : ProcessorModel<"sifive-e31", Rocket32Model, [FeatureStdExtM,
+ FeatureStdExtA,
+ FeatureStdExtC]>;
+
+def : ProcessorModel<"sifive-u54", Rocket64Model, [Feature64Bit,
+ FeatureStdExtM,
+ FeatureStdExtA,
+ FeatureStdExtF,
+ FeatureStdExtD,
+ FeatureStdExtC]>;
//===----------------------------------------------------------------------===//
// Define the RISC-V target.
diff --git a/contrib/llvm-project/llvm/lib/Target/X86/AsmParser/X86Operand.h b/contrib/llvm-project/llvm/lib/Target/X86/AsmParser/X86Operand.h
index 5cf4516ede97..e32335331879 100644
--- a/contrib/llvm-project/llvm/lib/Target/X86/AsmParser/X86Operand.h
+++ b/contrib/llvm-project/llvm/lib/Target/X86/AsmParser/X86Operand.h
@@ -463,7 +463,14 @@ struct X86Operand final : public MCParsedAsmOperand {
bool isGR32orGR64() const {
return Kind == Register &&
(X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
- X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
+ X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
+ }
+
+ bool isGR16orGR32orGR64() const {
+ return Kind == Register &&
+ (X86MCRegisterClasses[X86::GR16RegClassID].contains(getReg()) ||
+ X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
+ X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
}
bool isVectorReg() const {
@@ -520,6 +527,15 @@ struct X86Operand final : public MCParsedAsmOperand {
Inst.addOperand(MCOperand::createReg(RegNo));
}
+ void addGR16orGR32orGR64Operands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ MCRegister RegNo = getReg();
+ if (X86MCRegisterClasses[X86::GR32RegClassID].contains(RegNo) ||
+ X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
+ RegNo = getX86SubSuperRegister(RegNo, 16);
+ Inst.addOperand(MCOperand::createReg(RegNo));
+ }
+
void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
addExpr(Inst, getImm());
diff --git a/contrib/llvm-project/llvm/lib/Target/X86/X86ISelLowering.cpp b/contrib/llvm-project/llvm/lib/Target/X86/X86ISelLowering.cpp
index 450927aaf5cc..f8b6b7eb3aff 100644
--- a/contrib/llvm-project/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -6916,25 +6916,16 @@ static bool getTargetShuffleMask(SDNode *N, MVT VT, bool AllowSentinelZero,
DecodeZeroMoveLowMask(NumElems, Mask);
IsUnary = true;
break;
- case X86ISD::VBROADCAST: {
- SDValue N0 = N->getOperand(0);
- // See if we're broadcasting from index 0 of an EXTRACT_SUBVECTOR. If so,
- // add the pre-extracted value to the Ops vector.
- if (N0.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
- N0.getOperand(0).getValueType() == VT &&
- N0.getConstantOperandVal(1) == 0)
- Ops.push_back(N0.getOperand(0));
-
- // We only decode broadcasts of same-sized vectors, unless the broadcast
- // came from an extract from the original width. If we found one, we
- // pushed it the Ops vector above.
- if (N0.getValueType() == VT || !Ops.empty()) {
+ case X86ISD::VBROADCAST:
+ // We only decode broadcasts of same-sized vectors, peeking through to
+ // extracted subvectors is likely to cause hasOneUse issues with
+ // SimplifyDemandedBits etc.
+ if (N->getOperand(0).getValueType() == VT) {
DecodeVectorBroadcast(NumElems, Mask);
IsUnary = true;
break;
}
return false;
- }
case X86ISD::VPERMILPV: {
assert(N->getOperand(0).getValueType() == VT && "Unexpected value type");
IsUnary = true;
@@ -44523,6 +44514,8 @@ static SDValue combineFaddFsub(SDNode *N, SelectionDAG &DAG,
isHorizontalBinOp(LHS, RHS, DAG, Subtarget, IsFadd))
return DAG.getNode(HorizOpcode, SDLoc(N), VT, LHS, RHS);
+ // NOTE: isHorizontalBinOp may have changed LHS/RHS variables.
+
return SDValue();
}
@@ -47604,6 +47597,30 @@ static SDValue matchPMADDWD_2(SelectionDAG &DAG, SDValue N0, SDValue N1,
PMADDBuilder);
}
+static SDValue combineAddOrSubToHADDorHSUB(SDNode *N, SelectionDAG &DAG,
+ const X86Subtarget &Subtarget) {
+ EVT VT = N->getValueType(0);
+ SDValue Op0 = N->getOperand(0);
+ SDValue Op1 = N->getOperand(1);
+ bool IsAdd = N->getOpcode() == ISD::ADD;
+ assert((IsAdd || N->getOpcode() == ISD::SUB) && "Wrong opcode");
+
+ if ((VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v16i16 ||
+ VT == MVT::v8i32) &&
+ Subtarget.hasSSSE3() &&
+ isHorizontalBinOp(Op0, Op1, DAG, Subtarget, IsAdd)) {
+ auto HOpBuilder = [IsAdd](SelectionDAG &DAG, const SDLoc &DL,
+ ArrayRef<SDValue> Ops) {
+ return DAG.getNode(IsAdd ? X86ISD::HADD : X86ISD::HSUB,
+ DL, Ops[0].getValueType(), Ops);
+ };
+ return SplitOpsAndApply(DAG, Subtarget, SDLoc(N), VT, {Op0, Op1},
+ HOpBuilder);
+ }
+
+ return SDValue();
+}
+
static SDValue combineAdd(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const X86Subtarget &Subtarget) {
@@ -47617,17 +47634,8 @@ static SDValue combineAdd(SDNode *N, SelectionDAG &DAG,
return MAdd;
// Try to synthesize horizontal adds from adds of shuffles.
- if ((VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v16i16 ||
- VT == MVT::v8i32) &&
- Subtarget.hasSSSE3() &&
- isHorizontalBinOp(Op0, Op1, DAG, Subtarget, true)) {
- auto HADDBuilder = [](SelectionDAG &DAG, const SDLoc &DL,
- ArrayRef<SDValue> Ops) {
- return DAG.getNode(X86ISD::HADD, DL, Ops[0].getValueType(), Ops);
- };
- return SplitOpsAndApply(DAG, Subtarget, SDLoc(N), VT, {Op0, Op1},
- HADDBuilder);
- }
+ if (SDValue V = combineAddOrSubToHADDorHSUB(N, DAG, Subtarget))
+ return V;
// If vectors of i1 are legal, turn (add (zext (vXi1 X)), Y) into
// (sub Y, (sext (vXi1 X))).
@@ -47800,18 +47808,8 @@ static SDValue combineSub(SDNode *N, SelectionDAG &DAG,
}
// Try to synthesize horizontal subs from subs of shuffles.
- EVT VT = N->getValueType(0);
- if ((VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v16i16 ||
- VT == MVT::v8i32) &&
- Subtarget.hasSSSE3() &&
- isHorizontalBinOp(Op0, Op1, DAG, Subtarget, false)) {
- auto HSUBBuilder = [](SelectionDAG &DAG, const SDLoc &DL,
- ArrayRef<SDValue> Ops) {
- return DAG.getNode(X86ISD::HSUB, DL, Ops[0].getValueType(), Ops);
- };
- return SplitOpsAndApply(DAG, Subtarget, SDLoc(N), VT, {Op0, Op1},
- HSUBBuilder);
- }
+ if (SDValue V = combineAddOrSubToHADDorHSUB(N, DAG, Subtarget))
+ return V;
// Try to create PSUBUS if SUB's argument is max/min
if (SDValue V = combineSubToSubus(N, DAG, Subtarget))
diff --git a/contrib/llvm-project/llvm/lib/Target/X86/X86InstrInfo.td b/contrib/llvm-project/llvm/lib/Target/X86/X86InstrInfo.td
index 23841c3d7e50..3ea0ae8a8840 100644
--- a/contrib/llvm-project/llvm/lib/Target/X86/X86InstrInfo.td
+++ b/contrib/llvm-project/llvm/lib/Target/X86/X86InstrInfo.td
@@ -640,10 +640,17 @@ class ImmSExtAsmOperandClass : AsmOperandClass {
def X86GR32orGR64AsmOperand : AsmOperandClass {
let Name = "GR32orGR64";
}
-
def GR32orGR64 : RegisterOperand<GR32> {
let ParserMatchClass = X86GR32orGR64AsmOperand;
}
+
+def X86GR16orGR32orGR64AsmOperand : AsmOperandClass {
+ let Name = "GR16orGR32orGR64";
+}
+def GR16orGR32orGR64 : RegisterOperand<GR16> {
+ let ParserMatchClass = X86GR16orGR32orGR64AsmOperand;
+}
+
def AVX512RCOperand : AsmOperandClass {
let Name = "AVX512RC";
}
diff --git a/contrib/llvm-project/llvm/lib/Target/X86/X86InstrSystem.td b/contrib/llvm-project/llvm/lib/Target/X86/X86InstrSystem.td
index c23bc7ebbf70..13659b5c456e 100644
--- a/contrib/llvm-project/llvm/lib/Target/X86/X86InstrSystem.td
+++ b/contrib/llvm-project/llvm/lib/Target/X86/X86InstrSystem.td
@@ -207,45 +207,41 @@ let mayLoad = 1 in
def LAR16rm : I<0x02, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
"lar{w}\t{$src, $dst|$dst, $src}", []>, TB,
OpSize16, NotMemoryFoldable;
-def LAR16rr : I<0x02, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
+def LAR16rr : I<0x02, MRMSrcReg, (outs GR16:$dst), (ins GR16orGR32orGR64:$src),
"lar{w}\t{$src, $dst|$dst, $src}", []>, TB,
OpSize16, NotMemoryFoldable;
-// i16mem operand in LAR32rm and GR32 operand in LAR32rr is not a typo.
let mayLoad = 1 in
def LAR32rm : I<0x02, MRMSrcMem, (outs GR32:$dst), (ins i16mem:$src),
"lar{l}\t{$src, $dst|$dst, $src}", []>, TB,
OpSize32, NotMemoryFoldable;
-def LAR32rr : I<0x02, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
+def LAR32rr : I<0x02, MRMSrcReg, (outs GR32:$dst), (ins GR16orGR32orGR64:$src),
"lar{l}\t{$src, $dst|$dst, $src}", []>, TB,
OpSize32, NotMemoryFoldable;
-// i16mem operand in LAR64rm and GR32 operand in LAR64rr is not a typo.
let mayLoad = 1 in
def LAR64rm : RI<0x02, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src),
"lar{q}\t{$src, $dst|$dst, $src}", []>, TB, NotMemoryFoldable;
-def LAR64rr : RI<0x02, MRMSrcReg, (outs GR64:$dst), (ins GR32:$src),
+def LAR64rr : RI<0x02, MRMSrcReg, (outs GR64:$dst), (ins GR16orGR32orGR64:$src),
"lar{q}\t{$src, $dst|$dst, $src}", []>, TB, NotMemoryFoldable;
-// i16mem operand in LSL32rm and GR32 operand in LSL32rr is not a typo.
let mayLoad = 1 in
def LSL16rm : I<0x03, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
"lsl{w}\t{$src, $dst|$dst, $src}", []>, TB,
OpSize16, NotMemoryFoldable;
-def LSL16rr : I<0x03, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
+def LSL16rr : I<0x03, MRMSrcReg, (outs GR16:$dst), (ins GR16orGR32orGR64:$src),
"lsl{w}\t{$src, $dst|$dst, $src}", []>, TB,
OpSize16, NotMemoryFoldable;
-// i16mem operand in LSL64rm and GR32 operand in LSL64rr is not a typo.
let mayLoad = 1 in
def LSL32rm : I<0x03, MRMSrcMem, (outs GR32:$dst), (ins i16mem:$src),
"lsl{l}\t{$src, $dst|$dst, $src}", []>, TB,
OpSize32, NotMemoryFoldable;
-def LSL32rr : I<0x03, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
+def LSL32rr : I<0x03, MRMSrcReg, (outs GR32:$dst), (ins GR16orGR32orGR64:$src),
"lsl{l}\t{$src, $dst|$dst, $src}", []>, TB,
OpSize32, NotMemoryFoldable;
let mayLoad = 1 in
def LSL64rm : RI<0x03, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src),
"lsl{q}\t{$src, $dst|$dst, $src}", []>, TB, NotMemoryFoldable;
-def LSL64rr : RI<0x03, MRMSrcReg, (outs GR64:$dst), (ins GR32:$src),
+def LSL64rr : RI<0x03, MRMSrcReg, (outs GR64:$dst), (ins GR16orGR32orGR64:$src),
"lsl{q}\t{$src, $dst|$dst, $src}", []>, TB, NotMemoryFoldable;
def INVLPG : I<0x01, MRM7m, (outs), (ins i8mem:$addr), "invlpg\t$addr", []>, TB;
diff --git a/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index d3c718a919c0..1304d46fdef4 100644
--- a/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1148,11 +1148,12 @@ static Value *foldAndOrOfICmpsWithConstEq(ICmpInst *Cmp0, ICmpInst *Cmp1,
assert((IsAnd || Logic.getOpcode() == Instruction::Or) && "Wrong logic op");
// Match an equality compare with a non-poison constant as Cmp0.
+ // Also, give up if the compare can be constant-folded to avoid looping.
ICmpInst::Predicate Pred0;
Value *X;
Constant *C;
if (!match(Cmp0, m_ICmp(Pred0, m_Value(X), m_Constant(C))) ||
- !isGuaranteedNotToBeUndefOrPoison(C))
+ !isGuaranteedNotToBeUndefOrPoison(C) || isa<Constant>(X))
return nullptr;
if ((IsAnd && Pred0 != ICmpInst::ICMP_EQ) ||
(!IsAnd && Pred0 != ICmpInst::ICMP_NE))
diff --git a/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index c734c9a68fb2..836af6234ad5 100644
--- a/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -4220,16 +4220,11 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
break;
case Intrinsic::assume: {
Value *IIOperand = II->getArgOperand(0);
- SmallVector<OperandBundleDef, 4> OpBundles;
- II->getOperandBundlesAsDefs(OpBundles);
- bool HasOpBundles = !OpBundles.empty();
// Remove an assume if it is followed by an identical assume.
// TODO: Do we need this? Unless there are conflicting assumptions, the
// computeKnownBits(IIOperand) below here eliminates redundant assumes.
Instruction *Next = II->getNextNonDebugInstruction();
- if (HasOpBundles &&
- match(Next, m_Intrinsic<Intrinsic::assume>(m_Specific(IIOperand))) &&
- !cast<IntrinsicInst>(Next)->hasOperandBundles())
+ if (match(Next, m_Intrinsic<Intrinsic::assume>(m_Specific(IIOperand))))
return eraseInstFromFunction(CI);
// Canonicalize assume(a && b) -> assume(a); assume(b);
@@ -4239,15 +4234,14 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
Value *AssumeIntrinsic = II->getCalledOperand();
Value *A, *B;
if (match(IIOperand, m_And(m_Value(A), m_Value(B)))) {
- Builder.CreateCall(AssumeIntrinsicTy, AssumeIntrinsic, A, OpBundles,
- II->getName());
+ Builder.CreateCall(AssumeIntrinsicTy, AssumeIntrinsic, A, II->getName());
Builder.CreateCall(AssumeIntrinsicTy, AssumeIntrinsic, B, II->getName());
return eraseInstFromFunction(*II);
}
// assume(!(a || b)) -> assume(!a); assume(!b);
if (match(IIOperand, m_Not(m_Or(m_Value(A), m_Value(B))))) {
Builder.CreateCall(AssumeIntrinsicTy, AssumeIntrinsic,
- Builder.CreateNot(A), OpBundles, II->getName());
+ Builder.CreateNot(A), II->getName());
Builder.CreateCall(AssumeIntrinsicTy, AssumeIntrinsic,
Builder.CreateNot(B), II->getName());
return eraseInstFromFunction(*II);
@@ -4263,8 +4257,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
isValidAssumeForContext(II, LHS, &DT)) {
MDNode *MD = MDNode::get(II->getContext(), None);
LHS->setMetadata(LLVMContext::MD_nonnull, MD);
- if (!HasOpBundles)
- return eraseInstFromFunction(*II);
+ return eraseInstFromFunction(*II);
// TODO: apply nonnull return attributes to calls and invokes
// TODO: apply range metadata for range check patterns?
diff --git a/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index f918dc7198ca..ca51f37af4d9 100644
--- a/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -653,7 +653,7 @@ public:
"New instruction already inserted into a basic block!");
BasicBlock *BB = Old.getParent();
BB->getInstList().insert(Old.getIterator(), New); // Insert inst
- Worklist.push(New);
+ Worklist.add(New);
return New;
}
diff --git a/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 17124f717af7..db27711f29b1 100644
--- a/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -2469,6 +2469,10 @@ static Instruction *foldSelectToPhiImpl(SelectInst &Sel, BasicBlock *BB,
} else
return nullptr;
+ // Make sure the branches are actually different.
+ if (TrueSucc == FalseSucc)
+ return nullptr;
+
// We want to replace select %cond, %a, %b with a phi that takes value %a
// for all incoming edges that are dominated by condition `%cond == true`,
// and value %b for edges dominated by condition `%cond == false`. If %a
diff --git a/contrib/llvm-project/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp b/contrib/llvm-project/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
index bccf94fc217f..5c008585869c 100644
--- a/contrib/llvm-project/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
+++ b/contrib/llvm-project/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
@@ -15,7 +15,6 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/IR/Instructions.h"
#include "llvm/InitializePasses.h"
#define AA_NAME "alignment-from-assumptions"
#define DEBUG_TYPE AA_NAME
@@ -204,33 +203,103 @@ static Align getNewAlignment(const SCEV *AASCEV, const SCEV *AlignSCEV,
}
bool AlignmentFromAssumptionsPass::extractAlignmentInfo(CallInst *I,
- unsigned Idx,
Value *&AAPtr,
const SCEV *&AlignSCEV,
const SCEV *&OffSCEV) {
- Type *Int64Ty = Type::getInt64Ty(I->getContext());
- OperandBundleUse AlignOB = I->getOperandBundleAt(Idx);
- if (AlignOB.getTagName() != "align")
+ // An alignment assume must be a statement about the least-significant
+ // bits of the pointer being zero, possibly with some offset.
+ ICmpInst *ICI = dyn_cast<ICmpInst>(I->getArgOperand(0));
+ if (!ICI)
return false;
- assert(AlignOB.Inputs.size() >= 2);
- AAPtr = AlignOB.Inputs[0].get();
- // TODO: Consider accumulating the offset to the base.
- AAPtr = AAPtr->stripPointerCastsSameRepresentation();
- AlignSCEV = SE->getSCEV(AlignOB.Inputs[1].get());
- AlignSCEV = SE->getTruncateOrZeroExtend(AlignSCEV, Int64Ty);
- if (AlignOB.Inputs.size() == 3)
- OffSCEV = SE->getSCEV(AlignOB.Inputs[2].get());
- else
+
+ // This must be an expression of the form: x & m == 0.
+ if (ICI->getPredicate() != ICmpInst::ICMP_EQ)
+ return false;
+
+ // Swap things around so that the RHS is 0.
+ Value *CmpLHS = ICI->getOperand(0);
+ Value *CmpRHS = ICI->getOperand(1);
+ const SCEV *CmpLHSSCEV = SE->getSCEV(CmpLHS);
+ const SCEV *CmpRHSSCEV = SE->getSCEV(CmpRHS);
+ if (CmpLHSSCEV->isZero())
+ std::swap(CmpLHS, CmpRHS);
+ else if (!CmpRHSSCEV->isZero())
+ return false;
+
+ BinaryOperator *CmpBO = dyn_cast<BinaryOperator>(CmpLHS);
+ if (!CmpBO || CmpBO->getOpcode() != Instruction::And)
+ return false;
+
+ // Swap things around so that the right operand of the and is a constant
+ // (the mask); we cannot deal with variable masks.
+ Value *AndLHS = CmpBO->getOperand(0);
+ Value *AndRHS = CmpBO->getOperand(1);
+ const SCEV *AndLHSSCEV = SE->getSCEV(AndLHS);
+ const SCEV *AndRHSSCEV = SE->getSCEV(AndRHS);
+ if (isa<SCEVConstant>(AndLHSSCEV)) {
+ std::swap(AndLHS, AndRHS);
+ std::swap(AndLHSSCEV, AndRHSSCEV);
+ }
+
+ const SCEVConstant *MaskSCEV = dyn_cast<SCEVConstant>(AndRHSSCEV);
+ if (!MaskSCEV)
+ return false;
+
+ // The mask must have some trailing ones (otherwise the condition is
+ // trivial and tells us nothing about the alignment of the left operand).
+ unsigned TrailingOnes = MaskSCEV->getAPInt().countTrailingOnes();
+ if (!TrailingOnes)
+ return false;
+
+ // Cap the alignment at the maximum with which LLVM can deal (and make sure
+ // we don't overflow the shift).
+ uint64_t Alignment;
+ TrailingOnes = std::min(TrailingOnes,
+ unsigned(sizeof(unsigned) * CHAR_BIT - 1));
+ Alignment = std::min(1u << TrailingOnes, +Value::MaximumAlignment);
+
+ Type *Int64Ty = Type::getInt64Ty(I->getParent()->getParent()->getContext());
+ AlignSCEV = SE->getConstant(Int64Ty, Alignment);
+
+ // The LHS might be a ptrtoint instruction, or it might be the pointer
+ // with an offset.
+ AAPtr = nullptr;
+ OffSCEV = nullptr;
+ if (PtrToIntInst *PToI = dyn_cast<PtrToIntInst>(AndLHS)) {
+ AAPtr = PToI->getPointerOperand();
OffSCEV = SE->getZero(Int64Ty);
- OffSCEV = SE->getTruncateOrZeroExtend(OffSCEV, Int64Ty);
+ } else if (const SCEVAddExpr* AndLHSAddSCEV =
+ dyn_cast<SCEVAddExpr>(AndLHSSCEV)) {
+ // Try to find the ptrtoint; subtract it and the rest is the offset.
+ for (SCEVAddExpr::op_iterator J = AndLHSAddSCEV->op_begin(),
+ JE = AndLHSAddSCEV->op_end(); J != JE; ++J)
+ if (const SCEVUnknown *OpUnk = dyn_cast<SCEVUnknown>(*J))
+ if (PtrToIntInst *PToI = dyn_cast<PtrToIntInst>(OpUnk->getValue())) {
+ AAPtr = PToI->getPointerOperand();
+ OffSCEV = SE->getMinusSCEV(AndLHSAddSCEV, *J);
+ break;
+ }
+ }
+
+ if (!AAPtr)
+ return false;
+
+ // Sign extend the offset to 64 bits (so that it is like all of the other
+ // expressions).
+ unsigned OffSCEVBits = OffSCEV->getType()->getPrimitiveSizeInBits();
+ if (OffSCEVBits < 64)
+ OffSCEV = SE->getSignExtendExpr(OffSCEV, Int64Ty);
+ else if (OffSCEVBits > 64)
+ return false;
+
+ AAPtr = AAPtr->stripPointerCasts();
return true;
}
-bool AlignmentFromAssumptionsPass::processAssumption(CallInst *ACall,
- unsigned Idx) {
+bool AlignmentFromAssumptionsPass::processAssumption(CallInst *ACall) {
Value *AAPtr;
const SCEV *AlignSCEV, *OffSCEV;
- if (!extractAlignmentInfo(ACall, Idx, AAPtr, AlignSCEV, OffSCEV))
+ if (!extractAlignmentInfo(ACall, AAPtr, AlignSCEV, OffSCEV))
return false;
// Skip ConstantPointerNull and UndefValue. Assumptions on these shouldn't
@@ -248,14 +317,13 @@ bool AlignmentFromAssumptionsPass::processAssumption(CallInst *ACall,
continue;
if (Instruction *K = dyn_cast<Instruction>(J))
+ if (isValidAssumeForContext(ACall, K, DT))
WorkList.push_back(K);
}
while (!WorkList.empty()) {
Instruction *J = WorkList.pop_back_val();
if (LoadInst *LI = dyn_cast<LoadInst>(J)) {
- if (!isValidAssumeForContext(ACall, J, DT))
- continue;
Align NewAlignment = getNewAlignment(AASCEV, AlignSCEV, OffSCEV,
LI->getPointerOperand(), SE);
if (NewAlignment > LI->getAlign()) {
@@ -263,8 +331,6 @@ bool AlignmentFromAssumptionsPass::processAssumption(CallInst *ACall,
++NumLoadAlignChanged;
}
} else if (StoreInst *SI = dyn_cast<StoreInst>(J)) {
- if (!isValidAssumeForContext(ACall, J, DT))
- continue;
Align NewAlignment = getNewAlignment(AASCEV, AlignSCEV, OffSCEV,
SI->getPointerOperand(), SE);
if (NewAlignment > SI->getAlign()) {
@@ -272,8 +338,6 @@ bool AlignmentFromAssumptionsPass::processAssumption(CallInst *ACall,
++NumStoreAlignChanged;
}
} else if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(J)) {
- if (!isValidAssumeForContext(ACall, J, DT))
- continue;
Align NewDestAlignment =
getNewAlignment(AASCEV, AlignSCEV, OffSCEV, MI->getDest(), SE);
@@ -305,7 +369,7 @@ bool AlignmentFromAssumptionsPass::processAssumption(CallInst *ACall,
Visited.insert(J);
for (User *UJ : J->users()) {
Instruction *K = cast<Instruction>(UJ);
- if (!Visited.count(K))
+ if (!Visited.count(K) && isValidAssumeForContext(ACall, K, DT))
WorkList.push_back(K);
}
}
@@ -332,11 +396,8 @@ bool AlignmentFromAssumptionsPass::runImpl(Function &F, AssumptionCache &AC,
bool Changed = false;
for (auto &AssumeVH : AC.assumptions())
- if (AssumeVH) {
- CallInst *Call = cast<CallInst>(AssumeVH);
- for (unsigned Idx = 0; Idx < Call->getNumOperandBundles(); Idx++)
- Changed |= processAssumption(Call, Idx);
- }
+ if (AssumeVH)
+ Changed |= processAssumption(cast<CallInst>(AssumeVH));
return Changed;
}
diff --git a/contrib/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.cpp b/contrib/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.cpp
index 84f6d5210d74..6a245b5eb425 100644
--- a/contrib/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.cpp
+++ b/contrib/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.cpp
@@ -874,6 +874,7 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
TYPE("i16imm", TYPE_IMM)
TYPE("i16i8imm", TYPE_IMM)
TYPE("GR16", TYPE_R16)
+ TYPE("GR16orGR32orGR64", TYPE_R16)
TYPE("i32mem", TYPE_M)
TYPE("i32imm", TYPE_IMM)
TYPE("i32i8imm", TYPE_IMM)
@@ -1035,6 +1036,7 @@ RecognizableInstr::rmRegisterEncodingFromString(const std::string &s,
ENCODING("RST", ENCODING_FP)
ENCODING("RSTi", ENCODING_FP)
ENCODING("GR16", ENCODING_RM)
+ ENCODING("GR16orGR32orGR64",ENCODING_RM)
ENCODING("GR32", ENCODING_RM)
ENCODING("GR32orGR64", ENCODING_RM)
ENCODING("GR64", ENCODING_RM)
@@ -1072,6 +1074,7 @@ OperandEncoding
RecognizableInstr::roRegisterEncodingFromString(const std::string &s,
uint8_t OpSize) {
ENCODING("GR16", ENCODING_REG)
+ ENCODING("GR16orGR32orGR64",ENCODING_REG)
ENCODING("GR32", ENCODING_REG)
ENCODING("GR32orGR64", ENCODING_REG)
ENCODING("GR64", ENCODING_REG)