The package rpms/llvm9.0.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/llvm9.0.git/commit/?id=12437586df....
Change:
+%ifarch %{arm}
Thanks.
Full change:
============
commit 12437586df95e93633b3d3037def8f53367748f3
Author: serge-sans-paille <sguelton(a)redhat.com>
Date: Thu Feb 6 05:50:01 2020 +0000
Initial push
diff --git a/0001-AVR-Fix-endianness-handling-in-AVR-MC.patch
b/0001-AVR-Fix-endianness-handling-in-AVR-MC.patch
new file mode 100644
index 0000000..aba1d2a
--- /dev/null
+++ b/0001-AVR-Fix-endianness-handling-in-AVR-MC.patch
@@ -0,0 +1,42 @@
+From 29b4d8f19e30910c099c5453da258843d6b7869a Mon Sep 17 00:00:00 2001
+From: serge_sans_paille <sguelton(a)redhat.com>
+Date: Tue, 24 Sep 2019 10:20:08 +0200
+Subject: [PATCH] [AVR] Fix endianness handling in AVR MC
+
+Differential Revision:
https://reviews.llvm.org/D67926
+---
+ llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.cpp | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.cpp
b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.cpp
+index bc048877868..db995e24756 100644
+--- a/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.cpp
++++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.cpp
+@@ -25,6 +25,7 @@
+ #include "llvm/MC/MCRegisterInfo.h"
+ #include "llvm/MC/MCSubtargetInfo.h"
+ #include "llvm/Support/Casting.h"
++#include "llvm/Support/EndianStream.h"
+ #include "llvm/Support/raw_ostream.h"
+
+ #define DEBUG_TYPE "mccodeemitter"
+@@ -268,14 +269,11 @@ unsigned AVRMCCodeEmitter::getMachineOpValue(const MCInst &MI,
+ void AVRMCCodeEmitter::emitInstruction(uint64_t Val, unsigned Size,
+ const MCSubtargetInfo &STI,
+ raw_ostream &OS) const {
+- const uint16_t *Words = reinterpret_cast<uint16_t const *>(&Val);
+ size_t WordCount = Size / 2;
+
+ for (int64_t i = WordCount - 1; i >= 0; --i) {
+- uint16_t Word = Words[i];
+-
+- OS << (uint8_t) ((Word & 0x00ff) >> 0);
+- OS << (uint8_t) ((Word & 0xff00) >> 8);
++ uint16_t Word = (Val >> (i * 16)) & 0xFFFF;
++ support::endian::write(OS, Word, support::endianness::little);
+ }
+ }
+
+--
+2.20.1
+
diff --git a/0001-BPF-Handling-type-conversions-correctly-for-CO-RE.patch
b/0001-BPF-Handling-type-conversions-correctly-for-CO-RE.patch
new file mode 100644
index 0000000..bfde9bc
--- /dev/null
+++ b/0001-BPF-Handling-type-conversions-correctly-for-CO-RE.patch
@@ -0,0 +1,2510 @@
+From 20253836fbb1baf5c7cd6fb6558bd12dff682855 Mon Sep 17 00:00:00 2001
+From: Yonghong Song <yhs(a)fb.com>
+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 <stack>
+
+ #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<CallInst *> &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<DIDerivedType>(Ty)) {
++ if (!SkipDIDerivedTag(DTy->getTag()))
++ break;
++ Ty = DTy->getBaseType();
++ }
++ return Ty;
++}
++
++static const DIType * stripQualifiers(const DIType *Ty) {
++ while (auto *DTy = dyn_cast<DIDerivedType>(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<DINode>(Elements[I]))
++ if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
++ const DISubrange *SR = cast<DISubrange>(Element);
++ auto *CI = SR->getCount().dyn_cast<ConstantInt *>();
++ 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<ConstantInt>(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<ConstantInt>(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<ConstantInt>(Call->getArgOperand(2))
++ ->getZExtValue();
+ return true;
+ }
+
+@@ -200,7 +266,9 @@ bool
BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(Module &M) {
+ for (auto &I : BB) {
+ auto *Call = dyn_cast<CallInst>(&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<DIType>(ParentType));
++ const DIType *CType = stripQualifiers(cast<DIType>(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<DIDerivedType>(CType))
++ return false;
++
++ // Parent is a pointer type.
++ if (const auto *PtrTy = dyn_cast<DIDerivedType>(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<DICompositeType>(PType);
++ const auto *CTy = dyn_cast<DICompositeType>(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<DIType>(PTy->getElements()[ParentAI]);
++
++ return dyn_cast<DICompositeType>(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<Instruction>(U);
+ if (!Inst)
+ continue;
+
+ if (auto *BI = dyn_cast<BitCastInst>(Inst)) {
+- traceBitCast(BI, Call, Kind);
++ traceBitCast(BI, Call, Kind, ParentMeta, ParentAI);
+ } else if (auto *CI = dyn_cast<CallInst>(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<GetElementPtrInst>(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<Instruction>(U);
+ if (!Inst)
+ continue;
+
+ if (auto *BI = dyn_cast<BitCastInst>(Inst)) {
+- traceBitCast(BI, Parent, Kind);
++ traceBitCast(BI, Parent, Kind, ParentMeta, ParentAI);
+ } else if (auto *CI = dyn_cast<CallInst>(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<GetElementPtrInst>(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<Instruction>(U);
+ if (!Inst)
+ continue;
+
+ if (auto *BI = dyn_cast<BitCastInst>(Inst)) {
+- traceBitCast(BI, Parent, Kind);
++ traceBitCast(BI, Parent, Kind, ParentMeta, ParentAI);
+ } else if (auto *CI = dyn_cast<CallInst>(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<GetElementPtrInst>(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<CallInst>(&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<uint64_t> AccessIndices;
+- uint64_t TypeNameIndex = 0;
+- std::string LastTypeName;
++ std::string TypeName;
++ std::stack<std::pair<CallInst *, uint32_t>> 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<DIType>(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<DIType>(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<DICompositeType>(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<DIDerivedType>(Ty);
++ assert(DTy->getTag() == dwarf::DW_TAG_pointer_type);
++
++ BaseTy = stripQualifiers(DTy->getBaseType());
++ CTy = dyn_cast<DICompositeType>(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<DICompositeType>(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<DICompositeType>(stripQualifiers(cast<DIType>(MDN)));
++ uint32_t Tag = CTy->getTag();
++ if (Tag == dwarf::DW_TAG_structure_type) {
++ auto *MemberTy = cast<DIDerivedType>(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<DIDerivedType>(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<BTFTypeArray>(ElemType, ElemTypeId, 0, 0);
+- ArrayTypes.push_back(TypeEntry.get());
++ auto TypeEntry = llvm::make_unique<BTFTypeArray>(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<DISubrange>(Element);
+ auto *CI = SR->getCount().dyn_cast<ConstantInt *>();
+ int64_t Count = CI->getSExtValue();
+- const DIType *ArrayElemTy = (I == 0) ? ElemType : nullptr;
+
+ auto TypeEntry =
+- llvm::make_unique<BTFTypeArray>(ArrayElemTy, ElemTypeId,
+- ElemSize, Count);
+- ArrayTypes.push_back(TypeEntry.get());
++ llvm::make_unique<BTFTypeArray>(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<struct BTF::BTFMember> Members;
+- std::vector<uint32_t> 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<std::vector<std::string>> FileContent;
+ std::map<std::string, std::unique_ptr<BTFKindDataSec>> DataSecEntries;
+ std::vector<BTFTypeStruct *> StructTypes;
+- std::vector<BTFTypeArray *> ArrayTypes;
+ std::map<std::string, int64_t> AccessOffsets;
+ std::map<StringRef, std::pair<bool, std::vector<BTFTypeDerived *>>>
+ 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/0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch
b/0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch
new file mode 100644
index 0000000..60ba6d9
--- /dev/null
+++ b/0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch
@@ -0,0 +1,138 @@
+From f2ccdd2700174c717dc55a0f4c3f5a91ae73ff42 Mon Sep 17 00:00:00 2001
+From: Yonghong Song <yhs(a)fb.com>
+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 <yhs(a)fb.com>
+
+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<PointerType>(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/0001-CMake-Split-static-library-exports-into-their-own-ex.patch
b/0001-CMake-Split-static-library-exports-into-their-own-ex.patch
new file mode 100644
index 0000000..e780c34
--- /dev/null
+++ b/0001-CMake-Split-static-library-exports-into-their-own-ex.patch
@@ -0,0 +1,66 @@
+From 8f6917ea11bd1bfbfe07f3577756d1c4abfdb916 Mon Sep 17 00:00:00 2001
+From: Tom Stellard <tstellar(a)redhat.com>
+Date: Fri, 6 Sep 2019 11:03:18 -0700
+Subject: [PATCH] CMake: Split static library exports into their own export
+ file
+
+---
+ llvm/cmake/modules/AddLLVM.cmake | 6 +++++-
+ llvm/cmake/modules/CMakeLists.txt | 3 +++
+ llvm/cmake/modules/LLVMConfig.cmake.in | 2 ++
+ 3 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake
+index 619e986..200fc45 100644
+--- a/llvm/cmake/modules/AddLLVM.cmake
++++ b/llvm/cmake/modules/AddLLVM.cmake
+@@ -691,7 +691,11 @@ macro(add_llvm_library name)
+ if(${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR
+ (in_llvm_libs AND "llvm-libraries" IN_LIST
LLVM_DISTRIBUTION_COMPONENTS) OR
+ NOT LLVM_DISTRIBUTION_COMPONENTS)
+- set(export_to_llvmexports EXPORT LLVMExports)
++ if (ARG_SHARED)
++ set(export_to_llvmexports EXPORT LLVMExports)
++ else()
++ set(export_to_llvmexports EXPORT LLVMStaticExports)
++ endif()
+ set_property(GLOBAL PROPERTY LLVM_HAS_EXPORTS True)
+ endif()
+
+diff --git a/llvm/cmake/modules/CMakeLists.txt b/llvm/cmake/modules/CMakeLists.txt
+index 9cf22b4..dc982d2 100644
+--- a/llvm/cmake/modules/CMakeLists.txt
++++ b/llvm/cmake/modules/CMakeLists.txt
+@@ -105,6 +105,7 @@ set(LLVM_CONFIG_BINARY_DIR "\${LLVM_INSTALL_PREFIX}")
+ set(LLVM_CONFIG_TOOLS_BINARY_DIR "\${LLVM_INSTALL_PREFIX}/bin")
+ set(LLVM_CONFIG_EXPORTS_FILE "\${LLVM_CMAKE_DIR}/LLVMExports.cmake")
+ set(LLVM_CONFIG_EXPORTS "${LLVM_EXPORTS}")
++set(LLVM_CONFIG_STATIC_EXPORTS_FILE
"\${LLVM_CMAKE_DIR}/LLVMStaticExports.cmake")
+ configure_file(
+ LLVMConfig.cmake.in
+ ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/LLVMConfig.cmake
+@@ -121,6 +122,8 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
+ if(llvm_has_exports)
+ install(EXPORT LLVMExports DESTINATION ${LLVM_INSTALL_PACKAGE_DIR}
+ COMPONENT cmake-exports)
++ install(EXPORT LLVMStaticExports DESTINATION ${LLVM_INSTALL_PACKAGE_DIR}
++ COMPONENT cmake-exports)
+ endif()
+
+ install(FILES
+diff --git a/llvm/cmake/modules/LLVMConfig.cmake.in
b/llvm/cmake/modules/LLVMConfig.cmake.in
+index 536031f..6ef54a0 100644
+--- a/llvm/cmake/modules/LLVMConfig.cmake.in
++++ b/llvm/cmake/modules/LLVMConfig.cmake.in
+@@ -89,6 +89,8 @@ if(NOT TARGET LLVMSupport)
+ set(LLVM_EXPORTED_TARGETS "@LLVM_CONFIG_EXPORTS@")
+ include("@LLVM_CONFIG_EXPORTS_FILE@")
+ @llvm_config_include_buildtree_only_exports@
++
++ include("@LLVM_CONFIG_STATIC_EXPORTS_FILE@" OPTIONAL)
+ endif()
+
+ # By creating intrinsics_gen here, subprojects that depend on LLVM's
+--
+1.8.3.1
+
diff --git a/0001-CMake-Split-test-binary-exports-into-their-own-expor.patch
b/0001-CMake-Split-test-binary-exports-into-their-own-expor.patch
new file mode 100644
index 0000000..a3801ff
--- /dev/null
+++ b/0001-CMake-Split-test-binary-exports-into-their-own-expor.patch
@@ -0,0 +1,65 @@
+From 9d496e978f59e153bb76e92229d5a524d92dee04 Mon Sep 17 00:00:00 2001
+From: Tom Stellard <tstellar(a)redhat.com>
+Date: Tue, 10 Sep 2019 13:33:48 -0700
+Subject: [PATCH] CMake: Split test binary exports into their own export file
+
+---
+ llvm/cmake/modules/AddLLVM.cmake | 7 ++++++-
+ llvm/cmake/modules/CMakeLists.txt | 3 +++
+ llvm/cmake/modules/LLVMConfig.cmake.in | 1 +
+ 3 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake
+index 200fc45..9eec7a7 100644
+--- a/llvm/cmake/modules/AddLLVM.cmake
++++ b/llvm/cmake/modules/AddLLVM.cmake
+@@ -953,7 +953,12 @@ macro(add_llvm_utility name)
+ set(export_to_llvmexports)
+ if (${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR
+ NOT LLVM_DISTRIBUTION_COMPONENTS)
+- set(export_to_llvmexports EXPORT LLVMExports)
++ if (${name} STREQUAL "not" OR ${name} STREQUAL "count" OR
++ ${name} STREQUAL "yaml-bench" OR ${name} STREQUAL
"lli-child-target")
++ set(export_to_llvmexports EXPORT LLVMTestExports)
++ else()
++ set(export_to_llvmexports EXPORT LLVMExports)
++ endif()
+ set_property(GLOBAL PROPERTY LLVM_HAS_EXPORTS True)
+ endif()
+
+diff --git a/llvm/cmake/modules/CMakeLists.txt b/llvm/cmake/modules/CMakeLists.txt
+index dc982d2..c861f45 100644
+--- a/llvm/cmake/modules/CMakeLists.txt
++++ b/llvm/cmake/modules/CMakeLists.txt
+@@ -106,6 +106,7 @@ set(LLVM_CONFIG_TOOLS_BINARY_DIR
"\${LLVM_INSTALL_PREFIX}/bin")
+ set(LLVM_CONFIG_EXPORTS_FILE "\${LLVM_CMAKE_DIR}/LLVMExports.cmake")
+ set(LLVM_CONFIG_EXPORTS "${LLVM_EXPORTS}")
+ set(LLVM_CONFIG_STATIC_EXPORTS_FILE
"\${LLVM_CMAKE_DIR}/LLVMStaticExports.cmake")
++set(LLVM_CONFIG_TEST_EXPORTS_FILE "\${LLVM_CMAKE_DIR}/LLVMTestExports.cmake")
+ configure_file(
+ LLVMConfig.cmake.in
+ ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/LLVMConfig.cmake
+@@ -124,6 +125,8 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
+ COMPONENT cmake-exports)
+ install(EXPORT LLVMStaticExports DESTINATION ${LLVM_INSTALL_PACKAGE_DIR}
+ COMPONENT cmake-exports)
++ install(EXPORT LLVMTestExports DESTINATION ${LLVM_INSTALL_PACKAGE_DIR}
++ COMPONENT cmake-exports)
+ endif()
+
+ install(FILES
+diff --git a/llvm/cmake/modules/LLVMConfig.cmake.in
b/llvm/cmake/modules/LLVMConfig.cmake.in
+index 6ef54a0..d81b09a 100644
+--- a/llvm/cmake/modules/LLVMConfig.cmake.in
++++ b/llvm/cmake/modules/LLVMConfig.cmake.in
+@@ -91,6 +91,7 @@ if(NOT TARGET LLVMSupport)
+ @llvm_config_include_buildtree_only_exports@
+
+ include("@LLVM_CONFIG_STATIC_EXPORTS_FILE@" OPTIONAL)
++ include("@LLVM_CONFIG_TEST_EXPORTS_FILE@" OPTIONAL)
+ endif()
+
+ # By creating intrinsics_gen here, subprojects that depend on LLVM's
+--
+1.8.3.1
+
diff --git a/0001-Filter-out-cxxflags-not-supported-by-clang.patch
b/0001-Filter-out-cxxflags-not-supported-by-clang.patch
new file mode 100644
index 0000000..1351d2f
--- /dev/null
+++ b/0001-Filter-out-cxxflags-not-supported-by-clang.patch
@@ -0,0 +1,28 @@
+From d15c835028bcc72a8695d047f0acaa530aa54716 Mon Sep 17 00:00:00 2001
+From: Tom Stellard <tstellar(a)redhat.com>
+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/0001-Pass-target-to-gold-linker-to-avoid-faliures-on-i686.patch
b/0001-Pass-target-to-gold-linker-to-avoid-faliures-on-i686.patch
new file mode 100644
index 0000000..e8dd323
--- /dev/null
+++ b/0001-Pass-target-to-gold-linker-to-avoid-faliures-on-i686.patch
@@ -0,0 +1,34 @@
+From f0762684457a883b6813b48c98a1e94e377bc06b Mon Sep 17 00:00:00 2001
+From: Tom Stellard <tstellar(a)redhat.com>
+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/gating.yaml b/gating.yaml
new file mode 100644
index 0000000..219cd2c
--- /dev/null
+++ b/gating.yaml
@@ -0,0 +1,12 @@
+--- !Policy
+product_versions:
+ - fedora-*
+decision_context: bodhi_update_push_testing
+rules:
+ - !PassingTestCaseRule {test_case_name:
org.centos.prod.ci.pipeline.allpackages-build.package.test.functional.complete}
+--- !Policy
+product_versions:
+ - fedora-*
+decision_context: bodhi_update_push_stable
+rules:
+ - !PassingTestCaseRule {test_case_name:
org.centos.prod.ci.pipeline.allpackages-build.package.test.functional.complete}
diff --git a/lit.fedora.cfg.py b/lit.fedora.cfg.py
new file mode 100644
index 0000000..1c918b4
--- /dev/null
+++ b/lit.fedora.cfg.py
@@ -0,0 +1,17 @@
+
+config.llvm_tools_dir = '/usr/bin'
+config.llvm_shlib_dir = '%(llvm_shlib_dir)s' % lit_config.params
+
+if hasattr(config, 'host_triple'):
+ # This means we are running lit regression tests
+
+ # Regression tests write output to this directory, so we need to be able to specify
+ # a temp directory when invoking lit. e.g. lit -Dllvm_obj_root=/tmp/lit
+ config.llvm_obj_root = "%(llvm_obj_root)s" % lit_config.params
+ lit_config.load_config(config, '%(llvm_test_root)s/lit.cfg.py' %
lit_config.params)
+else:
+ # This means we are running lit unit tests
+
+ # For unit tests, llvm_obj_root is used to find the unit test binaries.
+ config.llvm_obj_root = '%(llvm_unittest_bindir)s' % lit_config.params
+ lit_config.load_config(config, '%(llvm_test_root)s/Unit/lit.cfg.py' %
lit_config.params)
diff --git a/llvm9.0.spec b/llvm9.0.spec
new file mode 100644
index 0000000..7ec6390
--- /dev/null
+++ b/llvm9.0.spec
@@ -0,0 +1,884 @@
+# Components enabled if supported by target architecture:
+%define gold_arches %{ix86} x86_64 %{arm} aarch64 %{power64} s390x
+%ifarch %{gold_arches}
+ %bcond_without gold
+%else
+ %bcond_with gold
+%endif
+
+%bcond_without compat_build
+
+%global llvm_libdir %{_libdir}/%{name}
+%global build_llvm_libdir %{buildroot}%{llvm_libdir}
+%global maj_ver 9
+%global min_ver 0
+%global patch_ver 1
+#%%global rc_ver 3
+%global baserelease 6
+
+
+%if %{with compat_build}
+%global pkg_name llvm%{maj_ver}.%{min_ver}
+%global exec_suffix -%{maj_ver}.%{min_ver}
+%global install_prefix %{_libdir}/%{name}
+%global install_bindir %{install_prefix}/bin
+%global install_includedir %{install_prefix}/include
+%global install_libdir %{install_prefix}/lib
+
+%global pkg_bindir %{install_bindir}
+%global pkg_includedir %{_includedir}/%{name}
+%global pkg_libdir %{install_libdir}
+%else
+%global pkg_name llvm
+%global install_prefix /usr
+%global install_libdir %{_libdir}
+%global pkg_libdir %{install_libdir}
+%endif
+
+%global build_install_prefix %{buildroot}%{install_prefix}
+
+Name: %{pkg_name}
+Version: %{maj_ver}.%{min_ver}.%{patch_ver}
+Release: %{baserelease}%{?rc_ver:.rc%{rc_ver}}%{?dist}
+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 %{without compat_build}
+Source1: run-lit-tests
+Source2: lit.fedora.cfg.py
+%endif
+
+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
+Patch2: 0001-CMake-Split-static-library-exports-into-their-own-ex.patch
+%if %{without compat_build}
+Patch3: 0001-CMake-Split-test-binary-exports-into-their-own-expor.patch
+%endif
+Patch4: 0001-AVR-Fix-endianness-handling-in-AVR-MC.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
+
+BuildRequires: gcc
+BuildRequires: gcc-c++
+BuildRequires: cmake
+BuildRequires: ninja-build
+BuildRequires: zlib-devel
+BuildRequires: libffi-devel
+BuildRequires: ncurses-devel
+BuildRequires: python3-sphinx
+BuildRequires: python3-recommonmark
+BuildRequires: multilib-rpm-config
+%if %{with gold}
+BuildRequires: binutils-devel
+%endif
+%ifarch %{valgrind_arches}
+# Enable extra functionality when run the LLVM JIT under valgrind.
+BuildRequires: valgrind-devel
+%endif
+# LLVM's LineEditor library will use libedit if it is available.
+BuildRequires: libedit-devel
+# We need python3-devel for pathfix.py.
+BuildRequires: python3-devel
+
+Requires: %{name}-libs%{?_isa} = %{version}-%{release}
+
+Provides: llvm(major) = %{maj_ver}
+
+%description
+LLVM is a compiler infrastructure designed for compile-time, link-time,
+runtime, and idle-time optimization of programs from arbitrary programming
+languages. The compiler infrastructure includes mirror sets of programming
+tools as well as libraries with equivalent functionality.
+
+%package devel
+Summary: Libraries and header files for LLVM
+Requires: %{name}%{?_isa} = %{version}-%{release}
+Requires: %{name}-libs%{?_isa} = %{version}-%{release}
+# The installed LLVM cmake files will add -ledit to the linker flags for any
+# app that requires the libLLVMLineEditor, so we need to make sure
+# libedit-devel is available.
+Requires: libedit-devel
+Requires(post): %{_sbindir}/alternatives
+Requires(postun): %{_sbindir}/alternatives
+
+Provides: llvm-devel(major) = %{maj_ver}
+
+%description devel
+This package contains library and header files needed to develop new native
+programs that use the LLVM infrastructure.
+
+%package doc
+Summary: Documentation for LLVM
+BuildArch: noarch
+Requires: %{name} = %{version}-%{release}
+
+%description doc
+Documentation for the LLVM compiler infrastructure.
+
+%package libs
+Summary: LLVM shared libraries
+
+%description libs
+Shared libraries for the LLVM compiler infrastructure.
+
+%package static
+Summary: LLVM static libraries
+Conflicts: %{name}-devel < 8
+
+%description static
+Static libraries for the LLVM compiler infrastructure.
+
+%if %{without compat_build}
+
+%package test
+Summary: LLVM regression tests
+Requires: %{name}%{?_isa} = %{version}-%{release}
+Requires: %{name}-libs%{?_isa} = %{version}-%{release}
+Requires: python3-lit
+# The regression tests need gold.
+Requires: binutils
+# This is for llvm-config
+Requires: %{name}-devel%{?_isa} = %{version}-%{release}
+# Bugpoint tests require gcc
+Requires: gcc
+Requires: findutils
+
+Provides: llvm-test(major) = %{maj_ver}
+
+%description test
+LLVM regression tests.
+
+%package googletest
+Summary: LLVM's modified googletest sources
+
+%description googletest
+LLVM's modified googletest sources.
+
+%endif
+
+%prep
+%autosetup -n llvm-%{version}%{?rc_ver:rc%{rc_ver}}.src -p2
+
+pathfix.py -i %{__python3} -pn \
+ test/BugPoint/compile-custom.ll.py \
+ tools/opt-viewer/*.py
+
+%build
+mkdir -p _build
+cd _build
+
+%ifarch s390 %{arm} %ix86
+# Decrease debuginfo verbosity to reduce memory consumption during final library linking
+%global optflags %(echo %{optflags} | sed 's/-g /-g1 /')
+%endif
+
+# force off shared libs as cmake macros turns it on.
+#
+# -DCMAKE_INSTALL_RPATH=";" is a workaround for llvm manually setting the
+# rpath of libraries and binaries. llvm will skip the manual setting
+# if CAMKE_INSTALL_RPATH is set to a value, but cmake interprets this value
+# as nothing, so it sets the rpath to "" when installing.
+%cmake .. -G Ninja \
+ -DBUILD_SHARED_LIBS:BOOL=OFF \
+ -DLLVM_PARALLEL_LINK_JOBS=1 \
+ -DCMAKE_BUILD_TYPE=RelWithDebInfo \
+ -DCMAKE_INSTALL_RPATH=";" \
+%ifarch s390 %{arm} %ix86
+ -DCMAKE_C_FLAGS_RELWITHDEBINFO="%{optflags} -DNDEBUG" \
+ -DCMAKE_CXX_FLAGS_RELWITHDEBINFO="%{optflags} -DNDEBUG" \
+%endif
+%if %{without compat_build}
+%if 0%{?__isa_bits} == 64
+ -DLLVM_LIBDIR_SUFFIX=64 \
+%else
+ -DLLVM_LIBDIR_SUFFIX= \
+%endif
+%endif
+ \
+ -DLLVM_TARGETS_TO_BUILD=all \
+ -DLLVM_ENABLE_LIBCXX:BOOL=OFF \
+ -DLLVM_ENABLE_ZLIB:BOOL=ON \
+ -DLLVM_ENABLE_FFI:BOOL=ON \
+ -DLLVM_ENABLE_RTTI:BOOL=ON \
+%if %{with gold}
+ -DLLVM_BINUTILS_INCDIR=%{_includedir} \
+%endif
+ -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=AVR \
+ \
+ -DLLVM_BUILD_RUNTIME:BOOL=ON \
+ \
+ -DLLVM_INCLUDE_TOOLS:BOOL=ON \
+ -DLLVM_BUILD_TOOLS:BOOL=ON \
+ \
+ -DLLVM_INCLUDE_TESTS:BOOL=ON \
+ -DLLVM_BUILD_TESTS:BOOL=ON \
+ \
+ -DLLVM_INCLUDE_EXAMPLES:BOOL=ON \
+ -DLLVM_BUILD_EXAMPLES:BOOL=OFF \
+ \
+ -DLLVM_INCLUDE_UTILS:BOOL=ON \
+%if %{with compat_build}
+ -DLLVM_INSTALL_UTILS:BOOL=OFF \
+%else
+ -DLLVM_INSTALL_UTILS:BOOL=ON \
+ -DLLVM_UTILS_INSTALL_DIR:PATH=%{_bindir} \
+ -DLLVM_TOOLS_INSTALL_DIR:PATH=bin \
+%endif
+ \
+ -DLLVM_INCLUDE_DOCS:BOOL=ON \
+ -DLLVM_BUILD_DOCS:BOOL=ON \
+ -DLLVM_ENABLE_SPHINX:BOOL=ON \
+ -DLLVM_ENABLE_DOXYGEN:BOOL=OFF \
+ \
+ -DLLVM_BUILD_LLVM_DYLIB:BOOL=ON \
+ -DLLVM_DYLIB_EXPORT_ALL:BOOL=ON \
+ -DLLVM_LINK_LLVM_DYLIB:BOOL=ON \
+ -DLLVM_BUILD_EXTERNAL_COMPILER_RT:BOOL=ON \
+ -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
+
+# Build libLLVM.so first. This ensures that when libLLVM.so is linking, there
+# are no other compile jobs running. This will help reduce OOM errors on the
+# builders without having to artificially limit the number of concurrent jobs.
+%ninja_build LLVM
+%ninja_build
+
+%install
+%ninja_install -C _build
+
+
+%if %{without compat_build}
+mkdir -p %{buildroot}/%{_bindir}
+mv %{buildroot}/%{_bindir}/llvm-config %{buildroot}/%{_bindir}/llvm-config-%{__isa_bits}
+
+# 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
+
+# Install binaries needed for lit tests
+%global test_binaries llvm-isel-fuzzer llvm-opt-fuzzer
+
+for f in %{test_binaries}
+do
+ install -m 0755 ./_build/bin/$f %{buildroot}%{_bindir}
+done
+
+
+%multilib_fix_c_header --file %{_includedir}/llvm/Config/llvm-config.h
+
+# Install libraries needed for unittests
+%if 0%{?__isa_bits} == 64
+%global build_libdir _build/lib64
+%else
+%global build_libdir _build/lib
+%endif
+
+install %{build_libdir}/libLLVMTestingSupport.a %{buildroot}%{_libdir}
+
+%global install_srcdir %{buildroot}%{_datadir}/llvm/src
+%global lit_cfg test/%{_arch}.site.cfg.py
+%global lit_unit_cfg test/Unit/%{_arch}.site.cfg.py
+%global lit_fedora_cfg %{_datadir}/llvm/lit.fedora.cfg.py
+
+# Install gtest sources so clang can use them for gtest
+install -d %{install_srcdir}
+install -d %{install_srcdir}/utils/
+cp -R utils/unittest %{install_srcdir}/utils/
+
+# Generate lit config files. Strip off the last line that initiates the
+# test run, so we can customize the configuration.
+head -n -1 _build/test/lit.site.cfg.py >> %{lit_cfg}
+head -n -1 _build/test/Unit/lit.site.cfg.py >> %{lit_unit_cfg}
+
+# Install custom fedora config file
+cp %{SOURCE2} %{buildroot}%{lit_fedora_cfg}
+
+# Patch lit config files to load custom fedora config:
+for f in %{lit_cfg} %{lit_unit_cfg}; do
+ echo "lit_config.load_config(config, '%{lit_fedora_cfg}')" >>
$f
+done
+
+install -d %{buildroot}%{_libexecdir}/tests/llvm
+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/
+
+# Install the unit test binaries
+mkdir -p %{build_llvm_libdir}
+cp -R _build/unittests %{build_llvm_libdir}/
+rm -rf `find %{build_llvm_libdir} -iname 'cmake*'`
+
+# Install libraries used for testing
+install -m 0755 %{build_libdir}/BugpointPasses.so %{buildroot}%{_libdir}
+install -m 0755 %{build_libdir}/LLVMHello.so %{buildroot}%{_libdir}
+
+# Install test inputs for PDB tests
+echo "%{_datadir}/llvm/src/unittests/DebugInfo/PDB" >
%{build_llvm_libdir}/unittests/DebugInfo/PDB/llvm.srcdir.txt
+mkdir -p %{buildroot}%{_datadir}/llvm/src/unittests/DebugInfo/PDB/
+cp -R unittests/DebugInfo/PDB/Inputs
%{buildroot}%{_datadir}/llvm/src/unittests/DebugInfo/PDB/
+
+%else
+
+# Add version suffix to binaries
+mkdir -p %{buildroot}/%{_bindir}
+for f in %{buildroot}/%{install_bindir}/*; do
+ filename=`basename $f`
+ ln -s ../../../%{install_bindir}/$filename
%{buildroot}/%{_bindir}/$filename%{exec_suffix}
+done
+
+# Move header files
+mkdir -p %{buildroot}/%{pkg_includedir}
+ln -s ../../../%{install_includedir}/llvm %{buildroot}/%{pkg_includedir}/llvm
+ln -s ../../../%{install_includedir}/llvm-c %{buildroot}/%{pkg_includedir}/llvm-c
+
+# Fix multi-lib
+mv %{buildroot}%{_bindir}/llvm-config{%{exec_suffix},%{exec_suffix}-%{__isa_bits}}
+%multilib_fix_c_header --file %{install_includedir}/llvm/Config/llvm-config.h
+
+# Create ld.so.conf.d entry
+mkdir -p %{buildroot}%{_sysconfdir}/ld.so.conf.d
+cat >> %{buildroot}%{_sysconfdir}/ld.so.conf.d/%{name}-%{_arch}.conf << EOF
+%{pkg_libdir}
+EOF
+
+# Add version suffix to man pages and move them to mandir.
+mkdir -p %{buildroot}/%{_mandir}/man1
+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
+
+# Remove opt-viewer, since this is just a compatibility package.
+rm -Rf %{build_install_prefix}/share/opt-viewer
+
+%endif
+
+
+%check
+# TODO: Fix test failures on arm
+ninja check-all -C _build || \
+%ifarch %{arm}
+ :
+%else
+ false
+%endif
+
+%ldconfig_scriptlets libs
+
+%if %{without compat_build}
+
+%post devel
+%{_sbindir}/update-alternatives --install %{_bindir}/llvm-config llvm-config
%{_bindir}/llvm-config-%{__isa_bits} %{__isa_bits}
+
+%postun devel
+if [ $1 -eq 0 ]; then
+ %{_sbindir}/update-alternatives --remove llvm-config %{_bindir}/llvm-config
+fi
+
+%endif
+
+%files
+%exclude %{_mandir}/man1/llvm-config*
+%{_mandir}/man1/*
+%{_bindir}/*
+
+%if %{without compat_build}
+%exclude %{_bindir}/llvm-config-%{__isa_bits}
+%exclude %{_bindir}/not
+%exclude %{_bindir}/count
+%exclude %{_bindir}/yaml-bench
+%exclude %{_bindir}/lli-child-target
+%exclude %{_bindir}/llvm-isel-fuzzer
+%exclude %{_bindir}/llvm-opt-fuzzer
+%{_datadir}/opt-viewer
+%else
+%exclude %{pkg_bindir}/llvm-config
+%{pkg_bindir}
+%endif
+
+%files libs
+%{pkg_libdir}/libLLVM-%{maj_ver}.so
+%if %{without compat_build}
+%if %{with gold}
+%{_libdir}/LLVMgold.so
+%endif
+%{_libdir}/libLLVM-%{maj_ver}.%{min_ver}*.so
+%{_libdir}/libLTO.so*
+%else
+%config(noreplace) %{_sysconfdir}/ld.so.conf.d/%{name}-%{_arch}.conf
+%if %{with gold}
+%{_libdir}/%{name}/lib/LLVMgold.so
+%endif
+%{pkg_libdir}/libLLVM-%{maj_ver}.%{min_ver}*.so
+%{pkg_libdir}/libLTO.so*
+%exclude %{pkg_libdir}/libLTO.so
+%endif
+%{pkg_libdir}/libRemarks.so*
+
+%files devel
+%if %{without compat_build}
+%{_bindir}/llvm-config-%{__isa_bits}
+%{_mandir}/man1/llvm-config*
+%{_includedir}/llvm
+%{_includedir}/llvm-c
+%{_libdir}/libLLVM.so
+%{_libdir}/cmake/llvm
+%exclude %{_libdir}/cmake/llvm/LLVMStaticExports.cmake
+%exclude %{_libdir}/cmake/llvm/LLVMTestExports.cmake
+%else
+%{_bindir}/llvm-config%{exec_suffix}-%{__isa_bits}
+%{pkg_bindir}/llvm-config
+%{_mandir}/man1/llvm-config%{exec_suffix}.1.gz
+%{install_includedir}/llvm
+%{install_includedir}/llvm-c
+%{pkg_includedir}/llvm
+%{pkg_includedir}/llvm-c
+%{pkg_libdir}/libLTO.so
+%{pkg_libdir}/libLLVM.so
+%{pkg_libdir}/cmake/llvm
+%endif
+
+%files doc
+%doc %{_pkgdocdir}/html
+
+%files static
+%if %{without compat_build}
+%{_libdir}/*.a
+%exclude %{_libdir}/libLLVMTestingSupport.a
+%{_libdir}/cmake/llvm/LLVMStaticExports.cmake
+%else
+%{_libdir}/%{name}/lib/*.a
+%endif
+
+%if %{without compat_build}
+
+%files test
+%{_libexecdir}/tests/llvm/
+%{llvm_libdir}/unittests/
+%{_datadir}/llvm/src/unittests
+%{_datadir}/llvm/src/test.tar.gz
+%{_datadir}/llvm/lit.fedora.cfg.py
+%{_bindir}/not
+%{_bindir}/count
+%{_bindir}/yaml-bench
+%{_bindir}/lli-child-target
+%{_bindir}/llvm-isel-fuzzer
+%{_bindir}/llvm-opt-fuzzer
+%{_libdir}/BugpointPasses.so
+%{_libdir}/LLVMHello.so
+%{_libdir}/cmake/llvm/LLVMTestExports.cmake
+
+%files googletest
+%{_datadir}/llvm/src/utils
+%{_libdir}/libLLVMTestingSupport.a
+
+%endif
+
+%changelog
+* Tue Feb 4 2020 sguelton(a)redhat.com - 9.0.1-6
+- Sync specfile with llvm9.0 package
+
+* Wed Jan 29 2020 Fedora Release Engineering <releng(a)fedoraproject.org> - 9.0.1-5
+- Rebuilt for
https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
+
+* Tue Jan 21 2020 Tom Stellard <tstellar(a)redhat.com> - 9.0.1-4
+- Rebuild after previous build failed to strip binaries
+
+* Fri Jan 17 2020 Tom Stellard <tstellar(a)redhat.com> - 9.0.1-3
+- Add explicit Requires from sub-packages to llvm-libs
+
+* Fri Jan 10 2020 Tom Stellard <tstellar(a)redhat.com> - 9.0.1-2
+- Fix crash with kernel bpf self-tests
+
+* Thu Dec 19 2019 tstellar(a)redhat.com - 9.0.1-1
+- 9.0.1 Release
+
+* Mon Nov 25 2019 sguelton(a)redhat.com - 9.0.0-4
+- Activate AVR on all architectures
+
+* Mon Sep 30 2019 Tom Stellard <tstellar(a)redhat.com> - 9.0.0-3
+- Build libLLVM.so first to avoid OOM errors
+
+* Fri Sep 27 2019 Tom Stellard <tstellar(a)redhat.com> - 9.0.0-2
+- Remove unneeded BuildRequires: libstdc++-static
+
+* Thu Sep 19 2019 sguelton(a)redhat.com - 9.0.0-1
+- 9.0.0 Release
+
+* Wed Sep 18 2019 sguelton(a)redhat.com - 9.0.0-0.5.rc3
+- Support avr target, see rhbz#1718492
+
+* Tue Sep 10 2019 Tom Stellard <tstellar(a)redhat.com> - 9.0.0-0.4.rc3
+- Split out test executables into their own export file
+
+* Fri Sep 06 2019 Tom Stellard <tstellar(a)redhat.com> - 9.0.0-0.3.rc3
+- Fix patch for splitting out static library exports
+
+* Fri Aug 30 2019 Tom Stellard <tstellar(a)redhat.com> - 9.0.0-0.2.rc3
+- 9.0.0-rc3 Release
+
+* Thu Aug 01 2019 Tom Stellard <tstellar(a)redhat.com> - 9.0.0-0.1.rc2
+- 9.0.0-rc2 Release
+
+* Tue Jul 30 2019 Tom Stellard <tstellar(a)redhat.com> - 8.0.0-9
+- Sync with llvm8.0 spec file
+
+* Thu Jul 25 2019 Fedora Release Engineering <releng(a)fedoraproject.org> -
8.0.0-8.1
+- Rebuilt for
https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
+
+* Wed Jul 17 2019 Tom Stellard <tstellar(a)redhat.com> - 8.0.0-8
+- Add provides for the major version of sub-packages
+
+* Fri May 17 2019 sguelton(a)redhat.com - 8.0.0-7
+- Fix conflicts between llvm-static = 8 and llvm-dev < 8 around
LLVMStaticExports.cmake
+
+* Wed Apr 24 2019 Tom Stellard <tstellar(a)redhat.com> - 8.0.0-6
+- Make sure we aren't passing -g on s390x
+
+* Sat Mar 30 2019 Tom Stellard <tstellar(a)redhat.com> - 8.0.0-5
+- Enable build rpath while keeping install rpath disabled
+
+* Wed Mar 27 2019 Tom Stellard <tstellar(a)redhat.com> - 8.0.0-4
+- Backport r351577 from trunk to fix ninja check failures
+
+* Tue Mar 26 2019 Tom Stellard <tstellar(a)redhat.com> - 8.0.0-3
+- Fix ninja check
+
+* Fri Mar 22 2019 Tom Stellard <tstellar(a)redhat.com> - 8.0.0-2
+- llvm-test fixes
+
+* Wed Mar 20 2019 sguelton(a)redhat.com - 8.0.0-1
+- 8.0.0 final
+
+* Fri Mar 15 2019 sguelton(a)redhat.com - 8.0.0-0.6.rc4
+- Activate all backends (rhbz#1689031)
+
+* Tue Mar 12 2019 sguelton(a)redhat.com - 8.0.0-0.5.rc4
+- 8.0.0 Release candidate 4
+
+* Mon Mar 4 2019 sguelton(a)redhat.com - 8.0.0-0.4.rc3
+- Move some binaries to -test package, cleanup specfile
+
+* Mon Mar 4 2019 sguelton(a)redhat.com - 8.0.0-0.3.rc3
+- 8.0.0 Release candidate 3
+
+* Fri Feb 22 2019 sguelton(a)redhat.com - 8.0.0-0.2.rc2
+- 8.0.0 Release candidate 2
+
+* Sat Feb 9 2019 sguelton(a)redhat.com - 8.0.0-0.1.rc1
+- 8.0.0 Release candidate 1
+
+* Fri Feb 01 2019 Fedora Release Engineering <releng(a)fedoraproject.org> -
7.0.1-2.1
+- Rebuilt for
https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
+
+* Mon Jan 21 2019 Josh Stone <jistone(a)redhat.com> - 7.0.1-2
+- Fix discriminators in metadata, rhbz#1668033
+
+* Mon Dec 17 2018 sguelton(a)redhat.com - 7.0.1-1
+- 7.0.1 release
+
+* Tue Dec 04 2018 sguelton(a)redhat.com - 7.0.0-5
+- Ensure rpmlint passes on specfile
+
+* Sat Nov 17 2018 Tom Stellard <tstellar(a)redhat.com> - 7.0.0-4
+- Install testing libraries for unittests
+
+* Sat Oct 27 2018 Tom Stellard <tstellar(a)redhat.com> - 7.0.0-3
+- Fix running unittests as not-root user
+
+* Thu Sep 27 2018 Tom Stellard <tstellar(a)redhat.com> - 7.0.0-2
+- Fixes for llvm-test package:
+- Add some missing Requires
+- Add --threads option to run-lit-tests script
+- Set PATH so lit can find tools like count, not, etc.
+- Don't hardcode tools directory to /usr/lib64/llvm
+- Fix typo in yaml-bench define
+- Only print information about failing tests
+
+* Fri Sep 21 2018 Tom Stellard <tstellar(a)redhat.com> - 7.0.0-1
+- 7.0.0 Release
+
+* Thu Sep 13 2018 Tom Stellard <tstellar(a)redhat.com> - 7.0.0-0.15.rc3
+- Disable rpath on install LLVM and related sub-projects
+
+* Wed Sep 12 2018 Tom Stellard <tstellar(a)redhat.com> - 7.0.0-0.14.rc3
+- Remove rpath from executables and libraries
+
+* Tue Sep 11 2018 Tom Stellard <tstellar(a)redhat.com> - 7.0.0-0.13.rc3
+- Re-enable arm and aarch64 targets on x86_64
+
+* Mon Sep 10 2018 Tom Stellard <tstellar(a)redhat.com> - 7.0.0-0.12.rc3
+- 7.0.0-rc3 Release
+
+* Fri Sep 07 2018 Tom Stellard <tstellar(a)redhat.com> - 7.0.0-0.11.rc2
+- Use python3 shebang for opt-viewewr scripts
+
+* Thu Aug 30 2018 Tom Stellard <tstellar(a)redhat.com> - 7.0.0-0.10.rc2
+- Drop all uses of python2 from lit tests
+
+* Thu Aug 30 2018 Tom Stellard <tstellar(a)redhat.com> - 7.0.0-0.9.rc2
+- Build the gold plugin on all supported architectures
+
+* Wed Aug 29 2018 Kevin Fenzi <kevin(a)scrye.com> - 7.0.0-0.8.rc2
+- Re-enable debuginfo to avoid 25x size increase.
+
+* Tue Aug 28 2018 Tom Stellard <tstellar(a)redhat.com> - 7.0.0-0.7.rc2
+- 7.0.0-rc2 Release
+
+* Tue Aug 28 2018 Tom Stellard <tstellar(a)redhat.com> - 7.0.0-0.6.rc1
+- Guard valgrind usage with valgrind_arches macro
+
+* Thu Aug 23 2018 Tom Stellard <tstellar(a)redhat.com> - 7.0.0-0.5.rc1
+- Package lit tests and googletest sources.
+
+* Mon Aug 20 2018 Tom Stellard <tstellar(a)redhat.com> - 7.0.0-0.4.rc1
+- Re-enable AMDGPU target on ARM rhbz#1618922
+
+* Mon Aug 13 2018 Tom Stellard <tstellar(a)redhat.com> - 7.0.0-0.3.rc1
+- Drop references to TestPlugin.so from cmake files
+
+* Fri Aug 10 2018 Tom Stellard <tstellar(a)redhat.com> - 7.0.0-0.2.rc1
+- Fixes for lit tests
+
+* Fri Aug 10 2018 Tom Stellard <tstellar(a)redhat.com> - 7.0.0-0.1.rc1
+- 7.0.0-rc1 Release
+- Reduce number of enabled targets on all arches.
+- Drop s390 detection patch, LLVM does not support s390 codegen.
+
+* Mon Aug 06 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.1-6
+- Backport some fixes needed by mesa and rust
+
+* Thu Jul 26 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.1-5
+- Move libLLVM-6.0.so to llvm6.0-libs.
+
+* Mon Jul 23 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.1-4
+- Rebuild because debuginfo stripping failed with the previous build
+
+* Fri Jul 13 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.1-3
+- Sync specfile with llvm6.0 package
+
+* Fri Jul 13 2018 Fedora Release Engineering <releng(a)fedoraproject.org> - 6.0.1-2
+- Rebuilt for
https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
+
+* Mon Jun 25 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.1-1
+- 6.0.1 Release
+
+* Thu Jun 07 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.1-0.4.rc2
+- 6.0.1-rc2
+
+* Wed Jun 06 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.1-0.3.rc1
+- Re-enable all targets to avoid breaking the ABI.
+
+* Mon Jun 04 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.1-0.2.rc1
+- Reduce the number of enabled targets based on the architecture
+
+* Thu May 10 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.1-0.1.rc1
+- 6.0.1 rc1
+
+* Tue Mar 27 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.0-11
+- Re-enable arm tests that used to hang
+
+* Thu Mar 22 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.0-10
+- Fix testcase in backported patch
+
+* Tue Mar 20 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.0-9
+- Prevent external projects from linking against both static and shared
+ libraries. rhbz#1558657
+
+* Mon Mar 19 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.0-8
+- Backport r327651 from trunk rhbz#1554349
+
+* Fri Mar 16 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.0-7
+- Filter out cxxflags and cflags from llvm-config that aren't supported by clang
+- rhbz#1556980
+
+* Wed Mar 14 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.0-6
+- Enable symbol versioning in libLLVM.so
+
+* Wed Mar 14 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.0-5
+- Stop statically linking libstdc++. This is no longer required by Steam
+ client, but the steam installer still needs a work-around which should
+ be handled in the steam package.
+* Wed Mar 14 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.0-4
+- s/make check/ninja check/
+
+* Fri Mar 09 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.0-3
+- Backport fix for compile time regression on rust rhbz#1552915
+
+* Thu Mar 08 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.0-2
+- Build with Ninja: This reduces RPM build time on a 6-core x86_64 builder
+ from 82 min to 52 min.
+
+* Thu Mar 08 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.0-1
+- 6.0.0 Release
+
+* Thu Mar 08 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.0-0.5.rc2
+- Reduce debuginfo size on i686 to avoid OOM errors during linking
+
+* Fri Feb 09 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.0-0.4.rc2
+- 6.0.1 rc2
+
+* Fri Feb 09 2018 Igor Gnatenko <ignatenkobrain(a)fedoraproject.org> - 6.0.0-0.3.rc1
+- Escape macros in %%changelog
+
+* Thu Feb 08 2018 Fedora Release Engineering <releng(a)fedoraproject.org> -
6.0.0-0.2.rc1
+- Rebuilt for
https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Fri Jan 19 2018 Tom Stellard <tstellar(a)redhat.com> - 6.0.0-0.1.rc1
+- 6.0.1 rc1
+
+* Tue Dec 19 2017 Tom Stellard <tstellar(a)redhat.com> - 5.0.1-1
+- 5.0.1 Release
+
+* Mon Nov 20 2017 Tom Stellard <tstellar(a)redhat.com> - 5.0.0-5
+- Backport debuginfo fix for rust
+
+* Fri Nov 03 2017 Tom Stellard <tstellar(a)redhat.com> - 5.0.0-4
+- Reduce debuginfo size for ARM
+
+* Tue Oct 10 2017 Tom Stellard <tstellar(a)redhat.com> - 5.0.0-2
+- Reduce memory usage on ARM by disabling debuginfo and some non-ARM targets.
+
+* Mon Sep 25 2017 Tom Stellard <tstellar(a)redhat.com> - 5.0.0-1
+- 5.0.0 Release
+
+* Mon Sep 18 2017 Tom Stellard <tstellar(a)redhat.com> - 4.0.1-6
+- Add Requires: libedit-devel for llvm-devel
+
+* Fri Sep 08 2017 Tom Stellard <tstellar(a)redhat.com> - 4.0.1-5
+- Enable libedit backend for LineEditor API
+
+* Fri Aug 25 2017 Tom Stellard <tstellar(a)redhat.com> - 4.0.1-4
+- Enable extra functionality when run the LLVM JIT under valgrind.
+
+* Thu Aug 03 2017 Fedora Release Engineering <releng(a)fedoraproject.org> - 4.0.1-3
+- Rebuilt for
https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
+
+* Wed Jul 26 2017 Fedora Release Engineering <releng(a)fedoraproject.org> - 4.0.1-2
+- Rebuilt for
https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Wed Jun 21 2017 Tom Stellard <tstellar(a)redhat.com> - 4.0.1-1
+- 4.0.1 Release
+
+* Thu Jun 15 2017 Tom Stellard <tstellar(a)redhat.com> - 4.0.0-6
+- Install llvm utils
+
+* Thu Jun 08 2017 Tom Stellard <tstellar(a)redhat.com> - 4.0.0-5
+- Fix docs-llvm-man target
+
+* Mon May 01 2017 Tom Stellard <tstellar(a)redhat.com> - 4.0.0-4
+- Make cmake files no longer depend on static libs (rhbz 1388200)
+
+* Tue Apr 18 2017 Josh Stone <jistone(a)redhat.com> - 4.0.0-3
+- Fix computeKnownBits for ARMISD::CMOV (rust-lang/llvm#67)
+
+* Mon Apr 03 2017 Tom Stellard <tstellar(a)redhat.com> - 4.0.0-2
+- Simplify spec with rpm macros.
+
+* Thu Mar 23 2017 Tom Stellard <tstellar(a)redhat.com> - 4.0.0-1
+- LLVM 4.0.0 Final Release
+
+* Wed Mar 22 2017 tstellar(a)redhat.com - 3.9.1-6
+- Fix %%postun sep for -devel package.
+
+* Mon Mar 13 2017 Tom Stellard <tstellar(a)redhat.com> - 3.9.1-5
+- Disable failing tests on ARM.
+
+* Sun Mar 12 2017 Peter Robinson <pbrobinson(a)fedoraproject.org> 3.9.1-4
+- Fix missing mask on relocation for aarch64 (rhbz 1429050)
+
+* Wed Mar 01 2017 Dave Airlie <airlied(a)redhat.com> - 3.9.1-3
+- revert upstream radeonsi breaking change.
+
+* Thu Feb 23 2017 Josh Stone <jistone(a)redhat.com> - 3.9.1-2
+- disable sphinx warnings-as-errors
+
+* Fri Feb 10 2017 Orion Poplawski <orion(a)cora.nwra.com> - 3.9.1-1
+- llvm 3.9.1
+
+* Fri Feb 10 2017 Fedora Release Engineering <releng(a)fedoraproject.org> - 3.9.0-8
+- Rebuilt for
https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Tue Nov 29 2016 Josh Stone <jistone(a)redhat.com> - 3.9.0-7
+- Apply backports from rust-lang/llvm#55, #57
+
+* Tue Nov 01 2016 Dave Airlie <airlied(a)gmail.com - 3.9.0-6
+- rebuild for new arches
+
+* Wed Oct 26 2016 Dave Airlie <airlied(a)redhat.com> - 3.9.0-5
+- apply the patch from -4
+
+* Wed Oct 26 2016 Dave Airlie <airlied(a)redhat.com> - 3.9.0-4
+- add fix for lldb out-of-tree build
+
+* Mon Oct 17 2016 Josh Stone <jistone(a)redhat.com> - 3.9.0-3
+- Apply backports from rust-lang/llvm#47, #48, #53, #54
+
+* Sat Oct 15 2016 Josh Stone <jistone(a)redhat.com> - 3.9.0-2
+- Apply an InstCombine backport via rust-lang/llvm#51
+
+* Wed Sep 07 2016 Dave Airlie <airlied(a)redhat.com> - 3.9.0-1
+- llvm 3.9.0
+- upstream moved where cmake files are packaged.
+- upstream dropped CppBackend
+
+* Wed Jul 13 2016 Adam Jackson <ajax(a)redhat.com> - 3.8.1-1
+- llvm 3.8.1
+- Add mips target
+- Fix some shared library mispackaging
+
+* Tue Jun 07 2016 Jan Vcelak <jvcelak(a)fedoraproject.org> - 3.8.0-2
+- fix color support detection on terminal
+
+* Thu Mar 10 2016 Dave Airlie <airlied(a)redhat.com> 3.8.0-1
+- llvm 3.8.0 release
+
+* Wed Mar 09 2016 Dan Hork <dan[at][danny.cz> 3.8.0-0.3
+- install back memory consumption workaround for s390
+
+* Thu Mar 03 2016 Dave Airlie <airlied(a)redhat.com> 3.8.0-0.2
+- llvm 3.8.0 rc3 release
+
+* Fri Feb 19 2016 Dave Airlie <airlied(a)redhat.com> 3.8.0-0.1
+- llvm 3.8.0 rc2 release
+
+* Tue Feb 16 2016 Dan Hork <dan[at][danny.cz> 3.7.1-7
+- recognize s390 as SystemZ when configuring build
+
+* Sat Feb 13 2016 Dave Airlie <airlied(a)redhat.com> 3.7.1-6
+- export C++ API for mesa.
+
+* Sat Feb 13 2016 Dave Airlie <airlied(a)redhat.com> 3.7.1-5
+- reintroduce llvm-static, clang needs it currently.
+
+* Fri Feb 12 2016 Dave Airlie <airlied(a)redhat.com> 3.7.1-4
+- jump back to single llvm library, the split libs aren't working very well.
+
+* Fri Feb 05 2016 Dave Airlie <airlied(a)redhat.com> 3.7.1-3
+- add missing obsoletes (#1303497)
+
+* Thu Feb 04 2016 Fedora Release Engineering <releng(a)fedoraproject.org> - 3.7.1-2
+- Rebuilt for
https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Thu Jan 07 2016 Jan Vcelak <jvcelak(a)fedoraproject.org> 3.7.1-1
+- new upstream release
+- enable gold linker
+
+* Wed Nov 04 2015 Jan Vcelak <jvcelak(a)fedoraproject.org> 3.7.0-100
+- fix Requires for subpackages on the main package
+
+* Tue Oct 06 2015 Jan Vcelak <jvcelak(a)fedoraproject.org> 3.7.0-100
+- initial version using cmake build system
diff --git a/run-lit-tests b/run-lit-tests
new file mode 100755
index 0000000..a0f27d8
--- /dev/null
+++ b/run-lit-tests
@@ -0,0 +1,58 @@
+#!/bin/bash
+
+usage() {
+ echo "usage: `basename $0` [OPTIONS]"
+ echo " --threads NUM The number of threads to use for running
tests."
+ echo " --multilib-arch ARCH Use this option to test 32-bit libs/binaries
on"
+ echo " 64-bit hosts."
+}
+
+threads_arg=''
+
+while [ $# -gt 0 ]; do
+ case $1 in
+ --threads)
+ shift
+ threads_arg="--threads $1"
+ ;;
+ --multilib-arch)
+ shift
+ ARCH=$1
+ ;;
+ * )
+ echo "unknown option: $1"
+ echo ""
+ usage
+ exit 1
+ ;;
+ esac
+ shift
+done
+
+set -xe
+
+if [ -z "$ARCH" ]; then
+ ARCH=`rpm --eval '%_arch'`
+fi
+
+case $ARCH in
+ arm)
+ ;&
+ i686)
+ LIB_DIR="/usr/lib/"
+ ;;
+ *)
+ LIB_DIR="/usr/lib64/"
+ ;;
+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
+lit -v -s $threads_arg test \
+ -Dllvm_obj_root=`pwd` \
+ -Dllvm_test_root=`pwd`/test \
+ -Dllvm_unittest_bindir=$LIB_DIR/llvm \
+ -Dllvm_shlib_dir=$LIB_DIR
diff --git a/sources b/sources
new file mode 100644
index 0000000..569b8de
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+SHA512 (llvm-9.0.1.src.tar.xz) =
bfb6960a4dd1e18f4005f324f478a781c69e8ec7c20569d9b243fcb9372dc7733b254f26c683373537990cc9c109c78eaf0f65449629ee17caca1bce9b9ccccd