From 6c366f903bf7260f580ea74114c02005772f17f3 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 03 2020 12:09:16 +0000 Subject: import llvm-10.0.1-3.module+el8.3.0+7719+53d428de --- diff --git a/.gitignore b/.gitignore index 7adc32b..35bc580 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/llvm-9.0.1.src.tar.xz +SOURCES/llvm-10.0.1.src.tar.xz diff --git a/.llvm.metadata b/.llvm.metadata index fe0c8ba..5ca21e3 100644 --- a/.llvm.metadata +++ b/.llvm.metadata @@ -1 +1 @@ -f7fcf3bd92d130784513c06efe6910f135372ce3 SOURCES/llvm-9.0.1.src.tar.xz +25d07260f3b7bf4f647e115c4a663fdeda130fbd SOURCES/llvm-10.0.1.src.tar.xz diff --git a/SOURCES/0001-BPF-Handling-type-conversions-correctly-for-CO-RE.patch b/SOURCES/0001-BPF-Handling-type-conversions-correctly-for-CO-RE.patch deleted file mode 100644 index bfde9bc..0000000 --- a/SOURCES/0001-BPF-Handling-type-conversions-correctly-for-CO-RE.patch +++ /dev/null @@ -1,2510 +0,0 @@ -From 20253836fbb1baf5c7cd6fb6558bd12dff682855 Mon Sep 17 00:00:00 2001 -From: Yonghong Song -Date: Fri, 2 Aug 2019 23:16:44 +0000 -Subject: [PATCH] [BPF] Handling type conversions correctly for CO-RE - -With newly added debuginfo type -metadata for preserve_array_access_index() intrinsic, -this patch did the following two things: - (1). checking validity before adding a new access index - to the access chain. - (2). calculating access byte offset in IR phase - BPFAbstractMemberAccess instead of when BTF is emitted. - -For (1), the metadata provided by all preserve_*_access_index() -intrinsics are used to check whether the to-be-added type -is a proper struct/union member or array element. - -For (2), with all available metadata, calculating access byte -offset becomes easier in BPFAbstractMemberAccess IR phase. -This enables us to remove the unnecessary complexity in -BTFDebug.cpp. - -New tests are added for - . user explicit casting to array/structure/union - . global variable (or its dereference) as the source of base - . multi demensional arrays - . array access given a base pointer - . cases where we won't generate relocation if we cannot find - type name. - -Differential Revision: https://reviews.llvm.org/D65618 - -llvm-svn: 367735 -(cherry picked from commit 37d24a696bf74f4830f2582d2f36256ca1b6bb30) ---- - llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp | 332 +++++++++++++++++---- - llvm/lib/Target/BPF/BTFDebug.cpp | 110 +------ - llvm/lib/Target/BPF/BTFDebug.h | 15 +- - .../CodeGen/BPF/CORE/offset-reloc-cast-array-1.ll | 124 ++++++++ - .../CodeGen/BPF/CORE/offset-reloc-cast-array-2.ll | 131 ++++++++ - .../CodeGen/BPF/CORE/offset-reloc-cast-struct-1.ll | 112 +++++++ - .../CodeGen/BPF/CORE/offset-reloc-cast-struct-2.ll | 117 ++++++++ - .../CodeGen/BPF/CORE/offset-reloc-cast-struct-3.ll | 116 +++++++ - .../CodeGen/BPF/CORE/offset-reloc-cast-union-1.ll | 117 ++++++++ - .../CodeGen/BPF/CORE/offset-reloc-cast-union-2.ll | 118 ++++++++ - .../test/CodeGen/BPF/CORE/offset-reloc-global-1.ll | 79 +++++ - .../test/CodeGen/BPF/CORE/offset-reloc-global-2.ll | 95 ++++++ - .../test/CodeGen/BPF/CORE/offset-reloc-global-3.ll | 84 ++++++ - llvm/test/CodeGen/BPF/CORE/offset-reloc-ignore.ll | 62 ++++ - .../CodeGen/BPF/CORE/offset-reloc-multi-array-1.ll | 101 +++++++ - .../CodeGen/BPF/CORE/offset-reloc-multi-array-2.ll | 107 +++++++ - .../CodeGen/BPF/CORE/offset-reloc-pointer-1.ll | 83 ++++++ - .../CodeGen/BPF/CORE/offset-reloc-pointer-2.ll | 85 ++++++ - .../BPF/CORE/offset-reloc-struct-anonymous.ll | 2 +- - .../CodeGen/BPF/CORE/offset-reloc-struct-array.ll | 2 +- - .../CodeGen/BPF/CORE/offset-reloc-typedef-array.ll | 2 +- - llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef.ll | 2 +- - 22 files changed, 1812 insertions(+), 184 deletions(-) - create mode 100644 llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-array-1.ll - create mode 100644 llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-array-2.ll - create mode 100644 llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-1.ll - create mode 100644 llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-2.ll - create mode 100644 llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-3.ll - create mode 100644 llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-union-1.ll - create mode 100644 llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-union-2.ll - create mode 100644 llvm/test/CodeGen/BPF/CORE/offset-reloc-global-1.ll - create mode 100644 llvm/test/CodeGen/BPF/CORE/offset-reloc-global-2.ll - create mode 100644 llvm/test/CodeGen/BPF/CORE/offset-reloc-global-3.ll - create mode 100644 llvm/test/CodeGen/BPF/CORE/offset-reloc-ignore.ll - create mode 100644 llvm/test/CodeGen/BPF/CORE/offset-reloc-multi-array-1.ll - create mode 100644 llvm/test/CodeGen/BPF/CORE/offset-reloc-multi-array-2.ll - create mode 100644 llvm/test/CodeGen/BPF/CORE/offset-reloc-pointer-1.ll - create mode 100644 llvm/test/CodeGen/BPF/CORE/offset-reloc-pointer-2.ll - -diff --git a/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp b/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp -index 509484b..f55f6f9 100644 ---- a/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp -+++ b/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp -@@ -65,6 +65,7 @@ - #include "llvm/IR/Value.h" - #include "llvm/Pass.h" - #include "llvm/Transforms/Utils/BasicBlockUtils.h" -+#include - - #define DEBUG_TYPE "bpf-abstract-member-access" - -@@ -106,18 +107,24 @@ private: - - bool doTransformation(Module &M); - -- void traceAICall(CallInst *Call, uint32_t Kind); -- void traceBitCast(BitCastInst *BitCast, CallInst *Parent, uint32_t Kind); -- void traceGEP(GetElementPtrInst *GEP, CallInst *Parent, uint32_t Kind); -+ void traceAICall(CallInst *Call, uint32_t Kind, const MDNode *ParentMeta, -+ uint32_t ParentAI); -+ void traceBitCast(BitCastInst *BitCast, CallInst *Parent, uint32_t Kind, -+ const MDNode *ParentMeta, uint32_t ParentAI); -+ void traceGEP(GetElementPtrInst *GEP, CallInst *Parent, uint32_t Kind, -+ const MDNode *ParentMeta, uint32_t ParentAI); - void collectAICallChains(Module &M, Function &F); - -- bool IsPreserveDIAccessIndexCall(const CallInst *Call, uint32_t &Kind); -+ bool IsPreserveDIAccessIndexCall(const CallInst *Call, uint32_t &Kind, -+ const MDNode *&TypeMeta, uint32_t &AccessIndex); -+ bool IsValidAIChain(const MDNode *ParentMeta, uint32_t ParentAI, -+ const MDNode *ChildMeta); - bool removePreserveAccessIndexIntrinsic(Module &M); - void replaceWithGEP(std::vector &CallList, - uint32_t NumOfZerosIndex, uint32_t DIIndex); - - Value *computeBaseAndAccessKey(CallInst *Call, std::string &AccessKey, -- uint32_t Kind, MDNode *&TypeMeta); -+ uint32_t Kind, MDNode *&BaseMeta); - bool getAccessIndex(const Value *IndexValue, uint64_t &AccessIndex); - bool transformGEPChain(Module &M, CallInst *Call, uint32_t Kind); - }; -@@ -141,9 +148,53 @@ bool BPFAbstractMemberAccess::runOnModule(Module &M) { - return doTransformation(M); - } - -+static bool SkipDIDerivedTag(unsigned Tag) { -+ if (Tag != dwarf::DW_TAG_typedef && Tag != dwarf::DW_TAG_const_type && -+ Tag != dwarf::DW_TAG_volatile_type && -+ Tag != dwarf::DW_TAG_restrict_type && -+ Tag != dwarf::DW_TAG_member) -+ return false; -+ return true; -+} -+ -+static DIType * stripQualifiers(DIType *Ty) { -+ while (auto *DTy = dyn_cast(Ty)) { -+ if (!SkipDIDerivedTag(DTy->getTag())) -+ break; -+ Ty = DTy->getBaseType(); -+ } -+ return Ty; -+} -+ -+static const DIType * stripQualifiers(const DIType *Ty) { -+ while (auto *DTy = dyn_cast(Ty)) { -+ if (!SkipDIDerivedTag(DTy->getTag())) -+ break; -+ Ty = DTy->getBaseType(); -+ } -+ return Ty; -+} -+ -+static uint32_t calcArraySize(const DICompositeType *CTy, uint32_t StartDim) { -+ DINodeArray Elements = CTy->getElements(); -+ uint32_t DimSize = 1; -+ for (uint32_t I = StartDim; I < Elements.size(); ++I) { -+ if (auto *Element = dyn_cast_or_null(Elements[I])) -+ if (Element->getTag() == dwarf::DW_TAG_subrange_type) { -+ const DISubrange *SR = cast(Element); -+ auto *CI = SR->getCount().dyn_cast(); -+ DimSize *= CI->getSExtValue(); -+ } -+ } -+ -+ return DimSize; -+} -+ - /// Check whether a call is a preserve_*_access_index intrinsic call or not. - bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(const CallInst *Call, -- uint32_t &Kind) { -+ uint32_t &Kind, -+ const MDNode *&TypeMeta, -+ uint32_t &AccessIndex) { - if (!Call) - return false; - -@@ -152,14 +203,29 @@ bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(const CallInst *Call, - return false; - if (GV->getName().startswith("llvm.preserve.array.access.index")) { - Kind = BPFPreserveArrayAI; -+ TypeMeta = Call->getMetadata(LLVMContext::MD_preserve_access_index); -+ if (!TypeMeta) -+ report_fatal_error("Missing metadata for llvm.preserve.array.access.index intrinsic"); -+ AccessIndex = cast(Call->getArgOperand(2)) -+ ->getZExtValue(); - return true; - } - if (GV->getName().startswith("llvm.preserve.union.access.index")) { - Kind = BPFPreserveUnionAI; -+ TypeMeta = Call->getMetadata(LLVMContext::MD_preserve_access_index); -+ if (!TypeMeta) -+ report_fatal_error("Missing metadata for llvm.preserve.union.access.index intrinsic"); -+ AccessIndex = cast(Call->getArgOperand(1)) -+ ->getZExtValue(); - return true; - } - if (GV->getName().startswith("llvm.preserve.struct.access.index")) { - Kind = BPFPreserveStructAI; -+ TypeMeta = Call->getMetadata(LLVMContext::MD_preserve_access_index); -+ if (!TypeMeta) -+ report_fatal_error("Missing metadata for llvm.preserve.struct.access.index intrinsic"); -+ AccessIndex = cast(Call->getArgOperand(2)) -+ ->getZExtValue(); - return true; - } - -@@ -200,7 +266,9 @@ bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(Module &M) { - for (auto &I : BB) { - auto *Call = dyn_cast(&I); - uint32_t Kind; -- if (!IsPreserveDIAccessIndexCall(Call, Kind)) -+ const MDNode *TypeMeta; -+ uint32_t AccessIndex; -+ if (!IsPreserveDIAccessIndexCall(Call, Kind, TypeMeta, AccessIndex)) - continue; - - Found = true; -@@ -232,25 +300,79 @@ bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(Module &M) { - return Found; - } - --void BPFAbstractMemberAccess::traceAICall(CallInst *Call, uint32_t Kind) { -+/// Check whether the access index chain is valid. We check -+/// here because there may be type casts between two -+/// access indexes. We want to ensure memory access still valid. -+bool BPFAbstractMemberAccess::IsValidAIChain(const MDNode *ParentType, -+ uint32_t ParentAI, -+ const MDNode *ChildType) { -+ const DIType *PType = stripQualifiers(cast(ParentType)); -+ const DIType *CType = stripQualifiers(cast(ChildType)); -+ -+ // Child is a derived/pointer type, which is due to type casting. -+ // Pointer type cannot be in the middle of chain. -+ if (const auto *PtrTy = dyn_cast(CType)) -+ return false; -+ -+ // Parent is a pointer type. -+ if (const auto *PtrTy = dyn_cast(PType)) { -+ if (PtrTy->getTag() != dwarf::DW_TAG_pointer_type) -+ return false; -+ return stripQualifiers(PtrTy->getBaseType()) == CType; -+ } -+ -+ // Otherwise, struct/union/array types -+ const auto *PTy = dyn_cast(PType); -+ const auto *CTy = dyn_cast(CType); -+ assert(PTy && CTy && "ParentType or ChildType is null or not composite"); -+ -+ uint32_t PTyTag = PTy->getTag(); -+ assert(PTyTag == dwarf::DW_TAG_array_type || -+ PTyTag == dwarf::DW_TAG_structure_type || -+ PTyTag == dwarf::DW_TAG_union_type); -+ -+ uint32_t CTyTag = CTy->getTag(); -+ assert(CTyTag == dwarf::DW_TAG_array_type || -+ CTyTag == dwarf::DW_TAG_structure_type || -+ CTyTag == dwarf::DW_TAG_union_type); -+ -+ // Multi dimensional arrays, base element should be the same -+ if (PTyTag == dwarf::DW_TAG_array_type && PTyTag == CTyTag) -+ return PTy->getBaseType() == CTy->getBaseType(); -+ -+ DIType *Ty; -+ if (PTyTag == dwarf::DW_TAG_array_type) -+ Ty = PTy->getBaseType(); -+ else -+ Ty = dyn_cast(PTy->getElements()[ParentAI]); -+ -+ return dyn_cast(stripQualifiers(Ty)) == CTy; -+} -+ -+void BPFAbstractMemberAccess::traceAICall(CallInst *Call, uint32_t Kind, -+ const MDNode *ParentMeta, -+ uint32_t ParentAI) { - for (User *U : Call->users()) { - Instruction *Inst = dyn_cast(U); - if (!Inst) - continue; - - if (auto *BI = dyn_cast(Inst)) { -- traceBitCast(BI, Call, Kind); -+ traceBitCast(BI, Call, Kind, ParentMeta, ParentAI); - } else if (auto *CI = dyn_cast(Inst)) { - uint32_t CIKind; -- if (IsPreserveDIAccessIndexCall(CI, CIKind)) { -+ const MDNode *ChildMeta; -+ uint32_t ChildAI; -+ if (IsPreserveDIAccessIndexCall(CI, CIKind, ChildMeta, ChildAI) && -+ IsValidAIChain(ParentMeta, ParentAI, ChildMeta)) { - AIChain[CI] = std::make_pair(Call, Kind); -- traceAICall(CI, CIKind); -+ traceAICall(CI, CIKind, ChildMeta, ChildAI); - } else { - BaseAICalls[Call] = Kind; - } - } else if (auto *GI = dyn_cast(Inst)) { - if (GI->hasAllZeroIndices()) -- traceGEP(GI, Call, Kind); -+ traceGEP(GI, Call, Kind, ParentMeta, ParentAI); - else - BaseAICalls[Call] = Kind; - } -@@ -258,25 +380,30 @@ void BPFAbstractMemberAccess::traceAICall(CallInst *Call, uint32_t Kind) { - } - - void BPFAbstractMemberAccess::traceBitCast(BitCastInst *BitCast, -- CallInst *Parent, uint32_t Kind) { -+ CallInst *Parent, uint32_t Kind, -+ const MDNode *ParentMeta, -+ uint32_t ParentAI) { - for (User *U : BitCast->users()) { - Instruction *Inst = dyn_cast(U); - if (!Inst) - continue; - - if (auto *BI = dyn_cast(Inst)) { -- traceBitCast(BI, Parent, Kind); -+ traceBitCast(BI, Parent, Kind, ParentMeta, ParentAI); - } else if (auto *CI = dyn_cast(Inst)) { - uint32_t CIKind; -- if (IsPreserveDIAccessIndexCall(CI, CIKind)) { -+ const MDNode *ChildMeta; -+ uint32_t ChildAI; -+ if (IsPreserveDIAccessIndexCall(CI, CIKind, ChildMeta, ChildAI) && -+ IsValidAIChain(ParentMeta, ParentAI, ChildMeta)) { - AIChain[CI] = std::make_pair(Parent, Kind); -- traceAICall(CI, CIKind); -+ traceAICall(CI, CIKind, ChildMeta, ChildAI); - } else { - BaseAICalls[Parent] = Kind; - } - } else if (auto *GI = dyn_cast(Inst)) { - if (GI->hasAllZeroIndices()) -- traceGEP(GI, Parent, Kind); -+ traceGEP(GI, Parent, Kind, ParentMeta, ParentAI); - else - BaseAICalls[Parent] = Kind; - } -@@ -284,25 +411,29 @@ void BPFAbstractMemberAccess::traceBitCast(BitCastInst *BitCast, - } - - void BPFAbstractMemberAccess::traceGEP(GetElementPtrInst *GEP, CallInst *Parent, -- uint32_t Kind) { -+ uint32_t Kind, const MDNode *ParentMeta, -+ uint32_t ParentAI) { - for (User *U : GEP->users()) { - Instruction *Inst = dyn_cast(U); - if (!Inst) - continue; - - if (auto *BI = dyn_cast(Inst)) { -- traceBitCast(BI, Parent, Kind); -+ traceBitCast(BI, Parent, Kind, ParentMeta, ParentAI); - } else if (auto *CI = dyn_cast(Inst)) { - uint32_t CIKind; -- if (IsPreserveDIAccessIndexCall(CI, CIKind)) { -+ const MDNode *ChildMeta; -+ uint32_t ChildAI; -+ if (IsPreserveDIAccessIndexCall(CI, CIKind, ChildMeta, ChildAI) && -+ IsValidAIChain(ParentMeta, ParentAI, ChildMeta)) { - AIChain[CI] = std::make_pair(Parent, Kind); -- traceAICall(CI, CIKind); -+ traceAICall(CI, CIKind, ChildMeta, ChildAI); - } else { - BaseAICalls[Parent] = Kind; - } - } else if (auto *GI = dyn_cast(Inst)) { - if (GI->hasAllZeroIndices()) -- traceGEP(GI, Parent, Kind); -+ traceGEP(GI, Parent, Kind, ParentMeta, ParentAI); - else - BaseAICalls[Parent] = Kind; - } -@@ -316,12 +447,14 @@ void BPFAbstractMemberAccess::collectAICallChains(Module &M, Function &F) { - for (auto &BB : F) - for (auto &I : BB) { - uint32_t Kind; -+ const MDNode *TypeMeta; -+ uint32_t AccessIndex; - auto *Call = dyn_cast(&I); -- if (!IsPreserveDIAccessIndexCall(Call, Kind) || -+ if (!IsPreserveDIAccessIndexCall(Call, Kind, TypeMeta, AccessIndex) || - AIChain.find(Call) != AIChain.end()) - continue; - -- traceAICall(Call, Kind); -+ traceAICall(Call, Kind, TypeMeta, AccessIndex); - } - } - -@@ -344,62 +477,131 @@ Value *BPFAbstractMemberAccess::computeBaseAndAccessKey(CallInst *Call, - uint32_t Kind, - MDNode *&TypeMeta) { - Value *Base = nullptr; -- std::vector AccessIndices; -- uint64_t TypeNameIndex = 0; -- std::string LastTypeName; -+ std::string TypeName; -+ std::stack> CallStack; - -+ // Put the access chain into a stack with the top as the head of the chain. - while (Call) { -- // Base of original corresponding GEP -- Base = Call->getArgOperand(0); -+ CallStack.push(std::make_pair(Call, Kind)); -+ Kind = AIChain[Call].second; -+ Call = AIChain[Call].first; -+ } - -- // Type Name -- std::string TypeName; -- MDNode *MDN; -+ // The access offset from the base of the head of chain is also -+ // calculated here as all debuginfo types are available. -+ -+ // Get type name and calculate the first index. -+ // We only want to get type name from structure or union. -+ // If user wants a relocation like -+ // int *p; ... __builtin_preserve_access_index(&p[4]) ... -+ // or -+ // int a[10][20]; ... __builtin_preserve_access_index(&a[2][3]) ... -+ // we will skip them. -+ uint32_t FirstIndex = 0; -+ uint32_t AccessOffset = 0; -+ while (CallStack.size()) { -+ auto StackElem = CallStack.top(); -+ Call = StackElem.first; -+ Kind = StackElem.second; -+ -+ if (!Base) -+ Base = Call->getArgOperand(0); -+ -+ MDNode *MDN = Call->getMetadata(LLVMContext::MD_preserve_access_index); -+ DIType *Ty = stripQualifiers(cast(MDN)); - if (Kind == BPFPreserveUnionAI || Kind == BPFPreserveStructAI) { -- MDN = Call->getMetadata(LLVMContext::MD_preserve_access_index); -- if (!MDN) -- return nullptr; -+ // struct or union type -+ TypeName = Ty->getName(); -+ TypeMeta = Ty; -+ AccessOffset += FirstIndex * Ty->getSizeInBits() >> 3; -+ break; -+ } - -- DIType *Ty = dyn_cast(MDN); -- if (!Ty) -+ // Array entries will always be consumed for accumulative initial index. -+ CallStack.pop(); -+ -+ // BPFPreserveArrayAI -+ uint64_t AccessIndex; -+ if (!getAccessIndex(Call->getArgOperand(2), AccessIndex)) -+ return nullptr; -+ -+ DIType *BaseTy = nullptr; -+ bool CheckElemType = false; -+ if (const auto *CTy = dyn_cast(Ty)) { -+ // array type -+ assert(CTy->getTag() == dwarf::DW_TAG_array_type); -+ -+ -+ FirstIndex += AccessIndex * calcArraySize(CTy, 1); -+ BaseTy = stripQualifiers(CTy->getBaseType()); -+ CheckElemType = CTy->getElements().size() == 1; -+ } else { -+ // pointer type -+ auto *DTy = cast(Ty); -+ assert(DTy->getTag() == dwarf::DW_TAG_pointer_type); -+ -+ BaseTy = stripQualifiers(DTy->getBaseType()); -+ CTy = dyn_cast(BaseTy); -+ if (!CTy) { -+ CheckElemType = true; -+ } else if (CTy->getTag() != dwarf::DW_TAG_array_type) { -+ FirstIndex += AccessIndex; -+ CheckElemType = true; -+ } else { -+ FirstIndex += AccessIndex * calcArraySize(CTy, 0); -+ } -+ } -+ -+ if (CheckElemType) { -+ auto *CTy = dyn_cast(BaseTy); -+ if (!CTy) - return nullptr; - -- TypeName = Ty->getName(); -+ unsigned CTag = CTy->getTag(); -+ if (CTag != dwarf::DW_TAG_structure_type && CTag != dwarf::DW_TAG_union_type) -+ return nullptr; -+ else -+ TypeName = CTy->getName(); -+ TypeMeta = CTy; -+ AccessOffset += FirstIndex * CTy->getSizeInBits() >> 3; -+ break; - } -+ } -+ assert(TypeName.size()); -+ AccessKey += std::to_string(FirstIndex); -+ -+ // Traverse the rest of access chain to complete offset calculation -+ // and access key construction. -+ while (CallStack.size()) { -+ auto StackElem = CallStack.top(); -+ Call = StackElem.first; -+ Kind = StackElem.second; -+ CallStack.pop(); - - // Access Index - uint64_t AccessIndex; - uint32_t ArgIndex = (Kind == BPFPreserveUnionAI) ? 1 : 2; - if (!getAccessIndex(Call->getArgOperand(ArgIndex), AccessIndex)) - return nullptr; -- -- AccessIndices.push_back(AccessIndex); -- if (TypeName.size()) { -- TypeNameIndex = AccessIndices.size() - 1; -- LastTypeName = TypeName; -- TypeMeta = MDN; -+ AccessKey += ":" + std::to_string(AccessIndex); -+ -+ MDNode *MDN = Call->getMetadata(LLVMContext::MD_preserve_access_index); -+ // At this stage, it cannot be pointer type. -+ auto *CTy = cast(stripQualifiers(cast(MDN))); -+ uint32_t Tag = CTy->getTag(); -+ if (Tag == dwarf::DW_TAG_structure_type) { -+ auto *MemberTy = cast(CTy->getElements()[AccessIndex]); -+ AccessOffset += MemberTy->getOffsetInBits() >> 3; -+ } else if (Tag == dwarf::DW_TAG_array_type) { -+ auto *EltTy = stripQualifiers(CTy->getBaseType()); -+ AccessOffset += AccessIndex * calcArraySize(CTy, 1) * -+ EltTy->getSizeInBits() >> 3; - } -- -- Kind = AIChain[Call].second; -- Call = AIChain[Call].first; - } - -- // The intial type name is required. -- // FIXME: if the initial type access is an array index, e.g., -- // &a[3].b.c, only one dimentional array is supported. -- if (!LastTypeName.size() || AccessIndices.size() > TypeNameIndex + 2) -- return nullptr; -- -- // Construct the type string AccessKey. -- for (unsigned I = 0; I < AccessIndices.size(); ++I) -- AccessKey = std::to_string(AccessIndices[I]) + ":" + AccessKey; -- -- if (TypeNameIndex == AccessIndices.size() - 1) -- AccessKey = "0:" + AccessKey; -- - // Access key is the type name + access string, uniquely identifying - // one kernel memory access. -- AccessKey = LastTypeName + ":" + AccessKey; -+ AccessKey = TypeName + ":" + std::to_string(AccessOffset) + "$" + AccessKey; - - return Base; - } -@@ -409,7 +611,7 @@ Value *BPFAbstractMemberAccess::computeBaseAndAccessKey(CallInst *Call, - bool BPFAbstractMemberAccess::transformGEPChain(Module &M, CallInst *Call, - uint32_t Kind) { - std::string AccessKey; -- MDNode *TypeMeta = nullptr; -+ MDNode *TypeMeta; - Value *Base = - computeBaseAndAccessKey(Call, AccessKey, Kind, TypeMeta); - if (!Base) -@@ -419,7 +621,7 @@ bool BPFAbstractMemberAccess::transformGEPChain(Module &M, CallInst *Call, - // For any original GEP Call and Base %2 like - // %4 = bitcast %struct.net_device** %dev1 to i64* - // it is transformed to: -- // %6 = load __BTF_0:sk_buff:0:0:2:0: -+ // %6 = load sk_buff:50:$0:0:0:2:0 - // %7 = bitcast %struct.sk_buff* %2 to i8* - // %8 = getelementptr i8, i8* %7, %6 - // %9 = bitcast i8* %8 to i64* -@@ -432,9 +634,7 @@ bool BPFAbstractMemberAccess::transformGEPChain(Module &M, CallInst *Call, - GV = new GlobalVariable(M, Type::getInt64Ty(BB->getContext()), false, - GlobalVariable::ExternalLinkage, NULL, AccessKey); - GV->addAttribute(BPFCoreSharedInfo::AmaAttr); -- // Set the metadata (debuginfo types) for the global. -- if (TypeMeta) -- GV->setMetadata(LLVMContext::MD_preserve_access_index, TypeMeta); -+ GV->setMetadata(LLVMContext::MD_preserve_access_index, TypeMeta); - GEPGlobals[AccessKey] = GV; - } else { - GV = GEPGlobals[AccessKey]; -diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp -index 5c542e7..9b966eb 100644 ---- a/llvm/lib/Target/BPF/BTFDebug.cpp -+++ b/llvm/lib/Target/BPF/BTFDebug.cpp -@@ -30,18 +30,6 @@ static const char *BTFKindStr[] = { - #include "BTF.def" - }; - --static const DIType * stripQualifiers(const DIType *Ty) { -- while (const auto *DTy = dyn_cast(Ty)) { -- unsigned Tag = DTy->getTag(); -- if (Tag != dwarf::DW_TAG_typedef && Tag != dwarf::DW_TAG_const_type && -- Tag != dwarf::DW_TAG_volatile_type && Tag != dwarf::DW_TAG_restrict_type) -- break; -- Ty = DTy->getBaseType(); -- } -- -- return Ty; --} -- - /// Emit a BTF common type. - void BTFTypeBase::emitType(MCStreamer &OS) { - OS.AddComment(std::string(BTFKindStr[Kind]) + "(id = " + std::to_string(Id) + -@@ -196,9 +184,7 @@ void BTFTypeEnum::emitType(MCStreamer &OS) { - } - } - --BTFTypeArray::BTFTypeArray(const DIType *Ty, uint32_t ElemTypeId, -- uint32_t ElemSize, uint32_t NumElems) -- : ElemTyNoQual(Ty), ElemSize(ElemSize) { -+BTFTypeArray::BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems) { - Kind = BTF::BTF_KIND_ARRAY; - BTFType.NameOff = 0; - BTFType.Info = Kind << 24; -@@ -219,9 +205,6 @@ void BTFTypeArray::completeType(BTFDebug &BDebug) { - // created during initial type traversal. Just - // retrieve that type id. - ArrayInfo.IndexType = BDebug.getArrayIndexTypeId(); -- -- ElemTypeNoQual = ElemTyNoQual ? BDebug.getTypeId(ElemTyNoQual) -- : ArrayInfo.ElemType; - } - - void BTFTypeArray::emitType(MCStreamer &OS) { -@@ -231,12 +214,6 @@ void BTFTypeArray::emitType(MCStreamer &OS) { - OS.EmitIntValue(ArrayInfo.Nelems, 4); - } - --void BTFTypeArray::getLocInfo(uint32_t Loc, uint32_t &LocOffset, -- uint32_t &ElementTypeId) { -- ElementTypeId = ElemTypeNoQual; -- LocOffset = Loc * ElemSize; --} -- - /// Represent either a struct or a union. - BTFTypeStruct::BTFTypeStruct(const DICompositeType *STy, bool IsStruct, - bool HasBitField, uint32_t Vlen) -@@ -268,7 +245,6 @@ void BTFTypeStruct::completeType(BTFDebug &BDebug) { - } - const auto *BaseTy = DDTy->getBaseType(); - BTFMember.Type = BDebug.getTypeId(BaseTy); -- MemberTypeNoQual.push_back(BDebug.getTypeId(stripQualifiers(BaseTy))); - Members.push_back(BTFMember); - } - } -@@ -285,15 +261,6 @@ void BTFTypeStruct::emitType(MCStreamer &OS) { - - std::string BTFTypeStruct::getName() { return STy->getName(); } - --void BTFTypeStruct::getMemberInfo(uint32_t Loc, uint32_t &MemberOffset, -- uint32_t &MemberType) { -- MemberType = MemberTypeNoQual[Loc]; -- MemberOffset = -- HasBitField ? Members[Loc].Offset & 0xffffff : Members[Loc].Offset; --} -- --uint32_t BTFTypeStruct::getStructSize() { return STy->getSizeInBits() >> 3; } -- - /// The Func kind represents both subprogram and pointee of function - /// pointers. If the FuncName is empty, it represents a pointee of function - /// pointer. Otherwise, it represents a subprogram. The func arg names -@@ -511,12 +478,10 @@ void BTFDebug::visitArrayType(const DICompositeType *CTy, uint32_t &TypeId) { - visitTypeEntry(ElemType, ElemTypeId, false, false); - - // Strip qualifiers from element type to get accurate element size. -- ElemType = stripQualifiers(ElemType); - ElemSize = ElemType->getSizeInBits() >> 3; - - if (!CTy->getSizeInBits()) { -- auto TypeEntry = llvm::make_unique(ElemType, ElemTypeId, 0, 0); -- ArrayTypes.push_back(TypeEntry.get()); -+ auto TypeEntry = llvm::make_unique(ElemTypeId, 0); - ElemTypeId = addType(std::move(TypeEntry), CTy); - } else { - // Visit array dimensions. -@@ -527,12 +492,9 @@ void BTFDebug::visitArrayType(const DICompositeType *CTy, uint32_t &TypeId) { - const DISubrange *SR = cast(Element); - auto *CI = SR->getCount().dyn_cast(); - int64_t Count = CI->getSExtValue(); -- const DIType *ArrayElemTy = (I == 0) ? ElemType : nullptr; - - auto TypeEntry = -- llvm::make_unique(ArrayElemTy, ElemTypeId, -- ElemSize, Count); -- ArrayTypes.push_back(TypeEntry.get()); -+ llvm::make_unique(ElemTypeId, Count); - if (I == 0) - ElemTypeId = addType(std::move(TypeEntry), CTy); - else -@@ -1002,74 +964,22 @@ unsigned BTFDebug::populateStructType(const DIType *Ty) { - return Id; - } - --// Find struct/array debuginfo types given a type id. --void BTFDebug::setTypeFromId(uint32_t TypeId, BTFTypeStruct **PrevStructType, -- BTFTypeArray **PrevArrayType) { -- for (const auto &StructType : StructTypes) { -- if (StructType->getId() == TypeId) { -- *PrevStructType = StructType; -- return; -- } -- } -- for (const auto &ArrayType : ArrayTypes) { -- if (ArrayType->getId() == TypeId) { -- *PrevArrayType = ArrayType; -- return; -- } -- } --} -- - /// Generate a struct member offset relocation. - void BTFDebug::generateOffsetReloc(const MachineInstr *MI, - const MCSymbol *ORSym, DIType *RootTy, - StringRef AccessPattern) { -- BTFTypeStruct *PrevStructType = nullptr; -- BTFTypeArray *PrevArrayType = nullptr; - unsigned RootId = populateStructType(RootTy); -- setTypeFromId(RootId, &PrevStructType, &PrevArrayType); -- unsigned RootTySize = PrevStructType->getStructSize(); -- StringRef IndexPattern = AccessPattern.substr(AccessPattern.find_first_of(':') + 1); -+ size_t FirstDollar = AccessPattern.find_first_of('$'); -+ size_t FirstColon = AccessPattern.find_first_of(':'); -+ StringRef IndexPattern = AccessPattern.substr(FirstDollar + 1); -+ StringRef OffsetStr = AccessPattern.substr(FirstColon + 1, -+ FirstDollar - FirstColon); - - BTFOffsetReloc OffsetReloc; - OffsetReloc.Label = ORSym; -- OffsetReloc.OffsetNameOff = addString(IndexPattern.drop_back()); -+ OffsetReloc.OffsetNameOff = addString(IndexPattern); - OffsetReloc.TypeID = RootId; -- -- uint32_t Start = 0, End = 0, Offset = 0; -- bool FirstAccess = true; -- for (auto C : IndexPattern) { -- if (C != ':') { -- End++; -- } else { -- std::string SubStr = IndexPattern.substr(Start, End - Start); -- int Loc = std::stoi(SubStr); -- -- if (FirstAccess) { -- Offset = Loc * RootTySize; -- FirstAccess = false; -- } else if (PrevStructType) { -- uint32_t MemberOffset, MemberTypeId; -- PrevStructType->getMemberInfo(Loc, MemberOffset, MemberTypeId); -- -- Offset += MemberOffset >> 3; -- PrevStructType = nullptr; -- setTypeFromId(MemberTypeId, &PrevStructType, &PrevArrayType); -- } else if (PrevArrayType) { -- uint32_t LocOffset, ElementTypeId; -- PrevArrayType->getLocInfo(Loc, LocOffset, ElementTypeId); -- -- Offset += LocOffset; -- PrevArrayType = nullptr; -- setTypeFromId(ElementTypeId, &PrevStructType, &PrevArrayType); -- } else { -- llvm_unreachable("Internal Error: BTF offset relocation type traversal error"); -- } -- -- Start = End + 1; -- End = Start; -- } -- } -- AccessOffsets[AccessPattern.str()] = Offset; -+ AccessOffsets[AccessPattern.str()] = std::stoi(OffsetStr); - OffsetRelocTable[SecNameOff].push_back(OffsetReloc); - } - -diff --git a/llvm/lib/Target/BPF/BTFDebug.h b/llvm/lib/Target/BPF/BTFDebug.h -index e210d18..a79527d 100644 ---- a/llvm/lib/Target/BPF/BTFDebug.h -+++ b/llvm/lib/Target/BPF/BTFDebug.h -@@ -104,18 +104,13 @@ public: - - /// Handle array type. - class BTFTypeArray : public BTFTypeBase { -- const DIType *ElemTyNoQual; -- uint32_t ElemSize; - struct BTF::BTFArray ArrayInfo; -- uint32_t ElemTypeNoQual; - - public: -- BTFTypeArray(const DIType *Ty, uint32_t ElemTypeId, -- uint32_t ElemSize, uint32_t NumElems); -+ BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems); - uint32_t getSize() { return BTFTypeBase::getSize() + BTF::BTFArraySize; } - void completeType(BTFDebug &BDebug); - void emitType(MCStreamer &OS); -- void getLocInfo(uint32_t Loc, uint32_t &LocOffset, uint32_t &ElementTypeId); - }; - - /// Handle struct/union type. -@@ -123,7 +118,6 @@ class BTFTypeStruct : public BTFTypeBase { - const DICompositeType *STy; - bool HasBitField; - std::vector Members; -- std::vector MemberTypeNoQual; - - public: - BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField, -@@ -134,8 +128,6 @@ public: - void completeType(BTFDebug &BDebug); - void emitType(MCStreamer &OS); - std::string getName(); -- void getMemberInfo(uint32_t Loc, uint32_t &Offset, uint32_t &MemberType); -- uint32_t getStructSize(); - }; - - /// Handle function pointer. -@@ -262,7 +254,6 @@ class BTFDebug : public DebugHandlerBase { - StringMap> FileContent; - std::map> DataSecEntries; - std::vector StructTypes; -- std::vector ArrayTypes; - std::map AccessOffsets; - std::map>> - FixupDerivedTypes; -@@ -312,10 +303,6 @@ class BTFDebug : public DebugHandlerBase { - void generateOffsetReloc(const MachineInstr *MI, const MCSymbol *ORSym, - DIType *RootTy, StringRef AccessPattern); - -- /// Set the to-be-traversed Struct/Array Type based on TypeId. -- void setTypeFromId(uint32_t TypeId, BTFTypeStruct **PrevStructType, -- BTFTypeArray **PrevArrayType); -- - /// Populating unprocessed struct type. - unsigned populateStructType(const DIType *Ty); - -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-array-1.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-array-1.ll -new file mode 100644 -index 0000000..9e291cd ---- /dev/null -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-array-1.ll -@@ -0,0 +1,124 @@ -+; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; Source code: -+; struct v1 {int a; int b;}; -+; typedef struct v1 __v1; -+; typedef __v1 arr[4]; -+; struct v3 { char c; int d[100]; }; -+; #define _(x) (__builtin_preserve_access_index(x)) -+; #define cast_to_arr(x) ((arr *)(x)) -+; int get_value(const int *arg); -+; int test(struct v3 *arg) { -+; return get_value(_(&cast_to_arr(&arg->d[0])[0][2].b)); -+; } -+; Compilation flag: -+; clang -target bpf -O2 -g -S -emit-llvm test.c -+ -+%struct.v3 = type { i8, [100 x i32] } -+%struct.v1 = type { i32, i32 } -+ -+; Function Attrs: nounwind -+define dso_local i32 @test(%struct.v3* %arg) local_unnamed_addr #0 !dbg !22 { -+entry: -+ call void @llvm.dbg.value(metadata %struct.v3* %arg, metadata !32, metadata !DIExpression()), !dbg !33 -+ %0 = tail call [100 x i32]* @llvm.preserve.struct.access.index.p0a100i32.p0s_struct.v3s(%struct.v3* %arg, i32 1, i32 1), !dbg !34, !llvm.preserve.access.index !26 -+ %1 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a100i32([100 x i32]* %0, i32 1, i32 0), !dbg !34, !llvm.preserve.access.index !15 -+ %2 = bitcast i32* %1 to [4 x %struct.v1]*, !dbg !34 -+ %3 = tail call [4 x %struct.v1]* @llvm.preserve.array.access.index.p0a4s_struct.v1s.p0a4s_struct.v1s([4 x %struct.v1]* %2, i32 0, i32 0), !dbg !34, !llvm.preserve.access.index !4 -+ %4 = tail call %struct.v1* @llvm.preserve.array.access.index.p0s_struct.v1s.p0a4s_struct.v1s([4 x %struct.v1]* %3, i32 1, i32 2), !dbg !34, !llvm.preserve.access.index !5 -+ %5 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1* %4, i32 1, i32 1), !dbg !34, !llvm.preserve.access.index !8 -+ %call = tail call i32 @get_value(i32* %5) #4, !dbg !35 -+ ret i32 %call, !dbg !36 -+} -+ -+; CHECK: r2 = 4 -+; CHECK: r1 += r2 -+; CHECK: r2 = 20 -+; CHECK: r1 += r2 -+; CHECK: call get_value -+ -+; CHECK: .long 1 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) -+; CHECK: .long 100 # BTF_KIND_STRUCT(id = [[TID2:[0-9]+]]) -+ -+; CHECK: .ascii "v3" # string offset=1 -+; CHECK: .ascii ".text" # string offset=46 -+; CHECK: .ascii "0:1:0" # string offset=52 -+; CHECK: .ascii "2:1" # string offset=107 -+ -+; CHECK: .long 12 # OffsetReloc -+; CHECK-NEXT: .long 46 # Offset reloc section string offset=46 -+; CHECK-NEXT: .long 2 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID1]] -+; CHECK-NEXT: .long 52 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID2]] -+; CHECK-NEXT: .long 107 -+ -+declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 -+ -+; Function Attrs: nounwind readnone -+declare [100 x i32]* @llvm.preserve.struct.access.index.p0a100i32.p0s_struct.v3s(%struct.v3*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare i32* @llvm.preserve.array.access.index.p0i32.p0a100i32([100 x i32]*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare [4 x %struct.v1]* @llvm.preserve.array.access.index.p0a4s_struct.v1s.p0a4s_struct.v1s([4 x %struct.v1]*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare %struct.v1* @llvm.preserve.array.access.index.p0s_struct.v1s.p0a4s_struct.v1s([4 x %struct.v1]*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone speculatable willreturn -+declare void @llvm.dbg.value(metadata, metadata, metadata) #3 -+ -+attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #2 = { nounwind readnone } -+attributes #3 = { nounwind readnone speculatable willreturn } -+attributes #4 = { nounwind } -+ -+!llvm.dbg.cu = !{!0} -+!llvm.module.flags = !{!18, !19, !20} -+!llvm.ident = !{!21} -+ -+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) -+!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") -+!2 = !{} -+!3 = !{!4, !15, !5} -+!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) -+!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "arr", file: !1, line: 3, baseType: !6) -+!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 256, elements: !13) -+!7 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v1", file: !1, line: 2, baseType: !8) -+!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v1", file: !1, line: 1, size: 64, elements: !9) -+!9 = !{!10, !12} -+!10 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !8, file: !1, line: 1, baseType: !11, size: 32) -+!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -+!12 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !8, file: !1, line: 1, baseType: !11, size: 32, offset: 32) -+!13 = !{!14} -+!14 = !DISubrange(count: 4) -+!15 = !DICompositeType(tag: DW_TAG_array_type, baseType: !11, size: 3200, elements: !16) -+!16 = !{!17} -+!17 = !DISubrange(count: 100) -+!18 = !{i32 2, !"Dwarf Version", i32 4} -+!19 = !{i32 2, !"Debug Info Version", i32 3} -+!20 = !{i32 1, !"wchar_size", i32 4} -+!21 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} -+!22 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 8, type: !23, scopeLine: 8, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !31) -+!23 = !DISubroutineType(types: !24) -+!24 = !{!11, !25} -+!25 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !26, size: 64) -+!26 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !1, line: 4, size: 3232, elements: !27) -+!27 = !{!28, !30} -+!28 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !26, file: !1, line: 4, baseType: !29, size: 8) -+!29 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) -+!30 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !26, file: !1, line: 4, baseType: !15, size: 3200, offset: 32) -+!31 = !{!32} -+!32 = !DILocalVariable(name: "arg", arg: 1, scope: !22, file: !1, line: 8, type: !25) -+!33 = !DILocation(line: 0, scope: !22) -+!34 = !DILocation(line: 9, column: 20, scope: !22) -+!35 = !DILocation(line: 9, column: 10, scope: !22) -+!36 = !DILocation(line: 9, column: 3, scope: !22) -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-array-2.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-array-2.ll -new file mode 100644 -index 0000000..7903179 ---- /dev/null -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-array-2.ll -@@ -0,0 +1,131 @@ -+; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; Source code: -+; struct v1 {int a; int b;}; -+; typedef struct v1 __v1; -+; typedef __v1 arr[4][4]; -+; struct v3 { char c; int d[100]; }; -+; #define _(x) (__builtin_preserve_access_index(x)) -+; #define cast_to_arr(x) ((arr *)(x)) -+; int get_value(const int *arg); -+; int test(struct v3 *arg) { -+; return get_value(_(&cast_to_arr(&arg->d[0])[0][2][3].b)); -+; } -+; Compilation flag: -+; clang -target bpf -O2 -g -S -emit-llvm test.c -+ -+%struct.v3 = type { i8, [100 x i32] } -+%struct.v1 = type { i32, i32 } -+ -+; Function Attrs: nounwind -+define dso_local i32 @test(%struct.v3* %arg) local_unnamed_addr #0 !dbg !24 { -+entry: -+ call void @llvm.dbg.value(metadata %struct.v3* %arg, metadata !34, metadata !DIExpression()), !dbg !35 -+ %0 = tail call [100 x i32]* @llvm.preserve.struct.access.index.p0a100i32.p0s_struct.v3s(%struct.v3* %arg, i32 1, i32 1), !dbg !36, !llvm.preserve.access.index !28 -+ %1 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a100i32([100 x i32]* %0, i32 1, i32 0), !dbg !36, !llvm.preserve.access.index !15 -+ %2 = bitcast i32* %1 to [4 x [4 x %struct.v1]]*, !dbg !36 -+ %3 = tail call [4 x [4 x %struct.v1]]* @llvm.preserve.array.access.index.p0a4a4s_struct.v1s.p0a4a4s_struct.v1s([4 x [4 x %struct.v1]]* %2, i32 0, i32 0), !dbg !36, !llvm.preserve.access.index !4 -+ %4 = tail call [4 x %struct.v1]* @llvm.preserve.array.access.index.p0a4s_struct.v1s.p0a4a4s_struct.v1s([4 x [4 x %struct.v1]]* %3, i32 1, i32 2), !dbg !36, !llvm.preserve.access.index !5 -+ %5 = tail call %struct.v1* @llvm.preserve.array.access.index.p0s_struct.v1s.p0a4s_struct.v1s([4 x %struct.v1]* %4, i32 1, i32 3), !dbg !36, !llvm.preserve.access.index !18 -+ %6 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1* %5, i32 1, i32 1), !dbg !36, !llvm.preserve.access.index !8 -+ %call = tail call i32 @get_value(i32* %6) #4, !dbg !37 -+ ret i32 %call, !dbg !38 -+} -+ -+; CHECK: r2 = 4 -+; CHECK: r1 += r2 -+; CHECK: r2 = 92 -+; CHECK: r1 += r2 -+; CHECK: call get_value -+ -+; CHECK: .long 1 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) -+; CHECK: .long 100 # BTF_KIND_STRUCT(id = [[TID2:[0-9]+]]) -+ -+; CHECK: .ascii "v3" # string offset=1 -+; CHECK: .ascii ".text" # string offset=46 -+; CHECK: .ascii "0:1:0" # string offset=52 -+; CHECK: .ascii "v1" # string offset=100 -+; CHECK: .ascii "11:1" # string offset=107 -+ -+; CHECK: .long 12 # OffsetReloc -+; CHECK-NEXT: .long 46 # Offset reloc section string offset=46 -+; CHECK-NEXT: .long 2 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID1]] -+; CHECK-NEXT: .long 52 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID2]] -+; CHECK-NEXT: .long 107 -+ -+declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 -+ -+; Function Attrs: nounwind readnone -+declare [100 x i32]* @llvm.preserve.struct.access.index.p0a100i32.p0s_struct.v3s(%struct.v3*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare i32* @llvm.preserve.array.access.index.p0i32.p0a100i32([100 x i32]*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare [4 x [4 x %struct.v1]]* @llvm.preserve.array.access.index.p0a4a4s_struct.v1s.p0a4a4s_struct.v1s([4 x [4 x %struct.v1]]*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare [4 x %struct.v1]* @llvm.preserve.array.access.index.p0a4s_struct.v1s.p0a4a4s_struct.v1s([4 x [4 x %struct.v1]]*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare %struct.v1* @llvm.preserve.array.access.index.p0s_struct.v1s.p0a4s_struct.v1s([4 x %struct.v1]*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone speculatable willreturn -+declare void @llvm.dbg.value(metadata, metadata, metadata) #3 -+ -+attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #2 = { nounwind readnone } -+attributes #3 = { nounwind readnone speculatable willreturn } -+attributes #4 = { nounwind } -+ -+!llvm.dbg.cu = !{!0} -+!llvm.module.flags = !{!20, !21, !22} -+!llvm.ident = !{!23} -+ -+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) -+!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") -+!2 = !{} -+!3 = !{!4, !15, !5, !18} -+!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) -+!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "arr", file: !1, line: 3, baseType: !6) -+!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 1024, elements: !13) -+!7 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v1", file: !1, line: 2, baseType: !8) -+!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v1", file: !1, line: 1, size: 64, elements: !9) -+!9 = !{!10, !12} -+!10 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !8, file: !1, line: 1, baseType: !11, size: 32) -+!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -+!12 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !8, file: !1, line: 1, baseType: !11, size: 32, offset: 32) -+!13 = !{!14, !14} -+!14 = !DISubrange(count: 4) -+!15 = !DICompositeType(tag: DW_TAG_array_type, baseType: !11, size: 3200, elements: !16) -+!16 = !{!17} -+!17 = !DISubrange(count: 100) -+!18 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 256, elements: !19) -+!19 = !{!14} -+!20 = !{i32 2, !"Dwarf Version", i32 4} -+!21 = !{i32 2, !"Debug Info Version", i32 3} -+!22 = !{i32 1, !"wchar_size", i32 4} -+!23 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} -+!24 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 8, type: !25, scopeLine: 8, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !33) -+!25 = !DISubroutineType(types: !26) -+!26 = !{!11, !27} -+!27 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !28, size: 64) -+!28 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !1, line: 4, size: 3232, elements: !29) -+!29 = !{!30, !32} -+!30 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !28, file: !1, line: 4, baseType: !31, size: 8) -+!31 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) -+!32 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !28, file: !1, line: 4, baseType: !15, size: 3200, offset: 32) -+!33 = !{!34} -+!34 = !DILocalVariable(name: "arg", arg: 1, scope: !24, file: !1, line: 8, type: !27) -+!35 = !DILocation(line: 0, scope: !24) -+!36 = !DILocation(line: 9, column: 20, scope: !24) -+!37 = !DILocation(line: 9, column: 10, scope: !24) -+!38 = !DILocation(line: 9, column: 3, scope: !24) -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-1.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-1.ll -new file mode 100644 -index 0000000..a97c6a0 ---- /dev/null -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-1.ll -@@ -0,0 +1,112 @@ -+; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; Source code: -+; struct v1 { int a; int b; }; -+; struct v2 { int c; int d; }; -+; struct v3 { char c; struct v2 d; }; -+; #define _(x) (__builtin_preserve_access_index(x)) -+; #define cast_to_v1(x) ((struct v1 *)(x)) -+; int get_value(const int *arg); -+; int test(struct v3 *arg) { -+; return get_value(_(&cast_to_v1(&arg->d)->b)); -+; } -+; Compilation flag: -+; clang -target bpf -O2 -g -S -emit-llvm test.c -+ -+%struct.v3 = type { i8, %struct.v2 } -+%struct.v2 = type { i32, i32 } -+%struct.v1 = type { i32, i32 } -+ -+; Function Attrs: nounwind -+define dso_local i32 @test(%struct.v3* %arg) local_unnamed_addr #0 !dbg !14 { -+entry: -+ call void @llvm.dbg.value(metadata %struct.v3* %arg, metadata !28, metadata !DIExpression()), !dbg !29 -+ %0 = tail call %struct.v2* @llvm.preserve.struct.access.index.p0s_struct.v2s.p0s_struct.v3s(%struct.v3* %arg, i32 1, i32 1), !dbg !30, !llvm.preserve.access.index !18 -+ %1 = bitcast %struct.v2* %0 to %struct.v1*, !dbg !30 -+ %2 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1* %1, i32 1, i32 1), !dbg !30, !llvm.preserve.access.index !5 -+ %call = tail call i32 @get_value(i32* %2) #4, !dbg !31 -+ ret i32 %call, !dbg !32 -+} -+ -+; CHECK: r2 = 4 -+; CHECK: r1 += r2 -+; CHECK: r2 = 4 -+; CHECK: r1 += r2 -+; CHECK: call get_value -+ -+; CHECK: .long 1 # BTF_KIND_STRUCT(id = [[V3_TID:[0-9]+]]) -+; CHECK: .long 81 # BTF_KIND_STRUCT(id = [[V1_TID:[0-9]+]]) -+ -+; CHECK: .ascii "v3" # string offset=1 -+; CHECK-NEXT: .byte 0 -+; CHECK: .ascii ".text" # string offset=[[SEC_STR:[0-9]+]] -+; CHECK-NEXT: .byte 0 -+; CHECK: .ascii "0:1" # string offset=[[ACCESS_STR:[0-9]+]] -+; CHECK-NEXT: .byte 0 -+; CHECK: .ascii "v1" # string offset=81 -+; CHECK-NEXT: .byte 0 -+ -+; CHECK: .long 12 # OffsetReloc -+; CHECK-NEXT: .long [[SEC_STR]] # Offset reloc section string offset=[[SEC_STR]] -+; CHECK-NEXT: .long 2 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[V3_TID]] -+; CHECK-NEXT: .long [[ACCESS_STR]] -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[V1_TID]] -+; CHECK-NEXT: .long [[ACCESS_STR]] -+ -+declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 -+ -+; Function Attrs: nounwind readnone -+declare %struct.v2* @llvm.preserve.struct.access.index.p0s_struct.v2s.p0s_struct.v3s(%struct.v3*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone speculatable willreturn -+declare void @llvm.dbg.value(metadata, metadata, metadata) #3 -+ -+attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #2 = { nounwind readnone } -+attributes #3 = { nounwind readnone speculatable willreturn } -+attributes #4 = { nounwind } -+ -+!llvm.dbg.cu = !{!0} -+!llvm.module.flags = !{!10, !11, !12} -+!llvm.ident = !{!13} -+ -+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) -+!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") -+!2 = !{} -+!3 = !{!4} -+!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) -+!5 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v1", file: !1, line: 1, size: 64, elements: !6) -+!6 = !{!7, !9} -+!7 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !5, file: !1, line: 1, baseType: !8, size: 32) -+!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -+!9 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !5, file: !1, line: 1, baseType: !8, size: 32, offset: 32) -+!10 = !{i32 2, !"Dwarf Version", i32 4} -+!11 = !{i32 2, !"Debug Info Version", i32 3} -+!12 = !{i32 1, !"wchar_size", i32 4} -+!13 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} -+!14 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 7, type: !15, scopeLine: 7, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !27) -+!15 = !DISubroutineType(types: !16) -+!16 = !{!8, !17} -+!17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !18, size: 64) -+!18 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !1, line: 3, size: 96, elements: !19) -+!19 = !{!20, !22} -+!20 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !18, file: !1, line: 3, baseType: !21, size: 8) -+!21 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) -+!22 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !18, file: !1, line: 3, baseType: !23, size: 64, offset: 32) -+!23 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v2", file: !1, line: 2, size: 64, elements: !24) -+!24 = !{!25, !26} -+!25 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !23, file: !1, line: 2, baseType: !8, size: 32) -+!26 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !23, file: !1, line: 2, baseType: !8, size: 32, offset: 32) -+!27 = !{!28} -+!28 = !DILocalVariable(name: "arg", arg: 1, scope: !14, file: !1, line: 7, type: !17) -+!29 = !DILocation(line: 0, scope: !14) -+!30 = !DILocation(line: 8, column: 20, scope: !14) -+!31 = !DILocation(line: 8, column: 10, scope: !14) -+!32 = !DILocation(line: 8, column: 3, scope: !14) -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-2.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-2.ll -new file mode 100644 -index 0000000..f65b3f3 ---- /dev/null -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-2.ll -@@ -0,0 +1,117 @@ -+; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; Source code: -+; struct v1 { int a; int b; }; -+; typedef struct v1 __v1; -+; struct v2 { int c; int d; }; -+; typedef struct v2 __v2; -+; struct v3 { char c; volatile const __v2 d; }; -+; typedef struct v3 __v3; -+; #define _(x) (__builtin_preserve_access_index(x)) -+; #define cast_to_v1(x) ((__v1 *)(x)) -+; int get_value(const int *arg); -+; int test(__v3 *arg) { -+; return get_value(_(&cast_to_v1(&arg->d)->b)); -+; } -+; Compilation flag: -+; clang -target bpf -O2 -g -S -emit-llvm test.c -+ -+%struct.v3 = type { i8, %struct.v2 } -+%struct.v2 = type { i32, i32 } -+%struct.v1 = type { i32, i32 } -+ -+; Function Attrs: nounwind -+define dso_local i32 @test(%struct.v3* %arg) local_unnamed_addr #0 !dbg !15 { -+entry: -+ call void @llvm.dbg.value(metadata %struct.v3* %arg, metadata !33, metadata !DIExpression()), !dbg !34 -+ %0 = tail call %struct.v2* @llvm.preserve.struct.access.index.p0s_struct.v2s.p0s_struct.v3s(%struct.v3* %arg, i32 1, i32 1), !dbg !35, !llvm.preserve.access.index !20 -+ %1 = bitcast %struct.v2* %0 to %struct.v1*, !dbg !35 -+ %2 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1* %1, i32 1, i32 1), !dbg !35, !llvm.preserve.access.index !6 -+ %call = tail call i32 @get_value(i32* %2) #4, !dbg !36 -+ ret i32 %call, !dbg !37 -+} -+ -+; CHECK: r2 = 4 -+; CHECK: r1 += r2 -+; CHECK: r2 = 4 -+; CHECK: r1 += r2 -+; CHECK: call get_value -+ -+; CHECK: .long 6 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) -+; CHECK: .long 91 # BTF_KIND_STRUCT(id = [[TID2:[0-9]+]]) -+ -+; CHECK: .ascii "v3" # string offset=6 -+; CHECK: .ascii ".text" # string offset=39 -+; CHECK: .ascii "0:1" # string offset=45 -+; CHECK: .ascii "v1" # string offset=91 -+ -+ -+; CHECK: .long 12 # OffsetReloc -+; CHECK-NEXT: .long 39 # Offset reloc section string offset=39 -+; CHECK-NEXT: .long 2 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID1]] -+; CHECK-NEXT: .long 45 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID2]] -+; CHECK-NEXT: .long 45 -+ -+declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 -+ -+; Function Attrs: nounwind readnone -+declare %struct.v2* @llvm.preserve.struct.access.index.p0s_struct.v2s.p0s_struct.v3s(%struct.v3*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone speculatable willreturn -+declare void @llvm.dbg.value(metadata, metadata, metadata) #3 -+ -+attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #2 = { nounwind readnone } -+attributes #3 = { nounwind readnone speculatable willreturn } -+attributes #4 = { nounwind } -+ -+!llvm.dbg.cu = !{!0} -+!llvm.module.flags = !{!11, !12, !13} -+!llvm.ident = !{!14} -+ -+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) -+!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") -+!2 = !{} -+!3 = !{!4} -+!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) -+!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v1", file: !1, line: 2, baseType: !6) -+!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v1", file: !1, line: 1, size: 64, elements: !7) -+!7 = !{!8, !10} -+!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !1, line: 1, baseType: !9, size: 32) -+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -+!10 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !6, file: !1, line: 1, baseType: !9, size: 32, offset: 32) -+!11 = !{i32 2, !"Dwarf Version", i32 4} -+!12 = !{i32 2, !"Debug Info Version", i32 3} -+!13 = !{i32 1, !"wchar_size", i32 4} -+!14 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} -+!15 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 10, type: !16, scopeLine: 10, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !32) -+!16 = !DISubroutineType(types: !17) -+!17 = !{!9, !18} -+!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) -+!19 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !1, line: 6, baseType: !20) -+!20 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !1, line: 5, size: 96, elements: !21) -+!21 = !{!22, !24} -+!22 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !20, file: !1, line: 5, baseType: !23, size: 8) -+!23 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) -+!24 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !20, file: !1, line: 5, baseType: !25, size: 64, offset: 32) -+!25 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !26) -+!26 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !27) -+!27 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v2", file: !1, line: 4, baseType: !28) -+!28 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v2", file: !1, line: 3, size: 64, elements: !29) -+!29 = !{!30, !31} -+!30 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !28, file: !1, line: 3, baseType: !9, size: 32) -+!31 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !28, file: !1, line: 3, baseType: !9, size: 32, offset: 32) -+!32 = !{!33} -+!33 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 10, type: !18) -+!34 = !DILocation(line: 0, scope: !15) -+!35 = !DILocation(line: 11, column: 20, scope: !15) -+!36 = !DILocation(line: 11, column: 10, scope: !15) -+!37 = !DILocation(line: 11, column: 3, scope: !15) -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-3.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-3.ll -new file mode 100644 -index 0000000..ed78b84 ---- /dev/null -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-struct-3.ll -@@ -0,0 +1,116 @@ -+; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; Source code: -+; struct v1 { int a; int b; }; -+; typedef struct v1 __v1; -+; typedef int __int; -+; struct v3 { char c; __int d[40]; }; -+; typedef struct v3 __v3; -+; #define _(x) (__builtin_preserve_access_index(x)) -+; #define cast_to_v1(x) ((__v1 *)(x)) -+; int get_value(const int *arg); -+; int test(__v3 *arg) { -+; return get_value(_(&cast_to_v1(&arg->d[4])->b)); -+; } -+; Compilation flag: -+; clang -target bpf -O2 -g -S -emit-llvm test.c -+ -+%struct.v3 = type { i8, [40 x i32] } -+%struct.v1 = type { i32, i32 } -+ -+; Function Attrs: nounwind -+define dso_local i32 @test(%struct.v3* %arg) local_unnamed_addr #0 !dbg !19 { -+entry: -+ call void @llvm.dbg.value(metadata %struct.v3* %arg, metadata !30, metadata !DIExpression()), !dbg !31 -+ %0 = tail call [40 x i32]* @llvm.preserve.struct.access.index.p0a40i32.p0s_struct.v3s(%struct.v3* %arg, i32 1, i32 1), !dbg !32, !llvm.preserve.access.index !24 -+ %1 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a40i32([40 x i32]* %0, i32 1, i32 4), !dbg !32, !llvm.preserve.access.index !11 -+ %2 = bitcast i32* %1 to %struct.v1*, !dbg !32 -+ %3 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1* %2, i32 1, i32 1), !dbg !32, !llvm.preserve.access.index !6 -+ %call = tail call i32 @get_value(i32* %3) #4, !dbg !33 -+ ret i32 %call, !dbg !34 -+} -+ -+; CHECK: r2 = 20 -+; CHECK: r1 += r2 -+; CHECK: r2 = 4 -+; CHECK: r1 += r2 -+; CHECK: call get_value -+ -+; CHECK: .long 6 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) -+; CHECK: .long 111 # BTF_KIND_STRUCT(id = [[TID2:[0-9]+]]) -+ -+; CHECK: .ascii "v3" # string offset=6 -+; CHECK: .ascii ".text" # string offset=57 -+; CHECK: .ascii "0:1:4" # string offset=63 -+; CHECK: .ascii "v1" # string offset=111 -+; CHECK: .ascii "0:1" # string offset=118 -+ -+; CHECK: .long 12 # OffsetReloc -+; CHECK-NEXT: .long 57 # Offset reloc section string offset=57 -+; CHECK-NEXT: .long 2 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID1]] -+; CHECK-NEXT: .long 63 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID2]] -+; CHECK-NEXT: .long 118 -+ -+declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 -+ -+; Function Attrs: nounwind readnone -+declare [40 x i32]* @llvm.preserve.struct.access.index.p0a40i32.p0s_struct.v3s(%struct.v3*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare i32* @llvm.preserve.array.access.index.p0i32.p0a40i32([40 x i32]*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v1s(%struct.v1*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone speculatable willreturn -+declare void @llvm.dbg.value(metadata, metadata, metadata) #3 -+ -+attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #2 = { nounwind readnone } -+attributes #3 = { nounwind readnone speculatable willreturn } -+attributes #4 = { nounwind } -+ -+!llvm.dbg.cu = !{!0} -+!llvm.module.flags = !{!15, !16, !17} -+!llvm.ident = !{!18} -+ -+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) -+!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") -+!2 = !{} -+!3 = !{!4, !11} -+!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) -+!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v1", file: !1, line: 2, baseType: !6) -+!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v1", file: !1, line: 1, size: 64, elements: !7) -+!7 = !{!8, !10} -+!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !1, line: 1, baseType: !9, size: 32) -+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -+!10 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !6, file: !1, line: 1, baseType: !9, size: 32, offset: 32) -+!11 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 1280, elements: !13) -+!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !1, line: 3, baseType: !9) -+!13 = !{!14} -+!14 = !DISubrange(count: 40) -+!15 = !{i32 2, !"Dwarf Version", i32 4} -+!16 = !{i32 2, !"Debug Info Version", i32 3} -+!17 = !{i32 1, !"wchar_size", i32 4} -+!18 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} -+!19 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 9, type: !20, scopeLine: 9, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !29) -+!20 = !DISubroutineType(types: !21) -+!21 = !{!9, !22} -+!22 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !23, size: 64) -+!23 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !1, line: 5, baseType: !24) -+!24 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !1, line: 4, size: 1312, elements: !25) -+!25 = !{!26, !28} -+!26 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !24, file: !1, line: 4, baseType: !27, size: 8) -+!27 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) -+!28 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !24, file: !1, line: 4, baseType: !11, size: 1280, offset: 32) -+!29 = !{!30} -+!30 = !DILocalVariable(name: "arg", arg: 1, scope: !19, file: !1, line: 9, type: !22) -+!31 = !DILocation(line: 0, scope: !19) -+!32 = !DILocation(line: 10, column: 20, scope: !19) -+!33 = !DILocation(line: 10, column: 10, scope: !19) -+!34 = !DILocation(line: 10, column: 3, scope: !19) -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-union-1.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-union-1.ll -new file mode 100644 -index 0000000..1e8f99c ---- /dev/null -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-union-1.ll -@@ -0,0 +1,117 @@ -+; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; Source code: -+; union v1 { int a; int b; }; -+; typedef union v1 __v1; -+; union v2 { int c; int d; }; -+; typedef union v2 __v2; -+; union v3 { char c; volatile const __v2 d; }; -+; typedef union v3 __v3; -+; #define _(x) (__builtin_preserve_access_index(x)) -+; #define cast_to_v1(x) ((__v1 *)(x)) -+; int get_value(const int *arg); -+; int test(__v3 *arg) { -+; return get_value(_(&cast_to_v1(&arg->d)->b)); -+; } -+; Compilation flag: -+; clang -target bpf -O2 -g -S -emit-llvm test.c -+ -+%union.v3 = type { %union.v2 } -+%union.v2 = type { i32 } -+%union.v1 = type { i32 } -+ -+; Function Attrs: nounwind -+define dso_local i32 @test(%union.v3* %arg) local_unnamed_addr #0 !dbg !15 { -+entry: -+ call void @llvm.dbg.value(metadata %union.v3* %arg, metadata !33, metadata !DIExpression()), !dbg !34 -+ %0 = tail call %union.v3* @llvm.preserve.union.access.index.p0s_union.v3s.p0s_union.v3s(%union.v3* %arg, i32 1), !dbg !35, !llvm.preserve.access.index !20 -+ %1 = bitcast %union.v3* %0 to %union.v1*, !dbg !35 -+ %2 = tail call %union.v1* @llvm.preserve.union.access.index.p0s_union.v1s.p0s_union.v1s(%union.v1* %1, i32 1), !dbg !35, !llvm.preserve.access.index !6 -+ %b = getelementptr inbounds %union.v1, %union.v1* %2, i64 0, i32 0, !dbg !35 -+ %call = tail call i32 @get_value(i32* %b) #4, !dbg !36 -+ ret i32 %call, !dbg !37 -+} -+ -+; CHECK: r2 = 0 -+; CHECK: r1 += r2 -+; CHECK: r2 = 0 -+; CHECK: r1 += r2 -+; CHECK: call get_value -+ -+; CHECK: .long 6 # BTF_KIND_UNION(id = [[TID1:[0-9]+]]) -+; CHECK: .long 91 # BTF_KIND_UNION(id = [[TID2:[0-9]+]]) -+ -+; CHECK: .ascii "v3" # string offset=6 -+; CHECK: .ascii ".text" # string offset=39 -+; CHECK: .ascii "0:1" # string offset=45 -+; CHECK: .ascii "v1" # string offset=91 -+ -+; CHECK: .long 12 # OffsetReloc -+; CHECK-NEXT: .long 39 # Offset reloc section string offset=39 -+; CHECK-NEXT: .long 2 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID1]] -+; CHECK-NEXT: .long 45 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID2]] -+; CHECK-NEXT: .long 45 -+ -+declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 -+ -+; Function Attrs: nounwind readnone -+declare %union.v3* @llvm.preserve.union.access.index.p0s_union.v3s.p0s_union.v3s(%union.v3*, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare %union.v1* @llvm.preserve.union.access.index.p0s_union.v1s.p0s_union.v1s(%union.v1*, i32) #2 -+ -+; Function Attrs: nounwind readnone speculatable willreturn -+declare void @llvm.dbg.value(metadata, metadata, metadata) #3 -+ -+attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #2 = { nounwind readnone } -+attributes #3 = { nounwind readnone speculatable willreturn } -+attributes #4 = { nounwind } -+ -+!llvm.dbg.cu = !{!0} -+!llvm.module.flags = !{!11, !12, !13} -+!llvm.ident = !{!14} -+ -+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) -+!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") -+!2 = !{} -+!3 = !{!4} -+!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) -+!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v1", file: !1, line: 2, baseType: !6) -+!6 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "v1", file: !1, line: 1, size: 32, elements: !7) -+!7 = !{!8, !10} -+!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !1, line: 1, baseType: !9, size: 32) -+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -+!10 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !6, file: !1, line: 1, baseType: !9, size: 32) -+!11 = !{i32 2, !"Dwarf Version", i32 4} -+!12 = !{i32 2, !"Debug Info Version", i32 3} -+!13 = !{i32 1, !"wchar_size", i32 4} -+!14 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} -+!15 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 10, type: !16, scopeLine: 10, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !32) -+!16 = !DISubroutineType(types: !17) -+!17 = !{!9, !18} -+!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) -+!19 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !1, line: 6, baseType: !20) -+!20 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "v3", file: !1, line: 5, size: 32, elements: !21) -+!21 = !{!22, !24} -+!22 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !20, file: !1, line: 5, baseType: !23, size: 8) -+!23 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) -+!24 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !20, file: !1, line: 5, baseType: !25, size: 32) -+!25 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !26) -+!26 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !27) -+!27 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v2", file: !1, line: 4, baseType: !28) -+!28 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "v2", file: !1, line: 3, size: 32, elements: !29) -+!29 = !{!30, !31} -+!30 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !28, file: !1, line: 3, baseType: !9, size: 32) -+!31 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !28, file: !1, line: 3, baseType: !9, size: 32) -+!32 = !{!33} -+!33 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 10, type: !18) -+!34 = !DILocation(line: 0, scope: !15) -+!35 = !DILocation(line: 11, column: 20, scope: !15) -+!36 = !DILocation(line: 11, column: 10, scope: !15) -+!37 = !DILocation(line: 11, column: 3, scope: !15) -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-union-2.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-union-2.ll -new file mode 100644 -index 0000000..320b0a9 ---- /dev/null -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-cast-union-2.ll -@@ -0,0 +1,118 @@ -+; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; Source code: -+; union v1 { int a; int b; }; -+; typedef union v1 __v1; -+; typedef int __int; -+; union v3 { char c; __int d[40]; }; -+; typedef union v3 __v3; -+; #define _(x) (__builtin_preserve_access_index(x)) -+; #define cast_to_v1(x) ((__v1 *)(x)) -+; int get_value(const int *arg); -+; int test(__v3 *arg) { -+; return get_value(_(&cast_to_v1(&arg->d[4])->b)); -+; } -+; Compilation flag: -+; clang -target bpf -O2 -g -S -emit-llvm test.c -+ -+%union.v3 = type { [40 x i32] } -+%union.v1 = type { i32 } -+ -+; Function Attrs: nounwind -+define dso_local i32 @test(%union.v3* %arg) local_unnamed_addr #0 !dbg !19 { -+entry: -+ call void @llvm.dbg.value(metadata %union.v3* %arg, metadata !30, metadata !DIExpression()), !dbg !31 -+ %0 = tail call %union.v3* @llvm.preserve.union.access.index.p0s_union.v3s.p0s_union.v3s(%union.v3* %arg, i32 1), !dbg !32, !llvm.preserve.access.index !24 -+ %d = getelementptr inbounds %union.v3, %union.v3* %0, i64 0, i32 0, !dbg !32 -+ %1 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a40i32([40 x i32]* %d, i32 1, i32 4), !dbg !32, !llvm.preserve.access.index !11 -+ %2 = bitcast i32* %1 to %union.v1*, !dbg !32 -+ %3 = tail call %union.v1* @llvm.preserve.union.access.index.p0s_union.v1s.p0s_union.v1s(%union.v1* %2, i32 1), !dbg !32, !llvm.preserve.access.index !6 -+ %b = getelementptr inbounds %union.v1, %union.v1* %3, i64 0, i32 0, !dbg !32 -+ %call = tail call i32 @get_value(i32* %b) #4, !dbg !33 -+ ret i32 %call, !dbg !34 -+} -+ -+; CHECK: r2 = 16 -+; CHECK: r1 += r2 -+; CHECK: r2 = 0 -+; CHECK: r1 += r2 -+; CHECK: call get_value -+ -+; CHECK: .long 6 # BTF_KIND_UNION(id = [[TID1:[0-9]+]]) -+; CHECK: .long 111 # BTF_KIND_UNION(id = [[TID2:[0-9]+]]) -+ -+; CHECK: .ascii "v3" # string offset=6 -+; CHECK: .ascii ".text" # string offset=57 -+; CHECK: .ascii "0:1:4" # string offset=63 -+; CHECK: .ascii "v1" # string offset=111 -+; CHECK: .ascii "0:1" # string offset=118 -+ -+; CHECK: .long 12 # OffsetReloc -+; CHECK-NEXT: .long 57 # Offset reloc section string offset=57 -+; CHECK-NEXT: .long 2 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID1]] -+; CHECK-NEXT: .long 63 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID2]] -+; CHECK-NEXT: .long 118 -+ -+declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 -+ -+; Function Attrs: nounwind readnone -+declare %union.v3* @llvm.preserve.union.access.index.p0s_union.v3s.p0s_union.v3s(%union.v3*, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare i32* @llvm.preserve.array.access.index.p0i32.p0a40i32([40 x i32]*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare %union.v1* @llvm.preserve.union.access.index.p0s_union.v1s.p0s_union.v1s(%union.v1*, i32) #2 -+ -+; Function Attrs: nounwind readnone speculatable willreturn -+declare void @llvm.dbg.value(metadata, metadata, metadata) #3 -+ -+attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #2 = { nounwind readnone } -+attributes #3 = { nounwind readnone speculatable willreturn } -+attributes #4 = { nounwind } -+ -+!llvm.dbg.cu = !{!0} -+!llvm.module.flags = !{!15, !16, !17} -+!llvm.ident = !{!18} -+ -+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) -+!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") -+!2 = !{} -+!3 = !{!4, !11} -+!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) -+!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v1", file: !1, line: 2, baseType: !6) -+!6 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "v1", file: !1, line: 1, size: 32, elements: !7) -+!7 = !{!8, !10} -+!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !1, line: 1, baseType: !9, size: 32) -+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -+!10 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !6, file: !1, line: 1, baseType: !9, size: 32) -+!11 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 1280, elements: !13) -+!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !1, line: 3, baseType: !9) -+!13 = !{!14} -+!14 = !DISubrange(count: 40) -+!15 = !{i32 2, !"Dwarf Version", i32 4} -+!16 = !{i32 2, !"Debug Info Version", i32 3} -+!17 = !{i32 1, !"wchar_size", i32 4} -+!18 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} -+!19 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 9, type: !20, scopeLine: 9, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !29) -+!20 = !DISubroutineType(types: !21) -+!21 = !{!9, !22} -+!22 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !23, size: 64) -+!23 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !1, line: 5, baseType: !24) -+!24 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "v3", file: !1, line: 4, size: 1280, elements: !25) -+!25 = !{!26, !28} -+!26 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !24, file: !1, line: 4, baseType: !27, size: 8) -+!27 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) -+!28 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !24, file: !1, line: 4, baseType: !11, size: 1280) -+!29 = !{!30} -+!30 = !DILocalVariable(name: "arg", arg: 1, scope: !19, file: !1, line: 9, type: !22) -+!31 = !DILocation(line: 0, scope: !19) -+!32 = !DILocation(line: 10, column: 20, scope: !19) -+!33 = !DILocation(line: 10, column: 10, scope: !19) -+!34 = !DILocation(line: 10, column: 3, scope: !19) -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-1.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-1.ll -new file mode 100644 -index 0000000..296e2d4 ---- /dev/null -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-1.ll -@@ -0,0 +1,79 @@ -+; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; Source code: -+; typedef struct v3 { int a; int b; } __v3; -+; #define _(x) (__builtin_preserve_access_index(x)) -+; int get_value(const int *arg); -+; __v3 g __attribute__((section("stats"))); -+; int test() { -+; return get_value(_(&g.b)); -+; } -+; Compilation flag: -+; clang -target bpf -O2 -g -S -emit-llvm test.c -+ -+%struct.v3 = type { i32, i32 } -+ -+@g = dso_local global %struct.v3 zeroinitializer, section "stats", align 4, !dbg !0 -+ -+; Function Attrs: nounwind -+define dso_local i32 @test() local_unnamed_addr #0 !dbg !16 { -+entry: -+ %0 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v3s(%struct.v3* nonnull @g, i32 1, i32 1), !dbg !19, !llvm.preserve.access.index !7 -+ %call = tail call i32 @get_value(i32* %0) #3, !dbg !20 -+ ret i32 %call, !dbg !21 -+} -+ -+; CHECK: r2 = 4 -+; CHECK: r1 = g ll -+; CHECK: r1 += r2 -+; CHECK: call get_value -+ -+; CHECK: .long 16 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) -+ -+; CHECK: .ascii ".text" # string offset=10 -+; CHECK: .ascii "v3" # string offset=16 -+; CHECK: .ascii "0:1" # string offset=23 -+ -+; CHECK: .long 12 # OffsetReloc -+; CHECK-NEXT: .long 10 # Offset reloc section string offset=10 -+; CHECK-NEXT: .long 1 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID1]] -+; CHECK-NEXT: .long 23 -+ -+declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 -+ -+; Function Attrs: nounwind readnone -+declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v3s(%struct.v3*, i32, i32) #2 -+ -+attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #2 = { nounwind readnone } -+attributes #3 = { nounwind } -+ -+!llvm.dbg.cu = !{!2} -+!llvm.module.flags = !{!12, !13, !14} -+!llvm.ident = !{!15} -+ -+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -+!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 4, type: !6, isLocal: false, isDefinition: true) -+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) -+!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") -+!4 = !{} -+!5 = !{!0} -+!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !3, line: 1, baseType: !7) -+!7 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !3, line: 1, size: 64, elements: !8) -+!8 = !{!9, !11} -+!9 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !7, file: !3, line: 1, baseType: !10, size: 32) -+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -+!11 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !7, file: !3, line: 1, baseType: !10, size: 32, offset: 32) -+!12 = !{i32 2, !"Dwarf Version", i32 4} -+!13 = !{i32 2, !"Debug Info Version", i32 3} -+!14 = !{i32 1, !"wchar_size", i32 4} -+!15 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} -+!16 = distinct !DISubprogram(name: "test", scope: !3, file: !3, line: 5, type: !17, scopeLine: 5, isDefinition: true, isOptimized: true, unit: !2, retainedNodes: !4) -+!17 = !DISubroutineType(types: !18) -+!18 = !{!10} -+!19 = !DILocation(line: 6, column: 20, scope: !16) -+!20 = !DILocation(line: 6, column: 10, scope: !16) -+!21 = !DILocation(line: 6, column: 3, scope: !16) -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-2.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-2.ll -new file mode 100644 -index 0000000..721081e ---- /dev/null -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-2.ll -@@ -0,0 +1,95 @@ -+; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; Source code: -+; typedef struct v3 { int a; int b; } __v3; -+; #define _(x) (__builtin_preserve_access_index(x)) -+; int get_value(const int *arg); -+; __v3 g[4][5] __attribute__((section("stats"))); -+; int test() { -+; return get_value(_(&g[1][2].b)); -+; } -+; Compilation flag: -+; clang -target bpf -O2 -g -S -emit-llvm test.c -+ -+%struct.v3 = type { i32, i32 } -+ -+@g = dso_local global [4 x [5 x %struct.v3]] zeroinitializer, section "stats", align 4, !dbg !0 -+ -+; Function Attrs: nounwind -+define dso_local i32 @test() local_unnamed_addr #0 !dbg !23 { -+entry: -+ %0 = tail call [5 x %struct.v3]* @llvm.preserve.array.access.index.p0a5s_struct.v3s.p0a4a5s_struct.v3s([4 x [5 x %struct.v3]]* nonnull @g, i32 1, i32 1), !dbg !26, !llvm.preserve.access.index !6 -+ %1 = tail call %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0a5s_struct.v3s([5 x %struct.v3]* %0, i32 1, i32 2), !dbg !26, !llvm.preserve.access.index !16 -+ %2 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v3s(%struct.v3* %1, i32 1, i32 1), !dbg !26, !llvm.preserve.access.index !8 -+ %call = tail call i32 @get_value(i32* %2) #3, !dbg !27 -+ ret i32 %call, !dbg !28 -+} -+ -+; CHECK: r2 = 60 -+; CHECK: r1 = g ll -+; CHECK: r1 += r2 -+; CHECK: call get_value -+ -+; CHECK: .long 16 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) -+ -+; CHECK: .ascii ".text" # string offset=10 -+; CHECK: .ascii "v3" # string offset=16 -+; CHECK: .ascii "7:1" # string offset=23 -+ -+; CHECK: .long 12 # OffsetReloc -+; CHECK-NEXT: .long 10 # Offset reloc section string offset=10 -+; CHECK-NEXT: .long 1 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID1]] -+; CHECK-NEXT: .long 23 -+ -+ -+declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 -+ -+; Function Attrs: nounwind readnone -+declare [5 x %struct.v3]* @llvm.preserve.array.access.index.p0a5s_struct.v3s.p0a4a5s_struct.v3s([4 x [5 x %struct.v3]]*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0a5s_struct.v3s([5 x %struct.v3]*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v3s(%struct.v3*, i32, i32) #2 -+ -+attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #2 = { nounwind readnone } -+attributes #3 = { nounwind } -+ -+!llvm.dbg.cu = !{!2} -+!llvm.module.flags = !{!19, !20, !21} -+!llvm.ident = !{!22} -+ -+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -+!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 4, type: !6, isLocal: false, isDefinition: true) -+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !18, nameTableKind: None) -+!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") -+!4 = !{} -+!5 = !{!6, !16} -+!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 1280, elements: !13) -+!7 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !3, line: 1, baseType: !8) -+!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !3, line: 1, size: 64, elements: !9) -+!9 = !{!10, !12} -+!10 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !8, file: !3, line: 1, baseType: !11, size: 32) -+!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -+!12 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !8, file: !3, line: 1, baseType: !11, size: 32, offset: 32) -+!13 = !{!14, !15} -+!14 = !DISubrange(count: 4) -+!15 = !DISubrange(count: 5) -+!16 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 320, elements: !17) -+!17 = !{!15} -+!18 = !{!0} -+!19 = !{i32 2, !"Dwarf Version", i32 4} -+!20 = !{i32 2, !"Debug Info Version", i32 3} -+!21 = !{i32 1, !"wchar_size", i32 4} -+!22 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} -+!23 = distinct !DISubprogram(name: "test", scope: !3, file: !3, line: 5, type: !24, scopeLine: 5, isDefinition: true, isOptimized: true, unit: !2, retainedNodes: !4) -+!24 = !DISubroutineType(types: !25) -+!25 = !{!11} -+!26 = !DILocation(line: 6, column: 20, scope: !23) -+!27 = !DILocation(line: 6, column: 10, scope: !23) -+!28 = !DILocation(line: 6, column: 3, scope: !23) -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-3.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-3.ll -new file mode 100644 -index 0000000..394d04f ---- /dev/null -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-global-3.ll -@@ -0,0 +1,84 @@ -+; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; Source code: -+; typedef struct v3 { int a; int b; } __v3; -+; #define _(x) (__builtin_preserve_access_index(x)) -+; int get_value(const int *arg); -+; __v3 *g __attribute__((section("stats"))); -+; int test() { -+; return get_value(_(&g->b)); -+; } -+; Compilation flag: -+; clang -target bpf -O2 -g -S -emit-llvm test.c -+ -+%struct.v3 = type { i32, i32 } -+ -+@g = dso_local local_unnamed_addr global %struct.v3* null, section "stats", align 8, !dbg !0 -+ -+; Function Attrs: nounwind -+define dso_local i32 @test() local_unnamed_addr #0 !dbg !17 { -+entry: -+ %0 = load %struct.v3*, %struct.v3** @g, align 8, !dbg !20, !tbaa !21 -+ %1 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v3s(%struct.v3* %0, i32 1, i32 1), !dbg !20, !llvm.preserve.access.index !8 -+ %call = tail call i32 @get_value(i32* %1) #3, !dbg !25 -+ ret i32 %call, !dbg !26 -+} -+ -+; CHECK: r2 = 4 -+; CHECK: r1 += r2 -+; CHECK: call get_value -+ -+; CHECK: .long 16 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) -+ -+; CHECK: .ascii ".text" # string offset=10 -+; CHECK: .ascii "v3" # string offset=16 -+; CHECK: .ascii "0:1" # string offset=23 -+ -+; CHECK: .long 12 # OffsetReloc -+; CHECK-NEXT: .long 10 # Offset reloc section string offset=10 -+; CHECK-NEXT: .long 1 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID1]] -+; CHECK-NEXT: .long 23 -+ -+declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 -+ -+; Function Attrs: nounwind readnone -+declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v3s(%struct.v3*, i32, i32) #2 -+ -+attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #2 = { nounwind readnone } -+attributes #3 = { nounwind } -+ -+!llvm.dbg.cu = !{!2} -+!llvm.module.flags = !{!13, !14, !15} -+!llvm.ident = !{!16} -+ -+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -+!1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 4, type: !6, isLocal: false, isDefinition: true) -+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) -+!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") -+!4 = !{} -+!5 = !{!0} -+!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) -+!7 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !3, line: 1, baseType: !8) -+!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !3, line: 1, size: 64, elements: !9) -+!9 = !{!10, !12} -+!10 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !8, file: !3, line: 1, baseType: !11, size: 32) -+!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -+!12 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !8, file: !3, line: 1, baseType: !11, size: 32, offset: 32) -+!13 = !{i32 2, !"Dwarf Version", i32 4} -+!14 = !{i32 2, !"Debug Info Version", i32 3} -+!15 = !{i32 1, !"wchar_size", i32 4} -+!16 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} -+!17 = distinct !DISubprogram(name: "test", scope: !3, file: !3, line: 5, type: !18, scopeLine: 5, isDefinition: true, isOptimized: true, unit: !2, retainedNodes: !4) -+!18 = !DISubroutineType(types: !19) -+!19 = !{!11} -+!20 = !DILocation(line: 6, column: 20, scope: !17) -+!21 = !{!22, !22, i64 0} -+!22 = !{!"any pointer", !23, i64 0} -+!23 = !{!"omnipotent char", !24, i64 0} -+!24 = !{!"Simple C/C++ TBAA"} -+!25 = !DILocation(line: 6, column: 10, scope: !17) -+!26 = !DILocation(line: 6, column: 3, scope: !17) -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-ignore.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-ignore.ll -new file mode 100644 -index 0000000..2d14e71 ---- /dev/null -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-ignore.ll -@@ -0,0 +1,62 @@ -+; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; Source code: -+; #define _(x) (__builtin_preserve_access_index(x)) -+; int get_value(const int *arg); -+; int test(int *arg) { -+; return get_value(_(&arg[4])); -+; } -+; Compilation flag: -+; clang -target bpf -O2 -g -S -emit-llvm test.c -+ -+; Function Attrs: nounwind -+define dso_local i32 @test(i32* %arg) local_unnamed_addr #0 !dbg !10 { -+entry: -+ call void @llvm.dbg.value(metadata i32* %arg, metadata !14, metadata !DIExpression()), !dbg !15 -+ %0 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0i32(i32* %arg, i32 0, i32 4), !dbg !16, !llvm.preserve.access.index !4 -+ %call = tail call i32 @get_value(i32* %0) #4, !dbg !17 -+ ret i32 %call, !dbg !18 -+} -+ -+; CHECK: r1 += 16 -+; CHECK: call get_value -+; CHECK: .section .BTF.ext,"",@progbits -+; CHECK-NOT: .long 12 # OffsetReloc -+ -+declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 -+ -+; Function Attrs: nounwind readnone -+declare i32* @llvm.preserve.array.access.index.p0i32.p0i32(i32*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone speculatable willreturn -+declare void @llvm.dbg.value(metadata, metadata, metadata) #3 -+ -+attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #2 = { nounwind readnone } -+attributes #3 = { nounwind readnone speculatable willreturn } -+attributes #4 = { nounwind } -+ -+!llvm.dbg.cu = !{!0} -+!llvm.module.flags = !{!6, !7, !8} -+!llvm.ident = !{!9} -+ -+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) -+!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") -+!2 = !{} -+!3 = !{!4} -+!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) -+!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -+!6 = !{i32 2, !"Dwarf Version", i32 4} -+!7 = !{i32 2, !"Debug Info Version", i32 3} -+!8 = !{i32 1, !"wchar_size", i32 4} -+!9 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} -+!10 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 3, type: !11, scopeLine: 3, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !13) -+!11 = !DISubroutineType(types: !12) -+!12 = !{!5, !4} -+!13 = !{!14} -+!14 = !DILocalVariable(name: "arg", arg: 1, scope: !10, file: !1, line: 3, type: !4) -+!15 = !DILocation(line: 0, scope: !10) -+!16 = !DILocation(line: 4, column: 20, scope: !10) -+!17 = !DILocation(line: 4, column: 10, scope: !10) -+!18 = !DILocation(line: 4, column: 3, scope: !10) -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-multi-array-1.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-multi-array-1.ll -new file mode 100644 -index 0000000..7f79196f ---- /dev/null -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-multi-array-1.ll -@@ -0,0 +1,101 @@ -+; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; Source code: -+; typedef int __int; -+; typedef struct v3 { int a; __int b[4][4]; } __v3; -+; #define _(x) (__builtin_preserve_access_index(x)) -+; int get_value(const int *arg); -+; int test(__v3 *arg) { -+; return get_value(_(&arg[1].b[2][3])); -+; } -+; Compilation flag: -+; clang -target bpf -O2 -g -S -emit-llvm test.c -+ -+%struct.v3 = type { i32, [4 x [4 x i32]] } -+ -+; Function Attrs: nounwind -+define dso_local i32 @test(%struct.v3* %arg) local_unnamed_addr #0 !dbg !21 { -+entry: -+ call void @llvm.dbg.value(metadata %struct.v3* %arg, metadata !25, metadata !DIExpression()), !dbg !26 -+ %0 = tail call %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0s_struct.v3s(%struct.v3* %arg, i32 0, i32 1), !dbg !27, !llvm.preserve.access.index !4 -+ %1 = tail call [4 x [4 x i32]]* @llvm.preserve.struct.access.index.p0a4a4i32.p0s_struct.v3s(%struct.v3* %0, i32 1, i32 1), !dbg !27, !llvm.preserve.access.index !6 -+ %2 = tail call [4 x i32]* @llvm.preserve.array.access.index.p0a4i32.p0a4a4i32([4 x [4 x i32]]* %1, i32 1, i32 2), !dbg !27, !llvm.preserve.access.index !11 -+ %3 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a4i32([4 x i32]* %2, i32 1, i32 3), !dbg !27, !llvm.preserve.access.index !15 -+ %call = tail call i32 @get_value(i32* %3) #4, !dbg !28 -+ ret i32 %call, !dbg !29 -+} -+ -+; CHECK: r2 = 116 -+; CHECK: r1 += r2 -+; CHECK: call get_value -+ -+; CHECK: .long 6 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) -+ -+; CHECK: .ascii "v3" # string offset=6 -+; CHECK: .ascii ".text" # string offset=52 -+; CHECK: .ascii "1:1:2:3" # string offset=58 -+ -+; CHECK: .long 12 # OffsetReloc -+; CHECK-NEXT: .long 52 # Offset reloc section string offset=52 -+; CHECK-NEXT: .long 1 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID1]] -+; CHECK-NEXT: .long 58 -+ -+declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 -+ -+; Function Attrs: nounwind readnone -+declare %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0s_struct.v3s(%struct.v3*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare [4 x [4 x i32]]* @llvm.preserve.struct.access.index.p0a4a4i32.p0s_struct.v3s(%struct.v3*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare [4 x i32]* @llvm.preserve.array.access.index.p0a4i32.p0a4a4i32([4 x [4 x i32]]*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare i32* @llvm.preserve.array.access.index.p0i32.p0a4i32([4 x i32]*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone speculatable willreturn -+declare void @llvm.dbg.value(metadata, metadata, metadata) #3 -+ -+attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #2 = { nounwind readnone } -+attributes #3 = { nounwind readnone speculatable willreturn } -+attributes #4 = { nounwind } -+ -+!llvm.dbg.cu = !{!0} -+!llvm.module.flags = !{!17, !18, !19} -+!llvm.ident = !{!20} -+ -+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) -+!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") -+!2 = !{} -+!3 = !{!4, !11, !15} -+!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) -+!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !1, line: 2, baseType: !6) -+!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !1, line: 2, size: 544, elements: !7) -+!7 = !{!8, !10} -+!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !1, line: 2, baseType: !9, size: 32) -+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -+!10 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !6, file: !1, line: 2, baseType: !11, size: 512, offset: 32) -+!11 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 512, elements: !13) -+!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !1, line: 1, baseType: !9) -+!13 = !{!14, !14} -+!14 = !DISubrange(count: 4) -+!15 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 128, elements: !16) -+!16 = !{!14} -+!17 = !{i32 2, !"Dwarf Version", i32 4} -+!18 = !{i32 2, !"Debug Info Version", i32 3} -+!19 = !{i32 1, !"wchar_size", i32 4} -+!20 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} -+!21 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 5, type: !22, scopeLine: 5, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !24) -+!22 = !DISubroutineType(types: !23) -+!23 = !{!9, !4} -+!24 = !{!25} -+!25 = !DILocalVariable(name: "arg", arg: 1, scope: !21, file: !1, line: 5, type: !4) -+!26 = !DILocation(line: 0, scope: !21) -+!27 = !DILocation(line: 6, column: 20, scope: !21) -+!28 = !DILocation(line: 6, column: 10, scope: !21) -+!29 = !DILocation(line: 6, column: 3, scope: !21) -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-multi-array-2.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-multi-array-2.ll -new file mode 100644 -index 0000000..a9c29aa ---- /dev/null -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-multi-array-2.ll -@@ -0,0 +1,107 @@ -+; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; Source code: -+; typedef int __int; -+; typedef struct v3 { int a; __int b[4][4][4]; } __v3; -+; #define _(x) (__builtin_preserve_access_index(x)) -+; int get_value(const int *arg); -+; int test(__v3 *arg) { -+; return get_value(_(&arg[1].b[2][3][2])); -+; } -+; Compilation flag: -+; clang -target bpf -O2 -g -S -emit-llvm test.c -+ -+%struct.v3 = type { i32, [4 x [4 x [4 x i32]]] } -+ -+; Function Attrs: nounwind -+define dso_local i32 @test(%struct.v3* %arg) local_unnamed_addr #0 !dbg !23 { -+entry: -+ call void @llvm.dbg.value(metadata %struct.v3* %arg, metadata !27, metadata !DIExpression()), !dbg !28 -+ %0 = tail call %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0s_struct.v3s(%struct.v3* %arg, i32 0, i32 1), !dbg !29, !llvm.preserve.access.index !4 -+ %1 = tail call [4 x [4 x [4 x i32]]]* @llvm.preserve.struct.access.index.p0a4a4a4i32.p0s_struct.v3s(%struct.v3* %0, i32 1, i32 1), !dbg !29, !llvm.preserve.access.index !6 -+ %2 = tail call [4 x [4 x i32]]* @llvm.preserve.array.access.index.p0a4a4i32.p0a4a4a4i32([4 x [4 x [4 x i32]]]* %1, i32 1, i32 2), !dbg !29, !llvm.preserve.access.index !11 -+ %3 = tail call [4 x i32]* @llvm.preserve.array.access.index.p0a4i32.p0a4a4i32([4 x [4 x i32]]* %2, i32 1, i32 3), !dbg !29, !llvm.preserve.access.index !15 -+ %4 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a4i32([4 x i32]* %3, i32 1, i32 2), !dbg !29, !llvm.preserve.access.index !17 -+ %call = tail call i32 @get_value(i32* %4) #4, !dbg !30 -+ ret i32 %call, !dbg !31 -+} -+ -+; CHECK: r2 = 448 -+; CHECK: r1 += r2 -+; CHECK: call get_value -+ -+; CHECK: .long 6 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) -+ -+; CHECK: .ascii "v3" # string offset=6 -+; CHECK: .ascii ".text" # string offset=52 -+; CHECK: .ascii "1:1:2:3:2" # string offset=58 -+ -+; CHECK: .long 12 # OffsetReloc -+; CHECK-NEXT: .long 52 # Offset reloc section string offset=52 -+; CHECK-NEXT: .long 1 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID1]] -+; CHECK-NEXT: .long 58 -+ -+declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 -+ -+; Function Attrs: nounwind readnone -+declare %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0s_struct.v3s(%struct.v3*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare [4 x [4 x [4 x i32]]]* @llvm.preserve.struct.access.index.p0a4a4a4i32.p0s_struct.v3s(%struct.v3*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare [4 x [4 x i32]]* @llvm.preserve.array.access.index.p0a4a4i32.p0a4a4a4i32([4 x [4 x [4 x i32]]]*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare [4 x i32]* @llvm.preserve.array.access.index.p0a4i32.p0a4a4i32([4 x [4 x i32]]*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare i32* @llvm.preserve.array.access.index.p0i32.p0a4i32([4 x i32]*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone speculatable willreturn -+declare void @llvm.dbg.value(metadata, metadata, metadata) #3 -+ -+attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #2 = { nounwind readnone } -+attributes #3 = { nounwind readnone speculatable willreturn } -+attributes #4 = { nounwind } -+ -+!llvm.dbg.cu = !{!0} -+!llvm.module.flags = !{!19, !20, !21} -+!llvm.ident = !{!22} -+ -+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) -+!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") -+!2 = !{} -+!3 = !{!4, !11, !15, !17} -+!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) -+!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !1, line: 2, baseType: !6) -+!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !1, line: 2, size: 2080, elements: !7) -+!7 = !{!8, !10} -+!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !1, line: 2, baseType: !9, size: 32) -+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -+!10 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !6, file: !1, line: 2, baseType: !11, size: 2048, offset: 32) -+!11 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 2048, elements: !13) -+!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !1, line: 1, baseType: !9) -+!13 = !{!14, !14, !14} -+!14 = !DISubrange(count: 4) -+!15 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 512, elements: !16) -+!16 = !{!14, !14} -+!17 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 128, elements: !18) -+!18 = !{!14} -+!19 = !{i32 2, !"Dwarf Version", i32 4} -+!20 = !{i32 2, !"Debug Info Version", i32 3} -+!21 = !{i32 1, !"wchar_size", i32 4} -+!22 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} -+!23 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 5, type: !24, scopeLine: 5, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !26) -+!24 = !DISubroutineType(types: !25) -+!25 = !{!9, !4} -+!26 = !{!27} -+!27 = !DILocalVariable(name: "arg", arg: 1, scope: !23, file: !1, line: 5, type: !4) -+!28 = !DILocation(line: 0, scope: !23) -+!29 = !DILocation(line: 6, column: 20, scope: !23) -+!30 = !DILocation(line: 6, column: 10, scope: !23) -+!31 = !DILocation(line: 6, column: 3, scope: !23) -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-pointer-1.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-pointer-1.ll -new file mode 100644 -index 0000000..e85b393 ---- /dev/null -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-pointer-1.ll -@@ -0,0 +1,83 @@ -+; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; Source code: -+; typedef struct v3 { int a; int b; } __v3; -+; #define _(x) (__builtin_preserve_access_index(x)) -+; int get_value(const int *arg); -+; int test(__v3 *arg) { -+; return get_value(_(&arg[1])); -+; } -+; Compilation flag: -+; clang -target bpf -O2 -g -S -emit-llvm test.c -+ -+%struct.v3 = type { i32, i32 } -+ -+; Function Attrs: nounwind -+define dso_local i32 @test(%struct.v3* %arg) local_unnamed_addr #0 !dbg !15 { -+entry: -+ call void @llvm.dbg.value(metadata %struct.v3* %arg, metadata !19, metadata !DIExpression()), !dbg !20 -+ %0 = tail call %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0s_struct.v3s(%struct.v3* %arg, i32 0, i32 1), !dbg !21, !llvm.preserve.access.index !4 -+ %1 = getelementptr inbounds %struct.v3, %struct.v3* %0, i64 0, i32 0, !dbg !21 -+ %call = tail call i32 @get_value(i32* %1) #4, !dbg !22 -+ ret i32 %call, !dbg !23 -+} -+ -+; CHECK: r2 = 8 -+; CHECK: r1 += r2 -+; CHECK: call get_value -+ -+; CHECK: .long 6 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) -+ -+; CHECK: .ascii "v3" # string offset=6 -+; CHECK: .ascii ".text" # string offset=26 -+; CHECK: .byte 49 # string offset=32 -+ -+; CHECK: .long 12 # OffsetReloc -+; CHECK-NEXT: .long 26 # Offset reloc section string offset=26 -+; CHECK-NEXT: .long 1 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID1]] -+; CHECK-NEXT: .long 32 -+ -+declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 -+ -+; Function Attrs: nounwind readnone -+declare %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0s_struct.v3s(%struct.v3*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone speculatable willreturn -+declare void @llvm.dbg.value(metadata, metadata, metadata) #3 -+ -+attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #2 = { nounwind readnone } -+attributes #3 = { nounwind readnone speculatable willreturn } -+attributes #4 = { nounwind } -+ -+!llvm.dbg.cu = !{!0} -+!llvm.module.flags = !{!11, !12, !13} -+!llvm.ident = !{!14} -+ -+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) -+!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") -+!2 = !{} -+!3 = !{!4} -+!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) -+!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !1, line: 1, baseType: !6) -+!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !1, line: 1, size: 64, elements: !7) -+!7 = !{!8, !10} -+!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !1, line: 1, baseType: !9, size: 32) -+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -+!10 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !6, file: !1, line: 1, baseType: !9, size: 32, offset: 32) -+!11 = !{i32 2, !"Dwarf Version", i32 4} -+!12 = !{i32 2, !"Debug Info Version", i32 3} -+!13 = !{i32 1, !"wchar_size", i32 4} -+!14 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} -+!15 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !16, scopeLine: 4, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !18) -+!16 = !DISubroutineType(types: !17) -+!17 = !{!9, !4} -+!18 = !{!19} -+!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 4, type: !4) -+!20 = !DILocation(line: 0, scope: !15) -+!21 = !DILocation(line: 5, column: 20, scope: !15) -+!22 = !DILocation(line: 5, column: 10, scope: !15) -+!23 = !DILocation(line: 5, column: 3, scope: !15) -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-pointer-2.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-pointer-2.ll -new file mode 100644 -index 0000000..1c54935 ---- /dev/null -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-pointer-2.ll -@@ -0,0 +1,85 @@ -+; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s -+; Source code: -+; typedef struct v3 { int a; int b; } __v3; -+; #define _(x) (__builtin_preserve_access_index(x)) -+; int get_value(const int *arg); -+; int test(__v3 *arg) { -+; return get_value(_(&arg[1].b)); -+; } -+; Compilation flag: -+; clang -target bpf -O2 -g -S -emit-llvm test.c -+ -+%struct.v3 = type { i32, i32 } -+ -+; Function Attrs: nounwind -+define dso_local i32 @test(%struct.v3* %arg) local_unnamed_addr #0 !dbg !15 { -+entry: -+ call void @llvm.dbg.value(metadata %struct.v3* %arg, metadata !19, metadata !DIExpression()), !dbg !20 -+ %0 = tail call %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0s_struct.v3s(%struct.v3* %arg, i32 0, i32 1), !dbg !21, !llvm.preserve.access.index !4 -+ %1 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v3s(%struct.v3* %0, i32 1, i32 1), !dbg !21, !llvm.preserve.access.index !6 -+ %call = tail call i32 @get_value(i32* %1) #4, !dbg !22 -+ ret i32 %call, !dbg !23 -+} -+ -+; CHECK: r2 = 12 -+; CHECK-NEXT: r1 += r2 -+; CHECK: call get_value -+ -+; CHECK: .long 6 # BTF_KIND_STRUCT(id = [[TID1:[0-9]+]]) -+; CHECK: .ascii "v3" # string offset=6 -+; CHECK: .ascii ".text" # string offset=26 -+; CHECK: .ascii "1:1" # string offset=32 -+ -+; CHECK: .long 12 # OffsetReloc -+; CHECK-NEXT: .long 26 # Offset reloc section string offset=26 -+; CHECK-NEXT: .long 1 -+; CHECK-NEXT: .long .Ltmp{{[0-9]+}} -+; CHECK-NEXT: .long [[TID1]] -+; CHECK-NEXT: .long 32 -+ -+declare dso_local i32 @get_value(i32*) local_unnamed_addr #1 -+ -+; Function Attrs: nounwind readnone -+declare %struct.v3* @llvm.preserve.array.access.index.p0s_struct.v3s.p0s_struct.v3s(%struct.v3*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone -+declare i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.v3s(%struct.v3*, i32, i32) #2 -+ -+; Function Attrs: nounwind readnone speculatable willreturn -+declare void @llvm.dbg.value(metadata, metadata, metadata) #3 -+ -+attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -+attributes #2 = { nounwind readnone } -+attributes #3 = { nounwind readnone speculatable willreturn } -+attributes #4 = { nounwind } -+ -+!llvm.dbg.cu = !{!0} -+!llvm.module.flags = !{!11, !12, !13} -+!llvm.ident = !{!14} -+ -+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) -+!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/cast") -+!2 = !{} -+!3 = !{!4} -+!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) -+!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "__v3", file: !1, line: 1, baseType: !6) -+!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "v3", file: !1, line: 1, size: 64, elements: !7) -+!7 = !{!8, !10} -+!8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !1, line: 1, baseType: !9, size: 32) -+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -+!10 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !6, file: !1, line: 1, baseType: !9, size: 32, offset: 32) -+!11 = !{i32 2, !"Dwarf Version", i32 4} -+!12 = !{i32 2, !"Debug Info Version", i32 3} -+!13 = !{i32 1, !"wchar_size", i32 4} -+!14 = !{!"clang version 10.0.0 (trunk 367256) (llvm/trunk 367266)"} -+!15 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 4, type: !16, scopeLine: 4, flags: DIFlagPrototyped, isDefinition: true, isOptimized: true, unit: !0, retainedNodes: !18) -+!16 = !DISubroutineType(types: !17) -+!17 = !{!9, !4} -+!18 = !{!19} -+!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 4, type: !4) -+!20 = !DILocation(line: 0, scope: !15) -+!21 = !DILocation(line: 5, column: 20, scope: !15) -+!22 = !DILocation(line: 5, column: 10, scope: !15) -+!23 = !DILocation(line: 5, column: 3, scope: !15) -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-struct-anonymous.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-struct-anonymous.ll -index 732187c..08a204f 100644 ---- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-struct-anonymous.ll -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-struct-anonymous.ll -@@ -30,7 +30,7 @@ define dso_local i32 @bpf_prog(%struct.sk_buff*) local_unnamed_addr #0 !dbg !15 - %3 = bitcast i32* %2 to i8*, !dbg !34 - call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %3) #4, !dbg !34 - %4 = tail call [10 x %struct.anon]* @llvm.preserve.struct.access.index.p0a10s_struct.anons.p0s_struct.sk_buffs(%struct.sk_buff* %0, i32 1, i32 1), !dbg !35, !llvm.preserve.access.index !19 -- %5 = tail call %struct.anon* @llvm.preserve.array.access.index.p0s_struct.anons.p0a10s_struct.anons([10 x %struct.anon]* %4, i32 1, i32 5), !dbg !35 -+ %5 = tail call %struct.anon* @llvm.preserve.array.access.index.p0s_struct.anons.p0a10s_struct.anons([10 x %struct.anon]* %4, i32 1, i32 5), !dbg !35, !llvm.preserve.access.index !23 - %6 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.anons(%struct.anon* %5, i32 0, i32 0), !dbg !35, !llvm.preserve.access.index !24 - %7 = bitcast i32* %6 to i8*, !dbg !35 - %8 = call i32 inttoptr (i64 4 to i32 (i8*, i32, i8*)*)(i8* nonnull %3, i32 4, i8* %7) #4, !dbg !36 -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-struct-array.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-struct-array.ll -index 77d2375..b18a4ab 100644 ---- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-struct-array.ll -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-struct-array.ll -@@ -31,7 +31,7 @@ define dso_local i32 @bpf_prog(%struct.sk_buff*) local_unnamed_addr #0 !dbg !15 - %3 = bitcast i32* %2 to i8*, !dbg !34 - call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %3) #4, !dbg !34 - %4 = tail call [10 x %struct.net_device]* @llvm.preserve.struct.access.index.p0a10s_struct.net_devices.p0s_struct.sk_buffs(%struct.sk_buff* %0, i32 1, i32 1), !dbg !35, !llvm.preserve.access.index !19 -- %5 = tail call %struct.net_device* @llvm.preserve.array.access.index.p0s_struct.net_devices.p0a10s_struct.net_devices([10 x %struct.net_device]* %4, i32 1, i32 5), !dbg !35 -+ %5 = tail call %struct.net_device* @llvm.preserve.array.access.index.p0s_struct.net_devices.p0a10s_struct.net_devices([10 x %struct.net_device]* %4, i32 1, i32 5), !dbg !35, !llvm.preserve.access.index !23 - %6 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.net_devices(%struct.net_device* %5, i32 0, i32 0), !dbg !35, !llvm.preserve.access.index !24 - %7 = bitcast i32* %6 to i8*, !dbg !35 - %8 = call i32 inttoptr (i64 4 to i32 (i8*, i32, i8*)*)(i8* nonnull %3, i32 4, i8* %7) #4, !dbg !36 -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-array.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-array.ll -index 7843c52..d63bc07 100644 ---- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-array.ll -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef-array.ll -@@ -21,7 +21,7 @@ define dso_local i32 @test(%struct.__s* %arg) local_unnamed_addr #0 !dbg !7 { - entry: - call void @llvm.dbg.value(metadata %struct.__s* %arg, metadata !24, metadata !DIExpression()), !dbg !25 - %0 = tail call [7 x i32]* @llvm.preserve.struct.access.index.p0a7i32.p0s_struct.__ss(%struct.__s* %arg, i32 0, i32 0), !dbg !26, !llvm.preserve.access.index !13 -- %1 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a7i32([7 x i32]* %0, i32 1, i32 1), !dbg !26 -+ %1 = tail call i32* @llvm.preserve.array.access.index.p0i32.p0a7i32([7 x i32]* %0, i32 1, i32 1), !dbg !26, !llvm.preserve.access.index !19 - %2 = bitcast i32* %1 to i8*, !dbg !26 - %call = tail call i32 @get_value(i8* %2) #4, !dbg !27 - ret i32 %call, !dbg !28 -diff --git a/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef.ll b/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef.ll -index c09d979..8281694 100644 ---- a/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef.ll -+++ b/llvm/test/CodeGen/BPF/CORE/offset-reloc-typedef.ll -@@ -24,7 +24,7 @@ - define dso_local i32 @test([7 x %union.u]* %arg) local_unnamed_addr #0 !dbg !7 { - entry: - call void @llvm.dbg.value(metadata [7 x %union.u]* %arg, metadata !28, metadata !DIExpression()), !dbg !29 -- %0 = tail call [7 x %union.u]* @llvm.preserve.array.access.index.p0a7s_union.us.p0a7s_union.us([7 x %union.u]* %arg, i32 0, i32 1), !dbg !30 -+ %0 = tail call [7 x %union.u]* @llvm.preserve.array.access.index.p0a7s_union.us.p0a7s_union.us([7 x %union.u]* %arg, i32 0, i32 1), !dbg !30, !llvm.preserve.access.index !14 - %arraydecay = getelementptr inbounds [7 x %union.u], [7 x %union.u]* %0, i64 0, i64 0, !dbg !30 - %1 = tail call %union.u* @llvm.preserve.union.access.index.p0s_union.us.p0s_union.us(%union.u* %arraydecay, i32 1), !dbg !30, !llvm.preserve.access.index !16 - %d = getelementptr inbounds %union.u, %union.u* %1, i64 0, i32 0, !dbg !30 --- -1.8.3.1 - diff --git a/SOURCES/0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch b/SOURCES/0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch deleted file mode 100644 index 60ba6d9..0000000 --- a/SOURCES/0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch +++ /dev/null @@ -1,138 +0,0 @@ -From f2ccdd2700174c717dc55a0f4c3f5a91ae73ff42 Mon Sep 17 00:00:00 2001 -From: Yonghong Song -Date: Fri, 2 Aug 2019 21:28:28 +0000 -Subject: [PATCH] [BPF] annotate DIType metadata for builtin - preseve_array_access_index() - -Previously, debuginfo types are annotated to -IR builtin preserve_struct_access_index() and -preserve_union_access_index(), but not -preserve_array_access_index(). The debug info -is useful to identify the root type name which -later will be used for type comparison. - -For user access without explicit type conversions, -the previous scheme works as we can ignore intermediate -compiler generated type conversions (e.g., from union types to -union members) and still generate correct access index string. - -The issue comes with user explicit type conversions, e.g., -converting an array to a structure like below: - struct t { int a; char b[40]; }; - struct p { int c; int d; }; - struct t *var = ...; - ... __builtin_preserve_access_index(&(((struct p *)&(var->b[0]))->d)) ... -Although BPF backend can derive the type of &(var->b[0]), -explicit type annotation make checking more consistent -and less error prone. - -Another benefit is for multiple dimension array handling. -For example, - struct p { int c; int d; } g[8][9][10]; - ... __builtin_preserve_access_index(&g[2][3][4].d) ... -It would be possible to calculate the number of "struct p"'s -before accessing its member "d" if array debug info is -available as it contains each dimension range. - -This patch enables to annotate IR builtin preserve_array_access_index() -with proper debuginfo type. The unit test case and language reference -is updated as well. - -Signed-off-by: Yonghong Song - -Differential Revision: https://reviews.llvm.org/D65664 - -llvm-svn: 367724 -(cherry picked from commit d0ea05d5eff475a27a5d3bbe4d9fd389935f9cb2) - -Also added back -Value *CreatePreserveArrayAccessIndex(Value *Base, unsigned Dimension, - unsigned LastIndex); - -To avoid breaking the ABI. ---- - clang/lib/CodeGen/CGExpr.cpp | 12 ++++++++--- - .../CodeGen/builtin-preserve-access-index-array.c | 18 +++++++++++++++++ - clang/test/CodeGen/builtin-preserve-access-index.c | 23 +++++++++++----------- - llvm/docs/LangRef.rst | 4 ++++ - llvm/include/llvm/IR/IRBuilder.h | 13 ++++++++++-- - llvm/test/CodeGen/BPF/CORE/intrinsic-array.ll | 2 +- - 6 files changed, 55 insertions(+), 17 deletions(-) - create mode 100644 clang/test/CodeGen/builtin-preserve-access-index-array.c - -diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst -index 87e8a55..b63e3af 100644 ---- a/llvm/docs/LangRef.rst -+++ b/llvm/docs/LangRef.rst -@@ -17349,6 +17349,10 @@ based on array base ``base``, array dimension ``dim`` and the last access index - into the array. The return type ``ret_type`` is a pointer type to the array element. - The array ``dim`` and ``index`` are preserved which is more robust than - getelementptr instruction which may be subject to compiler transformation. -+The ``llvm.preserve.access.index`` type of metadata is attached to this call instruction -+to provide array or pointer debuginfo type. -+The metadata is a ``DICompositeType`` or ``DIDerivedType`` representing the -+debuginfo version of ``type``. - - Arguments: - """""""""" -diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h -index a74364d..c2fa9a3 100644 ---- a/llvm/include/llvm/IR/IRBuilder.h -+++ b/llvm/include/llvm/IR/IRBuilder.h -@@ -2455,6 +2455,11 @@ public: - - Value *CreatePreserveArrayAccessIndex(Value *Base, unsigned Dimension, - unsigned LastIndex) { -+ return CreatePreserveArrayAccessIndex(Base, Dimension, LastIndex, nullptr); -+ } -+ -+ Value *CreatePreserveArrayAccessIndex(Value *Base, unsigned Dimension, -+ unsigned LastIndex, MDNode *DbgInfo) { - assert(isa(Base->getType()) && - "Invalid Base ptr type for preserve.array.access.index."); - auto *BaseType = Base->getType(); -@@ -2476,6 +2481,8 @@ public: - Value *DimV = getInt32(Dimension); - CallInst *Fn = - CreateCall(FnPreserveArrayAccessIndex, {Base, DimV, LastIndexV}); -+ if (DbgInfo) -+ Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo); - - return Fn; - } -@@ -2493,7 +2500,8 @@ public: - Value *DIIndex = getInt32(FieldIndex); - CallInst *Fn = - CreateCall(FnPreserveUnionAccessIndex, {Base, DIIndex}); -- Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo); -+ if (DbgInfo) -+ Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo); - - return Fn; - } -@@ -2516,7 +2524,8 @@ public: - Value *DIIndex = getInt32(FieldIndex); - CallInst *Fn = CreateCall(FnPreserveStructAccessIndex, - {Base, GEPIndex, DIIndex}); -- Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo); -+ if (DbgInfo) -+ Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo); - - return Fn; - } -diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-array.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-array.ll -index adbcb9f..fe2c196 100644 ---- a/llvm/test/CodeGen/BPF/CORE/intrinsic-array.ll -+++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-array.ll -@@ -14,7 +14,7 @@ - define dso_local i32 @test(%struct.s* %arg) local_unnamed_addr #0 !dbg !7 { - entry: - call void @llvm.dbg.value(metadata %struct.s* %arg, metadata !17, metadata !DIExpression()), !dbg !18 -- %0 = tail call %struct.s* @llvm.preserve.array.access.index.p0s_struct.ss.p0s_struct.ss(%struct.s* %arg, i32 0, i32 2), !dbg !19 -+ %0 = tail call %struct.s* @llvm.preserve.array.access.index.p0s_struct.ss.p0s_struct.ss(%struct.s* %arg, i32 0, i32 2), !dbg !19, !llvm.preserve.access.index !11 - %1 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ss(%struct.s* %0, i32 1, i32 1), !dbg !19, !llvm.preserve.access.index !12 - %2 = bitcast i32* %1 to i8*, !dbg !19 - %call = tail call i32 @get_value(i8* %2) #4, !dbg !20 --- -1.8.3.1 - diff --git a/SOURCES/0001-Docs-llvm-strip-Add-help-text-to-llvm-strip-rst-doc.patch b/SOURCES/0001-Docs-llvm-strip-Add-help-text-to-llvm-strip-rst-doc.patch deleted file mode 100644 index 0be06dd..0000000 --- a/SOURCES/0001-Docs-llvm-strip-Add-help-text-to-llvm-strip-rst-doc.patch +++ /dev/null @@ -1,223 +0,0 @@ -From 8987da9a2cac6c5bd39ba100ffd1aaede94dc6a0 Mon Sep 17 00:00:00 2001 -From: Michael Pozulp -Date: Fri, 9 Aug 2019 19:10:55 +0000 -Subject: [PATCH] [Docs][llvm-strip] Add help text to llvm-strip rst doc - -Summary: Addresses https://bugs.llvm.org/show_bug.cgi?id=42383 - -Reviewers: jhenderson, alexshap, rupprecht - -Reviewed By: jhenderson - -Subscribers: wolfgangp, jakehehrlich, llvm-commits - -Tags: #llvm - -Differential Revision: https://reviews.llvm.org/D65384 - -llvm-svn: 368464 ---- - llvm/docs/CommandGuide/llvm-strip.md | 16 ---- - llvm/docs/CommandGuide/llvm-strip.rst | 167 ++++++++++++++++++++++++++++++++++ - 2 files changed, 167 insertions(+), 16 deletions(-) - delete mode 100644 llvm/docs/CommandGuide/llvm-strip.md - create mode 100644 llvm/docs/CommandGuide/llvm-strip.rst - -diff --git a/llvm/docs/CommandGuide/llvm-strip.md b/llvm/docs/CommandGuide/llvm-strip.md -deleted file mode 100644 -index dd6e859..0000000 ---- a/llvm/docs/CommandGuide/llvm-strip.md -+++ /dev/null -@@ -1,16 +0,0 @@ --# llvm-strip - object stripping tool -- --## SYNOPSIS -- --**llvm-strip** [*options*] -- --## DESCRIPTION -- --**llvm-strip** is a tool to strip sections and symbols from object files. -- --The tool is still in active development, but in most scenarios it works as a --drop-in replacement for GNU's **strip**. -- --## SEE ALSO -- --[llvm-objcopy](llvm-objcopy.html) -diff --git a/llvm/docs/CommandGuide/llvm-strip.rst b/llvm/docs/CommandGuide/llvm-strip.rst -new file mode 100644 -index 0000000..6e02482 ---- /dev/null -+++ b/llvm/docs/CommandGuide/llvm-strip.rst -@@ -0,0 +1,167 @@ -+llvm-strip - object stripping tool -+================================== -+ -+.. program:: llvm-strip -+ -+SYNOPSIS -+-------- -+ -+:program:`llvm-strip` [*options*] *inputs...* -+ -+DESCRIPTION -+----------- -+ -+:program:`llvm-strip` is a tool to strip sections and symbols from object files. -+If no other stripping or remove options are specified, :option:`--strip-all` -+will be enabled by default. -+ -+The input files are modified in-place. If "-" is specified for the input file, -+the input is read from the program's standard input stream. -+ -+If the input is an archive, any requested operations will be applied to each -+archive member individually. -+ -+The tool is still in active development, but in most scenarios it works as a -+drop-in replacement for GNU's :program:`strip`. -+ -+GENERIC AND CROSS-PLATFORM OPTIONS -+---------------------------------- -+ -+The following options are either agnostic of the file format, or apply to -+multiple file formats. -+ -+.. option:: --disable-deterministic-archives, -U -+ -+ Use real values for UIDs, GIDs and timestamps when updating archive member -+ headers. -+ -+.. option:: --discard-all, -x -+ -+ Remove most local symbols from the output. Different file formats may limit -+ this to a subset of the local symbols. For example, file and section symbols in -+ ELF objects will not be discarded. -+ -+.. option:: --enable-deterministic-archives, -D -+ -+ Enable deterministic mode when stripping archives, i.e. use 0 for archive member -+ header UIDs, GIDs and timestamp fields. On by default. -+ -+.. option:: --help, -h -+ -+ Print a summary of command line options. -+ -+.. option:: --no-strip-all -+ -+ Disable --strip-all. -+ -+.. option:: -o -+ -+ Write output to . Multiple input files cannot be used in combination -+ with -o. -+ -+.. option:: --regex -+ -+ If specified, symbol and section names specified by other switches are treated -+ as extended POSIX regular expression patterns. -+ -+.. option:: --remove-section
, -R -+ -+ Remove the specified section from the output. Can be specified multiple times -+ to remove multiple sections simultaneously. -+ -+.. option:: --strip-all-gnu -+ -+ Remove all symbols, debug sections and relocations from the output. This option -+ is equivalent to GNU :program:`strip`'s ``--strip-all`` switch. -+ -+.. option:: --strip-all, -S -+ -+ For ELF objects, remove from the output all symbols and non-alloc sections not -+ within segments, except for .gnu.warning sections and the section name table. -+ -+ For COFF objects, remove all symbols, debug sections, and relocations from the -+ output. -+ -+.. option:: --strip-debug, -g -+ -+ Remove all debug sections. -+ -+.. option:: --strip-sections -+ -+ Remove all section headers and all sections not in segments. -+ -+.. option:: --strip-symbol , -N -+ -+ Remove all symbols named ```` from the output. Can be specified -+ multiple times to remove multiple symbols. -+ -+.. option:: --strip-unneeded -+ -+ Remove all local or undefined symbols that are not required by relocations. -+ -+.. option:: --version, -V -+ -+ Display the version of this program. -+ -+COFF-SPECIFIC OPTIONS -+--------------------- -+ -+The following options are implemented only for COFF objects. If used with other -+objects, :program:`llvm-strip` will either emit an error or silently ignore -+them. -+ -+.. option:: --only-keep-debug -+ -+ Remove the contents of non-debug sections from the output, but keep the section -+ headers. -+ -+ELF-SPECIFIC OPTIONS -+-------------------- -+ -+The following options are implemented only for ELF objects. If used with other -+objects, :program:`llvm-strip` will either emit an error or silently ignore -+them. -+ -+.. option:: --allow-broken-links -+ -+ Allow llvm-strip to remove sections even if it would leave invalid section -+ references. Any invalid sh_link fields will be set to zero. -+ -+.. option:: --discard-locals, -X -+ -+ Remove local symbols starting with ".L" from the output. -+ -+.. option:: --keep-file-symbols -+ -+ Keep symbols of type `STT_FILE`, even if they would otherwise be stripped. -+ -+ .. option:: --keep-section
-+ -+ When removing sections from the output, do not remove sections named -+ ``
``. Can be specified multiple times to keep multiple sections. -+ -+.. option:: --keep-symbol , -K -+ -+ Do not remove symbols named ````. Can be specified multiple times to -+ keep multiple symbols. -+ -+.. option:: --preserve-dates, -p -+ -+ Preserve access and modification timestamps. -+ -+ -+EXIT STATUS -+----------- -+ -+:program:`llvm-strip` exits with a non-zero exit code if there is an error. -+Otherwise, it exits with code 0. -+ -+BUGS -+---- -+ -+To report bugs, please visit . -+ -+SEE ALSO -+-------- -+ -+:manpage:`llvm-objcopy(1)` --- -1.8.3.1 - diff --git a/SOURCES/0001-Filter-out-cxxflags-not-supported-by-clang.patch b/SOURCES/0001-Filter-out-cxxflags-not-supported-by-clang.patch deleted file mode 100644 index 1351d2f..0000000 --- a/SOURCES/0001-Filter-out-cxxflags-not-supported-by-clang.patch +++ /dev/null @@ -1,28 +0,0 @@ -From d15c835028bcc72a8695d047f0acaa530aa54716 Mon Sep 17 00:00:00 2001 -From: Tom Stellard -Date: Wed, 31 Jul 2019 20:43:42 -0700 -Subject: [PATCH] Filter out cxxflags not supported by clang - ---- - llvm/tools/llvm-config/CMakeLists.txt | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/llvm/tools/llvm-config/CMakeLists.txt b/llvm/tools/llvm-config/CMakeLists.txt -index 8e97a10..9b9b7d1 100644 ---- a/llvm/tools/llvm-config/CMakeLists.txt -+++ b/llvm/tools/llvm-config/CMakeLists.txt -@@ -43,7 +43,11 @@ set(LLVM_SRC_ROOT ${LLVM_MAIN_SRC_DIR}) - set(LLVM_OBJ_ROOT ${LLVM_BINARY_DIR}) - set(LLVM_CPPFLAGS "${LLVM_DEFINITIONS}") - set(LLVM_CFLAGS "${LLVM_C_STD_FLAG} ${LLVM_DEFINITIONS}") -+STRING(REGEX REPLACE "-mcet" "" LLVM_CFLAGS ${LLVM_CFLAGS}) -+STRING(REGEX REPLACE "-fcf-protection" "" LLVM_CFLAGS ${LLVM_CFLAGS}) - set(LLVM_CXXFLAGS "${LLVM_CXX_STD_FLAG} ${LLVM_CXX_STDLIB_FLAG} ${COMPILE_FLAGS} ${LLVM_DEFINITIONS}") -+STRING(REGEX REPLACE "-mcet" "" LLVM_CXXFLAGS ${LLVM_CXXFLAGS}) -+STRING(REGEX REPLACE "-fcf-protection" "" LLVM_CXXFLAGS ${LLVM_CXXFLAGS}) - set(LLVM_BUILD_SYSTEM cmake) - set(LLVM_HAS_RTTI ${LLVM_CONFIG_HAS_RTTI}) - set(LLVM_DYLIB_VERSION "${LLVM_VERSION_MAJOR}${LLVM_VERSION_SUFFIX}") --- -1.8.3.1 - diff --git a/SOURCES/0001-InstCombine-Fix-big-endian-miscompile-of-bitcast-zex.patch b/SOURCES/0001-InstCombine-Fix-big-endian-miscompile-of-bitcast-zex.patch deleted file mode 100644 index fe381ac..0000000 --- a/SOURCES/0001-InstCombine-Fix-big-endian-miscompile-of-bitcast-zex.patch +++ /dev/null @@ -1,192 +0,0 @@ -From f8e146f3430de3a6cd904f3f3f7aa1bfaefee14c Mon Sep 17 00:00:00 2001 -From: Bjorn Pettersson -Date: Thu, 28 Nov 2019 23:18:28 +0100 -Subject: [PATCH] [InstCombine] Fix big-endian miscompile of (bitcast - (zext/trunc (bitcast))) - -Summary: -optimizeVectorResize is rewriting patterns like: - %1 = bitcast vector %src to integer - %2 = trunc/zext %1 - %dst = bitcast %2 to vector - -Since bitcasting between integer an vector types gives -different integer values depending on endianness, we need -to take endianness into account. As it happens the old -implementation only produced the correct result for little -endian targets. - -Fixes: https://bugs.llvm.org/show_bug.cgi?id=44178 - -Reviewers: spatel, lattner, lebedev.ri - -Reviewed By: spatel, lebedev.ri - -Subscribers: lebedev.ri, hiraditya, uabelho, llvm-commits - -Tags: #llvm - -Differential Revision: https://reviews.llvm.org/D70844 - -(cherry picked from commit a9d6b0e5444741d08ff1df7cf71d1559e7fefc1f) ---- - .../InstCombine/InstCombineCasts.cpp | 79 +++++++++++++------ - llvm/test/Transforms/InstCombine/cast.ll | 6 +- - 2 files changed, 60 insertions(+), 25 deletions(-) - -diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp -index 2c9ba203fbf3..0af3de300e77 100644 ---- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp -+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp -@@ -18,6 +18,7 @@ - #include "llvm/IR/DIBuilder.h" - #include "llvm/IR/PatternMatch.h" - #include "llvm/Support/KnownBits.h" -+#include - using namespace llvm; - using namespace PatternMatch; - -@@ -1820,12 +1821,24 @@ Instruction *InstCombiner::visitPtrToInt(PtrToIntInst &CI) { - } - - /// This input value (which is known to have vector type) is being zero extended --/// or truncated to the specified vector type. -+/// or truncated to the specified vector type. Since the zext/trunc is done -+/// using an integer type, we have a (bitcast(cast(bitcast))) pattern, -+/// endianness will impact which end of the vector that is extended or -+/// truncated. -+/// -+/// A vector is always stored with index 0 at the lowest address, which -+/// corresponds to the most significant bits for a big endian stored integer and -+/// the least significant bits for little endian. A trunc/zext of an integer -+/// impacts the big end of the integer. Thus, we need to add/remove elements at -+/// the front of the vector for big endian targets, and the back of the vector -+/// for little endian targets. -+/// - /// Try to replace it with a shuffle (and vector/vector bitcast) if possible. - /// - /// The source and destination vector types may have different element types. --static Instruction *optimizeVectorResize(Value *InVal, VectorType *DestTy, -- InstCombiner &IC) { -+static Instruction *optimizeVectorResizeWithIntegerBitCasts(Value *InVal, -+ VectorType *DestTy, -+ InstCombiner &IC) { - // We can only do this optimization if the output is a multiple of the input - // element size, or the input is a multiple of the output element size. - // Convert the input type to have the same element type as the output. -@@ -1844,31 +1857,53 @@ static Instruction *optimizeVectorResize(Value *InVal, VectorType *DestTy, - InVal = IC.Builder.CreateBitCast(InVal, SrcTy); - } - -+ bool IsBigEndian = IC.getDataLayout().isBigEndian(); -+ unsigned SrcElts = SrcTy->getNumElements(); -+ unsigned DestElts = DestTy->getNumElements(); -+ -+ assert(SrcElts != DestElts && "Element counts should be different."); -+ - // Now that the element types match, get the shuffle mask and RHS of the - // shuffle to use, which depends on whether we're increasing or decreasing the - // size of the input. -- SmallVector ShuffleMask; -+ SmallVector ShuffleMaskStorage; -+ ArrayRef ShuffleMask; - Value *V2; - -- if (SrcTy->getNumElements() > DestTy->getNumElements()) { -- // If we're shrinking the number of elements, just shuffle in the low -- // elements from the input and use undef as the second shuffle input. -- V2 = UndefValue::get(SrcTy); -- for (unsigned i = 0, e = DestTy->getNumElements(); i != e; ++i) -- ShuffleMask.push_back(i); -+ // Produce an identify shuffle mask for the src vector. -+ ShuffleMaskStorage.resize(SrcElts); -+ std::iota(ShuffleMaskStorage.begin(), ShuffleMaskStorage.end(), 0); - -+ if (SrcElts > DestElts) { -+ // If we're shrinking the number of elements (rewriting an integer -+ // truncate), just shuffle in the elements corresponding to the least -+ // significant bits from the input and use undef as the second shuffle -+ // input. -+ V2 = UndefValue::get(SrcTy); -+ // Make sure the shuffle mask selects the "least significant bits" by -+ // keeping elements from back of the src vector for big endian, and from the -+ // front for little endian. -+ ShuffleMask = ShuffleMaskStorage; -+ if (IsBigEndian) -+ ShuffleMask = ShuffleMask.take_back(DestElts); -+ else -+ ShuffleMask = ShuffleMask.take_front(DestElts); - } else { -- // If we're increasing the number of elements, shuffle in all of the -- // elements from InVal and fill the rest of the result elements with zeros -- // from a constant zero. -+ // If we're increasing the number of elements (rewriting an integer zext), -+ // shuffle in all of the elements from InVal. Fill the rest of the result -+ // elements with zeros from a constant zero. - V2 = Constant::getNullValue(SrcTy); -- unsigned SrcElts = SrcTy->getNumElements(); -- for (unsigned i = 0, e = SrcElts; i != e; ++i) -- ShuffleMask.push_back(i); -- -- // The excess elements reference the first element of the zero input. -- for (unsigned i = 0, e = DestTy->getNumElements()-SrcElts; i != e; ++i) -- ShuffleMask.push_back(SrcElts); -+ // Use first elt from V2 when indicating zero in the shuffle mask. -+ uint32_t NullElt = SrcElts; -+ // Extend with null values in the "most significant bits" by adding elements -+ // in front of the src vector for big endian, and at the back for little -+ // endian. -+ unsigned DeltaElts = DestElts - SrcElts; -+ if (IsBigEndian) -+ ShuffleMaskStorage.insert(ShuffleMaskStorage.begin(), DeltaElts, NullElt); -+ else -+ ShuffleMaskStorage.append(DeltaElts, NullElt); -+ ShuffleMask = ShuffleMaskStorage; - } - - return new ShuffleVectorInst(InVal, V2, -@@ -2359,8 +2394,8 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &CI) { - CastInst *SrcCast = cast(Src); - if (BitCastInst *BCIn = dyn_cast(SrcCast->getOperand(0))) - if (isa(BCIn->getOperand(0)->getType())) -- if (Instruction *I = optimizeVectorResize(BCIn->getOperand(0), -- cast(DestTy), *this)) -+ if (Instruction *I = optimizeVectorResizeWithIntegerBitCasts( -+ BCIn->getOperand(0), cast(DestTy), *this)) - return I; - } - -diff --git a/llvm/test/Transforms/InstCombine/cast.ll b/llvm/test/Transforms/InstCombine/cast.ll -index b6d1eda0601d..3ce8de033422 100644 ---- a/llvm/test/Transforms/InstCombine/cast.ll -+++ b/llvm/test/Transforms/InstCombine/cast.ll -@@ -824,7 +824,7 @@ define i64 @test59(i8 %A, i8 %B) { - - define <3 x i32> @test60(<4 x i32> %call4) { - ; CHECK-LABEL: @test60( --; CHECK-NEXT: [[P10:%.*]] = shufflevector <4 x i32> [[CALL4:%.*]], <4 x i32> undef, <3 x i32> -+; CHECK-NEXT: [[P10:%.*]] = shufflevector <4 x i32> [[CALL4:%.*]], <4 x i32> undef, <3 x i32> - ; CHECK-NEXT: ret <3 x i32> [[P10]] - ; - %p11 = bitcast <4 x i32> %call4 to i128 -@@ -836,7 +836,7 @@ define <3 x i32> @test60(<4 x i32> %call4) { - - define <4 x i32> @test61(<3 x i32> %call4) { - ; CHECK-LABEL: @test61( --; CHECK-NEXT: [[P10:%.*]] = shufflevector <3 x i32> [[CALL4:%.*]], <3 x i32> , <4 x i32> -+; CHECK-NEXT: [[P10:%.*]] = shufflevector <3 x i32> [[CALL4:%.*]], <3 x i32> , <4 x i32> - ; CHECK-NEXT: ret <4 x i32> [[P10]] - ; - %p11 = bitcast <3 x i32> %call4 to i96 -@@ -848,7 +848,7 @@ define <4 x i32> @test61(<3 x i32> %call4) { - define <4 x i32> @test62(<3 x float> %call4) { - ; CHECK-LABEL: @test62( - ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <3 x float> [[CALL4:%.*]] to <3 x i32> --; CHECK-NEXT: [[P10:%.*]] = shufflevector <3 x i32> [[TMP1]], <3 x i32> , <4 x i32> -+; CHECK-NEXT: [[P10:%.*]] = shufflevector <3 x i32> [[TMP1]], <3 x i32> , <4 x i32> - ; CHECK-NEXT: ret <4 x i32> [[P10]] - ; - %p11 = bitcast <3 x float> %call4 to i96 --- -2.26.2 - diff --git a/SOURCES/0001-Pass-target-to-gold-linker-to-avoid-faliures-on-i686.patch b/SOURCES/0001-Pass-target-to-gold-linker-to-avoid-faliures-on-i686.patch deleted file mode 100644 index e8dd323..0000000 --- a/SOURCES/0001-Pass-target-to-gold-linker-to-avoid-faliures-on-i686.patch +++ /dev/null @@ -1,34 +0,0 @@ -From f0762684457a883b6813b48c98a1e94e377bc06b Mon Sep 17 00:00:00 2001 -From: Tom Stellard -Date: Wed, 28 Aug 2019 19:31:21 -0700 -Subject: [PATCH] Pass target to gold linker to avoid faliures on i686 - ---- - llvm/test/tools/gold/X86/linkonce_odr_unnamed_addr.ll | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/llvm/test/tools/gold/X86/linkonce_odr_unnamed_addr.ll b/llvm/test/tools/gold/X86/linkonce_odr_unnamed_addr.ll -index 525bf2d..01291bd 100644 ---- a/llvm/test/tools/gold/X86/linkonce_odr_unnamed_addr.ll -+++ b/llvm/test/tools/gold/X86/linkonce_odr_unnamed_addr.ll -@@ -3,7 +3,7 @@ - - ; RUN: opt -module-summary %s -o %t.o - ; RUN: opt -module-summary %p/Inputs/linkonce_odr_unnamed_addr.ll -o %t2.o --; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext \ -+; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext \ - ; RUN: --plugin-opt=save-temps \ - ; RUN: %t.o %t2.o -o %t3.o - ; RUN: llvm-dis %t.o.1.promote.bc -o - | FileCheck %s -@@ -11,7 +11,7 @@ - ; Now test when one module is a native object. In that case we must be - ; conservative and not auto hide. - ; RUN: llc %p/Inputs/linkonce_odr_unnamed_addr.ll -o %t2native.o -filetype=obj --; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext \ -+; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext \ - ; RUN: --plugin-opt=save-temps \ - ; RUN: %t.o %t2native.o -o %t3.o - ; RUN: llvm-dis %t.o.1.promote.bc -o - | FileCheck %s --check-prefix=NOSUMMARY --- -1.8.3.1 - diff --git a/SOURCES/0001-PowerPC-PPCBoolRetToInt-Skip-translation-if-there-is.patch b/SOURCES/0001-PowerPC-PPCBoolRetToInt-Skip-translation-if-there-is.patch new file mode 100644 index 0000000..4489dab --- /dev/null +++ b/SOURCES/0001-PowerPC-PPCBoolRetToInt-Skip-translation-if-there-is.patch @@ -0,0 +1,86 @@ +From cf54ca458afff1f7827bfbbc939429a00496c4f7 Mon Sep 17 00:00:00 2001 +From: Tom Stellard +Date: Tue, 18 Aug 2020 10:54:49 -0700 +Subject: [PATCH] [PowerPC] PPCBoolRetToInt: Skip translation if there is + ConstantExpr + +PPCBoolRetToInt collects PHI, Argument, Call and Constant defs related to an `i1` value which later is translated to an `i32`/`i64` value. The `translate` method expects an `i1` value. However, if the `Constant` is a `ConstantExpr`, the type of the `ConstantExpr` might not be `i1`. + +Fixes https://bugs.llvm.org/show_bug.cgi?id=46923 which causes ICE +``` +llvm-project/llvm/lib/IR/Constants.cpp:1924: static llvm::Constant *llvm::ConstantExpr::getZExt(llvm::Constant *, llvm::Type *, bool): Assertion `C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&& "SrcTy must be smaller than DestTy for ZExt!"' failed. +``` + +Differential Revision: https://reviews.llvm.org/D85007 +--- + llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp | 8 ++++-- + llvm/test/CodeGen/PowerPC/pr46923.ll | 31 +++++++++++++++++++++ + 2 files changed, 37 insertions(+), 2 deletions(-) + create mode 100644 llvm/test/CodeGen/PowerPC/pr46923.ll + +diff --git a/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp b/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp +index 2259a29f838..cfe3b3ce2e9 100644 +--- a/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp ++++ b/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp +@@ -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()); + +@@ -227,8 +230,9 @@ class PPCBoolRetToInt : public FunctionPass { + // CallInst. Potentially, bitwise operations (AND, OR, XOR, NOT) and sign + // extension could also be handled in the future. + for (Value *V : Defs) +- if (!isa(V) && !isa(V) && +- !isa(V) && !isa(V)) ++ if ((!isa(V) && !isa(V) && !isa(V) && ++ !isa(V)) || ++ isa(V)) + return false; + + for (Value *V : Defs) +diff --git a/llvm/test/CodeGen/PowerPC/pr46923.ll b/llvm/test/CodeGen/PowerPC/pr46923.ll +new file mode 100644 +index 00000000000..d6f65508848 +--- /dev/null ++++ b/llvm/test/CodeGen/PowerPC/pr46923.ll +@@ -0,0 +1,31 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-unknown \ ++; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s ++ ++@bar = external constant i64, align 8 ++ ++define i1 @foo() { ++; CHECK-LABEL: foo: ++; CHECK: # %bb.0: # %entry ++; CHECK-NEXT: crxor 4*cr5+lt, 4*cr5+lt, 4*cr5+lt ++; CHECK-NEXT: li r3, 0 ++; CHECK-NEXT: li r4, 1 ++; CHECK-NEXT: isel r3, r4, r3, 4*cr5+lt ++; CHECK-NEXT: blr ++entry: ++ br label %next ++ ++next: ++ br i1 undef, label %true, label %false ++ ++true: ++ br label %end ++ ++false: ++ br label %end ++ ++end: ++ %a = phi i1 [ icmp ugt (i64 0, i64 ptrtoint (i64* @bar to i64)), %true ], ++ [ icmp ugt (i64 0, i64 2), %false ] ++ ret i1 %a ++} +-- +2.18.1 + diff --git a/SOURCES/0001-Revert-SCEV-add-no-wrap-flag-for-SCEVAddExpr.patch b/SOURCES/0001-Revert-SCEV-add-no-wrap-flag-for-SCEVAddExpr.patch deleted file mode 100644 index caf774c..0000000 --- a/SOURCES/0001-Revert-SCEV-add-no-wrap-flag-for-SCEVAddExpr.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 58e8c793d0e43150a6452e971a32d7407a8a7401 Mon Sep 17 00:00:00 2001 -From: Tim Northover -Date: Mon, 30 Sep 2019 07:46:52 +0000 -Subject: [PATCH] Revert "[SCEV] add no wrap flag for SCEVAddExpr." - -This reverts r366419 because the analysis performed is within the context of -the loop and it's only valid to add wrapping flags to "global" expressions if -they're always correct. - -llvm-svn: 373184 ---- - llvm/lib/Analysis/ScalarEvolution.cpp | 2 +- - llvm/test/Analysis/ScalarEvolution/limit-depth.ll | 2 +- - llvm/test/Analysis/ScalarEvolution/nsw.ll | 2 +- - llvm/test/Analysis/ScalarEvolution/trip-count12.ll | 2 +- - llvm/test/Analysis/ScalarEvolution/trip-count9.ll | 8 ++++---- - 5 files changed, 8 insertions(+), 8 deletions(-) - -diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp -index 354ae05bb841..c29fc5dbccfb 100644 ---- a/llvm/lib/Analysis/ScalarEvolution.cpp -+++ b/llvm/lib/Analysis/ScalarEvolution.cpp -@@ -4992,7 +4992,7 @@ const SCEV *ScalarEvolution::createSimpleAffineAddRec(PHINode *PN, - // overflow. - if (auto *BEInst = dyn_cast(BEValueV)) - if (isLoopInvariant(Accum, L) && isAddRecNeverPoison(BEInst, L)) -- (void)getAddRecExpr(getAddExpr(StartVal, Accum, Flags), Accum, L, Flags); -+ (void)getAddRecExpr(getAddExpr(StartVal, Accum), Accum, L, Flags); - - return PHISCEV; - } -diff --git a/llvm/test/Analysis/ScalarEvolution/limit-depth.ll b/llvm/test/Analysis/ScalarEvolution/limit-depth.ll -index db68a4f84c91..6fdf8c5df974 100644 ---- a/llvm/test/Analysis/ScalarEvolution/limit-depth.ll -+++ b/llvm/test/Analysis/ScalarEvolution/limit-depth.ll -@@ -46,7 +46,7 @@ define void @test_mul(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f) { - define void @test_sext(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f) { - ; CHECK-LABEL: @test_sext - ; CHECK: %se2 = sext i64 %iv2.inc to i128 --; CHECK-NEXT: --> {(1 + (sext i64 {(sext i32 (1 + %a) to i64),+,1}<%loop> to i128)),+,1}<%loop2> -+; CHECK-NEXT: --> {(1 + (sext i64 {(sext i32 (1 + %a) to i64),+,1}<%loop> to i128)),+,1}<%loop2> - entry: - br label %loop - -diff --git a/llvm/test/Analysis/ScalarEvolution/nsw.ll b/llvm/test/Analysis/ScalarEvolution/nsw.ll -index 69427368625d..ca24f9d4a04b 100644 ---- a/llvm/test/Analysis/ScalarEvolution/nsw.ll -+++ b/llvm/test/Analysis/ScalarEvolution/nsw.ll -@@ -163,7 +163,7 @@ bb5: ; preds = %bb2 - declare void @f(i32) - - ; CHECK-LABEL: nswnowrap --; CHECK: --> {(1 + %v),+,1}<%for.body>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (2 + %v) -+; CHECK: --> {(1 + %v),+,1}<%for.body>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (1 + ((1 + %v) smax %v)) - define void @nswnowrap(i32 %v, i32* %buf) { - entry: - %add = add nsw i32 %v, 1 -diff --git a/llvm/test/Analysis/ScalarEvolution/trip-count12.ll b/llvm/test/Analysis/ScalarEvolution/trip-count12.ll -index 5e7d72d5e4f3..d0086ee2e6ac 100644 ---- a/llvm/test/Analysis/ScalarEvolution/trip-count12.ll -+++ b/llvm/test/Analysis/ScalarEvolution/trip-count12.ll -@@ -1,7 +1,7 @@ - ; RUN: opt < %s -analyze -scalar-evolution | FileCheck %s - - ; CHECK: Determining loop execution counts for: @test --; CHECK: Loop %for.body: backedge-taken count is ((-2 + %len) /u 2) -+; CHECK: Loop %for.body: backedge-taken count is ((-2 + %len) /u 2) - ; CHECK: Loop %for.body: max backedge-taken count is 1073741823 - - define zeroext i16 @test(i16* nocapture %p, i32 %len) nounwind readonly { -diff --git a/llvm/test/Analysis/ScalarEvolution/trip-count9.ll b/llvm/test/Analysis/ScalarEvolution/trip-count9.ll -index c0a1d12fa00e..9a080b34743f 100644 ---- a/llvm/test/Analysis/ScalarEvolution/trip-count9.ll -+++ b/llvm/test/Analysis/ScalarEvolution/trip-count9.ll -@@ -179,7 +179,7 @@ exit: - } - - ; CHECK: Determining loop execution counts for: @nsw_startx --; CHECK: Loop %loop: backedge-taken count is (-1 + (-1 * %x) + ((1 + %x) smax %n)) -+; CHECK: Loop %loop: backedge-taken count is (-1 + (-1 * %x) + ((1 + %x) smax %n)) - ; CHECK: Loop %loop: max backedge-taken count is -1 - define void @nsw_startx(i4 %n, i4 %x) { - entry: -@@ -195,7 +195,7 @@ exit: - } - - ; CHECK: Determining loop execution counts for: @nsw_startx_step2 --; CHECK: Loop %loop: backedge-taken count is ((-1 + (-1 * %x) + ((2 + %x) smax %n)) /u 2) -+; CHECK: Loop %loop: backedge-taken count is ((-1 + (-1 * %x) + ((2 + %x) smax %n)) /u 2) - ; CHECK: Loop %loop: max backedge-taken count is 7 - define void @nsw_startx_step2(i4 %n, i4 %x) { - entry: -@@ -381,7 +381,7 @@ exit: - } - - ; CHECK: Determining loop execution counts for: @even_nsw_startx --; CHECK: Loop %loop: backedge-taken count is (-1 + (-1 * %x) + ((1 + %x) smax (2 * %n))) -+; CHECK: Loop %loop: backedge-taken count is (-1 + (-1 * %x) + ((1 + %x) smax (2 * %n))) - ; CHECK: Loop %loop: max backedge-taken count is -2 - define void @even_nsw_startx(i4 %n, i4 %x) { - entry: -@@ -398,7 +398,7 @@ exit: - } - - ; CHECK: Determining loop execution counts for: @even_nsw_startx_step2 --; CHECK: Loop %loop: backedge-taken count is ((-1 + (-1 * %x) + ((2 + %x) smax (2 * %n))) /u 2) -+; CHECK: Loop %loop: backedge-taken count is ((-1 + (-1 * %x) + ((2 + %x) smax (2 * %n))) /u 2) - ; CHECK: Loop %loop: max backedge-taken count is 7 - define void @even_nsw_startx_step2(i4 %n, i4 %x) { - entry: --- -2.24.1 - diff --git a/SOURCES/0001-docs-Convert-remaining-command-guide-entries-from-md.patch b/SOURCES/0001-docs-Convert-remaining-command-guide-entries-from-md.patch deleted file mode 100644 index 91b27b2..0000000 --- a/SOURCES/0001-docs-Convert-remaining-command-guide-entries-from-md.patch +++ /dev/null @@ -1,248 +0,0 @@ -From e4e77bb8bf741f52b43b90987646f1c118914848 Mon Sep 17 00:00:00 2001 -From: Jordan Rupprecht -Date: Wed, 21 Aug 2019 18:00:17 +0000 -Subject: [PATCH] [docs] Convert remaining command guide entries from md to - rst. - -Summary: -Linking between markdown and rst files is currently not supported very well, e.g. the current llvm-addr2line docs [1] link to "llvm-symbolizer" instead of "llvm-symbolizer.html". This is weirdly broken in different ways depending on which versions of sphinx and recommonmark are being used, so workaround the bug by using rst everywhere. - -[1] http://llvm.org/docs/CommandGuide/llvm-addr2line.html - -Reviewers: jhenderson - -Reviewed By: jhenderson - -Subscribers: lebedev.ri, llvm-commits - -Tags: #llvm - -Differential Revision: https://reviews.llvm.org/D66305 - -llvm-svn: 369553 ---- - llvm/docs/CommandGuide/llvm-addr2line.md | 28 ----------------------- - llvm/docs/CommandGuide/llvm-addr2line.rst | 38 +++++++++++++++++++++++++++++++ - llvm/docs/CommandGuide/llvm-ranlib.md | 17 -------------- - llvm/docs/CommandGuide/llvm-ranlib.rst | 23 +++++++++++++++++++ - llvm/docs/CommandGuide/llvm-size.md | 10 -------- - llvm/docs/CommandGuide/llvm-size.rst | 15 ++++++++++++ - llvm/docs/CommandGuide/llvm-strings.md | 10 -------- - llvm/docs/CommandGuide/llvm-strings.rst | 15 ++++++++++++ - 8 files changed, 91 insertions(+), 65 deletions(-) - delete mode 100644 llvm/docs/CommandGuide/llvm-addr2line.md - create mode 100644 llvm/docs/CommandGuide/llvm-addr2line.rst - delete mode 100644 llvm/docs/CommandGuide/llvm-ranlib.md - create mode 100644 llvm/docs/CommandGuide/llvm-ranlib.rst - delete mode 100644 llvm/docs/CommandGuide/llvm-size.md - create mode 100644 llvm/docs/CommandGuide/llvm-size.rst - delete mode 100644 llvm/docs/CommandGuide/llvm-strings.md - create mode 100644 llvm/docs/CommandGuide/llvm-strings.rst - -diff --git a/llvm/docs/CommandGuide/llvm-addr2line.md b/llvm/docs/CommandGuide/llvm-addr2line.md -deleted file mode 100644 -index 03224c4..0000000 ---- a/llvm/docs/CommandGuide/llvm-addr2line.md -+++ /dev/null -@@ -1,28 +0,0 @@ --# llvm-addr2line - a drop-in replacement for addr2line -- --## SYNOPSIS -- --**llvm-addr2line** [*options*] -- --## DESCRIPTION -- --**llvm-addr2line** is an alias for the [llvm-symbolizer](llvm-symbolizer) tool --with different defaults. The goal is to make it a drop-in replacement for --GNU's **addr2line**. -- --Here are some of those differences: -- --* Defaults not to print function names. Use [-f](llvm-symbolizer-opt-f) -- to enable that. -- --* Defaults not to demangle function names. Use [-C](llvm-symbolizer-opt-C) -- to switch the demangling on. -- --* Defaults not to print inlined frames. Use [-i](llvm-symbolizer-opt-i) -- to show inlined frames for a source code location in an inlined function. -- --* Uses [--output-style=GNU](llvm-symbolizer-opt-output-style) by default. -- --## SEE ALSO -- --Refer to [llvm-symbolizer](llvm-symbolizer) for additional information. -diff --git a/llvm/docs/CommandGuide/llvm-addr2line.rst b/llvm/docs/CommandGuide/llvm-addr2line.rst -new file mode 100644 -index 0000000..08f1b69 ---- /dev/null -+++ b/llvm/docs/CommandGuide/llvm-addr2line.rst -@@ -0,0 +1,38 @@ -+llvm-addr2line - a drop-in replacement for addr2line -+==================================================== -+ -+.. program:: llvm-addr2line -+ -+SYNOPSIS -+-------- -+ -+:program:`llvm-addr2line` [*options*] -+ -+DESCRIPTION -+----------- -+ -+:program:`llvm-addr2line` is an alias for the :manpage:`llvm-symbolizer(1)` -+tool with different defaults. The goal is to make it a drop-in replacement for -+GNU's :program:`addr2line`. -+ -+Here are some of those differences: -+ -+- Defaults not to print function names. Use `-f`_ to enable that. -+ -+- Defaults not to demangle function names. Use `-C`_ to switch the -+ demangling on. -+ -+- Defaults not to print inlined frames. Use `-i`_ to show inlined -+ frames for a source code location in an inlined function. -+ -+- Uses `--output-style=GNU`_ by default. -+ -+SEE ALSO -+-------- -+ -+:manpage:`llvm-symbolizer(1)` -+ -+.. _-f: llvm-symbolizer.html#llvm-symbolizer-opt-f -+.. _-C: llvm-symbolizer.html#llvm-symbolizer-opt-c -+.. _-i: llvm-symbolizer.html#llvm-symbolizer-opt-i -+.. _--output-style=GNU: llvm-symbolizer.html#llvm-symbolizer-opt-output-style -diff --git a/llvm/docs/CommandGuide/llvm-ranlib.md b/llvm/docs/CommandGuide/llvm-ranlib.md -deleted file mode 100644 -index 4377364..0000000 ---- a/llvm/docs/CommandGuide/llvm-ranlib.md -+++ /dev/null -@@ -1,17 +0,0 @@ --# llvm-ranlib - generates an archive index -- --## SYNOPSIS -- --**llvm-ranlib** [*options*] -- --## DESCRIPTION -- --**llvm-ranlib** is an alias for the [llvm-ar](llvm-ar.html) tool that generates --an index for an archive. It can be used as a replacement for GNU's **ranlib** --tool. -- --Running **llvm-ranlib** is equivalent to running **llvm-ar s**. -- --## SEE ALSO -- --Refer to [llvm-ar](llvm-ar.html) for additional information. -diff --git a/llvm/docs/CommandGuide/llvm-ranlib.rst b/llvm/docs/CommandGuide/llvm-ranlib.rst -new file mode 100644 -index 0000000..314a330 ---- /dev/null -+++ b/llvm/docs/CommandGuide/llvm-ranlib.rst -@@ -0,0 +1,23 @@ -+llvm-ranlib - generates an archive index -+======================================== -+ -+.. program:: llvm-ranlib -+ -+SYNOPSIS -+-------- -+ -+:program:`llvm-ranlib` [*options*] -+ -+DESCRIPTION -+----------- -+ -+:program:`llvm-ranlib` is an alias for the :doc:`llvm-ar ` tool that -+generates an index for an archive. It can be used as a replacement for GNU’s -+:program:`ranlib` tool. -+ -+Running :program:`llvm-ranlib` is equivalent to running ``llvm-ar s``. -+ -+SEE ALSO -+-------- -+ -+:manpage:`llvm-ar(1)` -diff --git a/llvm/docs/CommandGuide/llvm-size.md b/llvm/docs/CommandGuide/llvm-size.md -deleted file mode 100644 -index 3952708..0000000 ---- a/llvm/docs/CommandGuide/llvm-size.md -+++ /dev/null -@@ -1,10 +0,0 @@ --# llvm-size - print segment sizes -- --## SYNOPSIS -- --**llvm-size** [*options*] -- --## DESCRIPTION -- --**llvm-size** is a tool that prints segment sizes in object files. The goal is --to make it a drop-in replacement for GNU's **size**. -diff --git a/llvm/docs/CommandGuide/llvm-size.rst b/llvm/docs/CommandGuide/llvm-size.rst -new file mode 100644 -index 0000000..0dce15c ---- /dev/null -+++ b/llvm/docs/CommandGuide/llvm-size.rst -@@ -0,0 +1,15 @@ -+llvm-size - print size information -+================================== -+ -+.. program:: llvm-size -+ -+SYNOPSIS -+-------- -+ -+:program:`llvm-size` [*options*] -+ -+DESCRIPTION -+----------- -+ -+:program:`llvm-size` is a tool that prints size information for object files. -+The goal is to make it a drop-in replacement for GNU’s :program:`size`. -diff --git a/llvm/docs/CommandGuide/llvm-strings.md b/llvm/docs/CommandGuide/llvm-strings.md -deleted file mode 100644 -index b5871c4..0000000 ---- a/llvm/docs/CommandGuide/llvm-strings.md -+++ /dev/null -@@ -1,10 +0,0 @@ --# llvm-strings - print strings -- --## SYNOPSIS -- --**llvm-strings** [*options*] -- --## DESCRIPTION -- --**llvm-strings** is a tool that prints strings in object files. The goal is to --make it a drop-in replacement for GNU's **size**. -diff --git a/llvm/docs/CommandGuide/llvm-strings.rst b/llvm/docs/CommandGuide/llvm-strings.rst -new file mode 100644 -index 0000000..d8ab9cb ---- /dev/null -+++ b/llvm/docs/CommandGuide/llvm-strings.rst -@@ -0,0 +1,15 @@ -+llvm-strings - print strings -+============================ -+ -+.. program:: llvm-strings -+ -+SYNOPSIS -+-------- -+ -+:program:`llvm-strings` [*options*] -+ -+DESCRIPTION -+----------- -+ -+:program:`llvm-strings` is a tool that prints strings in files. The goal is to -+make it a drop-in replacement for GNU’s :program:`strings`. --- -1.8.3.1 - diff --git a/SOURCES/bab5908df544680ada0a3cf431f55aeccfbdb321.patch b/SOURCES/bab5908df544680ada0a3cf431f55aeccfbdb321.patch new file mode 100644 index 0000000..2a93e6a --- /dev/null +++ b/SOURCES/bab5908df544680ada0a3cf431f55aeccfbdb321.patch @@ -0,0 +1,23 @@ +From bab5908df544680ada0a3cf431f55aeccfbdb321 Mon Sep 17 00:00:00 2001 +From: serge-sans-paille +Date: Mon, 13 Apr 2020 13:44:15 +0200 +Subject: [PATCH] Normalize working directory when running llvm-mc in test + +Otherwise, depending on the lit location used to run the test, llvm-mc adds an +include_directories entry in the dwarf output, which breaks tests in some setup. + +Differential Revision: https://reviews.llvm.org/D77876 +--- + llvm/test/MC/MachO/gen-dwarf.s | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/llvm/test/MC/MachO/gen-dwarf.s b/llvm/test/MC/MachO/gen-dwarf.s +index 0813856d625f..6d39d278e818 100644 +--- a/llvm/test/MC/MachO/gen-dwarf.s ++++ b/llvm/test/MC/MachO/gen-dwarf.s +@@ -1,4 +1,4 @@ +-// RUN: llvm-mc -g -triple i386-apple-darwin10 %s -filetype=obj -o %t ++// RUN: mkdir -p %t0 && cd %t0 && llvm-mc -g -triple i386-apple-darwin10 %s -filetype=obj -o %t + // RUN: llvm-dwarfdump -all %t | FileCheck %s + + .globl _bar diff --git a/SOURCES/hans-gpg-key.asc b/SOURCES/hans-gpg-key.asc new file mode 100644 index 0000000..2cf5255 --- /dev/null +++ b/SOURCES/hans-gpg-key.asc @@ -0,0 +1,7 @@ + +404 Not Found + +

404 Not Found

+
nginx/1.4.6 (Ubuntu)
+ + diff --git a/SOURCES/llvm-10.0.1.src.tar.xz.sig b/SOURCES/llvm-10.0.1.src.tar.xz.sig new file mode 100644 index 0000000..d12fe88 Binary files /dev/null and b/SOURCES/llvm-10.0.1.src.tar.xz.sig differ diff --git a/SOURCES/run-lit-tests b/SOURCES/run-lit-tests index aed8165..11fc0f4 100755 --- a/SOURCES/run-lit-tests +++ b/SOURCES/run-lit-tests @@ -49,16 +49,10 @@ esac cd $(mktemp -d) ln -s /usr/include include tar -xzf /usr/share/llvm/src/test.tar.gz -ln -s $ARCH.site.cfg.py test/lit.site.cfg.py -ln -s $ARCH.site.cfg.py test/Unit/lit.site.cfg.py - -# llvm_obj_root is used to determine the directory the tests will run in. -# test/MC/MachO/gen-dwarf.s fails if llvm_obj_root is a parent directory -# of the source file. To workaround this, we set llvm_obj_root to a -# different directory than the one used to store the test sources. -# This also matches better how tests are run from the llvm source tree. +ln -s /usr/share/llvm/src/$ARCH.site.cfg.py test/lit.site.cfg.py +ln -s /usr/share/llvm/src/$ARCH.Unit.site.cfg.py test/Unit/lit.site.cfg.py lit -v -s $threads_arg test \ - -Dllvm_obj_root=$(mktemp -d) \ + -Dllvm_obj_root=`pwd` \ -Dllvm_test_root=`pwd`/test \ -Dllvm_unittest_bindir=$LIB_DIR/llvm \ -Dllvm_shlib_dir=$LIB_DIR diff --git a/SPECS/llvm.spec b/SPECS/llvm.spec index be23b16..c5843c0 100644 --- a/SPECS/llvm.spec +++ b/SPECS/llvm.spec @@ -10,12 +10,12 @@ %global llvm_libdir %{_libdir}/%{name} %global build_llvm_libdir %{buildroot}%{llvm_libdir} -%global maj_ver 9 +#%%global rc_ver 6 +%global baserelease 3 +%global llvm_srcdir llvm-%{version}%{?rc_ver:rc%{rc_ver}}.src +%global maj_ver 10 %global min_ver 0 %global patch_ver 1 -#%%global rc_ver 3 -%global baserelease 5 - %if %{with compat_build} %global pkg_name llvm%{maj_ver}.%{min_ver} @@ -50,34 +50,36 @@ Summary: The Low Level Virtual Machine License: NCSA URL: http://llvm.org -Source0: http://%{?rc_ver:pre}releases.llvm.org/%{version}/%{?rc_ver:rc%{rc_ver}}/llvm-%{version}%{?rc_ver:rc%{rc_ver}}.src.tar.xz +%if 0%{?rc_ver:1} +Source0: https://prereleases.llvm.org/%{version}/rc%{rc_ver}/%{llvm_srcdir}.tar.xz +Source3: https://prereleases.llvm.org/%{version}/rc%{rc_ver}/%{llvm_srcdir}.tar.xz.sig +%else +Source0: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{version}/%{llvm_srcdir}.tar.xz +Source3: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{version}/%{llvm_srcdir}.tar.xz.sig +%endif %if %{without compat_build} Source1: run-lit-tests Source2: lit.fedora.cfg.py %endif +Source4: https://prereleases.llvm.org/%{version}/hans-gpg-key.asc -Patch0: 0001-Filter-out-cxxflags-not-supported-by-clang.patch -# TODO: I'm not sure why this is needed. Could be a change in newer version -# of gold. -Patch1: 0001-Pass-target-to-gold-linker-to-avoid-faliures-on-i686.patch +##Patch0: 0001-Filter-out-cxxflags-not-supported-by-clang.patch Patch2: 0001-CMake-Split-static-library-exports-into-their-own-ex.patch Patch3: 0001-CMake-Split-test-binary-exports-into-their-own-expor.patch +Patch4: bab5908df544680ada0a3cf431f55aeccfbdb321.patch +Patch5: 0001-PowerPC-PPCBoolRetToInt-Skip-translation-if-there-is.patch # RHEL-specific patches. Patch101: 0001-Deactivate-markdown-doc.patch # Patches to convert md files to rst since we don't have the md parser in RHEL. -Patch102: 0001-Docs-llvm-strip-Add-help-text-to-llvm-strip-rst-doc.patch -Patch103: 0001-docs-Convert-remaining-command-guide-entries-from-md.patch - -# Fix crash in kernel bpf self-tests -Patch5: 0001-BPF-Handling-type-conversions-correctly-for-CO-RE.patch -Patch6: 0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch - -# Fix Rust codegen bug, https://github.com/rust-lang/rust/issues/69225 -Patch7: 0001-Revert-SCEV-add-no-wrap-flag-for-SCEVAddExpr.patch - -# Fix big-endian miscompilation in rustc, rhbz#1837660 -Patch8: 0001-InstCombine-Fix-big-endian-miscompile-of-bitcast-zex.patch +#Patch102: 0001-Docs-llvm-strip-Add-help-text-to-llvm-strip-rst-doc.patch +#Patch103: 0001-docs-Convert-remaining-command-guide-entries-from-md.patch +### Fix crash in kernel bpf self-tests +##Patch5: 0001-BPF-Handling-type-conversions-correctly-for-CO-RE.patch +##Patch6: 0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch +## +### Fix Rust codegen bug, https://github.com/rust-lang/rust/issues/69225 +##Patch7: 0001-Revert-SCEV-add-no-wrap-flag-for-SCEVAddExpr.patch BuildRequires: gcc BuildRequires: gcc-c++ @@ -89,6 +91,8 @@ BuildRequires: ncurses-devel BuildRequires: python3-sphinx %if !0%{?rhel} BuildRequires: python3-recommonmark +%else +BuildRequires: pandoc %endif BuildRequires: multilib-rpm-config %if %{with gold} @@ -184,12 +188,16 @@ LLVM's modified googletest sources. %endif %prep -%autosetup -n llvm-%{version}%{?rc_ver:rc%{rc_ver}}.src -p2 +%autosetup -n %{llvm_srcdir} -p2 pathfix.py -i %{__python3} -pn \ test/BugPoint/compile-custom.ll.py \ tools/opt-viewer/*.py +# Convert markdown files to rst to cope with the absence of recommonmark in rhel. +# The sed expression takes care of a slight difference between pandoc markdown and sphinx markdown. +find -name '*.md' | while read md; do sed -r -e 's/^( )*\* /\n\1\* /' ${md} | pandoc -f markdown -o ${md%.md}.rst ; done + %build mkdir -p _build cd _build @@ -263,6 +271,7 @@ cd _build -DLLVM_INSTALL_TOOLCHAIN_ONLY:BOOL=OFF \ \ -DSPHINX_WARNINGS_AS_ERRORS=OFF \ + -DCMAKE_INSTALL_PREFIX=%{install_prefix} \ -DLLVM_INSTALL_SPHINX_HTML_DIR=%{_pkgdocdir}/html \ -DSPHINX_EXECUTABLE=%{_bindir}/sphinx-build-3 @@ -280,6 +289,9 @@ cd _build mkdir -p %{buildroot}/%{_bindir} mv %{buildroot}/%{_bindir}/llvm-config %{buildroot}/%{_bindir}/llvm-config-%{__isa_bits} +# ghost presence +touch %{buildroot}%{_bindir}/llvm-config + # Fix some man pages ln -s llvm-config.1 %{buildroot}%{_mandir}/man1/llvm-config-%{__isa_bits}.1 mv %{buildroot}%{_mandir}/man1/tblgen.1 %{buildroot}%{_mandir}/man1/llvm-tblgen.1 @@ -292,6 +304,8 @@ do install -m 0755 ./_build/bin/$f %{buildroot}%{_bindir} done +# Remove testing of update utility tools +rm -rf test/tools/UpdateTestChecks %multilib_fix_c_header --file %{_includedir}/llvm/Config/llvm-config.h @@ -333,7 +347,12 @@ install -m 0755 %{SOURCE1} %{buildroot}%{_libexecdir}/tests/llvm # Install lit tests. We need to put these in a tarball otherwise rpm will complain # about some of the test inputs having the wrong object file format. install -d %{buildroot}%{_datadir}/llvm/ -tar -czf %{install_srcdir}/test.tar.gz test/ + +# The various tar options are there to make sur the archive is the same on 32 and 64 bit arch, i.e. +# the archive creation is reproducible. Move arch-specific content out of the tarball +mv %{lit_cfg} %{install_srcdir}/%{_arch}.site.cfg.py +mv %{lit_unit_cfg} %{install_srcdir}/%{_arch}.Unit.site.cfg.py +tar --sort=name --mtime='UTC 2020-01-01' -c test/ | gzip -n > %{install_srcdir}/test.tar.gz # Install the unit test binaries mkdir -p %{build_llvm_libdir} @@ -355,7 +374,7 @@ cp -R unittests/DebugInfo/PDB/Inputs %{buildroot}%{_datadir}/llvm/src/unittests/ mkdir -p %{buildroot}/%{_bindir} for f in %{buildroot}/%{install_bindir}/*; do filename=`basename $f` - ln -s %{install_bindir}/$filename %{buildroot}/%{_bindir}/$filename%{exec_suffix} + ln -s ../../../%{install_bindir}/$filename %{buildroot}/%{_bindir}/$filename%{exec_suffix} done # Move header files @@ -375,7 +394,7 @@ EOF # Add version suffix to man pages and move them to mandir. mkdir -p %{buildroot}/%{_mandir}/man1 -for f in `ls %{build_install_prefix}/share/man/man1/*`; do +for f in %{build_install_prefix}/share/man/man1/*; do filename=`basename $f | cut -f 1 -d '.'` mv $f %{buildroot}%{_mandir}/man1/$filename%{exec_suffix}.1 done @@ -404,7 +423,7 @@ ninja check-all -C _build || \ %postun devel if [ $1 -eq 0 ]; then - %{_sbindir}/update-alternatives --remove llvm-config %{_bindir}/llvm-config + %{_sbindir}/update-alternatives --remove llvm-config %{_bindir}/llvm-config-%{__isa_bits} fi %endif @@ -415,6 +434,7 @@ fi %{_bindir}/* %if %{without compat_build} +%exclude %{_bindir}/llvm-config %exclude %{_bindir}/llvm-config-%{__isa_bits} %exclude %{_bindir}/not %exclude %{_bindir}/count @@ -449,6 +469,7 @@ fi %files devel %if %{without compat_build} +%ghost %{_bindir}/llvm-config %{_bindir}/llvm-config-%{__isa_bits} %{_mandir}/man1/llvm-config* %{_includedir}/llvm @@ -489,6 +510,8 @@ fi %{llvm_libdir}/unittests/ %{_datadir}/llvm/src/unittests %{_datadir}/llvm/src/test.tar.gz +%{_datadir}/llvm/src/%{_arch}.site.cfg.py +%{_datadir}/llvm/src/%{_arch}.Unit.site.cfg.py %{_datadir}/llvm/lit.fedora.cfg.py %{_bindir}/not %{_bindir}/count @@ -507,8 +530,20 @@ fi %endif %changelog -* Tue May 26 2020 Josh Stone - 9.0.1-5 -- Fix big-endian miscompilation in rustc, rhbz#1840304 +* Wed Aug 19 2020 Tom Stellard - 10.0.1-3 +- Fix rust crash on ppc64le compiling firefox + +* Fri Jul 31 2020 sguelton@redhat.com - 10.0.1-2 +- Fix llvm-config alternative handling, see rhbz#1859996 + +* Fri Jul 24 2020 sguelton@redhat.com - 10.0.1-1 +- 10.0.1 Release + +* Wed Jun 24 2020 sguelton@redhat.com - 10.0.0-2 +- Reproducible build of test.tar.gz, see rhbz#1820319 + +* Tue Apr 7 2020 sguelton@redhat.com - 10.0.0-1 +- 10.0.0 Release * Thu Feb 27 2020 Josh Stone - 9.0.1-4 - Fix a codegen bug for Rust