aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-09-15 18:55:37 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-09-15 18:55:37 +0000
commite588341d487d7ec86b5282968e3223f8c0e6de27 (patch)
treefaa3fbdcd0e38085bd03d4960bc7ccbe4adf4a38
parentbdc6feb28f528ee3a365ca97577f7312ffa0dc65 (diff)
downloadsrc-e588341d487d7ec86b5282968e3223f8c0e6de27.tar.gz
src-e588341d487d7ec86b5282968e3223f8c0e6de27.zip
Vendor import of llvm-project branch release/11.xvendor/llvm-project/llvmorg-11.0.0-rc2-91-g6e042866c30
llvmorg-11.0.0-rc2-91-g6e042866c30.
Notes
Notes: svn path=/vendor/llvm-project/release-11.x/; revision=365757 svn path=/vendor/llvm-project/llvmorg-11.0.0-rc2-91-g6e042866c30/; revision=365758; tag=vendor/llvm-project/llvmorg-11.0.0-rc2-91-g6e042866c30
-rw-r--r--clang/include/clang/AST/ASTContext.h16
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td7
-rw-r--r--clang/lib/AST/ASTContext.cpp113
-rw-r--r--clang/lib/AST/DeclBase.cpp7
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp2
-rw-r--r--clang/lib/Basic/Targets.cpp4
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp46
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.cpp214
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.h12
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp61
-rw-r--r--clang/lib/CodeGen/CodeGenTypes.cpp51
-rw-r--r--clang/lib/Driver/ToolChains/Arch/Sparc.cpp9
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp16
-rw-r--r--clang/lib/Driver/ToolChains/OpenBSD.cpp67
-rw-r--r--clang/lib/Driver/ToolChains/OpenBSD.h16
-rw-r--r--clang/lib/Format/TokenAnnotator.cpp20
-rw-r--r--clang/lib/Frontend/InitHeaderSearch.cpp2
-rw-r--r--clang/lib/Headers/altivec.h178
-rw-r--r--clang/lib/Sema/SemaChecking.cpp5
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp7
-rw-r--r--clang/lib/Sema/SemaType.cpp5
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp2
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp138
-rw-r--r--clang/lib/StaticAnalyzer/Core/DynamicType.cpp13
-rw-r--r--compiler-rt/lib/builtins/clear_cache.c4
-rw-r--r--compiler-rt/lib/builtins/cpu_model.c2
-rw-r--r--compiler-rt/lib/profile/GCDAProfiling.c19
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h6
-rw-r--r--libunwind/src/AddressSpace.hpp7
-rw-r--r--lld/COFF/Writer.cpp3
-rw-r--r--lld/ELF/DWARF.cpp22
-rw-r--r--lld/ELF/DWARF.h4
-rw-r--r--lld/ELF/LinkerScript.cpp13
-rw-r--r--lld/ELF/LinkerScript.h4
-rw-r--r--lld/ELF/OutputSections.cpp6
-rw-r--r--lld/ELF/SyntheticSections.cpp50
-rw-r--r--lld/docs/ELF/linker_script.rst19
-rw-r--r--lld/docs/ReleaseNotes.rst133
-rw-r--r--lldb/source/Target/Target.cpp31
-rw-r--r--llvm/include/llvm/ADT/CoalescingBitVector.h7
-rw-r--r--llvm/include/llvm/Analysis/InstructionSimplify.h6
-rw-r--r--llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h11
-rw-r--r--llvm/include/llvm/IR/IRBuilder.h14
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp87
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp13
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp6
-rw-r--r--llvm/lib/CodeGen/MachineCopyPropagation.cpp4
-rw-r--r--llvm/lib/CodeGen/RegAllocFast.cpp217
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/FastISel.cpp6
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp4
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp29
-rw-r--r--llvm/lib/CodeGen/TargetLoweringBase.cpp5
-rw-r--r--llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp62
-rw-r--r--llvm/lib/IR/IRBuilder.cpp13
-rw-r--r--llvm/lib/IR/LegacyPassManager.cpp87
-rw-r--r--llvm/lib/Support/X86TargetParser.cpp2
-rw-r--r--llvm/lib/Target/AArch64/AArch64FrameLowering.cpp7
-rw-r--r--llvm/lib/Target/AArch64/SVEInstrFormats.td2
-rw-r--r--llvm/lib/Target/AMDGPU/SIFoldOperands.cpp44
-rw-r--r--llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp13
-rw-r--r--llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h3
-rw-r--r--llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp15
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.cpp13
-rw-r--r--llvm/lib/Target/PowerPC/PPCInstr64Bit.td4
-rw-r--r--llvm/lib/Target/PowerPC/PPCMIPeephole.cpp2
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp4
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp55
67 files changed, 1294 insertions, 775 deletions
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 2b988be60da9..9020e6629d08 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -60,6 +60,7 @@
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/TypeSize.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
@@ -1297,6 +1298,21 @@ public:
/// Returns a vla type where known sizes are replaced with [*].
QualType getVariableArrayDecayedType(QualType Ty) const;
+ // Convenience struct to return information about a builtin vector type.
+ struct BuiltinVectorTypeInfo {
+ QualType ElementType;
+ llvm::ElementCount EC;
+ unsigned NumVectors;
+ BuiltinVectorTypeInfo(QualType ElementType, llvm::ElementCount EC,
+ unsigned NumVectors)
+ : ElementType(ElementType), EC(EC), NumVectors(NumVectors) {}
+ };
+
+ /// Returns the element type, element count and number of vectors
+ /// (in case of tuple) for a builtin vector type.
+ BuiltinVectorTypeInfo
+ getBuiltinVectorTypeInfo(const BuiltinType *VecTy) const;
+
/// Return the unique reference to a scalable vector type of the specified
/// element type and scalable number of elements.
///
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index aa4de2812312..941f2cafc372 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6021,9 +6021,8 @@ def err_func_def_incomplete_result : Error<
def err_atomic_specifier_bad_type
: Error<"_Atomic cannot be applied to "
"%select{incomplete |array |function |reference |atomic |qualified "
- "|sizeless ||integer |integer }0type "
- "%1 %select{|||||||which is not trivially copyable|with less than "
- "1 byte of precision|with a non power of 2 precision}0">;
+ "|sizeless ||integer }0type "
+ "%1 %select{|||||||which is not trivially copyable|}0">;
// Expressions.
def ext_sizeof_alignof_function_type : Extension<
@@ -7941,6 +7940,8 @@ def err_atomic_exclusive_builtin_pointer_size : Error<
" 1,2,4 or 8 byte type (%0 invalid)">;
def err_atomic_builtin_ext_int_size : Error<
"Atomic memory operand must have a power-of-two size">;
+def err_atomic_builtin_ext_int_prohibit : Error<
+ "argument to atomic builtin of type '_ExtInt' is not supported">;
def err_atomic_op_needs_atomic : Error<
"address argument to atomic operation must be a pointer to _Atomic "
"type (%0 invalid)">;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index e3798bb46e86..bf51d35d9693 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3634,6 +3634,119 @@ QualType ASTContext::getIncompleteArrayType(QualType elementType,
return QualType(newType, 0);
}
+ASTContext::BuiltinVectorTypeInfo
+ASTContext::getBuiltinVectorTypeInfo(const BuiltinType *Ty) const {
+#define SVE_INT_ELTTY(BITS, ELTS, SIGNED, NUMVECTORS) \
+ {getIntTypeForBitwidth(BITS, SIGNED), llvm::ElementCount(ELTS, true), \
+ NUMVECTORS};
+
+#define SVE_ELTTY(ELTTY, ELTS, NUMVECTORS) \
+ {ELTTY, llvm::ElementCount(ELTS, true), NUMVECTORS};
+
+ switch (Ty->getKind()) {
+ default:
+ llvm_unreachable("Unsupported builtin vector type");
+ case BuiltinType::SveInt8:
+ return SVE_INT_ELTTY(8, 16, true, 1);
+ case BuiltinType::SveUint8:
+ return SVE_INT_ELTTY(8, 16, false, 1);
+ case BuiltinType::SveInt8x2:
+ return SVE_INT_ELTTY(8, 16, true, 2);
+ case BuiltinType::SveUint8x2:
+ return SVE_INT_ELTTY(8, 16, false, 2);
+ case BuiltinType::SveInt8x3:
+ return SVE_INT_ELTTY(8, 16, true, 3);
+ case BuiltinType::SveUint8x3:
+ return SVE_INT_ELTTY(8, 16, false, 3);
+ case BuiltinType::SveInt8x4:
+ return SVE_INT_ELTTY(8, 16, true, 4);
+ case BuiltinType::SveUint8x4:
+ return SVE_INT_ELTTY(8, 16, false, 4);
+ case BuiltinType::SveInt16:
+ return SVE_INT_ELTTY(16, 8, true, 1);
+ case BuiltinType::SveUint16:
+ return SVE_INT_ELTTY(16, 8, false, 1);
+ case BuiltinType::SveInt16x2:
+ return SVE_INT_ELTTY(16, 8, true, 2);
+ case BuiltinType::SveUint16x2:
+ return SVE_INT_ELTTY(16, 8, false, 2);
+ case BuiltinType::SveInt16x3:
+ return SVE_INT_ELTTY(16, 8, true, 3);
+ case BuiltinType::SveUint16x3:
+ return SVE_INT_ELTTY(16, 8, false, 3);
+ case BuiltinType::SveInt16x4:
+ return SVE_INT_ELTTY(16, 8, true, 4);
+ case BuiltinType::SveUint16x4:
+ return SVE_INT_ELTTY(16, 8, false, 4);
+ case BuiltinType::SveInt32:
+ return SVE_INT_ELTTY(32, 4, true, 1);
+ case BuiltinType::SveUint32:
+ return SVE_INT_ELTTY(32, 4, false, 1);
+ case BuiltinType::SveInt32x2:
+ return SVE_INT_ELTTY(32, 4, true, 2);
+ case BuiltinType::SveUint32x2:
+ return SVE_INT_ELTTY(32, 4, false, 2);
+ case BuiltinType::SveInt32x3:
+ return SVE_INT_ELTTY(32, 4, true, 3);
+ case BuiltinType::SveUint32x3:
+ return SVE_INT_ELTTY(32, 4, false, 3);
+ case BuiltinType::SveInt32x4:
+ return SVE_INT_ELTTY(32, 4, true, 4);
+ case BuiltinType::SveUint32x4:
+ return SVE_INT_ELTTY(32, 4, false, 4);
+ case BuiltinType::SveInt64:
+ return SVE_INT_ELTTY(64, 2, true, 1);
+ case BuiltinType::SveUint64:
+ return SVE_INT_ELTTY(64, 2, false, 1);
+ case BuiltinType::SveInt64x2:
+ return SVE_INT_ELTTY(64, 2, true, 2);
+ case BuiltinType::SveUint64x2:
+ return SVE_INT_ELTTY(64, 2, false, 2);
+ case BuiltinType::SveInt64x3:
+ return SVE_INT_ELTTY(64, 2, true, 3);
+ case BuiltinType::SveUint64x3:
+ return SVE_INT_ELTTY(64, 2, false, 3);
+ case BuiltinType::SveInt64x4:
+ return SVE_INT_ELTTY(64, 2, true, 4);
+ case BuiltinType::SveUint64x4:
+ return SVE_INT_ELTTY(64, 2, false, 4);
+ case BuiltinType::SveBool:
+ return SVE_ELTTY(BoolTy, 16, 1);
+ case BuiltinType::SveFloat16:
+ return SVE_ELTTY(HalfTy, 8, 1);
+ case BuiltinType::SveFloat16x2:
+ return SVE_ELTTY(HalfTy, 8, 2);
+ case BuiltinType::SveFloat16x3:
+ return SVE_ELTTY(HalfTy, 8, 3);
+ case BuiltinType::SveFloat16x4:
+ return SVE_ELTTY(HalfTy, 8, 4);
+ case BuiltinType::SveFloat32:
+ return SVE_ELTTY(FloatTy, 4, 1);
+ case BuiltinType::SveFloat32x2:
+ return SVE_ELTTY(FloatTy, 4, 2);
+ case BuiltinType::SveFloat32x3:
+ return SVE_ELTTY(FloatTy, 4, 3);
+ case BuiltinType::SveFloat32x4:
+ return SVE_ELTTY(FloatTy, 4, 4);
+ case BuiltinType::SveFloat64:
+ return SVE_ELTTY(DoubleTy, 2, 1);
+ case BuiltinType::SveFloat64x2:
+ return SVE_ELTTY(DoubleTy, 2, 2);
+ case BuiltinType::SveFloat64x3:
+ return SVE_ELTTY(DoubleTy, 2, 3);
+ case BuiltinType::SveFloat64x4:
+ return SVE_ELTTY(DoubleTy, 2, 4);
+ case BuiltinType::SveBFloat16:
+ return SVE_ELTTY(BFloat16Ty, 8, 1);
+ case BuiltinType::SveBFloat16x2:
+ return SVE_ELTTY(BFloat16Ty, 8, 2);
+ case BuiltinType::SveBFloat16x3:
+ return SVE_ELTTY(BFloat16Ty, 8, 3);
+ case BuiltinType::SveBFloat16x4:
+ return SVE_ELTTY(BFloat16Ty, 8, 4);
+ }
+}
+
/// getScalableVectorType - Return the unique reference to a scalable vector
/// type of the specified element type and size. VectorType must be a built-in
/// type.
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index da1eadd9d931..f4314d0bd961 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -1487,6 +1487,13 @@ static bool shouldBeHidden(NamedDecl *D) {
if (FD->isFunctionTemplateSpecialization())
return true;
+ // Hide destructors that are invalid. There should always be one destructor,
+ // but if it is an invalid decl, another one is created. We need to hide the
+ // invalid one from places that expect exactly one destructor, like the
+ // serialization code.
+ if (isa<CXXDestructorDecl>(D) && D->isInvalidDecl())
+ return true;
+
return false;
}
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index ddfbe9f86499..8b1419074df5 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3248,7 +3248,7 @@ static StringRef mangleAArch64VectorBase(const BuiltinType *EltType) {
case BuiltinType::Double:
return "Float64";
case BuiltinType::BFloat16:
- return "BFloat16";
+ return "Bfloat16";
default:
llvm_unreachable("Unexpected vector element base type");
}
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 818133f66f3f..965f273892bd 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -409,8 +409,6 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
return new SolarisTargetInfo<SparcV8TargetInfo>(Triple, Opts);
case llvm::Triple::NetBSD:
return new NetBSDTargetInfo<SparcV8TargetInfo>(Triple, Opts);
- case llvm::Triple::OpenBSD:
- return new OpenBSDTargetInfo<SparcV8TargetInfo>(Triple, Opts);
case llvm::Triple::RTEMS:
return new RTEMSTargetInfo<SparcV8TargetInfo>(Triple, Opts);
default:
@@ -424,8 +422,6 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
return new LinuxTargetInfo<SparcV8elTargetInfo>(Triple, Opts);
case llvm::Triple::NetBSD:
return new NetBSDTargetInfo<SparcV8elTargetInfo>(Triple, Opts);
- case llvm::Triple::OpenBSD:
- return new OpenBSDTargetInfo<SparcV8elTargetInfo>(Triple, Opts);
case llvm::Triple::RTEMS:
return new RTEMSTargetInfo<SparcV8elTargetInfo>(Triple, Opts);
default:
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 6965c4a1209c..703f5087370a 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -719,23 +719,39 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
case BuiltinType::Id: \
return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty);
#include "clang/Basic/OpenCLExtensionTypes.def"
- // TODO: real support for SVE types requires more infrastructure
- // to be added first. The types have a variable length and are
- // represented in debug info as types whose length depends on a
- // target-specific pseudo register.
-#define SVE_TYPE(Name, Id, SingletonId) \
- case BuiltinType::Id:
+
+#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/AArch64SVEACLETypes.def"
- {
- unsigned DiagID = CGM.getDiags().getCustomDiagID(
- DiagnosticsEngine::Error,
- "cannot yet generate debug info for SVE type '%0'");
- auto Name = BT->getName(CGM.getContext().getPrintingPolicy());
- CGM.getDiags().Report(DiagID) << Name;
- // Return something safe.
- return CreateType(cast<const BuiltinType>(CGM.getContext().IntTy));
- }
+ {
+ ASTContext::BuiltinVectorTypeInfo Info =
+ CGM.getContext().getBuiltinVectorTypeInfo(BT);
+ unsigned NumElemsPerVG = (Info.EC.Min * Info.NumVectors) / 2;
+
+ // Debuggers can't extract 1bit from a vector, so will display a
+ // bitpattern for svbool_t instead.
+ if (Info.ElementType == CGM.getContext().BoolTy) {
+ NumElemsPerVG /= 8;
+ Info.ElementType = CGM.getContext().UnsignedCharTy;
+ }
+ auto *LowerBound =
+ llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
+ llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
+ SmallVector<int64_t, 9> Expr(
+ {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
+ /* AArch64::VG */ 46, 0, llvm::dwarf::DW_OP_mul,
+ llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
+ auto *UpperBound = DBuilder.createExpression(Expr);
+
+ llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(
+ /*count*/ nullptr, LowerBound, UpperBound, /*stride*/ nullptr);
+ llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
+ llvm::DIType *ElemTy =
+ getOrCreateType(Info.ElementType, TheCU->getFile());
+ auto Align = getTypeAlignIfRequired(BT, CGM.getContext());
+ return DBuilder.createVectorType(/*Size*/ 0, Align, ElemTy,
+ SubscriptArray);
+ }
case BuiltinType::UChar:
case BuiltinType::Char_U:
Encoding = llvm::dwarf::DW_ATE_unsigned_char;
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index a7e1fe8560b6..14e0cba62b23 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -29,7 +29,6 @@
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Bitcode/BitcodeReader.h"
-#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/GlobalValue.h"
@@ -1064,23 +1063,6 @@ CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM, StringRef FirstSeparator,
StringRef Separator)
: CGM(CGM), FirstSeparator(FirstSeparator), Separator(Separator),
OMPBuilder(CGM.getModule()), OffloadEntriesInfoManager(CGM) {
- ASTContext &C = CGM.getContext();
- RecordDecl *RD = C.buildImplicitRecord("ident_t");
- QualType KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
- RD->startDefinition();
- // reserved_1
- addFieldToRecordDecl(C, RD, KmpInt32Ty);
- // flags
- addFieldToRecordDecl(C, RD, KmpInt32Ty);
- // reserved_2
- addFieldToRecordDecl(C, RD, KmpInt32Ty);
- // reserved_3
- addFieldToRecordDecl(C, RD, KmpInt32Ty);
- // psource
- addFieldToRecordDecl(C, RD, C.VoidPtrTy);
- RD->completeDefinition();
- IdentQTy = C.getRecordType(RD);
- IdentTy = CGM.getTypes().ConvertRecordDeclType(RD);
KmpCriticalNameTy = llvm::ArrayType::get(CGM.Int32Ty, /*NumElements*/ 8);
// Initialize Types used in OpenMPIRBuilder from OMPKinds.def
@@ -1397,39 +1379,6 @@ createConstantGlobalStructAndAddToParent(CodeGenModule &CGM, QualType Ty,
Fields.finishAndAddTo(Parent);
}
-Address CGOpenMPRuntime::getOrCreateDefaultLocation(unsigned Flags) {
- CharUnits Align = CGM.getContext().getTypeAlignInChars(IdentQTy);
- unsigned Reserved2Flags = getDefaultLocationReserved2Flags();
- FlagsTy FlagsKey(Flags, Reserved2Flags);
- llvm::Value *Entry = OpenMPDefaultLocMap.lookup(FlagsKey);
- if (!Entry) {
- if (!DefaultOpenMPPSource) {
- // Initialize default location for psource field of ident_t structure of
- // all ident_t objects. Format is ";file;function;line;column;;".
- // Taken from
- // https://github.com/llvm/llvm-project/blob/master/openmp/runtime/src/kmp_str.cpp
- DefaultOpenMPPSource =
- CGM.GetAddrOfConstantCString(";unknown;unknown;0;0;;").getPointer();
- DefaultOpenMPPSource =
- llvm::ConstantExpr::getBitCast(DefaultOpenMPPSource, CGM.Int8PtrTy);
- }
-
- llvm::Constant *Data[] = {
- llvm::ConstantInt::getNullValue(CGM.Int32Ty),
- llvm::ConstantInt::get(CGM.Int32Ty, Flags),
- llvm::ConstantInt::get(CGM.Int32Ty, Reserved2Flags),
- llvm::ConstantInt::getNullValue(CGM.Int32Ty), DefaultOpenMPPSource};
- llvm::GlobalValue *DefaultOpenMPLocation =
- createGlobalStruct(CGM, IdentQTy, isDefaultLocationConstant(), Data, "",
- llvm::GlobalValue::PrivateLinkage);
- DefaultOpenMPLocation->setUnnamedAddr(
- llvm::GlobalValue::UnnamedAddr::Global);
-
- OpenMPDefaultLocMap[FlagsKey] = Entry = DefaultOpenMPLocation;
- }
- return Address(Entry, Align);
-}
-
void CGOpenMPRuntime::setLocThreadIdInsertPt(CodeGenFunction &CGF,
bool AtCurrentPoint) {
auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
@@ -1458,62 +1407,24 @@ void CGOpenMPRuntime::clearLocThreadIdInsertPt(CodeGenFunction &CGF) {
llvm::Value *CGOpenMPRuntime::emitUpdateLocation(CodeGenFunction &CGF,
SourceLocation Loc,
unsigned Flags) {
- Flags |= OMP_IDENT_KMPC;
- // If no debug info is generated - return global default location.
+ llvm::Constant *SrcLocStr;
if (CGM.getCodeGenOpts().getDebugInfo() == codegenoptions::NoDebugInfo ||
- Loc.isInvalid())
- return getOrCreateDefaultLocation(Flags).getPointer();
-
- assert(CGF.CurFn && "No function in current CodeGenFunction.");
-
- CharUnits Align = CGM.getContext().getTypeAlignInChars(IdentQTy);
- Address LocValue = Address::invalid();
- auto I = OpenMPLocThreadIDMap.find(CGF.CurFn);
- if (I != OpenMPLocThreadIDMap.end())
- LocValue = Address(I->second.DebugLoc, Align);
-
- // OpenMPLocThreadIDMap may have null DebugLoc and non-null ThreadID, if
- // GetOpenMPThreadID was called before this routine.
- if (!LocValue.isValid()) {
- // Generate "ident_t .kmpc_loc.addr;"
- Address AI = CGF.CreateMemTemp(IdentQTy, ".kmpc_loc.addr");
- auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
- Elem.second.DebugLoc = AI.getPointer();
- LocValue = AI;
-
- if (!Elem.second.ServiceInsertPt)
- setLocThreadIdInsertPt(CGF);
- CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
- CGF.Builder.SetInsertPoint(Elem.second.ServiceInsertPt);
- CGF.Builder.CreateMemCpy(LocValue, getOrCreateDefaultLocation(Flags),
- CGF.getTypeSize(IdentQTy));
- }
-
- // char **psource = &.kmpc_loc_<flags>.addr.psource;
- LValue Base = CGF.MakeAddrLValue(LocValue, IdentQTy);
- auto Fields = cast<RecordDecl>(IdentQTy->getAsTagDecl())->field_begin();
- LValue PSource =
- CGF.EmitLValueForField(Base, *std::next(Fields, IdentField_PSource));
-
- llvm::Value *OMPDebugLoc = OpenMPDebugLocMap.lookup(Loc.getRawEncoding());
- if (OMPDebugLoc == nullptr) {
- SmallString<128> Buffer2;
- llvm::raw_svector_ostream OS2(Buffer2);
- // Build debug location
- PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc);
- OS2 << ";" << PLoc.getFilename() << ";";
+ Loc.isInvalid()) {
+ SrcLocStr = OMPBuilder.getOrCreateDefaultSrcLocStr();
+ } else {
+ std::string FunctionName = "";
if (const auto *FD = dyn_cast_or_null<FunctionDecl>(CGF.CurFuncDecl))
- OS2 << FD->getQualifiedNameAsString();
- OS2 << ";" << PLoc.getLine() << ";" << PLoc.getColumn() << ";;";
- OMPDebugLoc = CGF.Builder.CreateGlobalStringPtr(OS2.str());
- OpenMPDebugLocMap[Loc.getRawEncoding()] = OMPDebugLoc;
+ FunctionName = FD->getQualifiedNameAsString();
+ PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc);
+ const char *FileName = PLoc.getFilename();
+ unsigned Line = PLoc.getLine();
+ unsigned Column = PLoc.getColumn();
+ SrcLocStr = OMPBuilder.getOrCreateSrcLocStr(FunctionName.c_str(), FileName,
+ Line, Column);
}
- // *psource = ";<File>;<Function>;<Line>;<Column>;;";
- CGF.EmitStoreOfScalar(OMPDebugLoc, PSource);
-
- // Our callers always pass this to a runtime function, so for
- // convenience, go ahead and return a naked pointer.
- return LocValue.getPointer();
+ unsigned Reserved2Flags = getDefaultLocationReserved2Flags();
+ return OMPBuilder.getOrCreateIdent(SrcLocStr, llvm::omp::IdentFlag(Flags),
+ Reserved2Flags);
}
llvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF,
@@ -1595,7 +1506,7 @@ void CGOpenMPRuntime::functionFinished(CodeGenFunction &CGF) {
}
llvm::Type *CGOpenMPRuntime::getIdentTyPointerTy() {
- return IdentTy->getPointerTo();
+ return OMPBuilder.IdentPtr;
}
llvm::Type *CGOpenMPRuntime::getKmpc_MicroPointerTy() {
@@ -7354,6 +7265,8 @@ private:
// &p, &p, sizeof(float*), TARGET_PARAM | TO | FROM
//
// map(p[1:24])
+ // &p, &p[1], 24*sizeof(float), TARGET_PARAM | TO | FROM | PTR_AND_OBJ
+ // in unified shared memory mode or for local pointers
// p, &p[1], 24*sizeof(float), TARGET_PARAM | TO | FROM
//
// map(s)
@@ -7489,6 +7402,7 @@ private:
// Track if the map information being generated is the first for a list of
// components.
bool IsExpressionFirstInfo = true;
+ bool FirstPointerInComplexData = false;
Address BP = Address::invalid();
const Expr *AssocExpr = I->getAssociatedExpression();
const auto *AE = dyn_cast<ArraySubscriptExpr>(AssocExpr);
@@ -7531,10 +7445,15 @@ private:
QualType Ty =
I->getAssociatedDeclaration()->getType().getNonReferenceType();
if (Ty->isAnyPointerType() && std::next(I) != CE) {
- BP = CGF.EmitLoadOfPointer(BP, Ty->castAs<PointerType>());
-
- // We do not need to generate individual map information for the
- // pointer, it can be associated with the combined storage.
+ // No need to generate individual map information for the pointer, it
+ // can be associated with the combined storage if shared memory mode is
+ // active or the base declaration is not global variable.
+ const auto *VD = dyn_cast<VarDecl>(I->getAssociatedDeclaration());
+ if (CGF.CGM.getOpenMPRuntime().hasRequiresUnifiedSharedMemory() ||
+ !VD || VD->hasLocalStorage())
+ BP = CGF.EmitLoadOfPointer(BP, Ty->castAs<PointerType>());
+ else
+ FirstPointerInComplexData = IsCaptureFirstInfo;
++I;
}
}
@@ -7570,8 +7489,19 @@ private:
EncounteredME = dyn_cast<MemberExpr>(I->getAssociatedExpression());
// If we encounter a PTR_AND_OBJ entry from now on it should be marked
// as MEMBER_OF the parent struct.
- if (EncounteredME)
+ if (EncounteredME) {
ShouldBeMemberOf = true;
+ // Do not emit as complex pointer if this is actually not array-like
+ // expression.
+ if (FirstPointerInComplexData) {
+ QualType Ty = std::prev(I)
+ ->getAssociatedDeclaration()
+ ->getType()
+ .getNonReferenceType();
+ BP = CGF.EmitLoadOfPointer(BP, Ty->castAs<PointerType>());
+ FirstPointerInComplexData = false;
+ }
+ }
}
auto Next = std::next(I);
@@ -7704,10 +7634,11 @@ private:
// same expression except for the first one. We also need to signal
// this map is the first one that relates with the current capture
// (there is a set of entries for each capture).
- OpenMPOffloadMappingFlags Flags = getMapTypeBits(
- MapType, MapModifiers, IsImplicit,
- !IsExpressionFirstInfo || RequiresReference,
- IsCaptureFirstInfo && !RequiresReference);
+ OpenMPOffloadMappingFlags Flags =
+ getMapTypeBits(MapType, MapModifiers, IsImplicit,
+ !IsExpressionFirstInfo || RequiresReference ||
+ FirstPointerInComplexData,
+ IsCaptureFirstInfo && !RequiresReference);
if (!IsExpressionFirstInfo) {
// If we have a PTR_AND_OBJ pair where the OBJ is a pointer as well,
@@ -7765,6 +7696,7 @@ private:
IsExpressionFirstInfo = false;
IsCaptureFirstInfo = false;
+ FirstPointerInComplexData = false;
}
}
}
@@ -7995,6 +7927,10 @@ public:
// emission of that entry until the whole struct has been processed.
llvm::MapVector<const ValueDecl *, SmallVector<DeferredDevicePtrEntryTy, 4>>
DeferredInfo;
+ MapBaseValuesArrayTy UseDevicePtrBasePointers;
+ MapValuesArrayTy UseDevicePtrPointers;
+ MapValuesArrayTy UseDevicePtrSizes;
+ MapFlagsArrayTy UseDevicePtrTypes;
for (const auto *C :
CurExecDir->getClausesOfKind<OMPUseDevicePtrClause>()) {
@@ -8011,15 +7947,27 @@ public:
// We potentially have map information for this declaration already.
// Look for the first set of components that refer to it.
if (It != Info.end()) {
- auto CI = std::find_if(
- It->second.begin(), It->second.end(), [VD](const MapInfo &MI) {
- return MI.Components.back().getAssociatedDeclaration() == VD;
- });
+ auto *CI = llvm::find_if(It->second, [VD](const MapInfo &MI) {
+ return MI.Components.back().getAssociatedDeclaration() == VD;
+ });
// If we found a map entry, signal that the pointer has to be returned
// and move on to the next declaration.
+ // Exclude cases where the base pointer is mapped as array subscript,
+ // array section or array shaping. The base address is passed as a
+ // pointer to base in this case and cannot be used as a base for
+ // use_device_ptr list item.
if (CI != It->second.end()) {
- CI->ReturnDevicePointer = true;
- continue;
+ auto PrevCI = std::next(CI->Components.rbegin());
+ const auto *VarD = dyn_cast<VarDecl>(VD);
+ if (CGF.CGM.getOpenMPRuntime().hasRequiresUnifiedSharedMemory() ||
+ isa<MemberExpr>(IE) ||
+ !VD->getType().getNonReferenceType()->isPointerType() ||
+ PrevCI == CI->Components.rend() ||
+ isa<MemberExpr>(PrevCI->getAssociatedExpression()) || !VarD ||
+ VarD->hasLocalStorage()) {
+ CI->ReturnDevicePointer = true;
+ continue;
+ }
}
}
@@ -8040,10 +7988,12 @@ public:
} else {
llvm::Value *Ptr =
CGF.EmitLoadOfScalar(CGF.EmitLValue(IE), IE->getExprLoc());
- BasePointers.emplace_back(Ptr, VD);
- Pointers.push_back(Ptr);
- Sizes.push_back(llvm::Constant::getNullValue(CGF.Int64Ty));
- Types.push_back(OMP_MAP_RETURN_PARAM | OMP_MAP_TARGET_PARAM);
+ UseDevicePtrBasePointers.emplace_back(Ptr, VD);
+ UseDevicePtrPointers.push_back(Ptr);
+ UseDevicePtrSizes.push_back(
+ llvm::Constant::getNullValue(CGF.Int64Ty));
+ UseDevicePtrTypes.push_back(OMP_MAP_RETURN_PARAM |
+ OMP_MAP_TARGET_PARAM);
}
}
}
@@ -8104,10 +8054,12 @@ public:
Ptr = CGF.EmitLValue(IE).getPointer(CGF);
else
Ptr = CGF.EmitScalarExpr(IE);
- BasePointers.emplace_back(Ptr, VD);
- Pointers.push_back(Ptr);
- Sizes.push_back(llvm::Constant::getNullValue(CGF.Int64Ty));
- Types.push_back(OMP_MAP_RETURN_PARAM | OMP_MAP_TARGET_PARAM);
+ UseDevicePtrBasePointers.emplace_back(Ptr, VD);
+ UseDevicePtrPointers.push_back(Ptr);
+ UseDevicePtrSizes.push_back(
+ llvm::Constant::getNullValue(CGF.Int64Ty));
+ UseDevicePtrTypes.push_back(OMP_MAP_RETURN_PARAM |
+ OMP_MAP_TARGET_PARAM);
}
}
}
@@ -8197,6 +8149,12 @@ public:
Sizes.append(CurSizes.begin(), CurSizes.end());
Types.append(CurTypes.begin(), CurTypes.end());
}
+ // Append data for use_device_ptr clauses.
+ BasePointers.append(UseDevicePtrBasePointers.begin(),
+ UseDevicePtrBasePointers.end());
+ Pointers.append(UseDevicePtrPointers.begin(), UseDevicePtrPointers.end());
+ Sizes.append(UseDevicePtrSizes.begin(), UseDevicePtrSizes.end());
+ Types.append(UseDevicePtrTypes.begin(), UseDevicePtrTypes.end());
}
/// Generate all the base pointers, section pointers, sizes and map types for
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h
index eb22f155f5ef..cf3dbf59634d 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.h
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.h
@@ -374,17 +374,7 @@ protected:
private:
/// An OpenMP-IR-Builder instance.
llvm::OpenMPIRBuilder OMPBuilder;
- /// Default const ident_t object used for initialization of all other
- /// ident_t objects.
- llvm::Constant *DefaultOpenMPPSource = nullptr;
- using FlagsTy = std::pair<unsigned, unsigned>;
- /// Map of flags and corresponding default locations.
- using OpenMPDefaultLocMapTy = llvm::DenseMap<FlagsTy, llvm::Value *>;
- OpenMPDefaultLocMapTy OpenMPDefaultLocMap;
- Address getOrCreateDefaultLocation(unsigned Flags);
-
- QualType IdentQTy;
- llvm::StructType *IdentTy = nullptr;
+
/// Map for SourceLocation and OpenMP runtime library debug locations.
typedef llvm::DenseMap<unsigned, llvm::Value *> OpenMPDebugLocMapTy;
OpenMPDebugLocMapTy OpenMPDebugLocMap;
diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
index 1f79b33772f3..de78926755df 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
@@ -2857,8 +2857,12 @@ static llvm::Value *castValueToType(CodeGenFunction &CGF, llvm::Value *Val,
Address CastItem = CGF.CreateMemTemp(CastTy);
Address ValCastItem = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
CastItem, Val->getType()->getPointerTo(CastItem.getAddressSpace()));
- CGF.EmitStoreOfScalar(Val, ValCastItem, /*Volatile=*/false, ValTy);
- return CGF.EmitLoadOfScalar(CastItem, /*Volatile=*/false, CastTy, Loc);
+ CGF.EmitStoreOfScalar(Val, ValCastItem, /*Volatile=*/false, ValTy,
+ LValueBaseInfo(AlignmentSource::Type),
+ TBAAAccessInfo());
+ return CGF.EmitLoadOfScalar(CastItem, /*Volatile=*/false, CastTy, Loc,
+ LValueBaseInfo(AlignmentSource::Type),
+ TBAAAccessInfo());
}
/// This function creates calls to one of two shuffle functions to copy
@@ -2945,9 +2949,14 @@ static void shuffleAndStore(CodeGenFunction &CGF, Address SrcAddr,
ThenBB, ExitBB);
CGF.EmitBlock(ThenBB);
llvm::Value *Res = createRuntimeShuffleFunction(
- CGF, CGF.EmitLoadOfScalar(Ptr, /*Volatile=*/false, IntType, Loc),
+ CGF,
+ CGF.EmitLoadOfScalar(Ptr, /*Volatile=*/false, IntType, Loc,
+ LValueBaseInfo(AlignmentSource::Type),
+ TBAAAccessInfo()),
IntType, Offset, Loc);
- CGF.EmitStoreOfScalar(Res, ElemPtr, /*Volatile=*/false, IntType);
+ CGF.EmitStoreOfScalar(Res, ElemPtr, /*Volatile=*/false, IntType,
+ LValueBaseInfo(AlignmentSource::Type),
+ TBAAAccessInfo());
Address LocalPtr = Bld.CreateConstGEP(Ptr, 1);
Address LocalElemPtr = Bld.CreateConstGEP(ElemPtr, 1);
PhiSrc->addIncoming(LocalPtr.getPointer(), ThenBB);
@@ -2956,9 +2965,14 @@ static void shuffleAndStore(CodeGenFunction &CGF, Address SrcAddr,
CGF.EmitBlock(ExitBB);
} else {
llvm::Value *Res = createRuntimeShuffleFunction(
- CGF, CGF.EmitLoadOfScalar(Ptr, /*Volatile=*/false, IntType, Loc),
+ CGF,
+ CGF.EmitLoadOfScalar(Ptr, /*Volatile=*/false, IntType, Loc,
+ LValueBaseInfo(AlignmentSource::Type),
+ TBAAAccessInfo()),
IntType, Offset, Loc);
- CGF.EmitStoreOfScalar(Res, ElemPtr, /*Volatile=*/false, IntType);
+ CGF.EmitStoreOfScalar(Res, ElemPtr, /*Volatile=*/false, IntType,
+ LValueBaseInfo(AlignmentSource::Type),
+ TBAAAccessInfo());
Ptr = Bld.CreateConstGEP(Ptr, 1);
ElemPtr = Bld.CreateConstGEP(ElemPtr, 1);
}
@@ -3112,12 +3126,14 @@ static void emitReductionListCopy(
} else {
switch (CGF.getEvaluationKind(Private->getType())) {
case TEK_Scalar: {
- llvm::Value *Elem =
- CGF.EmitLoadOfScalar(SrcElementAddr, /*Volatile=*/false,
- Private->getType(), Private->getExprLoc());
+ llvm::Value *Elem = CGF.EmitLoadOfScalar(
+ SrcElementAddr, /*Volatile=*/false, Private->getType(),
+ Private->getExprLoc(), LValueBaseInfo(AlignmentSource::Type),
+ TBAAAccessInfo());
// Store the source element value to the dest element address.
- CGF.EmitStoreOfScalar(Elem, DestElementAddr, /*Volatile=*/false,
- Private->getType());
+ CGF.EmitStoreOfScalar(
+ Elem, DestElementAddr, /*Volatile=*/false, Private->getType(),
+ LValueBaseInfo(AlignmentSource::Type), TBAAAccessInfo());
break;
}
case TEK_Complex: {
@@ -3260,8 +3276,9 @@ static llvm::Value *emitInterWarpCopyFunction(CodeGenModule &CGM,
Address AddrReduceListArg = CGF.GetAddrOfLocalVar(&ReduceListArg);
Address LocalReduceList(
Bld.CreatePointerBitCastOrAddrSpaceCast(
- CGF.EmitLoadOfScalar(AddrReduceListArg, /*Volatile=*/false,
- C.VoidPtrTy, Loc),
+ CGF.EmitLoadOfScalar(
+ AddrReduceListArg, /*Volatile=*/false, C.VoidPtrTy, Loc,
+ LValueBaseInfo(AlignmentSource::Type), TBAAAccessInfo()),
CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo()),
CGF.getPointerAlign());
@@ -3339,10 +3356,13 @@ static llvm::Value *emitInterWarpCopyFunction(CodeGenModule &CGM,
// elem = *elemptr
//*MediumPtr = elem
- llvm::Value *Elem =
- CGF.EmitLoadOfScalar(ElemPtr, /*Volatile=*/false, CType, Loc);
+ llvm::Value *Elem = CGF.EmitLoadOfScalar(
+ ElemPtr, /*Volatile=*/false, CType, Loc,
+ LValueBaseInfo(AlignmentSource::Type), TBAAAccessInfo());
// Store the source element value to the dest element address.
- CGF.EmitStoreOfScalar(Elem, MediumPtr, /*Volatile=*/true, CType);
+ CGF.EmitStoreOfScalar(Elem, MediumPtr, /*Volatile=*/true, CType,
+ LValueBaseInfo(AlignmentSource::Type),
+ TBAAAccessInfo());
Bld.CreateBr(MergeBB);
@@ -3722,8 +3742,9 @@ static llvm::Value *emitListToGlobalCopyFunction(
GlobLVal.setAddress(Address(BufferPtr, GlobLVal.getAlignment()));
switch (CGF.getEvaluationKind(Private->getType())) {
case TEK_Scalar: {
- llvm::Value *V = CGF.EmitLoadOfScalar(ElemPtr, /*Volatile=*/false,
- Private->getType(), Loc);
+ llvm::Value *V = CGF.EmitLoadOfScalar(
+ ElemPtr, /*Volatile=*/false, Private->getType(), Loc,
+ LValueBaseInfo(AlignmentSource::Type), TBAAAccessInfo());
CGF.EmitStoreOfScalar(V, GlobLVal);
break;
}
@@ -3926,7 +3947,9 @@ static llvm::Value *emitGlobalToListCopyFunction(
switch (CGF.getEvaluationKind(Private->getType())) {
case TEK_Scalar: {
llvm::Value *V = CGF.EmitLoadOfScalar(GlobLVal, Loc);
- CGF.EmitStoreOfScalar(V, ElemPtr, /*Volatile=*/false, Private->getType());
+ CGF.EmitStoreOfScalar(V, ElemPtr, /*Volatile=*/false, Private->getType(),
+ LValueBaseInfo(AlignmentSource::Type),
+ TBAAAccessInfo());
break;
}
case TEK_Complex: {
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index d431c0263666..4792c10ecdae 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -533,99 +533,60 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
case BuiltinType::OCLReserveID:
ResultType = CGM.getOpenCLRuntime().convertOpenCLSpecificType(Ty);
break;
-#define GET_SVE_INT_VEC(BITS, ELTS) \
- llvm::ScalableVectorType::get( \
- llvm::IntegerType::get(getLLVMContext(), BITS), ELTS);
case BuiltinType::SveInt8:
case BuiltinType::SveUint8:
- return GET_SVE_INT_VEC(8, 16);
case BuiltinType::SveInt8x2:
case BuiltinType::SveUint8x2:
- return GET_SVE_INT_VEC(8, 32);
case BuiltinType::SveInt8x3:
case BuiltinType::SveUint8x3:
- return GET_SVE_INT_VEC(8, 48);
case BuiltinType::SveInt8x4:
case BuiltinType::SveUint8x4:
- return GET_SVE_INT_VEC(8, 64);
case BuiltinType::SveInt16:
case BuiltinType::SveUint16:
- return GET_SVE_INT_VEC(16, 8);
case BuiltinType::SveInt16x2:
case BuiltinType::SveUint16x2:
- return GET_SVE_INT_VEC(16, 16);
case BuiltinType::SveInt16x3:
case BuiltinType::SveUint16x3:
- return GET_SVE_INT_VEC(16, 24);
case BuiltinType::SveInt16x4:
case BuiltinType::SveUint16x4:
- return GET_SVE_INT_VEC(16, 32);
case BuiltinType::SveInt32:
case BuiltinType::SveUint32:
- return GET_SVE_INT_VEC(32, 4);
case BuiltinType::SveInt32x2:
case BuiltinType::SveUint32x2:
- return GET_SVE_INT_VEC(32, 8);
case BuiltinType::SveInt32x3:
case BuiltinType::SveUint32x3:
- return GET_SVE_INT_VEC(32, 12);
case BuiltinType::SveInt32x4:
case BuiltinType::SveUint32x4:
- return GET_SVE_INT_VEC(32, 16);
case BuiltinType::SveInt64:
case BuiltinType::SveUint64:
- return GET_SVE_INT_VEC(64, 2);
case BuiltinType::SveInt64x2:
case BuiltinType::SveUint64x2:
- return GET_SVE_INT_VEC(64, 4);
case BuiltinType::SveInt64x3:
case BuiltinType::SveUint64x3:
- return GET_SVE_INT_VEC(64, 6);
case BuiltinType::SveInt64x4:
case BuiltinType::SveUint64x4:
- return GET_SVE_INT_VEC(64, 8);
case BuiltinType::SveBool:
- return GET_SVE_INT_VEC(1, 16);
-#undef GET_SVE_INT_VEC
-#define GET_SVE_FP_VEC(TY, ISFP16, ELTS) \
- llvm::ScalableVectorType::get( \
- getTypeForFormat(getLLVMContext(), \
- Context.getFloatTypeSemantics(Context.TY), \
- /* UseNativeHalf = */ ISFP16), \
- ELTS);
case BuiltinType::SveFloat16:
- return GET_SVE_FP_VEC(HalfTy, true, 8);
case BuiltinType::SveFloat16x2:
- return GET_SVE_FP_VEC(HalfTy, true, 16);
case BuiltinType::SveFloat16x3:
- return GET_SVE_FP_VEC(HalfTy, true, 24);
case BuiltinType::SveFloat16x4:
- return GET_SVE_FP_VEC(HalfTy, true, 32);
case BuiltinType::SveFloat32:
- return GET_SVE_FP_VEC(FloatTy, false, 4);
case BuiltinType::SveFloat32x2:
- return GET_SVE_FP_VEC(FloatTy, false, 8);
case BuiltinType::SveFloat32x3:
- return GET_SVE_FP_VEC(FloatTy, false, 12);
case BuiltinType::SveFloat32x4:
- return GET_SVE_FP_VEC(FloatTy, false, 16);
case BuiltinType::SveFloat64:
- return GET_SVE_FP_VEC(DoubleTy, false, 2);
case BuiltinType::SveFloat64x2:
- return GET_SVE_FP_VEC(DoubleTy, false, 4);
case BuiltinType::SveFloat64x3:
- return GET_SVE_FP_VEC(DoubleTy, false, 6);
case BuiltinType::SveFloat64x4:
- return GET_SVE_FP_VEC(DoubleTy, false, 8);
case BuiltinType::SveBFloat16:
- return GET_SVE_FP_VEC(BFloat16Ty, false, 8);
case BuiltinType::SveBFloat16x2:
- return GET_SVE_FP_VEC(BFloat16Ty, false, 16);
case BuiltinType::SveBFloat16x3:
- return GET_SVE_FP_VEC(BFloat16Ty, false, 24);
- case BuiltinType::SveBFloat16x4:
- return GET_SVE_FP_VEC(BFloat16Ty, false, 32);
-#undef GET_SVE_FP_VEC
+ case BuiltinType::SveBFloat16x4: {
+ ASTContext::BuiltinVectorTypeInfo Info =
+ Context.getBuiltinVectorTypeInfo(cast<BuiltinType>(Ty));
+ return llvm::ScalableVectorType::get(ConvertType(Info.ElementType),
+ Info.EC.Min * Info.NumVectors);
+ }
case BuiltinType::Dependent:
#define BUILTIN_TYPE(Id, SingletonId)
#define PLACEHOLDER_TYPE(Id, SingletonId) \
diff --git a/clang/lib/Driver/ToolChains/Arch/Sparc.cpp b/clang/lib/Driver/ToolChains/Arch/Sparc.cpp
index 043b7f257c01..70ba8eb2a7d0 100644
--- a/clang/lib/Driver/ToolChains/Arch/Sparc.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/Sparc.cpp
@@ -21,12 +21,19 @@ using namespace llvm::opt;
const char *sparc::getSparcAsmModeForCPU(StringRef Name,
const llvm::Triple &Triple) {
if (Triple.getArch() == llvm::Triple::sparcv9) {
+ const char *DefV9CPU;
+
+ if (Triple.isOSLinux() || Triple.isOSFreeBSD() || Triple.isOSOpenBSD())
+ DefV9CPU = "-Av9a";
+ else
+ DefV9CPU = "-Av9";
+
return llvm::StringSwitch<const char *>(Name)
.Case("niagara", "-Av9b")
.Case("niagara2", "-Av9b")
.Case("niagara3", "-Av9d")
.Case("niagara4", "-Av9d")
- .Default("-Av9");
+ .Default(DefV9CPU);
} else {
return llvm::StringSwitch<const char *>(Name)
.Case("v8", "-Av8")
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index c77ae5a44a0e..f0a5451322aa 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -498,7 +498,7 @@ static codegenoptions::DebugInfoKind DebugLevelToInfoKind(const Arg &A) {
return codegenoptions::DebugLineTablesOnly;
if (A.getOption().matches(options::OPT_gline_directives_only))
return codegenoptions::DebugDirectivesOnly;
- return codegenoptions::DebugInfoConstructor;
+ return codegenoptions::LimitedDebugInfo;
}
static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) {
@@ -2380,7 +2380,7 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
CmdArgs.push_back(Value.data());
} else {
RenderDebugEnablingArgs(Args, CmdArgs,
- codegenoptions::DebugInfoConstructor,
+ codegenoptions::LimitedDebugInfo,
DwarfVersion, llvm::DebuggerKind::Default);
}
} else if (Value.startswith("-mcpu") || Value.startswith("-mfpu") ||
@@ -3653,7 +3653,7 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
if (const Arg *A =
Args.getLastArg(options::OPT_g_Group, options::OPT_gsplit_dwarf,
options::OPT_gsplit_dwarf_EQ)) {
- DebugInfoKind = codegenoptions::DebugInfoConstructor;
+ DebugInfoKind = codegenoptions::LimitedDebugInfo;
// If the last option explicitly specified a debug-info level, use it.
if (checkDebugInfoOption(A, Args, D, TC) &&
@@ -3758,7 +3758,7 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
if (checkDebugInfoOption(A, Args, D, TC)) {
if (DebugInfoKind != codegenoptions::DebugLineTablesOnly &&
DebugInfoKind != codegenoptions::DebugDirectivesOnly) {
- DebugInfoKind = codegenoptions::DebugInfoConstructor;
+ DebugInfoKind = codegenoptions::LimitedDebugInfo;
CmdArgs.push_back("-dwarf-ext-refs");
CmdArgs.push_back("-fmodule-format=obj");
}
@@ -3778,9 +3778,7 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
TC.GetDefaultStandaloneDebug());
if (const Arg *A = Args.getLastArg(options::OPT_fstandalone_debug))
(void)checkDebugInfoOption(A, Args, D, TC);
- if ((DebugInfoKind == codegenoptions::LimitedDebugInfo ||
- DebugInfoKind == codegenoptions::DebugInfoConstructor) &&
- NeedFullDebug)
+ if (DebugInfoKind == codegenoptions::LimitedDebugInfo && NeedFullDebug)
DebugInfoKind = codegenoptions::FullDebugInfo;
if (Args.hasFlag(options::OPT_gembed_source, options::OPT_gno_embed_source,
@@ -6566,7 +6564,7 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
options::OPT_gline_tables_only)) {
*EmitCodeView = true;
if (DebugInfoArg->getOption().matches(options::OPT__SLASH_Z7))
- *DebugInfoKind = codegenoptions::DebugInfoConstructor;
+ *DebugInfoKind = codegenoptions::LimitedDebugInfo;
else
*DebugInfoKind = codegenoptions::DebugLineTablesOnly;
} else {
@@ -6863,7 +6861,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
// the guard for source type, however there is a test which asserts
// that some assembler invocation receives no -debug-info-kind,
// and it's not clear whether that test is just overly restrictive.
- DebugInfoKind = (WantDebug ? codegenoptions::DebugInfoConstructor
+ DebugInfoKind = (WantDebug ? codegenoptions::LimitedDebugInfo
: codegenoptions::NoDebugInfo);
// Add the -fdebug-compilation-dir flag if needed.
addDebugCompDirArg(Args, CmdArgs, C.getDriver().getVFS());
diff --git a/clang/lib/Driver/ToolChains/OpenBSD.cpp b/clang/lib/Driver/ToolChains/OpenBSD.cpp
index 9c1a9c5f8228..5ca2fa0850e6 100644
--- a/clang/lib/Driver/ToolChains/OpenBSD.cpp
+++ b/clang/lib/Driver/ToolChains/OpenBSD.cpp
@@ -10,10 +10,12 @@
#include "Arch/Mips.h"
#include "Arch/Sparc.h"
#include "CommonArgs.h"
+#include "clang/Config/config.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/SanitizerArgs.h"
#include "llvm/Option/ArgList.h"
+#include "llvm/Support/Path.h"
using namespace clang::driver;
using namespace clang::driver::tools;
@@ -41,15 +43,6 @@ void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-many");
break;
- case llvm::Triple::sparc:
- case llvm::Triple::sparcel: {
- CmdArgs.push_back("-32");
- std::string CPU = getCPUName(Args, getToolChain().getTriple());
- CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
- AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
- break;
- }
-
case llvm::Triple::sparcv9: {
CmdArgs.push_back("-64");
std::string CPU = getCPUName(Args, getToolChain().getTriple());
@@ -256,6 +249,45 @@ OpenBSD::OpenBSD(const Driver &D, const llvm::Triple &Triple,
getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
}
+void OpenBSD::AddClangSystemIncludeArgs(
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const {
+ const Driver &D = getDriver();
+
+ if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
+ return;
+
+ if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+ SmallString<128> Dir(D.ResourceDir);
+ llvm::sys::path::append(Dir, "include");
+ addSystemInclude(DriverArgs, CC1Args, Dir.str());
+ }
+
+ if (DriverArgs.hasArg(options::OPT_nostdlibinc))
+ return;
+
+ // Check for configure-time C include directories.
+ StringRef CIncludeDirs(C_INCLUDE_DIRS);
+ if (CIncludeDirs != "") {
+ SmallVector<StringRef, 5> dirs;
+ CIncludeDirs.split(dirs, ":");
+ for (StringRef dir : dirs) {
+ StringRef Prefix =
+ llvm::sys::path::is_absolute(dir) ? StringRef(D.SysRoot) : "";
+ addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
+ }
+ return;
+ }
+
+ addExternCSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/include");
+}
+
+void OpenBSD::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const {
+ addSystemInclude(DriverArgs, CC1Args,
+ getDriver().SysRoot + "/usr/include/c++/v1");
+}
+
void OpenBSD::AddCXXStdlibLibArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
bool Profiling = Args.hasArg(options::OPT_pg);
@@ -264,17 +296,18 @@ void OpenBSD::AddCXXStdlibLibArgs(const ArgList &Args,
CmdArgs.push_back(Profiling ? "-lc++abi_p" : "-lc++abi");
}
+std::string OpenBSD::getCompilerRT(const ArgList &Args,
+ StringRef Component,
+ FileType Type) const {
+ SmallString<128> Path(getDriver().SysRoot);
+ llvm::sys::path::append(Path, "/usr/lib/libcompiler_rt.a");
+ return std::string(Path.str());
+}
+
Tool *OpenBSD::buildAssembler() const {
return new tools::openbsd::Assembler(*this);
}
Tool *OpenBSD::buildLinker() const { return new tools::openbsd::Linker(*this); }
-void OpenBSD::addClangTargetOptions(const ArgList &DriverArgs,
- ArgStringList &CC1Args,
- Action::OffloadKind) const {
- // Support for .init_array is still new (Aug 2016).
- if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
- options::OPT_fno_use_init_array, false))
- CC1Args.push_back("-fno-use-init-array");
-}
+bool OpenBSD::HasNativeLLVMSupport() const { return true; }
diff --git a/clang/lib/Driver/ToolChains/OpenBSD.h b/clang/lib/Driver/ToolChains/OpenBSD.h
index 897eee57ab68..5f9b259bf861 100644
--- a/clang/lib/Driver/ToolChains/OpenBSD.h
+++ b/clang/lib/Driver/ToolChains/OpenBSD.h
@@ -54,6 +54,8 @@ public:
OpenBSD(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args);
+ bool HasNativeLLVMSupport() const override;
+
bool IsMathErrnoDefault() const override { return false; }
bool IsObjCNonFragileABIDefault() const override { return true; }
bool isPIEDefault() const override { return true; }
@@ -65,9 +67,18 @@ public:
return ToolChain::CST_Libcxx;
}
+ void
+ AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const override;
+
+ void addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const override;
void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;
+ std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
+ FileType Type = ToolChain::FT_Static) const override;
+
unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
return 2;
}
@@ -75,11 +86,6 @@ public:
SanitizerMask getSupportedSanitizers() const override;
- void
- addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args,
- Action::OffloadKind DeviceOffloadKind) const override;
-
protected:
Tool *buildAssembler() const override;
Tool *buildLinker() const override;
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 7f8e35126512..914c05f72aec 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -56,6 +56,13 @@ static bool isLambdaParameterList(const FormatToken *Left) {
Left->Previous->MatchingParen->is(TT_LambdaLSquare);
}
+/// Returns \c true if the token is followed by a boolean condition, \c false
+/// otherwise.
+static bool isKeywordWithCondition(const FormatToken &Tok) {
+ return Tok.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,
+ tok::kw_constexpr, tok::kw_catch);
+}
+
/// A parser that gathers additional information about tokens.
///
/// The \c TokenAnnotator tries to match parenthesis and square brakets and
@@ -108,6 +115,12 @@ private:
while (CurrentToken) {
if (CurrentToken->is(tok::greater)) {
+ // Try to do a better job at looking for ">>" within the condition of
+ // a statement.
+ if (CurrentToken->Next && CurrentToken->Next->is(tok::greater) &&
+ Left->ParentBracket != tok::less &&
+ isKeywordWithCondition(*Line.First))
+ return false;
Left->MatchingParen = CurrentToken;
CurrentToken->MatchingParen = Left;
// In TT_Proto, we must distignuish between:
@@ -2733,13 +2746,6 @@ bool TokenAnnotator::spaceRequiredBeforeParens(const FormatToken &Right) const {
Right.ParameterCount > 0);
}
-/// Returns \c true if the token is followed by a boolean condition, \c false
-/// otherwise.
-static bool isKeywordWithCondition(const FormatToken &Tok) {
- return Tok.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,
- tok::kw_constexpr, tok::kw_catch);
-}
-
bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
const FormatToken &Left,
const FormatToken &Right) {
diff --git a/clang/lib/Frontend/InitHeaderSearch.cpp b/clang/lib/Frontend/InitHeaderSearch.cpp
index 16f1f1670e8d..bc31445d6d08 100644
--- a/clang/lib/Frontend/InitHeaderSearch.cpp
+++ b/clang/lib/Frontend/InitHeaderSearch.cpp
@@ -270,6 +270,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
case llvm::Triple::Linux:
case llvm::Triple::Hurd:
case llvm::Triple::Solaris:
+ case llvm::Triple::OpenBSD:
llvm_unreachable("Include management is handled in the driver.");
case llvm::Triple::CloudABI: {
@@ -423,6 +424,7 @@ void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang,
case llvm::Triple::Emscripten:
case llvm::Triple::Linux:
case llvm::Triple::Hurd:
+ case llvm::Triple::OpenBSD:
case llvm::Triple::Solaris:
case llvm::Triple::WASI:
case llvm::Triple::AIX:
diff --git a/clang/lib/Headers/altivec.h b/clang/lib/Headers/altivec.h
index ac5f43836316..c00c5561428a 100644
--- a/clang/lib/Headers/altivec.h
+++ b/clang/lib/Headers/altivec.h
@@ -1766,36 +1766,12 @@ vec_cmpne(vector unsigned int __a, vector unsigned int __b) {
(vector int)__b);
}
-static __inline__ vector bool long long __ATTRS_o_ai
-vec_cmpne(vector bool long long __a, vector bool long long __b) {
- return (vector bool long long)
- ~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b));
-}
-
-static __inline__ vector bool long long __ATTRS_o_ai
-vec_cmpne(vector signed long long __a, vector signed long long __b) {
- return (vector bool long long)
- ~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b));
-}
-
-static __inline__ vector bool long long __ATTRS_o_ai
-vec_cmpne(vector unsigned long long __a, vector unsigned long long __b) {
- return (vector bool long long)
- ~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b));
-}
-
static __inline__ vector bool int __ATTRS_o_ai
vec_cmpne(vector float __a, vector float __b) {
return (vector bool int)__builtin_altivec_vcmpnew((vector int)__a,
(vector int)__b);
}
-static __inline__ vector bool long long __ATTRS_o_ai
-vec_cmpne(vector double __a, vector double __b) {
- return (vector bool long long)
- ~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b));
-}
-
/* vec_cmpnez */
static __inline__ vector bool char __ATTRS_o_ai
@@ -1900,6 +1876,86 @@ vec_parity_lsbb(vector signed long long __a) {
return __builtin_altivec_vprtybd(__a);
}
+#else
+/* vec_cmpne */
+
+static __inline__ vector bool char __ATTRS_o_ai
+vec_cmpne(vector bool char __a, vector bool char __b) {
+ return ~(vec_cmpeq(__a, __b));
+}
+
+static __inline__ vector bool char __ATTRS_o_ai
+vec_cmpne(vector signed char __a, vector signed char __b) {
+ return ~(vec_cmpeq(__a, __b));
+}
+
+static __inline__ vector bool char __ATTRS_o_ai
+vec_cmpne(vector unsigned char __a, vector unsigned char __b) {
+ return ~(vec_cmpeq(__a, __b));
+}
+
+static __inline__ vector bool short __ATTRS_o_ai
+vec_cmpne(vector bool short __a, vector bool short __b) {
+ return ~(vec_cmpeq(__a, __b));
+}
+
+static __inline__ vector bool short __ATTRS_o_ai
+vec_cmpne(vector signed short __a, vector signed short __b) {
+ return ~(vec_cmpeq(__a, __b));
+}
+
+static __inline__ vector bool short __ATTRS_o_ai
+vec_cmpne(vector unsigned short __a, vector unsigned short __b) {
+ return ~(vec_cmpeq(__a, __b));
+}
+
+static __inline__ vector bool int __ATTRS_o_ai
+vec_cmpne(vector bool int __a, vector bool int __b) {
+ return ~(vec_cmpeq(__a, __b));
+}
+
+static __inline__ vector bool int __ATTRS_o_ai
+vec_cmpne(vector signed int __a, vector signed int __b) {
+ return ~(vec_cmpeq(__a, __b));
+}
+
+static __inline__ vector bool int __ATTRS_o_ai
+vec_cmpne(vector unsigned int __a, vector unsigned int __b) {
+ return ~(vec_cmpeq(__a, __b));
+}
+
+static __inline__ vector bool int __ATTRS_o_ai
+vec_cmpne(vector float __a, vector float __b) {
+ return ~(vec_cmpeq(__a, __b));
+}
+#endif
+
+#ifdef __POWER8_VECTOR__
+static __inline__ vector bool long long __ATTRS_o_ai
+vec_cmpne(vector bool long long __a, vector bool long long __b) {
+ return (vector bool long long)
+ ~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b));
+}
+
+static __inline__ vector bool long long __ATTRS_o_ai
+vec_cmpne(vector signed long long __a, vector signed long long __b) {
+ return (vector bool long long)
+ ~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b));
+}
+
+static __inline__ vector bool long long __ATTRS_o_ai
+vec_cmpne(vector unsigned long long __a, vector unsigned long long __b) {
+ return (vector bool long long)
+ ~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b));
+}
+#endif
+
+#ifdef __VSX__
+static __inline__ vector bool long long __ATTRS_o_ai
+vec_cmpne(vector double __a, vector double __b) {
+ return (vector bool long long)
+ ~(__builtin_altivec_vcmpequd((vector long long)__a, (vector long long)__b));
+}
#endif
/* vec_cmpgt */
@@ -2702,67 +2758,67 @@ vec_insert_exp(vector unsigned int __a, vector unsigned int __b) {
}
#if defined(__powerpc64__)
-static __inline__ vector signed char __ATTRS_o_ai vec_xl_len(signed char *__a,
+static __inline__ vector signed char __ATTRS_o_ai vec_xl_len(const signed char *__a,
size_t __b) {
return (vector signed char)__builtin_vsx_lxvl(__a, (__b << 56));
}
static __inline__ vector unsigned char __ATTRS_o_ai
-vec_xl_len(unsigned char *__a, size_t __b) {
+vec_xl_len(const unsigned char *__a, size_t __b) {
return (vector unsigned char)__builtin_vsx_lxvl(__a, (__b << 56));
}
-static __inline__ vector signed short __ATTRS_o_ai vec_xl_len(signed short *__a,
+static __inline__ vector signed short __ATTRS_o_ai vec_xl_len(const signed short *__a,
size_t __b) {
return (vector signed short)__builtin_vsx_lxvl(__a, (__b << 56));
}
static __inline__ vector unsigned short __ATTRS_o_ai
-vec_xl_len(unsigned short *__a, size_t __b) {
+vec_xl_len(const unsigned short *__a, size_t __b) {
return (vector unsigned short)__builtin_vsx_lxvl(__a, (__b << 56));
}
-static __inline__ vector signed int __ATTRS_o_ai vec_xl_len(signed int *__a,
+static __inline__ vector signed int __ATTRS_o_ai vec_xl_len(const signed int *__a,
size_t __b) {
return (vector signed int)__builtin_vsx_lxvl(__a, (__b << 56));
}
-static __inline__ vector unsigned int __ATTRS_o_ai vec_xl_len(unsigned int *__a,
+static __inline__ vector unsigned int __ATTRS_o_ai vec_xl_len(const unsigned int *__a,
size_t __b) {
return (vector unsigned int)__builtin_vsx_lxvl(__a, (__b << 56));
}
-static __inline__ vector float __ATTRS_o_ai vec_xl_len(float *__a, size_t __b) {
+static __inline__ vector float __ATTRS_o_ai vec_xl_len(const float *__a, size_t __b) {
return (vector float)__builtin_vsx_lxvl(__a, (__b << 56));
}
static __inline__ vector signed __int128 __ATTRS_o_ai
-vec_xl_len(signed __int128 *__a, size_t __b) {
+vec_xl_len(const signed __int128 *__a, size_t __b) {
return (vector signed __int128)__builtin_vsx_lxvl(__a, (__b << 56));
}
static __inline__ vector unsigned __int128 __ATTRS_o_ai
-vec_xl_len(unsigned __int128 *__a, size_t __b) {
+vec_xl_len(const unsigned __int128 *__a, size_t __b) {
return (vector unsigned __int128)__builtin_vsx_lxvl(__a, (__b << 56));
}
static __inline__ vector signed long long __ATTRS_o_ai
-vec_xl_len(signed long long *__a, size_t __b) {
+vec_xl_len(const signed long long *__a, size_t __b) {
return (vector signed long long)__builtin_vsx_lxvl(__a, (__b << 56));
}
static __inline__ vector unsigned long long __ATTRS_o_ai
-vec_xl_len(unsigned long long *__a, size_t __b) {
+vec_xl_len(const unsigned long long *__a, size_t __b) {
return (vector unsigned long long)__builtin_vsx_lxvl(__a, (__b << 56));
}
-static __inline__ vector double __ATTRS_o_ai vec_xl_len(double *__a,
+static __inline__ vector double __ATTRS_o_ai vec_xl_len(const double *__a,
size_t __b) {
return (vector double)__builtin_vsx_lxvl(__a, (__b << 56));
}
static __inline__ vector unsigned char __ATTRS_o_ai
-vec_xl_len_r(unsigned char *__a, size_t __b) {
+vec_xl_len_r(const unsigned char *__a, size_t __b) {
vector unsigned char __res =
(vector unsigned char)__builtin_vsx_lxvll(__a, (__b << 56));
#ifdef __LITTLE_ENDIAN__
@@ -16353,41 +16409,41 @@ typedef vector unsigned int unaligned_vec_uint __attribute__((aligned(1)));
typedef vector float unaligned_vec_float __attribute__((aligned(1)));
static inline __ATTRS_o_ai vector signed char vec_xl(signed long long __offset,
- signed char *__ptr) {
+ const signed char *__ptr) {
return *(unaligned_vec_schar *)(__ptr + __offset);
}
static inline __ATTRS_o_ai vector unsigned char
-vec_xl(signed long long __offset, unsigned char *__ptr) {
+vec_xl(signed long long __offset, const unsigned char *__ptr) {
return *(unaligned_vec_uchar*)(__ptr + __offset);
}
static inline __ATTRS_o_ai vector signed short vec_xl(signed long long __offset,
- signed short *__ptr) {
+ const signed short *__ptr) {
signed char *__addr = (signed char *)__ptr + __offset;
return *(unaligned_vec_sshort *)__addr;
}
static inline __ATTRS_o_ai vector unsigned short
-vec_xl(signed long long __offset, unsigned short *__ptr) {
+vec_xl(signed long long __offset, const unsigned short *__ptr) {
signed char *__addr = (signed char *)__ptr + __offset;
return *(unaligned_vec_ushort *)__addr;
}
static inline __ATTRS_o_ai vector signed int vec_xl(signed long long __offset,
- signed int *__ptr) {
+ const signed int *__ptr) {
signed char *__addr = (signed char *)__ptr + __offset;
return *(unaligned_vec_sint *)__addr;
}
static inline __ATTRS_o_ai vector unsigned int vec_xl(signed long long __offset,
- unsigned int *__ptr) {
+ const unsigned int *__ptr) {
signed char *__addr = (signed char *)__ptr + __offset;
return *(unaligned_vec_uint *)__addr;
}
static inline __ATTRS_o_ai vector float vec_xl(signed long long __offset,
- float *__ptr) {
+ const float *__ptr) {
signed char *__addr = (signed char *)__ptr + __offset;
return *(unaligned_vec_float *)__addr;
}
@@ -16398,19 +16454,19 @@ typedef vector unsigned long long unaligned_vec_ull __attribute__((aligned(1)));
typedef vector double unaligned_vec_double __attribute__((aligned(1)));
static inline __ATTRS_o_ai vector signed long long
-vec_xl(signed long long __offset, signed long long *__ptr) {
+vec_xl(signed long long __offset, const signed long long *__ptr) {
signed char *__addr = (signed char *)__ptr + __offset;
return *(unaligned_vec_sll *)__addr;
}
static inline __ATTRS_o_ai vector unsigned long long
-vec_xl(signed long long __offset, unsigned long long *__ptr) {
+vec_xl(signed long long __offset, const unsigned long long *__ptr) {
signed char *__addr = (signed char *)__ptr + __offset;
return *(unaligned_vec_ull *)__addr;
}
static inline __ATTRS_o_ai vector double vec_xl(signed long long __offset,
- double *__ptr) {
+ const double *__ptr) {
signed char *__addr = (signed char *)__ptr + __offset;
return *(unaligned_vec_double *)__addr;
}
@@ -16421,13 +16477,13 @@ typedef vector signed __int128 unaligned_vec_si128 __attribute__((aligned(1)));
typedef vector unsigned __int128 unaligned_vec_ui128
__attribute__((aligned(1)));
static inline __ATTRS_o_ai vector signed __int128
-vec_xl(signed long long __offset, signed __int128 *__ptr) {
+vec_xl(signed long long __offset, const signed __int128 *__ptr) {
signed char *__addr = (signed char *)__ptr + __offset;
return *(unaligned_vec_si128 *)__addr;
}
static inline __ATTRS_o_ai vector unsigned __int128
-vec_xl(signed long long __offset, unsigned __int128 *__ptr) {
+vec_xl(signed long long __offset, const unsigned __int128 *__ptr) {
signed char *__addr = (signed char *)__ptr + __offset;
return *(unaligned_vec_ui128 *)__addr;
}
@@ -16437,71 +16493,71 @@ vec_xl(signed long long __offset, unsigned __int128 *__ptr) {
#ifdef __LITTLE_ENDIAN__
static __inline__ vector signed char __ATTRS_o_ai
-vec_xl_be(signed long long __offset, signed char *__ptr) {
+vec_xl_be(signed long long __offset, const signed char *__ptr) {
vector signed char __vec = (vector signed char)__builtin_vsx_lxvd2x_be(__offset, __ptr);
return __builtin_shufflevector(__vec, __vec, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14,
13, 12, 11, 10, 9, 8);
}
static __inline__ vector unsigned char __ATTRS_o_ai
-vec_xl_be(signed long long __offset, unsigned char *__ptr) {
+vec_xl_be(signed long long __offset, const unsigned char *__ptr) {
vector unsigned char __vec = (vector unsigned char)__builtin_vsx_lxvd2x_be(__offset, __ptr);
return __builtin_shufflevector(__vec, __vec, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14,
13, 12, 11, 10, 9, 8);
}
static __inline__ vector signed short __ATTRS_o_ai
-vec_xl_be(signed long long __offset, signed short *__ptr) {
+vec_xl_be(signed long long __offset, const signed short *__ptr) {
vector signed short __vec = (vector signed short)__builtin_vsx_lxvd2x_be(__offset, __ptr);
return __builtin_shufflevector(__vec, __vec, 3, 2, 1, 0, 7, 6, 5, 4);
}
static __inline__ vector unsigned short __ATTRS_o_ai
-vec_xl_be(signed long long __offset, unsigned short *__ptr) {
+vec_xl_be(signed long long __offset, const unsigned short *__ptr) {
vector unsigned short __vec = (vector unsigned short)__builtin_vsx_lxvd2x_be(__offset, __ptr);
return __builtin_shufflevector(__vec, __vec, 3, 2, 1, 0, 7, 6, 5, 4);
}
static __inline__ vector signed int __ATTRS_o_ai
-vec_xl_be(signed long long __offset, signed int *__ptr) {
+vec_xl_be(signed long long __offset, const signed int *__ptr) {
return (vector signed int)__builtin_vsx_lxvw4x_be(__offset, __ptr);
}
static __inline__ vector unsigned int __ATTRS_o_ai
-vec_xl_be(signed long long __offset, unsigned int *__ptr) {
+vec_xl_be(signed long long __offset, const unsigned int *__ptr) {
return (vector unsigned int)__builtin_vsx_lxvw4x_be(__offset, __ptr);
}
static __inline__ vector float __ATTRS_o_ai
-vec_xl_be(signed long long __offset, float *__ptr) {
+vec_xl_be(signed long long __offset, const float *__ptr) {
return (vector float)__builtin_vsx_lxvw4x_be(__offset, __ptr);
}
#ifdef __VSX__
static __inline__ vector signed long long __ATTRS_o_ai
-vec_xl_be(signed long long __offset, signed long long *__ptr) {
+vec_xl_be(signed long long __offset, const signed long long *__ptr) {
return (vector signed long long)__builtin_vsx_lxvd2x_be(__offset, __ptr);
}
static __inline__ vector unsigned long long __ATTRS_o_ai
-vec_xl_be(signed long long __offset, unsigned long long *__ptr) {
+vec_xl_be(signed long long __offset, const unsigned long long *__ptr) {
return (vector unsigned long long)__builtin_vsx_lxvd2x_be(__offset, __ptr);
}
static __inline__ vector double __ATTRS_o_ai
-vec_xl_be(signed long long __offset, double *__ptr) {
+vec_xl_be(signed long long __offset, const double *__ptr) {
return (vector double)__builtin_vsx_lxvd2x_be(__offset, __ptr);
}
#endif
#if defined(__POWER8_VECTOR__) && defined(__powerpc64__)
static __inline__ vector signed __int128 __ATTRS_o_ai
-vec_xl_be(signed long long __offset, signed __int128 *__ptr) {
+vec_xl_be(signed long long __offset, const signed __int128 *__ptr) {
return vec_xl(__offset, __ptr);
}
static __inline__ vector unsigned __int128 __ATTRS_o_ai
-vec_xl_be(signed long long __offset, unsigned __int128 *__ptr) {
+vec_xl_be(signed long long __offset, const unsigned __int128 *__ptr) {
return vec_xl(__offset, __ptr);
}
#endif
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 509d88e25000..b00d2ff5f1d5 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -4956,6 +4956,11 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
? 0
: 1);
+ if (ValType->isExtIntType()) {
+ Diag(Ptr->getExprLoc(), diag::err_atomic_builtin_ext_int_prohibit);
+ return ExprError();
+ }
+
return AE;
}
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 2efb7acb9724..baec13ba627c 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2053,6 +2053,13 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(
// typedef (C++ [dcl.typedef]p4).
if (Previous.isSingleTagDecl())
Previous.clear();
+
+ // Filter out previous declarations that don't match the scope. The only
+ // effect this has is to remove declarations found in inline namespaces
+ // for friend declarations with unqualified names.
+ SemaRef.FilterLookupForScope(Previous, DC, /*Scope*/ nullptr,
+ /*ConsiderLinkage*/ true,
+ QualifierLoc.hasQualifier());
}
SemaRef.CheckFunctionDeclaration(/*Scope*/ nullptr, Function, Previous,
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index b8f7f1a58159..cc151a048b98 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -8880,11 +8880,8 @@ QualType Sema::BuildAtomicType(QualType T, SourceLocation Loc) {
else if (!T.isTriviallyCopyableType(Context))
// Some other non-trivially-copyable type (probably a C++ class)
DisallowedKind = 7;
- else if (auto *ExtTy = T->getAs<ExtIntType>()) {
- if (ExtTy->getNumBits() < 8)
+ else if (T->isExtIntType()) {
DisallowedKind = 8;
- else if (!llvm::isPowerOf2_32(ExtTy->getNumBits()))
- DisallowedKind = 9;
}
if (DisallowedKind != -1) {
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 117eb598bd5e..c0bf240464f7 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -583,7 +583,7 @@ void ASTDeclReader::VisitDecl(Decl *D) {
Reader.getContext());
}
D->setLocation(ThisDeclLoc);
- D->setInvalidDecl(Record.readInt());
+ D->InvalidDecl = Record.readInt();
if (Record.readInt()) { // hasAttrs
AttrVec Attrs;
Record.readAttributes(Attrs);
diff --git a/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
index 1ef70b650414..528f68c6c429 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
@@ -106,7 +106,7 @@ static const NoteTag *getNoteTag(CheckerContext &C,
QualType CastToTy, const Expr *Object,
bool CastSucceeds, bool IsKnownCast) {
std::string CastToName =
- CastInfo ? CastInfo->to()->getPointeeCXXRecordDecl()->getNameAsString()
+ CastInfo ? CastInfo->to()->getAsCXXRecordDecl()->getNameAsString()
: CastToTy->getPointeeCXXRecordDecl()->getNameAsString();
Object = Object->IgnoreParenImpCasts();
@@ -135,6 +135,47 @@ static const NoteTag *getNoteTag(CheckerContext &C,
/*IsPrunable=*/true);
}
+static const NoteTag *getNoteTag(CheckerContext &C,
+ SmallVector<QualType, 4> CastToTyVec,
+ const Expr *Object,
+ bool IsKnownCast) {
+ Object = Object->IgnoreParenImpCasts();
+
+ return C.getNoteTag(
+ [=]() -> std::string {
+ SmallString<128> Msg;
+ llvm::raw_svector_ostream Out(Msg);
+
+ if (!IsKnownCast)
+ Out << "Assuming ";
+
+ if (const auto *DRE = dyn_cast<DeclRefExpr>(Object)) {
+ Out << '\'' << DRE->getDecl()->getNameAsString() << '\'';
+ } else if (const auto *ME = dyn_cast<MemberExpr>(Object)) {
+ Out << (IsKnownCast ? "Field '" : "field '")
+ << ME->getMemberDecl()->getNameAsString() << '\'';
+ } else {
+ Out << (IsKnownCast ? "The object" : "the object");
+ }
+ Out << " is";
+
+ bool First = true;
+ for (QualType CastToTy: CastToTyVec) {
+ std::string CastToName =
+ CastToTy->getAsCXXRecordDecl() ?
+ CastToTy->getAsCXXRecordDecl()->getNameAsString() :
+ CastToTy->getPointeeCXXRecordDecl()->getNameAsString();
+ Out << ' ' << ((CastToTyVec.size() == 1) ? "not" :
+ (First ? "neither" : "nor")) << " a '" << CastToName
+ << '\'';
+ First = false;
+ }
+
+ return std::string(Out.str());
+ },
+ /*IsPrunable=*/true);
+}
+
//===----------------------------------------------------------------------===//
// Main logic to evaluate a cast.
//===----------------------------------------------------------------------===//
@@ -220,40 +261,76 @@ static void addInstanceOfTransition(const CallEvent &Call,
bool IsInstanceOf) {
const FunctionDecl *FD = Call.getDecl()->getAsFunction();
QualType CastFromTy = Call.parameters()[0]->getType();
- QualType CastToTy = FD->getTemplateSpecializationArgs()->get(0).getAsType();
- if (CastFromTy->isPointerType())
- CastToTy = C.getASTContext().getPointerType(CastToTy);
- else if (CastFromTy->isReferenceType())
- CastToTy = alignReferenceTypes(CastToTy, CastFromTy, C.getASTContext());
- else
- return;
+ SmallVector<QualType, 4> CastToTyVec;
+ for (unsigned idx = 0; idx < FD->getTemplateSpecializationArgs()->size() - 1;
+ ++idx) {
+ TemplateArgument CastToTempArg =
+ FD->getTemplateSpecializationArgs()->get(idx);
+ switch (CastToTempArg.getKind()) {
+ default:
+ return;
+ case TemplateArgument::Type:
+ CastToTyVec.push_back(CastToTempArg.getAsType());
+ break;
+ case TemplateArgument::Pack:
+ for (TemplateArgument ArgInPack: CastToTempArg.pack_elements())
+ CastToTyVec.push_back(ArgInPack.getAsType());
+ break;
+ }
+ }
const MemRegion *MR = DV.getAsRegion();
- const DynamicCastInfo *CastInfo =
- getDynamicCastInfo(State, MR, CastFromTy, CastToTy);
+ if (MR && CastFromTy->isReferenceType())
+ MR = State->getSVal(DV.castAs<Loc>()).getAsRegion();
+
+ bool Success = false;
+ bool IsAnyKnown = false;
+ for (QualType CastToTy: CastToTyVec) {
+ if (CastFromTy->isPointerType())
+ CastToTy = C.getASTContext().getPointerType(CastToTy);
+ else if (CastFromTy->isReferenceType())
+ CastToTy = alignReferenceTypes(CastToTy, CastFromTy, C.getASTContext());
+ else
+ return;
- bool CastSucceeds;
- if (CastInfo)
- CastSucceeds = IsInstanceOf && CastInfo->succeeds();
- else
- CastSucceeds = IsInstanceOf || CastFromTy == CastToTy;
+ const DynamicCastInfo *CastInfo =
+ getDynamicCastInfo(State, MR, CastFromTy, CastToTy);
- if (isInfeasibleCast(CastInfo, CastSucceeds)) {
- C.generateSink(State, C.getPredecessor());
- return;
+ bool CastSucceeds;
+ if (CastInfo)
+ CastSucceeds = IsInstanceOf && CastInfo->succeeds();
+ else
+ CastSucceeds = IsInstanceOf || CastFromTy == CastToTy;
+
+ // Store the type and the cast information.
+ bool IsKnownCast = CastInfo || CastFromTy == CastToTy;
+ IsAnyKnown = IsAnyKnown || IsKnownCast;
+ ProgramStateRef NewState = State;
+ if (!IsKnownCast)
+ NewState = setDynamicTypeAndCastInfo(State, MR, CastFromTy, CastToTy,
+ IsInstanceOf);
+
+ if (CastSucceeds) {
+ Success = true;
+ C.addTransition(
+ NewState->BindExpr(Call.getOriginExpr(), C.getLocationContext(),
+ C.getSValBuilder().makeTruthVal(true)),
+ getNoteTag(C, CastInfo, CastToTy, Call.getArgExpr(0), true,
+ IsKnownCast));
+ if (IsKnownCast)
+ return;
+ } else if (CastInfo && CastInfo->succeeds()) {
+ C.generateSink(NewState, C.getPredecessor());
+ return;
+ }
}
- // Store the type and the cast information.
- bool IsKnownCast = CastInfo || CastFromTy == CastToTy;
- if (!IsKnownCast)
- State = setDynamicTypeAndCastInfo(State, MR, CastFromTy, CastToTy,
- IsInstanceOf);
-
- C.addTransition(
- State->BindExpr(Call.getOriginExpr(), C.getLocationContext(),
- C.getSValBuilder().makeTruthVal(CastSucceeds)),
- getNoteTag(C, CastInfo, CastToTy, Call.getArgExpr(0), CastSucceeds,
- IsKnownCast));
+ if (!Success) {
+ C.addTransition(
+ State->BindExpr(Call.getOriginExpr(), C.getLocationContext(),
+ C.getSValBuilder().makeTruthVal(false)),
+ getNoteTag(C, CastToTyVec, Call.getArgExpr(0), IsAnyKnown));
+ }
}
//===----------------------------------------------------------------------===//
@@ -402,8 +479,9 @@ bool CastValueChecker::evalCall(const CallEvent &Call,
QualType ParamT = Call.parameters()[0]->getType();
QualType ResultT = Call.getResultType();
if (!(ParamT->isPointerType() && ResultT->isPointerType()) &&
- !(ParamT->isReferenceType() && ResultT->isReferenceType()))
+ !(ParamT->isReferenceType() && ResultT->isReferenceType())) {
return false;
+ }
DV = Call.getArgSVal(0).getAs<DefinedOrUnknownSVal>();
break;
diff --git a/clang/lib/StaticAnalyzer/Core/DynamicType.cpp b/clang/lib/StaticAnalyzer/Core/DynamicType.cpp
index e9b64fd79614..9ed915aafcab 100644
--- a/clang/lib/StaticAnalyzer/Core/DynamicType.cpp
+++ b/clang/lib/StaticAnalyzer/Core/DynamicType.cpp
@@ -65,6 +65,13 @@ const DynamicTypeInfo *getRawDynamicTypeInfo(ProgramStateRef State,
return State->get<DynamicTypeMap>(MR);
}
+static void unbox(QualType &Ty) {
+ // FIXME: Why are we being fed references to pointers in the first place?
+ while (Ty->isReferenceType() || Ty->isPointerType())
+ Ty = Ty->getPointeeType();
+ Ty = Ty.getCanonicalType().getUnqualifiedType();
+}
+
const DynamicCastInfo *getDynamicCastInfo(ProgramStateRef State,
const MemRegion *MR,
QualType CastFromTy,
@@ -73,6 +80,9 @@ const DynamicCastInfo *getDynamicCastInfo(ProgramStateRef State,
if (!Lookup)
return nullptr;
+ unbox(CastFromTy);
+ unbox(CastToTy);
+
for (const DynamicCastInfo &Cast : *Lookup)
if (Cast.equals(CastFromTy, CastToTy))
return &Cast;
@@ -112,6 +122,9 @@ ProgramStateRef setDynamicTypeAndCastInfo(ProgramStateRef State,
State = State->set<DynamicTypeMap>(MR, CastToTy);
}
+ unbox(CastFromTy);
+ unbox(CastToTy);
+
DynamicCastInfo::CastResult ResultKind =
CastSucceeds ? DynamicCastInfo::CastResult::Success
: DynamicCastInfo::CastResult::Failure;
diff --git a/compiler-rt/lib/builtins/clear_cache.c b/compiler-rt/lib/builtins/clear_cache.c
index 72e02e613de5..29e31f55d499 100644
--- a/compiler-rt/lib/builtins/clear_cache.c
+++ b/compiler-rt/lib/builtins/clear_cache.c
@@ -33,7 +33,7 @@ uintptr_t GetCurrentProcess(void);
#include <machine/sysarch.h>
#endif
-#if defined(__OpenBSD__) && defined(__mips__)
+#if defined(__OpenBSD__) && (defined(__arm__) || defined(__mips__))
// clang-format off
#include <sys/types.h>
#include <machine/sysarch.h>
@@ -58,7 +58,7 @@ void __clear_cache(void *start, void *end) {
#elif defined(_WIN32) && (defined(__arm__) || defined(__aarch64__))
FlushInstructionCache(GetCurrentProcess(), start, end - start);
#elif defined(__arm__) && !defined(__APPLE__)
-#if defined(__FreeBSD__) || defined(__NetBSD__)
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
struct arm_sync_icache_args arg;
arg.addr = (uintptr_t)start;
diff --git a/compiler-rt/lib/builtins/cpu_model.c b/compiler-rt/lib/builtins/cpu_model.c
index 8346bb62dcfb..468bcc84cbcb 100644
--- a/compiler-rt/lib/builtins/cpu_model.c
+++ b/compiler-rt/lib/builtins/cpu_model.c
@@ -277,7 +277,7 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
const unsigned *Features,
unsigned *Type, unsigned *Subtype) {
#define testFeature(F) \
- (Features[F / 32] & (F % 32)) != 0
+ (Features[F / 32] & (1 << (F % 32))) != 0
// We select CPU strings to match the code in Host.cpp, but we don't use them
// in compiler-rt.
diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c
index 57d8dec423cc..82369357e986 100644
--- a/compiler-rt/lib/profile/GCDAProfiling.c
+++ b/compiler-rt/lib/profile/GCDAProfiling.c
@@ -210,22 +210,6 @@ static void write_64bit_value(uint64_t i) {
write_32bit_value(hi);
}
-static uint32_t length_of_string(const char *s) {
- return (strlen(s) / 4) + 1;
-}
-
-// Remove when we support libgcov 9 current_working_directory.
-#if !defined(_MSC_VER) && defined(__clang__)
-__attribute__((unused))
-#endif
-static void
-write_string(const char *s) {
- uint32_t len = length_of_string(s);
- write_32bit_value(len);
- write_bytes(s, strlen(s));
- write_bytes("\0\0\0\0", 4 - (strlen(s) % 4));
-}
-
static uint32_t read_32bit_value() {
uint32_t val;
@@ -632,6 +616,9 @@ void llvm_writeout_files(void) {
// __attribute__((destructor)) and destructors whose priorities are greater than
// 100 run before this function and can thus be tracked. The priority is
// compatible with GCC 7 onwards.
+#if __GNUC__ >= 9
+#pragma GCC diagnostic ignored "-Wprio-ctor-dtor"
+#endif
__attribute__((destructor(100)))
#endif
static void llvm_writeout_and_clear(void) {
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
index ae54a8cf105e..d80280d9bf8c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
@@ -129,6 +129,12 @@ struct __sanitizer_shmid_ds {
void *_shm_internal;
};
+struct __sanitizer_protoent {
+ char *p_name;
+ char **p_aliases;
+ int p_proto;
+};
+
struct __sanitizer_netent {
char *n_name;
char **n_aliases;
diff --git a/libunwind/src/AddressSpace.hpp b/libunwind/src/AddressSpace.hpp
index e40c23291f84..93395ffb3b1d 100644
--- a/libunwind/src/AddressSpace.hpp
+++ b/libunwind/src/AddressSpace.hpp
@@ -473,8 +473,8 @@ static bool checkAddrInSegment(const Elf_Phdr *phdr, size_t image_base,
return false;
}
-int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo, size_t pinfo_size,
- void *data) {
+static int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo,
+ size_t pinfo_size, void *data) {
auto cbdata = static_cast<dl_iterate_cb_data *>(data);
if (pinfo->dlpi_phnum == 0 || cbdata->targetAddr < pinfo->dlpi_addr)
return 0;
@@ -523,7 +523,8 @@ int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo, size_t pinfo_size,
// Given all the #ifdef's above, the code here is for
// defined(LIBUNWIND_ARM_EHABI)
-int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo, size_t, void *data) {
+static int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo, size_t,
+ void *data) {
auto *cbdata = static_cast<dl_iterate_cb_data *>(data);
bool found_obj = false;
bool found_hdr = false;
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 082de5b8c1d6..0188f0971a75 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -599,6 +599,9 @@ void Writer::finalizeAddresses() {
void Writer::run() {
ScopedTimer t1(codeLayoutTimer);
+ // First, clear the output sections from previous runs
+ outputSections.clear();
+
createImportTables();
createSections();
createMiscChunks();
diff --git a/lld/ELF/DWARF.cpp b/lld/ELF/DWARF.cpp
index 24c44730bf64..5767f6020f93 100644
--- a/lld/ELF/DWARF.cpp
+++ b/lld/ELF/DWARF.cpp
@@ -26,7 +26,12 @@ using namespace lld;
using namespace lld::elf;
template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *obj) {
- for (InputSectionBase *sec : obj->getSections()) {
+ // Get the ELF sections to retrieve sh_flags. See the SHF_GROUP comment below.
+ ArrayRef<typename ELFT::Shdr> objSections =
+ CHECK(obj->getObj().sections(), obj);
+ assert(objSections.size() == obj->getSections().size());
+ for (auto it : llvm::enumerate(obj->getSections())) {
+ InputSectionBase *sec = it.value();
if (!sec)
continue;
@@ -35,7 +40,6 @@ template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *obj) {
.Case(".debug_addr", &addrSection)
.Case(".debug_gnu_pubnames", &gnuPubnamesSection)
.Case(".debug_gnu_pubtypes", &gnuPubtypesSection)
- .Case(".debug_info", &infoSection)
.Case(".debug_loclists", &loclistsSection)
.Case(".debug_ranges", &rangesSection)
.Case(".debug_rnglists", &rnglistsSection)
@@ -53,6 +57,20 @@ template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *obj) {
strSection = toStringRef(sec->data());
else if (sec->name == ".debug_line_str")
lineStrSection = toStringRef(sec->data());
+ else if (sec->name == ".debug_info" &&
+ !(objSections[it.index()].sh_flags & ELF::SHF_GROUP)) {
+ // In DWARF v5, -fdebug-types-section places type units in .debug_info
+ // sections in COMDAT groups. They are not compile units and thus should
+ // be ignored for .gdb_index/diagnostics purposes.
+ //
+ // We use a simple heuristic: the compile unit does not have the SHF_GROUP
+ // flag. If we place compile units in COMDAT groups in the future, we may
+ // need to perform a lightweight parsing. We drop the SHF_GROUP flag when
+ // the InputSection was created, so we need to retrieve sh_flags from the
+ // associated ELF section header.
+ infoSection.Data = toStringRef(sec->data());
+ infoSection.sec = sec;
+ }
}
}
diff --git a/lld/ELF/DWARF.h b/lld/ELF/DWARF.h
index a12dae6e9960..900c63de26ff 100644
--- a/lld/ELF/DWARF.h
+++ b/lld/ELF/DWARF.h
@@ -32,6 +32,10 @@ public:
f(infoSection);
}
+ InputSection *getInfoSection() const {
+ return cast<InputSection>(infoSection.sec);
+ }
+
const llvm::DWARFSection &getLoclistsSection() const override {
return loclistsSection;
}
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 72e2ebff9b8c..6de2cd65b973 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -180,7 +180,7 @@ void LinkerScript::addSymbol(SymbolAssignment *cmd) {
// write expressions like this: `alignment = 16; . = ALIGN(., alignment)`.
uint64_t symValue = value.sec ? 0 : value.getValue();
- Defined newSym(nullptr, cmd->name, STB_GLOBAL, visibility, STT_NOTYPE,
+ Defined newSym(nullptr, cmd->name, STB_GLOBAL, visibility, value.type,
symValue, 0, sec);
Symbol *sym = symtab->insert(cmd->name);
@@ -317,6 +317,7 @@ void LinkerScript::assignSymbol(SymbolAssignment *cmd, bool inSec) {
cmd->sym->section = v.sec;
cmd->sym->value = v.getSectionOffset();
}
+ cmd->sym->type = v.type;
}
static std::string getFilename(InputFile *file) {
@@ -1215,8 +1216,14 @@ ExprValue LinkerScript::getSymbolValue(StringRef name, const Twine &loc) {
}
if (Symbol *sym = symtab->find(name)) {
- if (auto *ds = dyn_cast<Defined>(sym))
- return {ds->section, false, ds->value, loc};
+ if (auto *ds = dyn_cast<Defined>(sym)) {
+ ExprValue v{ds->section, false, ds->value, loc};
+ // Retain the original st_type, so that the alias will get the same
+ // behavior in relocation processing. Any operation will reset st_type to
+ // STT_NOTYPE.
+ v.type = ds->type;
+ return v;
+ }
if (isa<SharedSymbol>(sym))
if (!errorOnMissingSection)
return {nullptr, false, 0, loc};
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index ec4fc22db486..4a1a5fd71b67 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -59,6 +59,10 @@ struct ExprValue {
uint64_t val;
uint64_t alignment = 1;
+ // The original st_type if the expression represents a symbol. Any operation
+ // resets type to STT_NOTYPE.
+ uint8_t type = llvm::ELF::STT_NOTYPE;
+
// Original source location. Used for error messages.
std::string loc;
};
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 7e9e76b070ec..881c375a1159 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -77,10 +77,14 @@ OutputSection::OutputSection(StringRef name, uint32_t type, uint64_t flags)
// to be allocated for nobits sections. Other ones don't require
// any special treatment on top of progbits, so there doesn't
// seem to be a harm in merging them.
+//
+// NOTE: clang since rL252300 emits SHT_X86_64_UNWIND .eh_frame sections. Allow
+// them to be merged into SHT_PROGBITS .eh_frame (GNU as .cfi_*).
static bool canMergeToProgbits(unsigned type) {
return type == SHT_NOBITS || type == SHT_PROGBITS || type == SHT_INIT_ARRAY ||
type == SHT_PREINIT_ARRAY || type == SHT_FINI_ARRAY ||
- type == SHT_NOTE;
+ type == SHT_NOTE ||
+ (type == SHT_X86_64_UNWIND && config->emachine == EM_X86_64);
}
// Record that isec will be placed in the OutputSection. isec does not become
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 731b9f658060..09f771d12359 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -28,6 +28,7 @@
#include "lld/Common/Strings.h"
#include "lld/Common/Version.h"
#include "llvm/ADT/SetOperations.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
@@ -2653,15 +2654,6 @@ void GdbIndexSection::initOutputSize() {
}
}
-static std::vector<InputSection *> getDebugInfoSections() {
- std::vector<InputSection *> ret;
- for (InputSectionBase *s : inputSections)
- if (InputSection *isec = dyn_cast<InputSection>(s))
- if (isec->name == ".debug_info")
- ret.push_back(isec);
- return ret;
-}
-
static std::vector<GdbIndexSection::CuEntry> readCuList(DWARFContext &dwarf) {
std::vector<GdbIndexSection::CuEntry> ret;
for (std::unique_ptr<DWARFUnit> &cu : dwarf.compile_units())
@@ -2815,30 +2807,40 @@ createSymbols(ArrayRef<std::vector<GdbIndexSection::NameAttrEntry>> nameAttrs,
// Returns a newly-created .gdb_index section.
template <class ELFT> GdbIndexSection *GdbIndexSection::create() {
- std::vector<InputSection *> sections = getDebugInfoSections();
-
- // .debug_gnu_pub{names,types} are useless in executables.
- // They are present in input object files solely for creating
- // a .gdb_index. So we can remove them from the output.
- for (InputSectionBase *s : inputSections)
+ // Collect InputFiles with .debug_info. See the comment in
+ // LLDDwarfObj<ELFT>::LLDDwarfObj. If we do lightweight parsing in the future,
+ // note that isec->data() may uncompress the full content, which should be
+ // parallelized.
+ SetVector<InputFile *> files;
+ for (InputSectionBase *s : inputSections) {
+ InputSection *isec = dyn_cast<InputSection>(s);
+ if (!isec)
+ continue;
+ // .debug_gnu_pub{names,types} are useless in executables.
+ // They are present in input object files solely for creating
+ // a .gdb_index. So we can remove them from the output.
if (s->name == ".debug_gnu_pubnames" || s->name == ".debug_gnu_pubtypes")
s->markDead();
+ else if (isec->name == ".debug_info")
+ files.insert(isec->file);
+ }
- std::vector<GdbChunk> chunks(sections.size());
- std::vector<std::vector<NameAttrEntry>> nameAttrs(sections.size());
+ std::vector<GdbChunk> chunks(files.size());
+ std::vector<std::vector<NameAttrEntry>> nameAttrs(files.size());
- parallelForEachN(0, sections.size(), [&](size_t i) {
+ parallelForEachN(0, files.size(), [&](size_t i) {
// To keep memory usage low, we don't want to keep cached DWARFContext, so
// avoid getDwarf() here.
- ObjFile<ELFT> *file = sections[i]->getFile<ELFT>();
+ ObjFile<ELFT> *file = cast<ObjFile<ELFT>>(files[i]);
DWARFContext dwarf(std::make_unique<LLDDwarfObj<ELFT>>(file));
+ auto &dobj = static_cast<const LLDDwarfObj<ELFT> &>(dwarf.getDWARFObj());
- chunks[i].sec = sections[i];
+ // If the are multiple compile units .debug_info (very rare ld -r --unique),
+ // this only picks the last one. Other address ranges are lost.
+ chunks[i].sec = dobj.getInfoSection();
chunks[i].compilationUnits = readCuList(dwarf);
- chunks[i].addressAreas = readAddressAreas(dwarf, sections[i]);
- nameAttrs[i] = readPubNamesAndTypes<ELFT>(
- static_cast<const LLDDwarfObj<ELFT> &>(dwarf.getDWARFObj()),
- chunks[i].compilationUnits);
+ chunks[i].addressAreas = readAddressAreas(dwarf, chunks[i].sec);
+ nameAttrs[i] = readPubNamesAndTypes<ELFT>(dobj, chunks[i].compilationUnits);
});
auto *ret = make<GdbIndexSection>();
diff --git a/lld/docs/ELF/linker_script.rst b/lld/docs/ELF/linker_script.rst
index 0f409b2020ac..debddbf511b6 100644
--- a/lld/docs/ELF/linker_script.rst
+++ b/lld/docs/ELF/linker_script.rst
@@ -17,6 +17,25 @@ possible. We reserve the right to make different implementation choices where
it is appropriate for LLD. Intentional deviations will be documented in this
file.
+Symbol assignment
+~~~~~~~~~~~~~~~~~
+
+A symbol assignment looks like:
+
+::
+
+ symbol = expression;
+ symbol += expression;
+
+The first form defines ``symbol``. If ``symbol`` is already defined, it will be
+overridden. The other form requires ``symbol`` to be already defined.
+
+For a simple assignment like ``alias = aliasee;``, the ``st_type`` field is
+copied from the original symbol. Any arithmetic operation (e.g. ``+ 0`` will
+reset ``st_type`` to ``STT_NOTYPE``.
+
+The ``st_size`` field is set to 0.
+
Output section description
~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst
index 513ad37e278e..880f933e51be 100644
--- a/lld/docs/ReleaseNotes.rst
+++ b/lld/docs/ReleaseNotes.rst
@@ -24,22 +24,143 @@ Non-comprehensive list of changes in this release
ELF Improvements
----------------
-* New ``--time-trace`` option records a time trace file that can be viewed in
+* ``--lto-emit-asm`` is added to emit assembly output for debugging purposes.
+ (`D77231 <https://reviews.llvm.org/D77231>`_)
+* ``--lto-whole-program-visibility`` is added to specify that classes have hidden LTO visibility in LTO and ThinLTO links of source files compiled with ``-fwhole-program-vtables``. See `LTOVisibility <https://clang.llvm.org/docs/LTOVisibility.html>`_ for details.
+ (`D71913 <https://reviews.llvm.org/D71913>`_)
+* ``--print-archive-stats=`` is added to print the number of members and the number of fetched members for each archive.
+ The feature is similar to GNU gold's ``--print-symbol-counts=``.
+ (`D78983 <https://reviews.llvm.org/D78983>`_)
+* ``--shuffle-sections=`` is added to introduce randomization in the output to help reduce measurement bias and detect static initialization order fiasco.
+ (`D74791 <https://reviews.llvm.org/D74791>`_)
+ (`D74887 <https://reviews.llvm.org/D74887>`_)
+* ``--time-trace`` is added. It records a time trace file that can be viewed in
chrome://tracing. The file can be specified with ``--time-trace-file``.
Trace granularity can be specified with ``--time-trace-granularity``.
(`D71060 <https://reviews.llvm.org/D71060>`_)
-* For ARM architectures the default max page size was increased to 64k.
- This increases compatibility with systems where a non standard page
- size was configured. This also is inline with GNU ld defaults.
- (`D77330 <https://reviews.llvm.org/D77330>`_)
-* ...
+* ``--thinlto-single-module`` is added to compile a subset of modules in ThinLTO for debugging purposes.
+ (`D80406 <https://reviews.llvm.org/D80406>`_)
+* ``--unique`` is added to create separate output sections for orphan sections.
+ (`D75536 <https://reviews.llvm.org/D75536>`_)
+* ``--warn-backrefs`` has been improved to emulate GNU ld's archive semantics.
+ If a link passes with warnings from ``--warn-backrefs``, it almost assuredly
+ means that the link will fail with GNU ld, or the symbol will get different
+ resolutions in GNU ld and LLD. ``--warn-backrefs-exclude=`` is added to
+ exclude known issues.
+ (`D77522 <https://reviews.llvm.org/D77522>`_)
+ (`D77630 <https://reviews.llvm.org/D77630>`_)
+ (`D77512 <https://reviews.llvm.org/D77512>`_)
+* ``--no-relax`` is accepted but ignored. The Linux kernel's RISC-V port uses this option.
+ (`D81359 <https://reviews.llvm.org/D81359>`_)
+* ``--rosegment`` (default) is added to complement ``--no-rosegment``.
+ GNU gold from 2.35 onwards support both options.
+* ``--threads=N`` is added. The default uses all threads.
+ (`D76885 <https://reviews.llvm.org/D76885>`_)
+* ``--wrap`` has better compatibility with GNU ld.
+* ``-z dead-reloc-in-nonalloc=<section_glob>=<value>`` is added to resolve an absolute relocation
+ referencing a discarded symbol.
+ (`D83264 <https://reviews.llvm.org/D83264>`_)
+* Changed tombstone values to (``.debug_ranges``/``.debug_loc``) 1 and (other ``.debug_*``) 0.
+ A tombstone value is the computed value of a relocation referencing a discarded symbol (``--gc-sections``, ICF or ``/DISCARD/``).
+ (`D84825 <https://reviews.llvm.org/D84825>`_)
+ In the future many .debug_* may switch to 0xffffffff/0xffffffffffffffff as the tombstone value.
+* ``-z keep-text-section-prefix`` moves ``.text.unknown.*`` input sections to ``.text.unknown``.
+* ``-z rel`` and ``-z rela`` are added to select the REL/RELA format for dynamic relocations.
+ The default is target specific and typically matches the form used in relocatable objects.
+* ``-z start-stop-visibility={default,protected,internal,hidden}`` is added.
+ GNU ld/gold from 2.35 onwards support this option.
+ (`D55682 <https://reviews.llvm.org/D55682>`_)
+* When ``-r`` or ``--emit-relocs`` is specified, the GNU ld compatible
+ ``--discard-all`` and ``--discard-locals`` semantics are implemented.
+ (`D77807 <https://reviews.llvm.org/D77807>`_)
+* ``--emit-relocs --strip-debug`` can now be used together.
+ (`D74375 <https://reviews.llvm.org/D74375>`_)
+* ``--gdb-index`` supports DWARF v5.
+ (`D79061 <https://reviews.llvm.org/D79061>`_)
+ (`D85579 <https://reviews.llvm.org/D85579>`_)
+* ``-r`` allows SHT_X86_64_UNWIND to be merged into SHT_PROGBITS.
+ This allows clang/GCC produced object files to be mixed together.
+ (`D85785 <https://reviews.llvm.org/D85785>`_)
+* Better linker script support related to output section alignments and LMA regions.
+ (`D74286 <https://reviews.llvm.org/D75724>`_)
+ (`D74297 <https://reviews.llvm.org/D75724>`_)
+ (`D75724 <https://reviews.llvm.org/D75724>`_)
+ (`D81986 <https://reviews.llvm.org/D81986>`_)
+* In a input section description, the filename can be specified in double quotes.
+ ``archive:file`` syntax is added.
+ (`D72517 <https://reviews.llvm.org/D72517>`_)
+ (`D75100 <https://reviews.llvm.org/D75100>`_)
+* Linker script specified empty ``(.init|.preinit|.fini)_array`` are allowed with RELRO.
+ (`D76915 <https://reviews.llvm.org/D76915>`_)
+* ``INSERT AFTER`` and ``INSERT BEFORE`` work for orphan sections now.
+ (`D74375 <https://reviews.llvm.org/D74375>`_)
+* ``INPUT_SECTION_FLAGS`` is supported in linker scripts.
+ (`D72745 <https://reviews.llvm.org/D72745>`_)
+* ``DF_1_PIE`` is set for position-independent executables.
+ (`D80872 <https://reviews.llvm.org/D80872>`_)
+* For a symbol assignment ``alias = aliasee;``, ``alias`` inherits the ``aliasee``'s symbol type.
+ (`D86263 <https://reviews.llvm.org/D86263>`_)
+* ``SHT_GNU_verneed`` in shared objects are parsed, and versioned undefined symbols in shared objects are respected.
+ (`D80059 <https://reviews.llvm.org/D80059>`_)
+* SHF_LINK_ORDER and non-SHF_LINK_ORDER sections can be mixed along as the SHF_LINK_ORDER components are contiguous.
+ (`D77007 <https://reviews.llvm.org/D77007>`_)
+* An out-of-range relocation diagnostic mentions the referenced symbol now.
+ (`D73518 <https://reviews.llvm.org/D73518>`_)
+* AArch64: ``R_AARCH64_PLT32`` is supported.
+ (`D81184 <https://reviews.llvm.org/D81184>`_)
+* ARM: SBREL type relocations are supported.
+ (`D74375 <https://reviews.llvm.org/D74375>`_)
+* ARM: ``R_ARM_ALU_PC_G0``, ``R_ARM_LDR_PC_G0``, ``R_ARM_THUMB_PC8`` and ``R_ARM_THUMB__PC12`` are supported.
+ (`D75349 <https://reviews.llvm.org/D75349>`_)
+ (`D77200 <https://reviews.llvm.org/D77200>`_)
+* ARM: various improvements to .ARM.exidx: ``/DISCARD/`` support for a subset, out-of-range handling, support for non monotonic section order.
+ (`PR44824 <https://llvm.org/PR44824>`_)
+* AVR: many relocation types are supported.
+ (`D78741 <https://reviews.llvm.org/D78741>`_)
+* Hexagon: General Dynamic and some other relocation types are supported.
+* PPC: Canonical PLT and range extension thunks with addends are supported.
+ (`D73399 <https://reviews.llvm.org/D73399>`_)
+ (`D73424 <https://reviews.llvm.org/D73424>`_)
+ (`D75394 <https://reviews.llvm.org/D75394>`_)
+* PPC and PPC64: copy relocations.
+ (`D73255 <https://reviews.llvm.org/D73255>`_)
+* PPC64: ``_savegpr[01]_{14..31}`` and ``_restgpr[01]_{14..31}`` can be synthesized.
+ (`D79977 <https://reviews.llvm.org/D79977>`_)
+* PPC64: ``R_PPC64_GOT_PCREL34`` and ``R_PPC64_REL24_NOTOC`` are supported. r2 save stub is supported.
+ (`D81948 <https://reviews.llvm.org/D81948>`_)
+ (`D82950 <https://reviews.llvm.org/D82950>`_)
+ (`D82816 <https://reviews.llvm.org/D82816>`_)
+* RISC-V: ``R_RISCV_IRELATIVE`` is supported.
+ (`D74022 <https://reviews.llvm.org/D74022>`_)
+* RISC-V: ``R_RISCV_ALIGN`` is errored because GNU ld style linker relaxation is not supported.
+ (`D71820 <https://reviews.llvm.org/D71820>`_)
+* SPARCv9: more relocation types are supported.
+ (`D77672 <https://reviews.llvm.org/D77672>`_)
Breaking changes
----------------
* One-dash form of some long option (``--thinlto-*``, ``--lto-*``, ``--shuffle-sections=``)
are no longer supported.
+ (`D79371 <https://reviews.llvm.org/D79371>`_)
* ``--export-dynamic-symbol`` no longer implies ``-u``.
+ The new behavior matches GNU ld from binutils 2.35 onwards.
+ (`D80487 <https://reviews.llvm.org/D80487>`_)
+* ARM: the default max page size was increased from 4096 to 65536.
+ This increases compatibility with systems where a non standard page
+ size was configured. This also is inline with GNU ld defaults.
+ (`D77330 <https://reviews.llvm.org/D77330>`_)
+* ARM: for non-STT_FUNC symbols, Thumb interworking thunks are not added and BL/BLX are not substituted.
+ (`D73474 <https://reviews.llvm.org/D73474>`_)
+ (`D73542 <https://reviews.llvm.org/D73542>`_)
+* AArch64: ``--force-bti`` is renamed to ``-z force-bti`. ``--pac-plt`` is renamed to ``-z pac-plt``.
+ This change is compatibile with GNU ld.
+* A readonly ``PT_LOAD`` is created in the presence of a ``SECTIONS`` command.
+ The new behavior is consistent with the longstanding behavior in the absence of a SECTIONS command.
+* Orphan section names like ``.rodata.foo`` and ``.text.foo`` are not grouped into ``.rodata`` and ``.text`` in the presence of a ``SECTIONS`` command.
+ The new behavior matches GNU ld.
+ (`D75225 <https://reviews.llvm.org/D75225>`_)
+* ``--no-threads`` is removed. Use ``--threads=1`` instead. ``--threads`` (no-op) is removed.
COFF Improvements
-----------------
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index dad56376005c..707344f99fcb 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -2401,21 +2401,13 @@ lldb::addr_t Target::GetPersistentSymbol(ConstString name) {
llvm::Expected<lldb_private::Address> Target::GetEntryPointAddress() {
Module *exe_module = GetExecutableModulePointer();
- llvm::Error error = llvm::Error::success();
- assert(!error); // Check the success value when assertions are enabled.
- if (!exe_module || !exe_module->GetObjectFile()) {
- error = llvm::make_error<llvm::StringError>("No primary executable found",
- llvm::inconvertibleErrorCode());
- } else {
+ // Try to find the entry point address in the primary executable.
+ const bool has_primary_executable = exe_module && exe_module->GetObjectFile();
+ if (has_primary_executable) {
Address entry_addr = exe_module->GetObjectFile()->GetEntryPointAddress();
if (entry_addr.IsValid())
return entry_addr;
-
- error = llvm::make_error<llvm::StringError>(
- "Could not find entry point address for executable module \"" +
- exe_module->GetFileSpec().GetFilename().GetStringRef() + "\"",
- llvm::inconvertibleErrorCode());
}
const ModuleList &modules = GetImages();
@@ -2426,14 +2418,21 @@ llvm::Expected<lldb_private::Address> Target::GetEntryPointAddress() {
continue;
Address entry_addr = module_sp->GetObjectFile()->GetEntryPointAddress();
- if (entry_addr.IsValid()) {
- // Discard the error.
- llvm::consumeError(std::move(error));
+ if (entry_addr.IsValid())
return entry_addr;
- }
}
- return std::move(error);
+ // We haven't found the entry point address. Return an appropriate error.
+ if (!has_primary_executable)
+ return llvm::make_error<llvm::StringError>(
+ "No primary executable found and could not find entry point address in "
+ "any executable module",
+ llvm::inconvertibleErrorCode());
+
+ return llvm::make_error<llvm::StringError>(
+ "Could not find entry point address for primary executable module \"" +
+ exe_module->GetFileSpec().GetFilename().GetStringRef() + "\"",
+ llvm::inconvertibleErrorCode());
}
lldb::addr_t Target::GetCallableLoadAddress(lldb::addr_t load_addr,
diff --git a/llvm/include/llvm/ADT/CoalescingBitVector.h b/llvm/include/llvm/ADT/CoalescingBitVector.h
index f8c8fec0ec9e..0a7dcfe22631 100644
--- a/llvm/include/llvm/ADT/CoalescingBitVector.h
+++ b/llvm/include/llvm/ADT/CoalescingBitVector.h
@@ -34,15 +34,14 @@ namespace llvm {
/// performance for non-sequential find() operations.
///
/// \tparam IndexT - The type of the index into the bitvector.
-/// \tparam N - The first N coalesced intervals of set bits are stored in-place.
-template <typename IndexT, unsigned N = 16> class CoalescingBitVector {
+template <typename IndexT> class CoalescingBitVector {
static_assert(std::is_unsigned<IndexT>::value,
"Index must be an unsigned integer.");
- using ThisT = CoalescingBitVector<IndexT, N>;
+ using ThisT = CoalescingBitVector<IndexT>;
/// An interval map for closed integer ranges. The mapped values are unused.
- using MapT = IntervalMap<IndexT, char, N>;
+ using MapT = IntervalMap<IndexT, char>;
using UnderlyingIterator = typename MapT::const_iterator;
diff --git a/llvm/include/llvm/Analysis/InstructionSimplify.h b/llvm/include/llvm/Analysis/InstructionSimplify.h
index 2a39a4e09087..b5ae54fb98bc 100644
--- a/llvm/include/llvm/Analysis/InstructionSimplify.h
+++ b/llvm/include/llvm/Analysis/InstructionSimplify.h
@@ -268,6 +268,12 @@ Value *SimplifyFreezeInst(Value *Op, const SimplifyQuery &Q);
Value *SimplifyInstruction(Instruction *I, const SimplifyQuery &Q,
OptimizationRemarkEmitter *ORE = nullptr);
+/// See if V simplifies when its operand Op is replaced with RepOp.
+/// AllowRefinement specifies whether the simplification can be a refinement,
+/// or whether it needs to be strictly identical.
+Value *SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
+ const SimplifyQuery &Q, bool AllowRefinement);
+
/// Replace all uses of 'I' with 'SimpleV' and simplify the uses recursively.
///
/// This first performs a normal RAUW of I with SimpleV. It then recursively
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
index 95eed59f1b3d..a2a440d65fd8 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
+++ b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
@@ -210,12 +210,19 @@ public:
/// Return the (LLVM-IR) string describing the default source location.
Constant *getOrCreateDefaultSrcLocStr();
+ /// Return the (LLVM-IR) string describing the source location identified by
+ /// the arguments.
+ Constant *getOrCreateSrcLocStr(StringRef FunctionName, StringRef FileName,
+ unsigned Line, unsigned Column);
+
/// Return the (LLVM-IR) string describing the source location \p Loc.
Constant *getOrCreateSrcLocStr(const LocationDescription &Loc);
/// Return an ident_t* encoding the source location \p SrcLocStr and \p Flags.
+ /// TODO: Create a enum class for the Reserve2Flags
Value *getOrCreateIdent(Constant *SrcLocStr,
- omp::IdentFlag Flags = omp::IdentFlag(0));
+ omp::IdentFlag Flags = omp::IdentFlag(0),
+ unsigned Reserve2Flags = 0);
/// Generate control flow and cleanup for cancellation.
///
@@ -280,7 +287,7 @@ public:
StringMap<Constant *> SrcLocStrMap;
/// Map to remember existing ident_t*.
- DenseMap<std::pair<Constant *, uint64_t>, GlobalVariable *> IdentMap;
+ DenseMap<std::pair<Constant *, uint64_t>, Value *> IdentMap;
/// Helper that contains information about regions we need to outline
/// during finalization.
diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h
index ffec4ff64ca6..b90480ebc59e 100644
--- a/llvm/include/llvm/IR/IRBuilder.h
+++ b/llvm/include/llvm/IR/IRBuilder.h
@@ -386,8 +386,12 @@ public:
/// filled in with the null terminated string value specified. The new global
/// variable will be marked mergable with any others of the same contents. If
/// Name is specified, it is the name of the global variable created.
+ ///
+ /// If no module is given via \p M, it is take from the insertion point basic
+ /// block.
GlobalVariable *CreateGlobalString(StringRef Str, const Twine &Name = "",
- unsigned AddressSpace = 0);
+ unsigned AddressSpace = 0,
+ Module *M = nullptr);
/// Get a constant value representing either true or false.
ConstantInt *getInt1(bool V) {
@@ -1934,9 +1938,13 @@ public:
/// Same as CreateGlobalString, but return a pointer with "i8*" type
/// instead of a pointer to array of i8.
+ ///
+ /// If no module is given via \p M, it is take from the insertion point basic
+ /// block.
Constant *CreateGlobalStringPtr(StringRef Str, const Twine &Name = "",
- unsigned AddressSpace = 0) {
- GlobalVariable *GV = CreateGlobalString(Str, Name, AddressSpace);
+ unsigned AddressSpace = 0,
+ Module *M = nullptr) {
+ GlobalVariable *GV = CreateGlobalString(Str, Name, AddressSpace, M);
Constant *Zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
Constant *Indices[] = {Zero, Zero};
return ConstantExpr::getInBoundsGetElementPtr(GV->getValueType(), GV,
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index d3bdf9d6aafd..e744a966a104 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3810,10 +3810,10 @@ Value *llvm::SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
return ::SimplifyFCmpInst(Predicate, LHS, RHS, FMF, Q, RecursionLimit);
}
-/// See if V simplifies when its operand Op is replaced with RepOp.
-static const Value *SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
- const SimplifyQuery &Q,
- unsigned MaxRecurse) {
+static Value *SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
+ const SimplifyQuery &Q,
+ bool AllowRefinement,
+ unsigned MaxRecurse) {
// Trivial replacement.
if (V == Op)
return RepOp;
@@ -3826,23 +3826,19 @@ static const Value *SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
if (!I)
return nullptr;
+ // Consider:
+ // %cmp = icmp eq i32 %x, 2147483647
+ // %add = add nsw i32 %x, 1
+ // %sel = select i1 %cmp, i32 -2147483648, i32 %add
+ //
+ // We can't replace %sel with %add unless we strip away the flags (which will
+ // be done in InstCombine).
+ // TODO: This is unsound, because it only catches some forms of refinement.
+ if (!AllowRefinement && canCreatePoison(I))
+ return nullptr;
+
// If this is a binary operator, try to simplify it with the replaced op.
if (auto *B = dyn_cast<BinaryOperator>(I)) {
- // Consider:
- // %cmp = icmp eq i32 %x, 2147483647
- // %add = add nsw i32 %x, 1
- // %sel = select i1 %cmp, i32 -2147483648, i32 %add
- //
- // We can't replace %sel with %add unless we strip away the flags.
- // TODO: This is an unusual limitation because better analysis results in
- // worse simplification. InstCombine can do this fold more generally
- // by dropping the flags. Remove this fold to save compile-time?
- if (isa<OverflowingBinaryOperator>(B))
- if (Q.IIQ.hasNoSignedWrap(B) || Q.IIQ.hasNoUnsignedWrap(B))
- return nullptr;
- if (isa<PossiblyExactOperator>(B) && Q.IIQ.isExact(B))
- return nullptr;
-
if (MaxRecurse) {
if (B->getOperand(0) == Op)
return SimplifyBinOp(B->getOpcode(), RepOp, B->getOperand(1), Q,
@@ -3909,6 +3905,13 @@ static const Value *SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
return nullptr;
}
+Value *llvm::SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
+ const SimplifyQuery &Q,
+ bool AllowRefinement) {
+ return ::SimplifyWithOpReplaced(V, Op, RepOp, Q, AllowRefinement,
+ RecursionLimit);
+}
+
/// Try to simplify a select instruction when its condition operand is an
/// integer comparison where one operand of the compare is a constant.
static Value *simplifySelectBitTest(Value *TrueVal, Value *FalseVal, Value *X,
@@ -3968,12 +3971,18 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
if (!match(CondVal, m_ICmp(Pred, m_Value(CmpLHS), m_Value(CmpRHS))))
return nullptr;
- if (ICmpInst::isEquality(Pred) && match(CmpRHS, m_Zero())) {
+ // Canonicalize ne to eq predicate.
+ if (Pred == ICmpInst::ICMP_NE) {
+ Pred = ICmpInst::ICMP_EQ;
+ std::swap(TrueVal, FalseVal);
+ }
+
+ if (Pred == ICmpInst::ICMP_EQ && match(CmpRHS, m_Zero())) {
Value *X;
const APInt *Y;
if (match(CmpLHS, m_And(m_Value(X), m_APInt(Y))))
if (Value *V = simplifySelectBitTest(TrueVal, FalseVal, X, Y,
- Pred == ICmpInst::ICMP_EQ))
+ /*TrueWhenUnset=*/true))
return V;
// Test for a bogus zero-shift-guard-op around funnel-shift or rotate.
@@ -3984,13 +3993,7 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
m_Value(ShAmt)));
// (ShAmt == 0) ? fshl(X, *, ShAmt) : X --> X
// (ShAmt == 0) ? fshr(*, X, ShAmt) : X --> X
- if (match(TrueVal, isFsh) && FalseVal == X && CmpLHS == ShAmt &&
- Pred == ICmpInst::ICMP_EQ)
- return X;
- // (ShAmt != 0) ? X : fshl(X, *, ShAmt) --> X
- // (ShAmt != 0) ? X : fshr(*, X, ShAmt) --> X
- if (match(FalseVal, isFsh) && TrueVal == X && CmpLHS == ShAmt &&
- Pred == ICmpInst::ICMP_NE)
+ if (match(TrueVal, isFsh) && FalseVal == X && CmpLHS == ShAmt)
return X;
// Test for a zero-shift-guard-op around rotates. These are used to
@@ -4004,11 +4007,6 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
m_Intrinsic<Intrinsic::fshr>(m_Value(X),
m_Deferred(X),
m_Value(ShAmt)));
- // (ShAmt != 0) ? fshl(X, X, ShAmt) : X --> fshl(X, X, ShAmt)
- // (ShAmt != 0) ? fshr(X, X, ShAmt) : X --> fshr(X, X, ShAmt)
- if (match(TrueVal, isRotate) && FalseVal == X && CmpLHS == ShAmt &&
- Pred == ICmpInst::ICMP_NE)
- return TrueVal;
// (ShAmt == 0) ? X : fshl(X, X, ShAmt) --> fshl(X, X, ShAmt)
// (ShAmt == 0) ? X : fshr(X, X, ShAmt) --> fshr(X, X, ShAmt)
if (match(FalseVal, isRotate) && TrueVal == X && CmpLHS == ShAmt &&
@@ -4025,27 +4023,20 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
// arms of the select. See if substituting this value into the arm and
// simplifying the result yields the same value as the other arm.
if (Pred == ICmpInst::ICMP_EQ) {
- if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, Q, MaxRecurse) ==
+ if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, Q,
+ /* AllowRefinement */ false, MaxRecurse) ==
TrueVal ||
- SimplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, Q, MaxRecurse) ==
+ SimplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, Q,
+ /* AllowRefinement */ false, MaxRecurse) ==
TrueVal)
return FalseVal;
- if (SimplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, Q, MaxRecurse) ==
+ if (SimplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, Q,
+ /* AllowRefinement */ true, MaxRecurse) ==
FalseVal ||
- SimplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, Q, MaxRecurse) ==
+ SimplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, Q,
+ /* AllowRefinement */ true, MaxRecurse) ==
FalseVal)
return FalseVal;
- } else if (Pred == ICmpInst::ICMP_NE) {
- if (SimplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, Q, MaxRecurse) ==
- FalseVal ||
- SimplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, Q, MaxRecurse) ==
- FalseVal)
- return TrueVal;
- if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, Q, MaxRecurse) ==
- TrueVal ||
- SimplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, Q, MaxRecurse) ==
- TrueVal)
- return TrueVal;
}
return nullptr;
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 3f053c7a38c7..39069e24e061 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -1592,11 +1592,16 @@ TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) {
assert(Element->getTag() == dwarf::DW_TAG_subrange_type);
const DISubrange *Subrange = cast<DISubrange>(Element);
- assert(!Subrange->getRawLowerBound() &&
- "codeview doesn't support subranges with lower bounds");
int64_t Count = -1;
- if (auto *CI = Subrange->getCount().dyn_cast<ConstantInt*>())
- Count = CI->getSExtValue();
+ // Calculate the count if either LowerBound is absent or is zero and
+ // either of Count or UpperBound are constant.
+ auto *LI = Subrange->getLowerBound().dyn_cast<ConstantInt *>();
+ if (!Subrange->getRawLowerBound() || (LI && (LI->getSExtValue() == 0))) {
+ if (auto *CI = Subrange->getCount().dyn_cast<ConstantInt*>())
+ Count = CI->getSExtValue();
+ else if (auto *UI = Subrange->getUpperBound().dyn_cast<ConstantInt*>())
+ Count = UI->getSExtValue() + 1; // LowerBound is zero
+ }
// Forward declarations of arrays without a size and VLAs use a count of -1.
// Emit a count of zero in these cases to match what MSVC does for arrays
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index e958f38e486b..ceeae14c1073 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1417,8 +1417,10 @@ static bool hasVectorBeenPadded(const DICompositeType *CTy) {
Elements[0]->getTag() == dwarf::DW_TAG_subrange_type &&
"Invalid vector element array, expected one element of type subrange");
const auto Subrange = cast<DISubrange>(Elements[0]);
- const auto CI = Subrange->getCount().get<ConstantInt *>();
- const int32_t NumVecElements = CI->getSExtValue();
+ const auto NumVecElements =
+ Subrange->getCount()
+ ? Subrange->getCount().get<ConstantInt *>()->getSExtValue()
+ : 0;
// Ensure we found the element count and that the actual size is wide
// enough to contain the requested size.
diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
index 70d6dcc2e3e2..4c4839ca6522 100644
--- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp
+++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
@@ -336,10 +336,8 @@ static bool isNopCopy(const MachineInstr &PreviousCopy, unsigned Src,
unsigned Def, const TargetRegisterInfo *TRI) {
Register PreviousSrc = PreviousCopy.getOperand(1).getReg();
Register PreviousDef = PreviousCopy.getOperand(0).getReg();
- if (Src == PreviousSrc) {
- assert(Def == PreviousDef);
+ if (Src == PreviousSrc && Def == PreviousDef)
return true;
- }
if (!TRI->isSubRegister(PreviousSrc, Src))
return false;
unsigned SubIdx = TRI->getSubRegIndex(PreviousSrc, Src);
diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp
index 5396f9f3a143..cf3eaba23bee 100644
--- a/llvm/lib/CodeGen/RegAllocFast.cpp
+++ b/llvm/lib/CodeGen/RegAllocFast.cpp
@@ -106,8 +106,13 @@ namespace {
/// that it is alive across blocks.
BitVector MayLiveAcrossBlocks;
- /// State of a register unit.
- enum RegUnitState {
+ /// State of a physical register.
+ enum RegState {
+ /// A disabled register is not available for allocation, but an alias may
+ /// be in use. A register can only be moved out of the disabled state if
+ /// all aliases are disabled.
+ regDisabled,
+
/// A free register is not currently in use and can be allocated
/// immediately without checking aliases.
regFree,
@@ -121,8 +126,8 @@ namespace {
/// register. In that case, LiveVirtRegs contains the inverse mapping.
};
- /// Maps each physical register to a RegUnitState enum or virtual register.
- std::vector<unsigned> RegUnitStates;
+ /// Maps each physical register to a RegState enum or a virtual register.
+ std::vector<unsigned> PhysRegState;
SmallVector<Register, 16> VirtDead;
SmallVector<MachineInstr *, 32> Coalesced;
@@ -184,10 +189,6 @@ namespace {
bool isLastUseOfLocalReg(const MachineOperand &MO) const;
void addKillFlag(const LiveReg &LRI);
-#ifndef NDEBUG
- bool verifyRegStateMapping(const LiveReg &LR) const;
-#endif
-
void killVirtReg(LiveReg &LR);
void killVirtReg(Register VirtReg);
void spillVirtReg(MachineBasicBlock::iterator MI, LiveReg &LR);
@@ -195,7 +196,7 @@ namespace {
void usePhysReg(MachineOperand &MO);
void definePhysReg(MachineBasicBlock::iterator MI, MCPhysReg PhysReg,
- unsigned NewState);
+ RegState NewState);
unsigned calcSpillCost(MCPhysReg PhysReg) const;
void assignVirtToPhysReg(LiveReg &, MCPhysReg PhysReg);
@@ -228,7 +229,7 @@ namespace {
bool mayLiveOut(Register VirtReg);
bool mayLiveIn(Register VirtReg);
- void dumpState() const;
+ void dumpState();
};
} // end anonymous namespace
@@ -239,8 +240,7 @@ INITIALIZE_PASS(RegAllocFast, "regallocfast", "Fast Register Allocator", false,
false)
void RegAllocFast::setPhysRegState(MCPhysReg PhysReg, unsigned NewState) {
- for (MCRegUnitIterator UI(PhysReg, TRI); UI.isValid(); ++UI)
- RegUnitStates[*UI] = NewState;
+ PhysRegState[PhysReg] = NewState;
}
/// This allocates space for the specified virtual register to be held on the
@@ -384,23 +384,12 @@ void RegAllocFast::addKillFlag(const LiveReg &LR) {
}
}
-#ifndef NDEBUG
-bool RegAllocFast::verifyRegStateMapping(const LiveReg &LR) const {
- for (MCRegUnitIterator UI(LR.PhysReg, TRI); UI.isValid(); ++UI) {
- if (RegUnitStates[*UI] != LR.VirtReg)
- return false;
- }
-
- return true;
-}
-#endif
-
/// Mark virtreg as no longer available.
void RegAllocFast::killVirtReg(LiveReg &LR) {
- assert(verifyRegStateMapping(LR) && "Broken RegState mapping");
addKillFlag(LR);
- MCPhysReg PhysReg = LR.PhysReg;
- setPhysRegState(PhysReg, regFree);
+ assert(PhysRegState[LR.PhysReg] == LR.VirtReg &&
+ "Broken RegState mapping");
+ setPhysRegState(LR.PhysReg, regFree);
LR.PhysReg = 0;
}
@@ -427,9 +416,7 @@ void RegAllocFast::spillVirtReg(MachineBasicBlock::iterator MI,
/// Do the actual work of spilling.
void RegAllocFast::spillVirtReg(MachineBasicBlock::iterator MI, LiveReg &LR) {
- assert(verifyRegStateMapping(LR) && "Broken RegState mapping");
-
- MCPhysReg PhysReg = LR.PhysReg;
+ assert(PhysRegState[LR.PhysReg] == LR.VirtReg && "Broken RegState mapping");
if (LR.Dirty) {
// If this physreg is used by the instruction, we want to kill it on the
@@ -437,7 +424,7 @@ void RegAllocFast::spillVirtReg(MachineBasicBlock::iterator MI, LiveReg &LR) {
bool SpillKill = MachineBasicBlock::iterator(LR.LastUse) != MI;
LR.Dirty = false;
- spill(MI, LR.VirtReg, PhysReg, SpillKill);
+ spill(MI, LR.VirtReg, LR.PhysReg, SpillKill);
if (SpillKill)
LR.LastUse = nullptr; // Don't kill register again
@@ -473,16 +460,53 @@ void RegAllocFast::usePhysReg(MachineOperand &MO) {
assert(PhysReg.isPhysical() && "Bad usePhysReg operand");
markRegUsedInInstr(PhysReg);
+ switch (PhysRegState[PhysReg]) {
+ case regDisabled:
+ break;
+ case regReserved:
+ PhysRegState[PhysReg] = regFree;
+ LLVM_FALLTHROUGH;
+ case regFree:
+ MO.setIsKill();
+ return;
+ default:
+ // The physreg was allocated to a virtual register. That means the value we
+ // wanted has been clobbered.
+ llvm_unreachable("Instruction uses an allocated register");
+ }
- for (MCRegUnitIterator UI(PhysReg, TRI); UI.isValid(); ++UI) {
- switch (RegUnitStates[*UI]) {
+ // Maybe a superregister is reserved?
+ for (MCRegAliasIterator AI(PhysReg, TRI, false); AI.isValid(); ++AI) {
+ MCPhysReg Alias = *AI;
+ switch (PhysRegState[Alias]) {
+ case regDisabled:
+ break;
case regReserved:
- RegUnitStates[*UI] = regFree;
+ // Either PhysReg is a subregister of Alias and we mark the
+ // whole register as free, or PhysReg is the superregister of
+ // Alias and we mark all the aliases as disabled before freeing
+ // PhysReg.
+ // In the latter case, since PhysReg was disabled, this means that
+ // its value is defined only by physical sub-registers. This check
+ // is performed by the assert of the default case in this loop.
+ // Note: The value of the superregister may only be partial
+ // defined, that is why regDisabled is a valid state for aliases.
+ assert((TRI->isSuperRegister(PhysReg, Alias) ||
+ TRI->isSuperRegister(Alias, PhysReg)) &&
+ "Instruction is not using a subregister of a reserved register");
LLVM_FALLTHROUGH;
case regFree:
+ if (TRI->isSuperRegister(PhysReg, Alias)) {
+ // Leave the superregister in the working set.
+ setPhysRegState(Alias, regFree);
+ MO.getParent()->addRegisterKilled(Alias, TRI, true);
+ return;
+ }
+ // Some other alias was in the working set - clear it.
+ setPhysRegState(Alias, regDisabled);
break;
default:
- llvm_unreachable("Unexpected reg unit state");
+ llvm_unreachable("Instruction uses an alias of an allocated register");
}
}
@@ -495,20 +519,38 @@ void RegAllocFast::usePhysReg(MachineOperand &MO) {
/// similar to defineVirtReg except the physreg is reserved instead of
/// allocated.
void RegAllocFast::definePhysReg(MachineBasicBlock::iterator MI,
- MCPhysReg PhysReg, unsigned NewState) {
- for (MCRegUnitIterator UI(PhysReg, TRI); UI.isValid(); ++UI) {
- switch (unsigned VirtReg = RegUnitStates[*UI]) {
+ MCPhysReg PhysReg, RegState NewState) {
+ markRegUsedInInstr(PhysReg);
+ switch (Register VirtReg = PhysRegState[PhysReg]) {
+ case regDisabled:
+ break;
+ default:
+ spillVirtReg(MI, VirtReg);
+ LLVM_FALLTHROUGH;
+ case regFree:
+ case regReserved:
+ setPhysRegState(PhysReg, NewState);
+ return;
+ }
+
+ // This is a disabled register, disable all aliases.
+ setPhysRegState(PhysReg, NewState);
+ for (MCRegAliasIterator AI(PhysReg, TRI, false); AI.isValid(); ++AI) {
+ MCPhysReg Alias = *AI;
+ switch (Register VirtReg = PhysRegState[Alias]) {
+ case regDisabled:
+ break;
default:
spillVirtReg(MI, VirtReg);
- break;
+ LLVM_FALLTHROUGH;
case regFree:
case regReserved:
+ setPhysRegState(Alias, regDisabled);
+ if (TRI->isSuperRegister(PhysReg, Alias))
+ return;
break;
}
}
-
- markRegUsedInInstr(PhysReg);
- setPhysRegState(PhysReg, NewState);
}
/// Return the cost of spilling clearing out PhysReg and aliases so it is free
@@ -521,24 +563,46 @@ unsigned RegAllocFast::calcSpillCost(MCPhysReg PhysReg) const {
<< " is already used in instr.\n");
return spillImpossible;
}
+ switch (Register VirtReg = PhysRegState[PhysReg]) {
+ case regDisabled:
+ break;
+ case regFree:
+ return 0;
+ case regReserved:
+ LLVM_DEBUG(dbgs() << printReg(VirtReg, TRI) << " corresponding "
+ << printReg(PhysReg, TRI) << " is reserved already.\n");
+ return spillImpossible;
+ default: {
+ LiveRegMap::const_iterator LRI = findLiveVirtReg(VirtReg);
+ assert(LRI != LiveVirtRegs.end() && LRI->PhysReg &&
+ "Missing VirtReg entry");
+ return LRI->Dirty ? spillDirty : spillClean;
+ }
+ }
- for (MCRegUnitIterator UI(PhysReg, TRI); UI.isValid(); ++UI) {
- switch (unsigned VirtReg = RegUnitStates[*UI]) {
+ // This is a disabled register, add up cost of aliases.
+ LLVM_DEBUG(dbgs() << printReg(PhysReg, TRI) << " is disabled.\n");
+ unsigned Cost = 0;
+ for (MCRegAliasIterator AI(PhysReg, TRI, false); AI.isValid(); ++AI) {
+ MCPhysReg Alias = *AI;
+ switch (Register VirtReg = PhysRegState[Alias]) {
+ case regDisabled:
+ break;
case regFree:
+ ++Cost;
break;
case regReserved:
- LLVM_DEBUG(dbgs() << printReg(VirtReg, TRI) << " corresponding "
- << printReg(PhysReg, TRI) << " is reserved already.\n");
return spillImpossible;
default: {
LiveRegMap::const_iterator LRI = findLiveVirtReg(VirtReg);
assert(LRI != LiveVirtRegs.end() && LRI->PhysReg &&
"Missing VirtReg entry");
- return LRI->Dirty ? spillDirty : spillClean;
+ Cost += LRI->Dirty ? spillDirty : spillClean;
+ break;
}
}
}
- return 0;
+ return Cost;
}
/// This method updates local state so that we know that PhysReg is the
@@ -845,17 +909,9 @@ void RegAllocFast::handleThroughOperands(MachineInstr &MI,
if (!Reg || !Reg.isPhysical())
continue;
markRegUsedInInstr(Reg);
-
- for (MCRegUnitIterator UI(Reg, TRI); UI.isValid(); ++UI) {
- if (!ThroughRegs.count(RegUnitStates[*UI]))
- continue;
-
- // Need to spill any aliasing registers.
- for (MCRegUnitRootIterator RI(*UI, TRI); RI.isValid(); ++RI) {
- for (MCSuperRegIterator SI(*RI, TRI, true); SI.isValid(); ++SI) {
- definePhysReg(MI, *SI, regFree);
- }
- }
+ for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) {
+ if (ThroughRegs.count(PhysRegState[*AI]))
+ definePhysReg(MI, *AI, regFree);
}
}
@@ -919,40 +975,37 @@ void RegAllocFast::handleThroughOperands(MachineInstr &MI,
}
#ifndef NDEBUG
-
-void RegAllocFast::dumpState() const {
- for (unsigned Unit = 1, UnitE = TRI->getNumRegUnits(); Unit != UnitE;
- ++Unit) {
- switch (unsigned VirtReg = RegUnitStates[Unit]) {
+void RegAllocFast::dumpState() {
+ for (unsigned Reg = 1, E = TRI->getNumRegs(); Reg != E; ++Reg) {
+ if (PhysRegState[Reg] == regDisabled) continue;
+ dbgs() << " " << printReg(Reg, TRI);
+ switch(PhysRegState[Reg]) {
case regFree:
break;
case regReserved:
- dbgs() << " " << printRegUnit(Unit, TRI) << "[P]";
+ dbgs() << "*";
break;
default: {
- dbgs() << ' ' << printRegUnit(Unit, TRI) << '=' << printReg(VirtReg);
- LiveRegMap::const_iterator I = findLiveVirtReg(VirtReg);
- assert(I != LiveVirtRegs.end() && "have LiveVirtRegs entry");
- if (I->Dirty)
- dbgs() << "[D]";
- assert(TRI->hasRegUnit(I->PhysReg, Unit) && "inverse mapping present");
+ dbgs() << '=' << printReg(PhysRegState[Reg]);
+ LiveRegMap::iterator LRI = findLiveVirtReg(PhysRegState[Reg]);
+ assert(LRI != LiveVirtRegs.end() && LRI->PhysReg &&
+ "Missing VirtReg entry");
+ if (LRI->Dirty)
+ dbgs() << "*";
+ assert(LRI->PhysReg == Reg && "Bad inverse map");
break;
}
}
}
dbgs() << '\n';
// Check that LiveVirtRegs is the inverse.
- for (const LiveReg &LR : LiveVirtRegs) {
- Register VirtReg = LR.VirtReg;
- assert(VirtReg.isVirtual() && "Bad map key");
- MCPhysReg PhysReg = LR.PhysReg;
- if (PhysReg != 0) {
- assert(Register::isPhysicalRegister(PhysReg) &&
- "mapped to physreg");
- for (MCRegUnitIterator UI(PhysReg, TRI); UI.isValid(); ++UI) {
- assert(RegUnitStates[*UI] == VirtReg && "inverse map valid");
- }
- }
+ for (LiveRegMap::iterator i = LiveVirtRegs.begin(),
+ e = LiveVirtRegs.end(); i != e; ++i) {
+ if (!i->PhysReg)
+ continue;
+ assert(i->VirtReg.isVirtual() && "Bad map key");
+ assert(Register::isPhysicalRegister(i->PhysReg) && "Bad map value");
+ assert(PhysRegState[i->PhysReg] == i->VirtReg && "Bad inverse map");
}
}
#endif
@@ -1194,7 +1247,7 @@ void RegAllocFast::allocateBasicBlock(MachineBasicBlock &MBB) {
this->MBB = &MBB;
LLVM_DEBUG(dbgs() << "\nAllocating " << MBB);
- RegUnitStates.assign(TRI->getNumRegUnits(), regFree);
+ PhysRegState.assign(TRI->getNumRegs(), regDisabled);
assert(LiveVirtRegs.empty() && "Mapping not cleared from last block?");
MachineBasicBlock::iterator MII = MBB.begin();
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index fc6c3a145f13..f5948d2a20dc 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -690,6 +690,12 @@ bool FastISel::selectGetElementPtr(const User *I) {
Register N = getRegForValue(I->getOperand(0));
if (!N) // Unhandled operand. Halt "fast" selection and bail.
return false;
+
+ // FIXME: The code below does not handle vector GEPs. Halt "fast" selection
+ // and bail.
+ if (isa<VectorType>(I->getType()))
+ return false;
+
bool NIsKill = hasTrivialKill(I->getOperand(0));
// Keep a running tab of the total offset to coalesce multiple N = N + Offset
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 1d596c89c911..feb949f81eba 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -409,7 +409,7 @@ static SDValue getCopyFromPartsVector(SelectionDAG &DAG, const SDLoc &DL,
// as appropriate.
for (unsigned i = 0; i != NumParts; ++i)
Ops[i] = getCopyFromParts(DAG, DL, &Parts[i], 1,
- PartVT, IntermediateVT, V);
+ PartVT, IntermediateVT, V, CallConv);
} else if (NumParts > 0) {
// If the intermediate type was expanded, build the intermediate
// operands from the parts.
@@ -418,7 +418,7 @@ static SDValue getCopyFromPartsVector(SelectionDAG &DAG, const SDLoc &DL,
unsigned Factor = NumParts / NumIntermediates;
for (unsigned i = 0; i != NumIntermediates; ++i)
Ops[i] = getCopyFromParts(DAG, DL, &Parts[i * Factor], Factor,
- PartVT, IntermediateVT, V);
+ PartVT, IntermediateVT, V, CallConv);
}
// Build a vector with BUILD_VECTOR or CONCAT_VECTORS from the
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 96df20039b15..819e608c6896 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -5726,6 +5726,11 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
return SDValue();
}
+ auto RemoveDeadNode = [&](SDValue N) {
+ if (N && N.getNode()->use_empty())
+ DAG.RemoveDeadNode(N.getNode());
+ };
+
SDLoc DL(Op);
switch (Opcode) {
@@ -5804,13 +5809,17 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
// Negate the X if its cost is less or equal than Y.
if (NegX && (CostX <= CostY)) {
Cost = CostX;
- return DAG.getNode(ISD::FSUB, DL, VT, NegX, Y, Flags);
+ SDValue N = DAG.getNode(ISD::FSUB, DL, VT, NegX, Y, Flags);
+ RemoveDeadNode(NegY);
+ return N;
}
// Negate the Y if it is not expensive.
if (NegY) {
Cost = CostY;
- return DAG.getNode(ISD::FSUB, DL, VT, NegY, X, Flags);
+ SDValue N = DAG.getNode(ISD::FSUB, DL, VT, NegY, X, Flags);
+ RemoveDeadNode(NegX);
+ return N;
}
break;
}
@@ -5847,7 +5856,9 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
// Negate the X if its cost is less or equal than Y.
if (NegX && (CostX <= CostY)) {
Cost = CostX;
- return DAG.getNode(Opcode, DL, VT, NegX, Y, Flags);
+ SDValue N = DAG.getNode(Opcode, DL, VT, NegX, Y, Flags);
+ RemoveDeadNode(NegY);
+ return N;
}
// Ignore X * 2.0 because that is expected to be canonicalized to X + X.
@@ -5858,7 +5869,9 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
// Negate the Y if it is not expensive.
if (NegY) {
Cost = CostY;
- return DAG.getNode(Opcode, DL, VT, X, NegY, Flags);
+ SDValue N = DAG.getNode(Opcode, DL, VT, X, NegY, Flags);
+ RemoveDeadNode(NegX);
+ return N;
}
break;
}
@@ -5887,13 +5900,17 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
// Negate the X if its cost is less or equal than Y.
if (NegX && (CostX <= CostY)) {
Cost = std::min(CostX, CostZ);
- return DAG.getNode(Opcode, DL, VT, NegX, Y, NegZ, Flags);
+ SDValue N = DAG.getNode(Opcode, DL, VT, NegX, Y, NegZ, Flags);
+ RemoveDeadNode(NegY);
+ return N;
}
// Negate the Y if it is not expensive.
if (NegY) {
Cost = std::min(CostY, CostZ);
- return DAG.getNode(Opcode, DL, VT, X, NegY, NegZ, Flags);
+ SDValue N = DAG.getNode(Opcode, DL, VT, X, NegY, NegZ, Flags);
+ RemoveDeadNode(NegX);
+ return N;
}
break;
}
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index 2c94c2c62e5f..42c1fa8af0e6 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -1827,7 +1827,10 @@ Value *TargetLoweringBase::getIRStackGuard(IRBuilder<> &IRB) const {
if (getTargetMachine().getTargetTriple().isOSOpenBSD()) {
Module &M = *IRB.GetInsertBlock()->getParent()->getParent();
PointerType *PtrTy = Type::getInt8PtrTy(M.getContext());
- return M.getOrInsertGlobal("__guard_local", PtrTy);
+ Constant *C = M.getOrInsertGlobal("__guard_local", PtrTy);
+ if (GlobalVariable *G = dyn_cast_or_null<GlobalVariable>(C))
+ G->setVisibility(GlobalValue::HiddenVisibility);
+ return C;
}
return nullptr;
}
diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index 9468a3aa3c8d..6c72cd01ce6e 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -185,16 +185,18 @@ void OpenMPIRBuilder::finalize() {
}
Value *OpenMPIRBuilder::getOrCreateIdent(Constant *SrcLocStr,
- IdentFlag LocFlags) {
+ IdentFlag LocFlags,
+ unsigned Reserve2Flags) {
// Enable "C-mode".
LocFlags |= OMP_IDENT_FLAG_KMPC;
- GlobalVariable *&DefaultIdent = IdentMap[{SrcLocStr, uint64_t(LocFlags)}];
- if (!DefaultIdent) {
+ Value *&Ident =
+ IdentMap[{SrcLocStr, uint64_t(LocFlags) << 31 | Reserve2Flags}];
+ if (!Ident) {
Constant *I32Null = ConstantInt::getNullValue(Int32);
- Constant *IdentData[] = {I32Null,
- ConstantInt::get(Int32, uint64_t(LocFlags)),
- I32Null, I32Null, SrcLocStr};
+ Constant *IdentData[] = {
+ I32Null, ConstantInt::get(Int32, uint32_t(LocFlags)),
+ ConstantInt::get(Int32, Reserve2Flags), I32Null, SrcLocStr};
Constant *Initializer = ConstantStruct::get(
cast<StructType>(IdentPtr->getPointerElementType()), IdentData);
@@ -203,15 +205,16 @@ Value *OpenMPIRBuilder::getOrCreateIdent(Constant *SrcLocStr,
for (GlobalVariable &GV : M.getGlobalList())
if (GV.getType() == IdentPtr && GV.hasInitializer())
if (GV.getInitializer() == Initializer)
- return DefaultIdent = &GV;
-
- DefaultIdent = new GlobalVariable(M, IdentPtr->getPointerElementType(),
- /* isConstant = */ false,
- GlobalValue::PrivateLinkage, Initializer);
- DefaultIdent->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
- DefaultIdent->setAlignment(Align(8));
+ return Ident = &GV;
+
+ auto *GV = new GlobalVariable(M, IdentPtr->getPointerElementType(),
+ /* isConstant = */ true,
+ GlobalValue::PrivateLinkage, Initializer);
+ GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
+ GV->setAlignment(Align(8));
+ Ident = GV;
}
- return DefaultIdent;
+ return Ident;
}
Constant *OpenMPIRBuilder::getOrCreateSrcLocStr(StringRef LocStr) {
@@ -227,11 +230,30 @@ Constant *OpenMPIRBuilder::getOrCreateSrcLocStr(StringRef LocStr) {
GV.getInitializer() == Initializer)
return SrcLocStr = ConstantExpr::getPointerCast(&GV, Int8Ptr);
- SrcLocStr = Builder.CreateGlobalStringPtr(LocStr);
+ SrcLocStr = Builder.CreateGlobalStringPtr(LocStr, /* Name */ "",
+ /* AddressSpace */ 0, &M);
}
return SrcLocStr;
}
+Constant *OpenMPIRBuilder::getOrCreateSrcLocStr(StringRef FunctionName,
+ StringRef FileName,
+ unsigned Line,
+ unsigned Column) {
+ SmallString<128> Buffer;
+ Buffer.push_back(';');
+ Buffer.append(FileName);
+ Buffer.push_back(';');
+ Buffer.append(FunctionName);
+ Buffer.push_back(';');
+ Buffer.append(std::to_string(Line));
+ Buffer.push_back(';');
+ Buffer.append(std::to_string(Column));
+ Buffer.push_back(';');
+ Buffer.push_back(';');
+ return getOrCreateSrcLocStr(Buffer.str());
+}
+
Constant *OpenMPIRBuilder::getOrCreateDefaultSrcLocStr() {
return getOrCreateSrcLocStr(";unknown;unknown;0;0;;");
}
@@ -241,17 +263,13 @@ OpenMPIRBuilder::getOrCreateSrcLocStr(const LocationDescription &Loc) {
DILocation *DIL = Loc.DL.get();
if (!DIL)
return getOrCreateDefaultSrcLocStr();
- StringRef Filename =
+ StringRef FileName =
!DIL->getFilename().empty() ? DIL->getFilename() : M.getName();
StringRef Function = DIL->getScope()->getSubprogram()->getName();
Function =
!Function.empty() ? Function : Loc.IP.getBlock()->getParent()->getName();
- std::string LineStr = std::to_string(DIL->getLine());
- std::string ColumnStr = std::to_string(DIL->getColumn());
- std::stringstream SrcLocStr;
- SrcLocStr << ";" << Filename.data() << ";" << Function.data() << ";"
- << LineStr << ";" << ColumnStr << ";;";
- return getOrCreateSrcLocStr(SrcLocStr.str());
+ return getOrCreateSrcLocStr(Function, FileName, DIL->getLine(),
+ DIL->getColumn());
}
Value *OpenMPIRBuilder::getOrCreateThreadID(Value *Ident) {
diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp
index 1fffce015f70..a82f15895782 100644
--- a/llvm/lib/IR/IRBuilder.cpp
+++ b/llvm/lib/IR/IRBuilder.cpp
@@ -42,13 +42,14 @@ using namespace llvm;
/// created.
GlobalVariable *IRBuilderBase::CreateGlobalString(StringRef Str,
const Twine &Name,
- unsigned AddressSpace) {
+ unsigned AddressSpace,
+ Module *M) {
Constant *StrConstant = ConstantDataArray::getString(Context, Str);
- Module &M = *BB->getParent()->getParent();
- auto *GV = new GlobalVariable(M, StrConstant->getType(), true,
- GlobalValue::PrivateLinkage, StrConstant, Name,
- nullptr, GlobalVariable::NotThreadLocal,
- AddressSpace);
+ if (!M)
+ M = BB->getParent()->getParent();
+ auto *GV = new GlobalVariable(
+ *M, StrConstant->getType(), true, GlobalValue::PrivateLinkage,
+ StrConstant, Name, nullptr, GlobalVariable::NotThreadLocal, AddressSpace);
GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
GV->setAlignment(Align(1));
return GV;
diff --git a/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp
index 74869fa62c66..4189aea46294 100644
--- a/llvm/lib/IR/LegacyPassManager.cpp
+++ b/llvm/lib/IR/LegacyPassManager.cpp
@@ -1475,74 +1475,6 @@ void FPPassManager::dumpPassStructure(unsigned Offset) {
}
}
-#ifdef EXPENSIVE_CHECKS
-namespace {
-namespace details {
-
-// Basic hashing mechanism to detect structural change to the IR, used to verify
-// pass return status consistency with actual change. Loosely copied from
-// llvm/lib/Transforms/Utils/FunctionComparator.cpp
-
-class StructuralHash {
- uint64_t Hash = 0x6acaa36bef8325c5ULL;
-
- void update(uint64_t V) { Hash = hashing::detail::hash_16_bytes(Hash, V); }
-
-public:
- StructuralHash() = default;
-
- void update(Function &F) {
- if (F.empty())
- return;
-
- update(F.isVarArg());
- update(F.arg_size());
-
- SmallVector<const BasicBlock *, 8> BBs;
- SmallPtrSet<const BasicBlock *, 16> VisitedBBs;
-
- BBs.push_back(&F.getEntryBlock());
- VisitedBBs.insert(BBs[0]);
- while (!BBs.empty()) {
- const BasicBlock *BB = BBs.pop_back_val();
- update(45798); // Block header
- for (auto &Inst : *BB)
- update(Inst.getOpcode());
-
- const Instruction *Term = BB->getTerminator();
- for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
- if (!VisitedBBs.insert(Term->getSuccessor(i)).second)
- continue;
- BBs.push_back(Term->getSuccessor(i));
- }
- }
- }
-
- void update(Module &M) {
- for (Function &F : M)
- update(F);
- }
-
- uint64_t getHash() const { return Hash; }
-};
-
-} // namespace details
-
-uint64_t StructuralHash(Function &F) {
- details::StructuralHash H;
- H.update(F);
- return H.getHash();
-}
-
-uint64_t StructuralHash(Module &M) {
- details::StructuralHash H;
- H.update(M);
- return H.getHash();
-}
-
-} // end anonymous namespace
-
-#endif
/// Execute all of the passes scheduled for execution by invoking
/// runOnFunction method. Keep track of whether any of the passes modifies
@@ -1581,16 +1513,7 @@ bool FPPassManager::runOnFunction(Function &F) {
{
PassManagerPrettyStackEntry X(FP, F);
TimeRegion PassTimer(getPassTimer(FP));
-#ifdef EXPENSIVE_CHECKS
- uint64_t RefHash = StructuralHash(F);
-#endif
LocalChanged |= FP->runOnFunction(F);
-
-#ifdef EXPENSIVE_CHECKS
- assert((LocalChanged || (RefHash == StructuralHash(F))) &&
- "Pass modifies its input and doesn't report it.");
-#endif
-
if (EmitICRemark) {
unsigned NewSize = F.getInstructionCount();
@@ -1691,17 +1614,7 @@ MPPassManager::runOnModule(Module &M) {
PassManagerPrettyStackEntry X(MP, M);
TimeRegion PassTimer(getPassTimer(MP));
-#ifdef EXPENSIVE_CHECKS
- uint64_t RefHash = StructuralHash(M);
-#endif
-
LocalChanged |= MP->runOnModule(M);
-
-#ifdef EXPENSIVE_CHECKS
- assert((LocalChanged || (RefHash == StructuralHash(M))) &&
- "Pass modifies its input and doesn't report it.");
-#endif
-
if (EmitICRemark) {
// Update the size of the module.
unsigned ModuleCount = M.getInstructionCount();
diff --git a/llvm/lib/Support/X86TargetParser.cpp b/llvm/lib/Support/X86TargetParser.cpp
index c629f872df12..4c2d4efbfca8 100644
--- a/llvm/lib/Support/X86TargetParser.cpp
+++ b/llvm/lib/Support/X86TargetParser.cpp
@@ -522,7 +522,7 @@ static constexpr FeatureBitset ImpliedFeaturesAVX5124FMAPS = {};
static constexpr FeatureBitset ImpliedFeaturesAVX5124VNNIW = {};
// SSE4_A->FMA4->XOP chain.
-static constexpr FeatureBitset ImpliedFeaturesSSE4_A = FeatureSSSE3;
+static constexpr FeatureBitset ImpliedFeaturesSSE4_A = FeatureSSE3;
static constexpr FeatureBitset ImpliedFeaturesFMA4 = FeatureAVX | FeatureSSE4_A;
static constexpr FeatureBitset ImpliedFeaturesXOP = FeatureFMA4;
diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index 83653dcbb8cf..c6cc6e9e8471 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -1694,11 +1694,10 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
StackOffset DeallocateBefore = {}, DeallocateAfter = SVEStackSize;
MachineBasicBlock::iterator RestoreBegin = LastPopI, RestoreEnd = LastPopI;
if (int64_t CalleeSavedSize = AFI->getSVECalleeSavedStackSize()) {
- RestoreBegin = std::prev(RestoreEnd);;
- while (IsSVECalleeSave(RestoreBegin) &&
- RestoreBegin != MBB.begin())
+ RestoreBegin = std::prev(RestoreEnd);
+ while (RestoreBegin != MBB.begin() &&
+ IsSVECalleeSave(std::prev(RestoreBegin)))
--RestoreBegin;
- ++RestoreBegin;
assert(IsSVECalleeSave(RestoreBegin) &&
IsSVECalleeSave(std::prev(RestoreEnd)) && "Unexpected instruction");
diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index c56a65b9e212..e86f2a6ebde4 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -5416,7 +5416,7 @@ multiclass sve_mem_64b_sst_vi_ptrs<bits<3> opc, string asm,
def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $imm5]",
(!cast<Instruction>(NAME # _IMM) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5), 0>;
def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
- (!cast<Instruction>(NAME # _IMM) Z_s:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
+ (!cast<Instruction>(NAME # _IMM) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), (nxv2i64 ZPR:$ptrs), imm_ty:$index, vt),
(!cast<Instruction>(NAME # _IMM) ZPR:$data, PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
diff --git a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp
index ffcf4c30bc70..92980d2406cf 100644
--- a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp
+++ b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp
@@ -192,8 +192,8 @@ static bool updateOperand(FoldCandidate &Fold,
if (Fold.isImm()) {
if (MI->getDesc().TSFlags & SIInstrFlags::IsPacked &&
!(MI->getDesc().TSFlags & SIInstrFlags::IsMAI) &&
- AMDGPU::isInlinableLiteralV216(static_cast<uint16_t>(Fold.ImmToFold),
- ST.hasInv2PiInlineImm())) {
+ AMDGPU::isFoldableLiteralV216(Fold.ImmToFold,
+ ST.hasInv2PiInlineImm())) {
// Set op_sel/op_sel_hi on this operand or bail out if op_sel is
// already set.
unsigned Opcode = MI->getOpcode();
@@ -209,30 +209,30 @@ static bool updateOperand(FoldCandidate &Fold,
ModIdx = AMDGPU::getNamedOperandIdx(Opcode, ModIdx);
MachineOperand &Mod = MI->getOperand(ModIdx);
unsigned Val = Mod.getImm();
- if ((Val & SISrcMods::OP_SEL_0) || !(Val & SISrcMods::OP_SEL_1))
- return false;
- // Only apply the following transformation if that operand requries
- // a packed immediate.
- switch (TII.get(Opcode).OpInfo[OpNo].OperandType) {
- case AMDGPU::OPERAND_REG_IMM_V2FP16:
- case AMDGPU::OPERAND_REG_IMM_V2INT16:
- case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:
- case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
- // If upper part is all zero we do not need op_sel_hi.
- if (!isUInt<16>(Fold.ImmToFold)) {
- if (!(Fold.ImmToFold & 0xffff)) {
- Mod.setImm(Mod.getImm() | SISrcMods::OP_SEL_0);
+ if (!(Val & SISrcMods::OP_SEL_0) && (Val & SISrcMods::OP_SEL_1)) {
+ // Only apply the following transformation if that operand requries
+ // a packed immediate.
+ switch (TII.get(Opcode).OpInfo[OpNo].OperandType) {
+ case AMDGPU::OPERAND_REG_IMM_V2FP16:
+ case AMDGPU::OPERAND_REG_IMM_V2INT16:
+ case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:
+ case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
+ // If upper part is all zero we do not need op_sel_hi.
+ if (!isUInt<16>(Fold.ImmToFold)) {
+ if (!(Fold.ImmToFold & 0xffff)) {
+ Mod.setImm(Mod.getImm() | SISrcMods::OP_SEL_0);
+ Mod.setImm(Mod.getImm() & ~SISrcMods::OP_SEL_1);
+ Old.ChangeToImmediate((Fold.ImmToFold >> 16) & 0xffff);
+ return true;
+ }
Mod.setImm(Mod.getImm() & ~SISrcMods::OP_SEL_1);
- Old.ChangeToImmediate((Fold.ImmToFold >> 16) & 0xffff);
+ Old.ChangeToImmediate(Fold.ImmToFold & 0xffff);
return true;
}
- Mod.setImm(Mod.getImm() & ~SISrcMods::OP_SEL_1);
- Old.ChangeToImmediate(Fold.ImmToFold & 0xffff);
- return true;
+ break;
+ default:
+ break;
}
- break;
- default:
- break;
}
}
}
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
index 00e6d517bde5..3df2157fc402 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
@@ -1282,6 +1282,19 @@ bool isInlinableIntLiteralV216(int32_t Literal) {
return Lo16 == Hi16 && isInlinableIntLiteral(Lo16);
}
+bool isFoldableLiteralV216(int32_t Literal, bool HasInv2Pi) {
+ assert(HasInv2Pi);
+
+ int16_t Lo16 = static_cast<int16_t>(Literal);
+ if (isInt<16>(Literal) || isUInt<16>(Literal))
+ return true;
+
+ int16_t Hi16 = static_cast<int16_t>(Literal >> 16);
+ if (!(Literal & 0xffff))
+ return true;
+ return Lo16 == Hi16;
+}
+
bool isArgPassedInSGPR(const Argument *A) {
const Function *F = A->getParent();
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
index e71554575f6a..26bb77f4b4c7 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
@@ -660,6 +660,9 @@ bool isInlinableLiteralV216(int32_t Literal, bool HasInv2Pi);
LLVM_READNONE
bool isInlinableIntLiteralV216(int32_t Literal);
+LLVM_READNONE
+bool isFoldableLiteralV216(int32_t Literal, bool HasInv2Pi);
+
bool isArgPassedInSGPR(const Argument *Arg);
LLVM_READONLY
diff --git a/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp b/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp
index 2259a29f838a..f125ca011cd2 100644
--- a/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp
+++ b/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp
@@ -78,9 +78,9 @@ class PPCBoolRetToInt : public FunctionPass {
Value *Curr = WorkList.back();
WorkList.pop_back();
auto *CurrUser = dyn_cast<User>(Curr);
- // Operands of CallInst are skipped because they may not be Bool type,
- // and their positions are defined by ABI.
- if (CurrUser && !isa<CallInst>(Curr))
+ // Operands of CallInst/Constant are skipped because they may not be Bool
+ // type. For CallInst, their positions are defined by ABI.
+ if (CurrUser && !isa<CallInst>(Curr) && !isa<Constant>(Curr))
for (auto &Op : CurrUser->operands())
if (Defs.insert(Op).second)
WorkList.push_back(Op);
@@ -90,6 +90,9 @@ class PPCBoolRetToInt : public FunctionPass {
// Translate a i1 value to an equivalent i32/i64 value:
Value *translate(Value *V) {
+ assert(V->getType() == Type::getInt1Ty(V->getContext()) &&
+ "Expect an i1 value");
+
Type *IntTy = ST->isPPC64() ? Type::getInt64Ty(V->getContext())
: Type::getInt32Ty(V->getContext());
@@ -252,9 +255,9 @@ class PPCBoolRetToInt : public FunctionPass {
auto *First = dyn_cast<User>(Pair.first);
auto *Second = dyn_cast<User>(Pair.second);
assert((!First || Second) && "translated from user to non-user!?");
- // Operands of CallInst are skipped because they may not be Bool type,
- // and their positions are defined by ABI.
- if (First && !isa<CallInst>(First))
+ // Operands of CallInst/Constant are skipped because they may not be Bool
+ // type. For CallInst, their positions are defined by ABI.
+ if (First && !isa<CallInst>(First) && !isa<Constant>(First))
for (unsigned i = 0; i < First->getNumOperands(); ++i)
Second->setOperand(i, BoolToIntMap[First->getOperand(i)]);
}
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 5c1a4cb16568..f54f1673526d 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -799,7 +799,7 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setOperationAction(ISD::MUL, MVT::v4f32, Legal);
setOperationAction(ISD::FMA, MVT::v4f32, Legal);
- if (TM.Options.UnsafeFPMath || Subtarget.hasVSX()) {
+ if (Subtarget.hasVSX()) {
setOperationAction(ISD::FDIV, MVT::v4f32, Legal);
setOperationAction(ISD::FSQRT, MVT::v4f32, Legal);
}
@@ -920,6 +920,8 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setOperationAction(ISD::SUB, MVT::v2i64, Expand);
}
+ setOperationAction(ISD::SETCC, MVT::v1i128, Expand);
+
setOperationAction(ISD::LOAD, MVT::v2i64, Promote);
AddPromotedToType (ISD::LOAD, MVT::v2i64, MVT::v2f64);
setOperationAction(ISD::STORE, MVT::v2i64, Promote);
@@ -1258,6 +1260,9 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setLibcallName(RTLIB::SRA_I128, nullptr);
}
+ if (!isPPC64)
+ setMaxAtomicSizeInBitsSupported(32);
+
setStackPointerRegisterToSaveRestore(isPPC64 ? PPC::X1 : PPC::R1);
// We have target-specific dag combine patterns for the following nodes:
@@ -1295,12 +1300,6 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setTargetDAGCombine(ISD::SELECT_CC);
}
- // Use reciprocal estimates.
- if (TM.Options.UnsafeFPMath) {
- setTargetDAGCombine(ISD::FDIV);
- setTargetDAGCombine(ISD::FSQRT);
- }
-
if (Subtarget.hasP9Altivec()) {
setTargetDAGCombine(ISD::ABS);
setTargetDAGCombine(ISD::VSELECT);
diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
index 6956c40a70be..de42d354a048 100644
--- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -1026,8 +1026,8 @@ def : InstAlias<"mfamr $Rx", (MFSPR8 g8rc:$Rx, 29)>;
foreach SPRG = 0-3 in {
def : InstAlias<"mfsprg $RT, "#SPRG, (MFSPR8 g8rc:$RT, !add(SPRG, 272))>;
def : InstAlias<"mfsprg"#SPRG#" $RT", (MFSPR8 g8rc:$RT, !add(SPRG, 272))>;
- def : InstAlias<"mfsprg "#SPRG#", $RT", (MTSPR8 !add(SPRG, 272), g8rc:$RT)>;
- def : InstAlias<"mfsprg"#SPRG#" $RT", (MTSPR8 !add(SPRG, 272), g8rc:$RT)>;
+ def : InstAlias<"mtsprg "#SPRG#", $RT", (MTSPR8 !add(SPRG, 272), g8rc:$RT)>;
+ def : InstAlias<"mtsprg"#SPRG#" $RT", (MTSPR8 !add(SPRG, 272), g8rc:$RT)>;
}
def : InstAlias<"mfasr $RT", (MFSPR8 g8rc:$RT, 280)>;
diff --git a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
index d2aba6bd6e8d..227c863685ae 100644
--- a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
+++ b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
@@ -1555,6 +1555,8 @@ bool PPCMIPeephole::emitRLDICWhenLoweringJumpTables(MachineInstr &MI) {
MI.getOperand(1).setReg(SrcMI->getOperand(1).getReg());
MI.getOperand(2).setImm(NewSH);
MI.getOperand(3).setImm(NewMB);
+ MI.getOperand(1).setIsKill(SrcMI->getOperand(1).isKill());
+ SrcMI->getOperand(1).setIsKill(false);
LLVM_DEBUG(dbgs() << "To: ");
LLVM_DEBUG(MI.dump());
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index a9b9eceb4130..925636c82321 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -601,8 +601,8 @@ bool WebAssemblyTargetLowering::isIntDivCheap(EVT VT,
}
bool WebAssemblyTargetLowering::isVectorLoadExtDesirable(SDValue ExtVal) const {
- MVT ExtT = ExtVal.getSimpleValueType();
- MVT MemT = cast<LoadSDNode>(ExtVal->getOperand(0))->getSimpleValueType(0);
+ EVT ExtT = ExtVal.getValueType();
+ EVT MemT = cast<LoadSDNode>(ExtVal->getOperand(0))->getValueType(0);
return (ExtT == MVT::v8i16 && MemT == MVT::v8i8) ||
(ExtT == MVT::v4i32 && MemT == MVT::v4i16) ||
(ExtT == MVT::v2i64 && MemT == MVT::v2i32);
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index db27711f29b1..fa695c39cd1e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -1148,22 +1148,6 @@ static Instruction *canonicalizeAbsNabs(SelectInst &Sel, ICmpInst &Cmp,
return &Sel;
}
-static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *ReplaceOp,
- const SimplifyQuery &Q) {
- // If this is a binary operator, try to simplify it with the replaced op
- // because we know Op and ReplaceOp are equivalant.
- // For example: V = X + 1, Op = X, ReplaceOp = 42
- // Simplifies as: add(42, 1) --> 43
- if (auto *BO = dyn_cast<BinaryOperator>(V)) {
- if (BO->getOperand(0) == Op)
- return SimplifyBinOp(BO->getOpcode(), ReplaceOp, BO->getOperand(1), Q);
- if (BO->getOperand(1) == Op)
- return SimplifyBinOp(BO->getOpcode(), BO->getOperand(0), ReplaceOp, Q);
- }
-
- return nullptr;
-}
-
/// If we have a select with an equality comparison, then we know the value in
/// one of the arms of the select. See if substituting this value into an arm
/// and simplifying the result yields the same value as the other arm.
@@ -1190,20 +1174,45 @@ static Value *foldSelectValueEquivalence(SelectInst &Sel, ICmpInst &Cmp,
if (Cmp.getPredicate() == ICmpInst::ICMP_NE)
std::swap(TrueVal, FalseVal);
+ auto *FalseInst = dyn_cast<Instruction>(FalseVal);
+ if (!FalseInst)
+ return nullptr;
+
+ // InstSimplify already performed this fold if it was possible subject to
+ // current poison-generating flags. Try the transform again with
+ // poison-generating flags temporarily dropped.
+ bool WasNUW = false, WasNSW = false, WasExact = false;
+ if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(FalseVal)) {
+ WasNUW = OBO->hasNoUnsignedWrap();
+ WasNSW = OBO->hasNoSignedWrap();
+ FalseInst->setHasNoUnsignedWrap(false);
+ FalseInst->setHasNoSignedWrap(false);
+ }
+ if (auto *PEO = dyn_cast<PossiblyExactOperator>(FalseVal)) {
+ WasExact = PEO->isExact();
+ FalseInst->setIsExact(false);
+ }
+
// Try each equivalence substitution possibility.
// We have an 'EQ' comparison, so the select's false value will propagate.
// Example:
// (X == 42) ? 43 : (X + 1) --> (X == 42) ? (X + 1) : (X + 1) --> X + 1
- // (X == 42) ? (X + 1) : 43 --> (X == 42) ? (42 + 1) : 43 --> 43
Value *CmpLHS = Cmp.getOperand(0), *CmpRHS = Cmp.getOperand(1);
- if (simplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, Q) == TrueVal ||
- simplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, Q) == TrueVal ||
- simplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, Q) == FalseVal ||
- simplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, Q) == FalseVal) {
- if (auto *FalseInst = dyn_cast<Instruction>(FalseVal))
- FalseInst->dropPoisonGeneratingFlags();
+ if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, Q,
+ /* AllowRefinement */ false) == TrueVal ||
+ SimplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, Q,
+ /* AllowRefinement */ false) == TrueVal) {
return FalseVal;
}
+
+ // Restore poison-generating flags if the transform did not apply.
+ if (WasNUW)
+ FalseInst->setHasNoUnsignedWrap();
+ if (WasNSW)
+ FalseInst->setHasNoSignedWrap();
+ if (WasExact)
+ FalseInst->setIsExact();
+
return nullptr;
}