diff --git a/.gitignore b/.gitignore
index 7adc32b..35bc580 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/llvm-9.0.1.src.tar.xz
+SOURCES/llvm-10.0.1.src.tar.xz
diff --git a/.llvm.metadata b/.llvm.metadata
index fe0c8ba..5ca21e3 100644
--- a/.llvm.metadata
+++ b/.llvm.metadata
@@ -1 +1 @@
-f7fcf3bd92d130784513c06efe6910f135372ce3 SOURCES/llvm-9.0.1.src.tar.xz
+25d07260f3b7bf4f647e115c4a663fdeda130fbd SOURCES/llvm-10.0.1.src.tar.xz
diff --git a/SOURCES/0001-BPF-Handling-type-conversions-correctly-for-CO-RE.patch b/SOURCES/0001-BPF-Handling-type-conversions-correctly-for-CO-RE.patch
deleted file mode 100644
index bfde9bc..0000000
--- a/SOURCES/0001-BPF-Handling-type-conversions-correctly-for-CO-RE.patch
+++ /dev/null
@@ -1,2510 +0,0 @@
-From 20253836fbb1baf5c7cd6fb6558bd12dff682855 Mon Sep 17 00:00:00 2001
-From: Yonghong Song <yhs@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/SOURCES/0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch b/SOURCES/0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch
deleted file mode 100644
index 60ba6d9..0000000
--- a/SOURCES/0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch
+++ /dev/null
@@ -1,138 +0,0 @@
-From f2ccdd2700174c717dc55a0f4c3f5a91ae73ff42 Mon Sep 17 00:00:00 2001
-From: Yonghong Song <yhs@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@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/SOURCES/0001-Docs-llvm-strip-Add-help-text-to-llvm-strip-rst-doc.patch b/SOURCES/0001-Docs-llvm-strip-Add-help-text-to-llvm-strip-rst-doc.patch
deleted file mode 100644
index 0be06dd..0000000
--- a/SOURCES/0001-Docs-llvm-strip-Add-help-text-to-llvm-strip-rst-doc.patch
+++ /dev/null
@@ -1,223 +0,0 @@
-From 8987da9a2cac6c5bd39ba100ffd1aaede94dc6a0 Mon Sep 17 00:00:00 2001
-From: Michael Pozulp <pozulp.llvm@gmail.com>
-Date: Fri, 9 Aug 2019 19:10:55 +0000
-Subject: [PATCH] [Docs][llvm-strip] Add help text to llvm-strip rst doc
-
-Summary: Addresses https://bugs.llvm.org/show_bug.cgi?id=42383
-
-Reviewers: jhenderson, alexshap, rupprecht
-
-Reviewed By: jhenderson
-
-Subscribers: wolfgangp, jakehehrlich, llvm-commits
-
-Tags: #llvm
-
-Differential Revision: https://reviews.llvm.org/D65384
-
-llvm-svn: 368464
----
- llvm/docs/CommandGuide/llvm-strip.md  |  16 ----
- llvm/docs/CommandGuide/llvm-strip.rst | 167 ++++++++++++++++++++++++++++++++++
- 2 files changed, 167 insertions(+), 16 deletions(-)
- delete mode 100644 llvm/docs/CommandGuide/llvm-strip.md
- create mode 100644 llvm/docs/CommandGuide/llvm-strip.rst
-
-diff --git a/llvm/docs/CommandGuide/llvm-strip.md b/llvm/docs/CommandGuide/llvm-strip.md
-deleted file mode 100644
-index dd6e859..0000000
---- a/llvm/docs/CommandGuide/llvm-strip.md
-+++ /dev/null
-@@ -1,16 +0,0 @@
--# llvm-strip - object stripping tool
--
--## SYNOPSIS
--
--**llvm-strip** [*options*]
--
--## DESCRIPTION
--
--**llvm-strip** is a tool to strip sections and symbols from object files.
--
--The tool is still in active development, but in most scenarios it works as a
--drop-in replacement for GNU's **strip**.
--
--## SEE ALSO
--
--[llvm-objcopy](llvm-objcopy.html)
-diff --git a/llvm/docs/CommandGuide/llvm-strip.rst b/llvm/docs/CommandGuide/llvm-strip.rst
-new file mode 100644
-index 0000000..6e02482
---- /dev/null
-+++ b/llvm/docs/CommandGuide/llvm-strip.rst
-@@ -0,0 +1,167 @@
-+llvm-strip - object stripping tool
-+==================================
-+
-+.. program:: llvm-strip
-+
-+SYNOPSIS
-+--------
-+
-+:program:`llvm-strip` [*options*] *inputs...*
-+
-+DESCRIPTION
-+-----------
-+
-+:program:`llvm-strip` is a tool to strip sections and symbols from object files.
-+If no other stripping or remove options are specified, :option:`--strip-all`
-+will be enabled by default.
-+
-+The input files are modified in-place. If "-" is specified for the input file,
-+the input is read from the program's standard input stream.
-+
-+If the input is an archive, any requested operations will be applied to each
-+archive member individually.
-+
-+The tool is still in active development, but in most scenarios it works as a
-+drop-in replacement for GNU's :program:`strip`.
-+
-+GENERIC AND CROSS-PLATFORM OPTIONS
-+----------------------------------
-+
-+The following options are either agnostic of the file format, or apply to
-+multiple file formats.
-+
-+.. option:: --disable-deterministic-archives, -U
-+
-+ Use real values for UIDs, GIDs and timestamps when updating archive member
-+ headers.
-+
-+.. option:: --discard-all, -x
-+
-+ Remove most local symbols from the output. Different file formats may limit
-+ this to a subset of the local symbols. For example, file and section symbols in
-+ ELF objects will not be discarded.
-+
-+.. option::  --enable-deterministic-archives, -D
-+
-+ Enable deterministic mode when stripping archives, i.e. use 0 for archive member
-+ header UIDs, GIDs and timestamp fields. On by default.
-+
-+.. option:: --help, -h
-+
-+ Print a summary of command line options.
-+
-+.. option::  --no-strip-all
-+
-+ Disable --strip-all.
-+
-+.. option::  -o <file>
-+
-+ Write output to <file>. Multiple input files cannot be used in combination
-+ with -o.
-+
-+.. option:: --regex
-+
-+ If specified, symbol and section names specified by other switches are treated
-+ as extended POSIX regular expression patterns.
-+
-+.. option:: --remove-section <section>, -R
-+
-+ Remove the specified section from the output. Can be specified multiple times
-+ to remove multiple sections simultaneously.
-+
-+.. option:: --strip-all-gnu
-+
-+ Remove all symbols, debug sections and relocations from the output. This option
-+ is equivalent to GNU :program:`strip`'s ``--strip-all`` switch.
-+
-+.. option:: --strip-all, -S
-+
-+ For ELF objects, remove from the output all symbols and non-alloc sections not
-+ within segments, except for .gnu.warning sections and the section name table.
-+
-+ For COFF objects, remove all symbols, debug sections, and relocations from the
-+ output.
-+
-+.. option:: --strip-debug, -g
-+
-+ Remove all debug sections.
-+
-+.. option:: --strip-sections
-+
-+ Remove all section headers and all sections not in segments.
-+
-+.. option:: --strip-symbol <symbol>, -N
-+
-+ Remove all symbols named ``<symbol>`` from the output. Can be specified
-+ multiple times to remove multiple symbols.
-+
-+.. option:: --strip-unneeded
-+
-+ Remove all local or undefined symbols that are not required by relocations.
-+
-+.. option:: --version, -V
-+
-+  Display the version of this program.
-+
-+COFF-SPECIFIC OPTIONS
-+---------------------
-+
-+The following options are implemented only for COFF objects. If used with other
-+objects, :program:`llvm-strip` will either emit an error or silently ignore
-+them.
-+
-+.. option:: --only-keep-debug
-+
-+ Remove the contents of non-debug sections from the output, but keep the section
-+ headers.
-+
-+ELF-SPECIFIC OPTIONS
-+--------------------
-+
-+The following options are implemented only for ELF objects. If used with other
-+objects, :program:`llvm-strip` will either emit an error or silently ignore
-+them.
-+
-+.. option:: --allow-broken-links
-+
-+ Allow llvm-strip to remove sections even if it would leave invalid section
-+ references. Any invalid sh_link fields will be set to zero.
-+
-+.. option:: --discard-locals, -X
-+
-+ Remove local symbols starting with ".L" from the output.
-+
-+.. option:: --keep-file-symbols
-+
-+ Keep symbols of type `STT_FILE`, even if they would otherwise be stripped.
-+
-+ .. option:: --keep-section <section>
-+
-+ When removing sections from the output, do not remove sections named
-+ ``<section>``. Can be specified multiple times to keep multiple sections.
-+
-+.. option:: --keep-symbol <symbol>, -K
-+
-+ Do not remove symbols named ``<symbol>``. Can be specified multiple times to
-+ keep multiple symbols.
-+
-+.. option::  --preserve-dates, -p
-+
-+ Preserve access and modification timestamps.
-+
-+
-+EXIT STATUS
-+-----------
-+
-+:program:`llvm-strip` exits with a non-zero exit code if there is an error.
-+Otherwise, it exits with code 0.
-+
-+BUGS
-+----
-+
-+To report bugs, please visit <http://llvm.org/bugs/>.
-+
-+SEE ALSO
-+--------
-+
-+:manpage:`llvm-objcopy(1)`
--- 
-1.8.3.1
-
diff --git a/SOURCES/0001-Filter-out-cxxflags-not-supported-by-clang.patch b/SOURCES/0001-Filter-out-cxxflags-not-supported-by-clang.patch
deleted file mode 100644
index 1351d2f..0000000
--- a/SOURCES/0001-Filter-out-cxxflags-not-supported-by-clang.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From d15c835028bcc72a8695d047f0acaa530aa54716 Mon Sep 17 00:00:00 2001
-From: Tom Stellard <tstellar@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/SOURCES/0001-InstCombine-Fix-big-endian-miscompile-of-bitcast-zex.patch b/SOURCES/0001-InstCombine-Fix-big-endian-miscompile-of-bitcast-zex.patch
deleted file mode 100644
index fe381ac..0000000
--- a/SOURCES/0001-InstCombine-Fix-big-endian-miscompile-of-bitcast-zex.patch
+++ /dev/null
@@ -1,192 +0,0 @@
-From f8e146f3430de3a6cd904f3f3f7aa1bfaefee14c Mon Sep 17 00:00:00 2001
-From: Bjorn Pettersson <bjorn.a.pettersson@ericsson.com>
-Date: Thu, 28 Nov 2019 23:18:28 +0100
-Subject: [PATCH] [InstCombine] Fix big-endian miscompile of (bitcast
- (zext/trunc (bitcast)))
-
-Summary:
-optimizeVectorResize is rewriting patterns like:
-  %1 = bitcast vector %src to integer
-  %2 = trunc/zext %1
-  %dst = bitcast %2 to vector
-
-Since bitcasting between integer an vector types gives
-different integer values depending on endianness, we need
-to take endianness into account. As it happens the old
-implementation only produced the correct result for little
-endian targets.
-
-Fixes: https://bugs.llvm.org/show_bug.cgi?id=44178
-
-Reviewers: spatel, lattner, lebedev.ri
-
-Reviewed By: spatel, lebedev.ri
-
-Subscribers: lebedev.ri, hiraditya, uabelho, llvm-commits
-
-Tags: #llvm
-
-Differential Revision: https://reviews.llvm.org/D70844
-
-(cherry picked from commit a9d6b0e5444741d08ff1df7cf71d1559e7fefc1f)
----
- .../InstCombine/InstCombineCasts.cpp          | 79 +++++++++++++------
- llvm/test/Transforms/InstCombine/cast.ll      |  6 +-
- 2 files changed, 60 insertions(+), 25 deletions(-)
-
-diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
-index 2c9ba203fbf3..0af3de300e77 100644
---- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
-+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
-@@ -18,6 +18,7 @@
- #include "llvm/IR/DIBuilder.h"
- #include "llvm/IR/PatternMatch.h"
- #include "llvm/Support/KnownBits.h"
-+#include <numeric>
- using namespace llvm;
- using namespace PatternMatch;
- 
-@@ -1820,12 +1821,24 @@ Instruction *InstCombiner::visitPtrToInt(PtrToIntInst &CI) {
- }
- 
- /// This input value (which is known to have vector type) is being zero extended
--/// or truncated to the specified vector type.
-+/// or truncated to the specified vector type. Since the zext/trunc is done
-+/// using an integer type, we have a (bitcast(cast(bitcast))) pattern,
-+/// endianness will impact which end of the vector that is extended or
-+/// truncated.
-+///
-+/// A vector is always stored with index 0 at the lowest address, which
-+/// corresponds to the most significant bits for a big endian stored integer and
-+/// the least significant bits for little endian. A trunc/zext of an integer
-+/// impacts the big end of the integer. Thus, we need to add/remove elements at
-+/// the front of the vector for big endian targets, and the back of the vector
-+/// for little endian targets.
-+///
- /// Try to replace it with a shuffle (and vector/vector bitcast) if possible.
- ///
- /// The source and destination vector types may have different element types.
--static Instruction *optimizeVectorResize(Value *InVal, VectorType *DestTy,
--                                         InstCombiner &IC) {
-+static Instruction *optimizeVectorResizeWithIntegerBitCasts(Value *InVal,
-+                                                            VectorType *DestTy,
-+                                                            InstCombiner &IC) {
-   // We can only do this optimization if the output is a multiple of the input
-   // element size, or the input is a multiple of the output element size.
-   // Convert the input type to have the same element type as the output.
-@@ -1844,31 +1857,53 @@ static Instruction *optimizeVectorResize(Value *InVal, VectorType *DestTy,
-     InVal = IC.Builder.CreateBitCast(InVal, SrcTy);
-   }
- 
-+  bool IsBigEndian = IC.getDataLayout().isBigEndian();
-+  unsigned SrcElts = SrcTy->getNumElements();
-+  unsigned DestElts = DestTy->getNumElements();
-+
-+  assert(SrcElts != DestElts && "Element counts should be different.");
-+
-   // Now that the element types match, get the shuffle mask and RHS of the
-   // shuffle to use, which depends on whether we're increasing or decreasing the
-   // size of the input.
--  SmallVector<uint32_t, 16> ShuffleMask;
-+  SmallVector<uint32_t, 16> ShuffleMaskStorage;
-+  ArrayRef<uint32_t> ShuffleMask;
-   Value *V2;
- 
--  if (SrcTy->getNumElements() > DestTy->getNumElements()) {
--    // If we're shrinking the number of elements, just shuffle in the low
--    // elements from the input and use undef as the second shuffle input.
--    V2 = UndefValue::get(SrcTy);
--    for (unsigned i = 0, e = DestTy->getNumElements(); i != e; ++i)
--      ShuffleMask.push_back(i);
-+  // Produce an identify shuffle mask for the src vector.
-+  ShuffleMaskStorage.resize(SrcElts);
-+  std::iota(ShuffleMaskStorage.begin(), ShuffleMaskStorage.end(), 0);
- 
-+  if (SrcElts > DestElts) {
-+    // If we're shrinking the number of elements (rewriting an integer
-+    // truncate), just shuffle in the elements corresponding to the least
-+    // significant bits from the input and use undef as the second shuffle
-+    // input.
-+    V2 = UndefValue::get(SrcTy);
-+    // Make sure the shuffle mask selects the "least significant bits" by
-+    // keeping elements from back of the src vector for big endian, and from the
-+    // front for little endian.
-+    ShuffleMask = ShuffleMaskStorage;
-+    if (IsBigEndian)
-+      ShuffleMask = ShuffleMask.take_back(DestElts);
-+    else
-+      ShuffleMask = ShuffleMask.take_front(DestElts);
-   } else {
--    // If we're increasing the number of elements, shuffle in all of the
--    // elements from InVal and fill the rest of the result elements with zeros
--    // from a constant zero.
-+    // If we're increasing the number of elements (rewriting an integer zext),
-+    // shuffle in all of the elements from InVal. Fill the rest of the result
-+    // elements with zeros from a constant zero.
-     V2 = Constant::getNullValue(SrcTy);
--    unsigned SrcElts = SrcTy->getNumElements();
--    for (unsigned i = 0, e = SrcElts; i != e; ++i)
--      ShuffleMask.push_back(i);
--
--    // The excess elements reference the first element of the zero input.
--    for (unsigned i = 0, e = DestTy->getNumElements()-SrcElts; i != e; ++i)
--      ShuffleMask.push_back(SrcElts);
-+    // Use first elt from V2 when indicating zero in the shuffle mask.
-+    uint32_t NullElt = SrcElts;
-+    // Extend with null values in the "most significant bits" by adding elements
-+    // in front of the src vector for big endian, and at the back for little
-+    // endian.
-+    unsigned DeltaElts = DestElts - SrcElts;
-+    if (IsBigEndian)
-+      ShuffleMaskStorage.insert(ShuffleMaskStorage.begin(), DeltaElts, NullElt);
-+    else
-+      ShuffleMaskStorage.append(DeltaElts, NullElt);
-+    ShuffleMask = ShuffleMaskStorage;
-   }
- 
-   return new ShuffleVectorInst(InVal, V2,
-@@ -2359,8 +2394,8 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
-         CastInst *SrcCast = cast<CastInst>(Src);
-         if (BitCastInst *BCIn = dyn_cast<BitCastInst>(SrcCast->getOperand(0)))
-           if (isa<VectorType>(BCIn->getOperand(0)->getType()))
--            if (Instruction *I = optimizeVectorResize(BCIn->getOperand(0),
--                                               cast<VectorType>(DestTy), *this))
-+            if (Instruction *I = optimizeVectorResizeWithIntegerBitCasts(
-+                    BCIn->getOperand(0), cast<VectorType>(DestTy), *this))
-               return I;
-       }
- 
-diff --git a/llvm/test/Transforms/InstCombine/cast.ll b/llvm/test/Transforms/InstCombine/cast.ll
-index b6d1eda0601d..3ce8de033422 100644
---- a/llvm/test/Transforms/InstCombine/cast.ll
-+++ b/llvm/test/Transforms/InstCombine/cast.ll
-@@ -824,7 +824,7 @@ define i64 @test59(i8 %A, i8 %B) {
- 
- define <3 x i32> @test60(<4 x i32> %call4) {
- ; CHECK-LABEL: @test60(
--; CHECK-NEXT:    [[P10:%.*]] = shufflevector <4 x i32> [[CALL4:%.*]], <4 x i32> undef, <3 x i32> <i32 0, i32 1, i32 2>
-+; CHECK-NEXT:    [[P10:%.*]] = shufflevector <4 x i32> [[CALL4:%.*]], <4 x i32> undef, <3 x i32> <i32 1, i32 2, i32 3>
- ; CHECK-NEXT:    ret <3 x i32> [[P10]]
- ;
-   %p11 = bitcast <4 x i32> %call4 to i128
-@@ -836,7 +836,7 @@ define <3 x i32> @test60(<4 x i32> %call4) {
- 
- define <4 x i32> @test61(<3 x i32> %call4) {
- ; CHECK-LABEL: @test61(
--; CHECK-NEXT:    [[P10:%.*]] = shufflevector <3 x i32> [[CALL4:%.*]], <3 x i32> <i32 0, i32 undef, i32 undef>, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
-+; CHECK-NEXT:    [[P10:%.*]] = shufflevector <3 x i32> [[CALL4:%.*]], <3 x i32> <i32 0, i32 undef, i32 undef>, <4 x i32> <i32 3, i32 0, i32 1, i32 2>
- ; CHECK-NEXT:    ret <4 x i32> [[P10]]
- ;
-   %p11 = bitcast <3 x i32> %call4 to i96
-@@ -848,7 +848,7 @@ define <4 x i32> @test61(<3 x i32> %call4) {
- define <4 x i32> @test62(<3 x float> %call4) {
- ; CHECK-LABEL: @test62(
- ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <3 x float> [[CALL4:%.*]] to <3 x i32>
--; CHECK-NEXT:    [[P10:%.*]] = shufflevector <3 x i32> [[TMP1]], <3 x i32> <i32 0, i32 undef, i32 undef>, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
-+; CHECK-NEXT:    [[P10:%.*]] = shufflevector <3 x i32> [[TMP1]], <3 x i32> <i32 0, i32 undef, i32 undef>, <4 x i32> <i32 3, i32 0, i32 1, i32 2>
- ; CHECK-NEXT:    ret <4 x i32> [[P10]]
- ;
-   %p11 = bitcast <3 x float> %call4 to i96
--- 
-2.26.2
-
diff --git a/SOURCES/0001-Pass-target-to-gold-linker-to-avoid-faliures-on-i686.patch b/SOURCES/0001-Pass-target-to-gold-linker-to-avoid-faliures-on-i686.patch
deleted file mode 100644
index e8dd323..0000000
--- a/SOURCES/0001-Pass-target-to-gold-linker-to-avoid-faliures-on-i686.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From f0762684457a883b6813b48c98a1e94e377bc06b Mon Sep 17 00:00:00 2001
-From: Tom Stellard <tstellar@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/SOURCES/0001-PowerPC-PPCBoolRetToInt-Skip-translation-if-there-is.patch b/SOURCES/0001-PowerPC-PPCBoolRetToInt-Skip-translation-if-there-is.patch
new file mode 100644
index 0000000..4489dab
--- /dev/null
+++ b/SOURCES/0001-PowerPC-PPCBoolRetToInt-Skip-translation-if-there-is.patch
@@ -0,0 +1,86 @@
+From cf54ca458afff1f7827bfbbc939429a00496c4f7 Mon Sep 17 00:00:00 2001
+From: Tom Stellard <tstellar@redhat.com>
+Date: Tue, 18 Aug 2020 10:54:49 -0700
+Subject: [PATCH] [PowerPC] PPCBoolRetToInt: Skip translation if there is
+ ConstantExpr
+
+PPCBoolRetToInt collects PHI, Argument, Call and Constant defs related to an `i1` value which later is translated to an `i32`/`i64` value. The `translate` method expects an `i1` value. However, if the `Constant` is a `ConstantExpr`, the type of the `ConstantExpr` might not be `i1`.
+
+Fixes https://bugs.llvm.org/show_bug.cgi?id=46923 which causes ICE
+```
+llvm-project/llvm/lib/IR/Constants.cpp:1924: static llvm::Constant *llvm::ConstantExpr::getZExt(llvm::Constant *, llvm::Type *, bool): Assertion `C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&& "SrcTy must be smaller than DestTy for ZExt!"' failed.
+```
+
+Differential Revision: https://reviews.llvm.org/D85007
+---
+ llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp |  8 ++++--
+ llvm/test/CodeGen/PowerPC/pr46923.ll        | 31 +++++++++++++++++++++
+ 2 files changed, 37 insertions(+), 2 deletions(-)
+ create mode 100644 llvm/test/CodeGen/PowerPC/pr46923.ll
+
+diff --git a/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp b/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp
+index 2259a29f838..cfe3b3ce2e9 100644
+--- a/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp
++++ b/llvm/lib/Target/PowerPC/PPCBoolRetToInt.cpp
+@@ -90,6 +90,9 @@ class PPCBoolRetToInt : public FunctionPass {
+ 
+   // Translate a i1 value to an equivalent i32/i64 value:
+   Value *translate(Value *V) {
++    assert(V->getType() == Type::getInt1Ty(V->getContext()) &&
++           "Expect an i1 value");
++
+     Type *IntTy = ST->isPPC64() ? Type::getInt64Ty(V->getContext())
+                                 : Type::getInt32Ty(V->getContext());
+ 
+@@ -227,8 +230,9 @@ class PPCBoolRetToInt : public FunctionPass {
+     // CallInst. Potentially, bitwise operations (AND, OR, XOR, NOT) and sign
+     // extension could also be handled in the future.
+     for (Value *V : Defs)
+-      if (!isa<PHINode>(V) && !isa<Constant>(V) &&
+-          !isa<Argument>(V) && !isa<CallInst>(V))
++      if ((!isa<PHINode>(V) && !isa<Constant>(V) && !isa<Argument>(V) &&
++           !isa<CallInst>(V)) ||
++          isa<ConstantExpr>(V))
+         return false;
+ 
+     for (Value *V : Defs)
+diff --git a/llvm/test/CodeGen/PowerPC/pr46923.ll b/llvm/test/CodeGen/PowerPC/pr46923.ll
+new file mode 100644
+index 00000000000..d6f65508848
+--- /dev/null
++++ b/llvm/test/CodeGen/PowerPC/pr46923.ll
+@@ -0,0 +1,31 @@
++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
++; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-unknown \
++; RUN:   -ppc-asm-full-reg-names < %s | FileCheck %s
++
++@bar = external constant i64, align 8
++
++define i1 @foo() {
++; CHECK-LABEL: foo:
++; CHECK:       # %bb.0: # %entry
++; CHECK-NEXT:    crxor 4*cr5+lt, 4*cr5+lt, 4*cr5+lt
++; CHECK-NEXT:    li r3, 0
++; CHECK-NEXT:    li r4, 1
++; CHECK-NEXT:    isel r3, r4, r3, 4*cr5+lt
++; CHECK-NEXT:    blr
++entry:
++  br label %next
++
++next:
++  br i1 undef, label %true, label %false
++
++true:
++  br label %end
++
++false:
++  br label %end
++
++end:
++  %a = phi i1 [ icmp ugt (i64 0, i64 ptrtoint (i64* @bar to i64)), %true ],
++              [ icmp ugt (i64 0, i64 2), %false ]
++  ret i1 %a
++}
+-- 
+2.18.1
+
diff --git a/SOURCES/0001-Revert-SCEV-add-no-wrap-flag-for-SCEVAddExpr.patch b/SOURCES/0001-Revert-SCEV-add-no-wrap-flag-for-SCEVAddExpr.patch
deleted file mode 100644
index caf774c..0000000
--- a/SOURCES/0001-Revert-SCEV-add-no-wrap-flag-for-SCEVAddExpr.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From 58e8c793d0e43150a6452e971a32d7407a8a7401 Mon Sep 17 00:00:00 2001
-From: Tim Northover <tnorthover@apple.com>
-Date: Mon, 30 Sep 2019 07:46:52 +0000
-Subject: [PATCH] Revert "[SCEV] add no wrap flag for SCEVAddExpr."
-
-This reverts r366419 because the analysis performed is within the context of
-the loop and it's only valid to add wrapping flags to "global" expressions if
-they're always correct.
-
-llvm-svn: 373184
----
- llvm/lib/Analysis/ScalarEvolution.cpp              | 2 +-
- llvm/test/Analysis/ScalarEvolution/limit-depth.ll  | 2 +-
- llvm/test/Analysis/ScalarEvolution/nsw.ll          | 2 +-
- llvm/test/Analysis/ScalarEvolution/trip-count12.ll | 2 +-
- llvm/test/Analysis/ScalarEvolution/trip-count9.ll  | 8 ++++----
- 5 files changed, 8 insertions(+), 8 deletions(-)
-
-diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
-index 354ae05bb841..c29fc5dbccfb 100644
---- a/llvm/lib/Analysis/ScalarEvolution.cpp
-+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
-@@ -4992,7 +4992,7 @@ const SCEV *ScalarEvolution::createSimpleAffineAddRec(PHINode *PN,
-   // overflow.
-   if (auto *BEInst = dyn_cast<Instruction>(BEValueV))
-     if (isLoopInvariant(Accum, L) && isAddRecNeverPoison(BEInst, L))
--      (void)getAddRecExpr(getAddExpr(StartVal, Accum, Flags), Accum, L, Flags);
-+      (void)getAddRecExpr(getAddExpr(StartVal, Accum), Accum, L, Flags);
- 
-   return PHISCEV;
- }
-diff --git a/llvm/test/Analysis/ScalarEvolution/limit-depth.ll b/llvm/test/Analysis/ScalarEvolution/limit-depth.ll
-index db68a4f84c91..6fdf8c5df974 100644
---- a/llvm/test/Analysis/ScalarEvolution/limit-depth.ll
-+++ b/llvm/test/Analysis/ScalarEvolution/limit-depth.ll
-@@ -46,7 +46,7 @@ define void @test_mul(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f) {
- define void @test_sext(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f) {
- ; CHECK-LABEL: @test_sext
- ; CHECK:        %se2 = sext i64 %iv2.inc to i128
--; CHECK-NEXT:   -->  {(1 + (sext i64 {(sext i32 (1 + %a)<nsw> to i64),+,1}<nsw><%loop> to i128))<nsw>,+,1}<nsw><%loop2>
-+; CHECK-NEXT:   -->  {(1 + (sext i64 {(sext i32 (1 + %a) to i64),+,1}<nsw><%loop> to i128))<nsw>,+,1}<nsw><%loop2>
- entry:
-   br label %loop
- 
-diff --git a/llvm/test/Analysis/ScalarEvolution/nsw.ll b/llvm/test/Analysis/ScalarEvolution/nsw.ll
-index 69427368625d..ca24f9d4a04b 100644
---- a/llvm/test/Analysis/ScalarEvolution/nsw.ll
-+++ b/llvm/test/Analysis/ScalarEvolution/nsw.ll
-@@ -163,7 +163,7 @@ bb5:                                              ; preds = %bb2
- declare void @f(i32)
- 
- ; CHECK-LABEL: nswnowrap
--; CHECK: --> {(1 + %v)<nsw>,+,1}<nsw><%for.body>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (2 + %v)
-+; CHECK: --> {(1 + %v)<nsw>,+,1}<nsw><%for.body>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (1 + ((1 + %v)<nsw> smax %v))
- define void @nswnowrap(i32 %v, i32* %buf) {
- entry:
-   %add = add nsw i32 %v, 1
-diff --git a/llvm/test/Analysis/ScalarEvolution/trip-count12.ll b/llvm/test/Analysis/ScalarEvolution/trip-count12.ll
-index 5e7d72d5e4f3..d0086ee2e6ac 100644
---- a/llvm/test/Analysis/ScalarEvolution/trip-count12.ll
-+++ b/llvm/test/Analysis/ScalarEvolution/trip-count12.ll
-@@ -1,7 +1,7 @@
- ; RUN: opt < %s -analyze -scalar-evolution | FileCheck %s
- 
- ; CHECK: Determining loop execution counts for: @test
--; CHECK: Loop %for.body: backedge-taken count is ((-2 + %len)<nsw> /u 2)
-+; CHECK: Loop %for.body: backedge-taken count is ((-2 + %len) /u 2)
- ; CHECK: Loop %for.body: max backedge-taken count is 1073741823
- 
- define zeroext i16 @test(i16* nocapture %p, i32 %len) nounwind readonly {
-diff --git a/llvm/test/Analysis/ScalarEvolution/trip-count9.ll b/llvm/test/Analysis/ScalarEvolution/trip-count9.ll
-index c0a1d12fa00e..9a080b34743f 100644
---- a/llvm/test/Analysis/ScalarEvolution/trip-count9.ll
-+++ b/llvm/test/Analysis/ScalarEvolution/trip-count9.ll
-@@ -179,7 +179,7 @@ exit:
- }
- 
- ; CHECK: Determining loop execution counts for: @nsw_startx
--; CHECK: Loop %loop: backedge-taken count is (-1 + (-1 * %x) + ((1 + %x)<nsw> smax %n))
-+; CHECK: Loop %loop: backedge-taken count is (-1 + (-1 * %x) + ((1 + %x) smax %n))
- ; CHECK: Loop %loop: max backedge-taken count is -1
- define void @nsw_startx(i4 %n, i4 %x) {
- entry:
-@@ -195,7 +195,7 @@ exit:
- }
- 
- ; CHECK: Determining loop execution counts for: @nsw_startx_step2
--; CHECK: Loop %loop: backedge-taken count is ((-1 + (-1 * %x) + ((2 + %x)<nsw> smax %n)) /u 2)
-+; CHECK: Loop %loop: backedge-taken count is ((-1 + (-1 * %x) + ((2 + %x) smax %n)) /u 2)
- ; CHECK: Loop %loop: max backedge-taken count is 7
- define void @nsw_startx_step2(i4 %n, i4 %x) {
- entry:
-@@ -381,7 +381,7 @@ exit:
- }
- 
- ; CHECK: Determining loop execution counts for: @even_nsw_startx
--; CHECK: Loop %loop: backedge-taken count is (-1 + (-1 * %x) + ((1 + %x)<nsw> smax (2 * %n)))
-+; CHECK: Loop %loop: backedge-taken count is (-1 + (-1 * %x) + ((1 + %x) smax (2 * %n)))
- ; CHECK: Loop %loop: max backedge-taken count is -2
- define void @even_nsw_startx(i4 %n, i4 %x) {
- entry:
-@@ -398,7 +398,7 @@ exit:
- }
- 
- ; CHECK: Determining loop execution counts for: @even_nsw_startx_step2
--; CHECK: Loop %loop: backedge-taken count is ((-1 + (-1 * %x) + ((2 + %x)<nsw> smax (2 * %n))) /u 2)
-+; CHECK: Loop %loop: backedge-taken count is ((-1 + (-1 * %x) + ((2 + %x) smax (2 * %n))) /u 2)
- ; CHECK: Loop %loop: max backedge-taken count is 7
- define void @even_nsw_startx_step2(i4 %n, i4 %x) {
- entry:
--- 
-2.24.1
-
diff --git a/SOURCES/0001-docs-Convert-remaining-command-guide-entries-from-md.patch b/SOURCES/0001-docs-Convert-remaining-command-guide-entries-from-md.patch
deleted file mode 100644
index 91b27b2..0000000
--- a/SOURCES/0001-docs-Convert-remaining-command-guide-entries-from-md.patch
+++ /dev/null
@@ -1,248 +0,0 @@
-From e4e77bb8bf741f52b43b90987646f1c118914848 Mon Sep 17 00:00:00 2001
-From: Jordan Rupprecht <rupprecht@google.com>
-Date: Wed, 21 Aug 2019 18:00:17 +0000
-Subject: [PATCH] [docs] Convert remaining command guide entries from md to
- rst.
-
-Summary:
-Linking between markdown and rst files is currently not supported very well, e.g. the current llvm-addr2line docs [1] link to "llvm-symbolizer" instead of "llvm-symbolizer.html". This is weirdly broken in different ways depending on which versions of sphinx and recommonmark are being used, so workaround the bug by using rst everywhere.
-
-[1] http://llvm.org/docs/CommandGuide/llvm-addr2line.html
-
-Reviewers: jhenderson
-
-Reviewed By: jhenderson
-
-Subscribers: lebedev.ri, llvm-commits
-
-Tags: #llvm
-
-Differential Revision: https://reviews.llvm.org/D66305
-
-llvm-svn: 369553
----
- llvm/docs/CommandGuide/llvm-addr2line.md  | 28 -----------------------
- llvm/docs/CommandGuide/llvm-addr2line.rst | 38 +++++++++++++++++++++++++++++++
- llvm/docs/CommandGuide/llvm-ranlib.md     | 17 --------------
- llvm/docs/CommandGuide/llvm-ranlib.rst    | 23 +++++++++++++++++++
- llvm/docs/CommandGuide/llvm-size.md       | 10 --------
- llvm/docs/CommandGuide/llvm-size.rst      | 15 ++++++++++++
- llvm/docs/CommandGuide/llvm-strings.md    | 10 --------
- llvm/docs/CommandGuide/llvm-strings.rst   | 15 ++++++++++++
- 8 files changed, 91 insertions(+), 65 deletions(-)
- delete mode 100644 llvm/docs/CommandGuide/llvm-addr2line.md
- create mode 100644 llvm/docs/CommandGuide/llvm-addr2line.rst
- delete mode 100644 llvm/docs/CommandGuide/llvm-ranlib.md
- create mode 100644 llvm/docs/CommandGuide/llvm-ranlib.rst
- delete mode 100644 llvm/docs/CommandGuide/llvm-size.md
- create mode 100644 llvm/docs/CommandGuide/llvm-size.rst
- delete mode 100644 llvm/docs/CommandGuide/llvm-strings.md
- create mode 100644 llvm/docs/CommandGuide/llvm-strings.rst
-
-diff --git a/llvm/docs/CommandGuide/llvm-addr2line.md b/llvm/docs/CommandGuide/llvm-addr2line.md
-deleted file mode 100644
-index 03224c4..0000000
---- a/llvm/docs/CommandGuide/llvm-addr2line.md
-+++ /dev/null
-@@ -1,28 +0,0 @@
--# llvm-addr2line - a drop-in replacement for addr2line
--
--## SYNOPSIS
--
--**llvm-addr2line** [*options*]
--
--## DESCRIPTION
--
--**llvm-addr2line** is an alias for the [llvm-symbolizer](llvm-symbolizer) tool
--with different defaults. The goal is to make it a drop-in replacement for
--GNU's **addr2line**.
--
--Here are some of those differences:
--
--* Defaults not to print function names. Use [-f](llvm-symbolizer-opt-f)
--  to enable that.
--
--* Defaults not to demangle function names. Use [-C](llvm-symbolizer-opt-C)
--  to switch the demangling on.
--
--* Defaults not to print inlined frames. Use [-i](llvm-symbolizer-opt-i)
--  to show inlined frames for a source code location in an inlined function.
--
--* Uses [--output-style=GNU](llvm-symbolizer-opt-output-style) by default.
--
--## SEE ALSO
--
--Refer to [llvm-symbolizer](llvm-symbolizer) for additional information.
-diff --git a/llvm/docs/CommandGuide/llvm-addr2line.rst b/llvm/docs/CommandGuide/llvm-addr2line.rst
-new file mode 100644
-index 0000000..08f1b69
---- /dev/null
-+++ b/llvm/docs/CommandGuide/llvm-addr2line.rst
-@@ -0,0 +1,38 @@
-+llvm-addr2line - a drop-in replacement for addr2line
-+====================================================
-+
-+.. program:: llvm-addr2line
-+
-+SYNOPSIS
-+--------
-+
-+:program:`llvm-addr2line` [*options*]
-+
-+DESCRIPTION
-+-----------
-+
-+:program:`llvm-addr2line` is an alias for the :manpage:`llvm-symbolizer(1)`
-+tool with different defaults. The goal is to make it a drop-in replacement for
-+GNU's :program:`addr2line`.
-+
-+Here are some of those differences:
-+
-+-  Defaults not to print function names. Use `-f`_ to enable that.
-+
-+-  Defaults not to demangle function names. Use `-C`_ to switch the
-+   demangling on.
-+
-+-  Defaults not to print inlined frames. Use `-i`_ to show inlined
-+   frames for a source code location in an inlined function.
-+
-+-  Uses `--output-style=GNU`_ by default.
-+
-+SEE ALSO
-+--------
-+
-+:manpage:`llvm-symbolizer(1)`
-+
-+.. _-f: llvm-symbolizer.html#llvm-symbolizer-opt-f
-+.. _-C: llvm-symbolizer.html#llvm-symbolizer-opt-c
-+.. _-i: llvm-symbolizer.html#llvm-symbolizer-opt-i
-+.. _--output-style=GNU: llvm-symbolizer.html#llvm-symbolizer-opt-output-style
-diff --git a/llvm/docs/CommandGuide/llvm-ranlib.md b/llvm/docs/CommandGuide/llvm-ranlib.md
-deleted file mode 100644
-index 4377364..0000000
---- a/llvm/docs/CommandGuide/llvm-ranlib.md
-+++ /dev/null
-@@ -1,17 +0,0 @@
--# llvm-ranlib - generates an archive index
--
--## SYNOPSIS
--
--**llvm-ranlib** [*options*]
--
--## DESCRIPTION
--
--**llvm-ranlib** is an alias for the [llvm-ar](llvm-ar.html) tool that generates
--an index for an archive. It can be used as a replacement for GNU's **ranlib**
--tool.
--
--Running **llvm-ranlib** is equivalent to running **llvm-ar s**.
--
--## SEE ALSO
--
--Refer to [llvm-ar](llvm-ar.html) for additional information.
-diff --git a/llvm/docs/CommandGuide/llvm-ranlib.rst b/llvm/docs/CommandGuide/llvm-ranlib.rst
-new file mode 100644
-index 0000000..314a330
---- /dev/null
-+++ b/llvm/docs/CommandGuide/llvm-ranlib.rst
-@@ -0,0 +1,23 @@
-+llvm-ranlib - generates an archive index
-+========================================
-+
-+.. program:: llvm-ranlib
-+
-+SYNOPSIS
-+--------
-+
-+:program:`llvm-ranlib` [*options*]
-+
-+DESCRIPTION
-+-----------
-+
-+:program:`llvm-ranlib` is an alias for the :doc:`llvm-ar <llvm-ar>` tool that
-+generates an index for an archive. It can be used as a replacement for GNU’s
-+:program:`ranlib` tool.
-+
-+Running :program:`llvm-ranlib` is equivalent to running ``llvm-ar s``.
-+
-+SEE ALSO
-+--------
-+
-+:manpage:`llvm-ar(1)`
-diff --git a/llvm/docs/CommandGuide/llvm-size.md b/llvm/docs/CommandGuide/llvm-size.md
-deleted file mode 100644
-index 3952708..0000000
---- a/llvm/docs/CommandGuide/llvm-size.md
-+++ /dev/null
-@@ -1,10 +0,0 @@
--# llvm-size - print segment sizes
--
--## SYNOPSIS
--
--**llvm-size** [*options*]
--
--## DESCRIPTION
--
--**llvm-size** is a tool that prints segment sizes in object files. The goal is
--to make it a drop-in replacement for GNU's **size**.
-diff --git a/llvm/docs/CommandGuide/llvm-size.rst b/llvm/docs/CommandGuide/llvm-size.rst
-new file mode 100644
-index 0000000..0dce15c
---- /dev/null
-+++ b/llvm/docs/CommandGuide/llvm-size.rst
-@@ -0,0 +1,15 @@
-+llvm-size - print size information
-+==================================
-+
-+.. program:: llvm-size
-+
-+SYNOPSIS
-+--------
-+
-+:program:`llvm-size` [*options*]
-+
-+DESCRIPTION
-+-----------
-+
-+:program:`llvm-size` is a tool that prints size information for object files.
-+The goal is to make it a drop-in replacement for GNU’s :program:`size`.
-diff --git a/llvm/docs/CommandGuide/llvm-strings.md b/llvm/docs/CommandGuide/llvm-strings.md
-deleted file mode 100644
-index b5871c4..0000000
---- a/llvm/docs/CommandGuide/llvm-strings.md
-+++ /dev/null
-@@ -1,10 +0,0 @@
--# llvm-strings - print strings
--
--## SYNOPSIS
--
--**llvm-strings** [*options*]
--
--## DESCRIPTION
--
--**llvm-strings** is a tool that prints strings in object files. The goal is to
--make it a drop-in replacement for GNU's **size**.
-diff --git a/llvm/docs/CommandGuide/llvm-strings.rst b/llvm/docs/CommandGuide/llvm-strings.rst
-new file mode 100644
-index 0000000..d8ab9cb
---- /dev/null
-+++ b/llvm/docs/CommandGuide/llvm-strings.rst
-@@ -0,0 +1,15 @@
-+llvm-strings - print strings
-+============================
-+
-+.. program:: llvm-strings
-+
-+SYNOPSIS
-+--------
-+
-+:program:`llvm-strings` [*options*]
-+
-+DESCRIPTION
-+-----------
-+
-+:program:`llvm-strings` is a tool that prints strings in files. The goal is to
-+make it a drop-in replacement for GNU’s :program:`strings`.
--- 
-1.8.3.1
-
diff --git a/SOURCES/bab5908df544680ada0a3cf431f55aeccfbdb321.patch b/SOURCES/bab5908df544680ada0a3cf431f55aeccfbdb321.patch
new file mode 100644
index 0000000..2a93e6a
--- /dev/null
+++ b/SOURCES/bab5908df544680ada0a3cf431f55aeccfbdb321.patch
@@ -0,0 +1,23 @@
+From bab5908df544680ada0a3cf431f55aeccfbdb321 Mon Sep 17 00:00:00 2001
+From: serge-sans-paille <sguelton@redhat.com>
+Date: Mon, 13 Apr 2020 13:44:15 +0200
+Subject: [PATCH] Normalize working directory when running llvm-mc in test
+
+Otherwise, depending on the lit location used to run the test, llvm-mc adds an
+include_directories entry in the dwarf output, which breaks tests in some setup.
+
+Differential Revision: https://reviews.llvm.org/D77876
+---
+ llvm/test/MC/MachO/gen-dwarf.s | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/llvm/test/MC/MachO/gen-dwarf.s b/llvm/test/MC/MachO/gen-dwarf.s
+index 0813856d625f..6d39d278e818 100644
+--- a/llvm/test/MC/MachO/gen-dwarf.s
++++ b/llvm/test/MC/MachO/gen-dwarf.s
+@@ -1,4 +1,4 @@
+-// RUN: llvm-mc -g -triple i386-apple-darwin10 %s -filetype=obj -o %t
++// RUN: mkdir -p %t0 && cd %t0 && llvm-mc -g -triple i386-apple-darwin10 %s -filetype=obj -o %t
+ // RUN: llvm-dwarfdump -all %t | FileCheck %s
+ 
+ .globl _bar
diff --git a/SOURCES/hans-gpg-key.asc b/SOURCES/hans-gpg-key.asc
new file mode 100644
index 0000000..2cf5255
--- /dev/null
+++ b/SOURCES/hans-gpg-key.asc
@@ -0,0 +1,7 @@
+<html>
+<head><title>404 Not Found</title></head>
+<body bgcolor="white">
+<center><h1>404 Not Found</h1></center>
+<hr><center>nginx/1.4.6 (Ubuntu)</center>
+</body>
+</html>
diff --git a/SOURCES/llvm-10.0.1.src.tar.xz.sig b/SOURCES/llvm-10.0.1.src.tar.xz.sig
new file mode 100644
index 0000000..d12fe88
Binary files /dev/null and b/SOURCES/llvm-10.0.1.src.tar.xz.sig differ
diff --git a/SOURCES/run-lit-tests b/SOURCES/run-lit-tests
index aed8165..11fc0f4 100755
--- a/SOURCES/run-lit-tests
+++ b/SOURCES/run-lit-tests
@@ -49,16 +49,10 @@ esac
 cd $(mktemp -d)
 ln -s /usr/include include
 tar -xzf /usr/share/llvm/src/test.tar.gz
-ln -s $ARCH.site.cfg.py test/lit.site.cfg.py
-ln -s $ARCH.site.cfg.py test/Unit/lit.site.cfg.py
-
-# llvm_obj_root is used to determine the directory the tests will run in.
-# test/MC/MachO/gen-dwarf.s fails if llvm_obj_root is a parent directory
-# of the source file.  To workaround this, we set llvm_obj_root to a
-# different directory than the one used to store the test sources.
-# This also matches better how tests are run from the llvm source tree.
+ln -s /usr/share/llvm/src/$ARCH.site.cfg.py test/lit.site.cfg.py
+ln -s /usr/share/llvm/src/$ARCH.Unit.site.cfg.py test/Unit/lit.site.cfg.py
 lit -v -s $threads_arg test \
-	-Dllvm_obj_root=$(mktemp -d) \
+	-Dllvm_obj_root=`pwd` \
 	-Dllvm_test_root=`pwd`/test \
 	-Dllvm_unittest_bindir=$LIB_DIR/llvm \
 	-Dllvm_shlib_dir=$LIB_DIR
diff --git a/SPECS/llvm.spec b/SPECS/llvm.spec
index be23b16..c5843c0 100644
--- a/SPECS/llvm.spec
+++ b/SPECS/llvm.spec
@@ -10,12 +10,12 @@
 
 %global llvm_libdir %{_libdir}/%{name}
 %global build_llvm_libdir %{buildroot}%{llvm_libdir}
-%global maj_ver 9
+#%%global rc_ver 6
+%global baserelease 3
+%global llvm_srcdir llvm-%{version}%{?rc_ver:rc%{rc_ver}}.src
+%global maj_ver 10
 %global min_ver 0
 %global patch_ver 1
-#%%global rc_ver 3
-%global baserelease 5
-
 
 %if %{with compat_build}
 %global pkg_name llvm%{maj_ver}.%{min_ver}
@@ -50,34 +50,36 @@ Summary:	The Low Level Virtual Machine
 
 License:	NCSA
 URL:		http://llvm.org
-Source0:	http://%{?rc_ver:pre}releases.llvm.org/%{version}/%{?rc_ver:rc%{rc_ver}}/llvm-%{version}%{?rc_ver:rc%{rc_ver}}.src.tar.xz
+%if 0%{?rc_ver:1}
+Source0:	https://prereleases.llvm.org/%{version}/rc%{rc_ver}/%{llvm_srcdir}.tar.xz
+Source3:	https://prereleases.llvm.org/%{version}/rc%{rc_ver}/%{llvm_srcdir}.tar.xz.sig
+%else
+Source0:	https://github.com/llvm/llvm-project/releases/download/llvmorg-%{version}/%{llvm_srcdir}.tar.xz
+Source3:	https://github.com/llvm/llvm-project/releases/download/llvmorg-%{version}/%{llvm_srcdir}.tar.xz.sig
+%endif
 %if %{without compat_build}
 Source1:	run-lit-tests
 Source2:	lit.fedora.cfg.py
 %endif
+Source4:	https://prereleases.llvm.org/%{version}/hans-gpg-key.asc
 
-Patch0:		0001-Filter-out-cxxflags-not-supported-by-clang.patch
-# TODO: I'm not sure why this is needed.  Could be a change in newer version
-# of gold.
-Patch1:		0001-Pass-target-to-gold-linker-to-avoid-faliures-on-i686.patch
+##Patch0:		0001-Filter-out-cxxflags-not-supported-by-clang.patch
 Patch2:		0001-CMake-Split-static-library-exports-into-their-own-ex.patch
 Patch3:		0001-CMake-Split-test-binary-exports-into-their-own-expor.patch
+Patch4:		bab5908df544680ada0a3cf431f55aeccfbdb321.patch
+Patch5:		0001-PowerPC-PPCBoolRetToInt-Skip-translation-if-there-is.patch
 
 # RHEL-specific patches.
 Patch101:	0001-Deactivate-markdown-doc.patch
 # Patches to convert md files to rst since we don't have the md parser in RHEL.
-Patch102:	0001-Docs-llvm-strip-Add-help-text-to-llvm-strip-rst-doc.patch
-Patch103:	0001-docs-Convert-remaining-command-guide-entries-from-md.patch
-
-# Fix crash in kernel bpf self-tests
-Patch5: 0001-BPF-Handling-type-conversions-correctly-for-CO-RE.patch
-Patch6: 0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch
-
-# Fix Rust codegen bug, https://github.com/rust-lang/rust/issues/69225
-Patch7:	0001-Revert-SCEV-add-no-wrap-flag-for-SCEVAddExpr.patch
-
-# Fix big-endian miscompilation in rustc, rhbz#1837660
-Patch8:	0001-InstCombine-Fix-big-endian-miscompile-of-bitcast-zex.patch
+#Patch102:	0001-Docs-llvm-strip-Add-help-text-to-llvm-strip-rst-doc.patch
+#Patch103:	0001-docs-Convert-remaining-command-guide-entries-from-md.patch
+### Fix crash in kernel bpf self-tests
+##Patch5: 0001-BPF-Handling-type-conversions-correctly-for-CO-RE.patch
+##Patch6: 0001-BPF-annotate-DIType-metadata-for-builtin-preseve_arr.patch
+##
+### Fix Rust codegen bug, https://github.com/rust-lang/rust/issues/69225
+##Patch7:	0001-Revert-SCEV-add-no-wrap-flag-for-SCEVAddExpr.patch
 
 BuildRequires:	gcc
 BuildRequires:	gcc-c++
@@ -89,6 +91,8 @@ BuildRequires:	ncurses-devel
 BuildRequires:	python3-sphinx
 %if !0%{?rhel}
 BuildRequires:	python3-recommonmark
+%else
+BuildRequires:	pandoc
 %endif
 BuildRequires:	multilib-rpm-config
 %if %{with gold}
@@ -184,12 +188,16 @@ LLVM's modified googletest sources.
 %endif
 
 %prep
-%autosetup -n llvm-%{version}%{?rc_ver:rc%{rc_ver}}.src -p2
+%autosetup -n %{llvm_srcdir} -p2
 
 pathfix.py -i %{__python3} -pn \
 	test/BugPoint/compile-custom.ll.py \
 	tools/opt-viewer/*.py
 
+# Convert markdown files to rst to cope with the absence of recommonmark in rhel.
+# The sed expression takes care of a slight difference between pandoc markdown and sphinx markdown.
+find -name '*.md' | while read md; do sed -r -e 's/^( )*\* /\n\1\* /' ${md} | pandoc -f markdown -o ${md%.md}.rst  ; done
+
 %build
 mkdir -p _build
 cd _build
@@ -263,6 +271,7 @@ cd _build
 	-DLLVM_INSTALL_TOOLCHAIN_ONLY:BOOL=OFF \
 	\
 	-DSPHINX_WARNINGS_AS_ERRORS=OFF \
+	-DCMAKE_INSTALL_PREFIX=%{install_prefix} \
 	-DLLVM_INSTALL_SPHINX_HTML_DIR=%{_pkgdocdir}/html \
 	-DSPHINX_EXECUTABLE=%{_bindir}/sphinx-build-3
 
@@ -280,6 +289,9 @@ cd _build
 mkdir -p %{buildroot}/%{_bindir}
 mv %{buildroot}/%{_bindir}/llvm-config %{buildroot}/%{_bindir}/llvm-config-%{__isa_bits}
 
+# ghost presence
+touch %{buildroot}%{_bindir}/llvm-config
+
 # Fix some man pages
 ln -s llvm-config.1 %{buildroot}%{_mandir}/man1/llvm-config-%{__isa_bits}.1
 mv %{buildroot}%{_mandir}/man1/tblgen.1 %{buildroot}%{_mandir}/man1/llvm-tblgen.1
@@ -292,6 +304,8 @@ do
     install -m 0755 ./_build/bin/$f %{buildroot}%{_bindir}
 done
 
+# Remove testing of update utility tools
+rm -rf test/tools/UpdateTestChecks
 
 %multilib_fix_c_header --file %{_includedir}/llvm/Config/llvm-config.h
 
@@ -333,7 +347,12 @@ install -m 0755 %{SOURCE1} %{buildroot}%{_libexecdir}/tests/llvm
 # Install lit tests.  We need to put these in a tarball otherwise rpm will complain
 # about some of the test inputs having the wrong object file format.
 install -d %{buildroot}%{_datadir}/llvm/
-tar -czf %{install_srcdir}/test.tar.gz test/
+
+# The various tar options are there to make sur the archive is the same on 32 and 64 bit arch, i.e.
+# the archive creation is reproducible. Move arch-specific content out of the tarball
+mv %{lit_cfg} %{install_srcdir}/%{_arch}.site.cfg.py
+mv %{lit_unit_cfg} %{install_srcdir}/%{_arch}.Unit.site.cfg.py
+tar --sort=name --mtime='UTC 2020-01-01' -c test/ | gzip -n > %{install_srcdir}/test.tar.gz
 
 # Install the unit test binaries
 mkdir -p %{build_llvm_libdir}
@@ -355,7 +374,7 @@ cp -R unittests/DebugInfo/PDB/Inputs %{buildroot}%{_datadir}/llvm/src/unittests/
 mkdir -p %{buildroot}/%{_bindir}
 for f in %{buildroot}/%{install_bindir}/*; do
   filename=`basename $f`
-  ln -s %{install_bindir}/$filename %{buildroot}/%{_bindir}/$filename%{exec_suffix}
+  ln -s ../../../%{install_bindir}/$filename %{buildroot}/%{_bindir}/$filename%{exec_suffix}
 done
 
 # Move header files
@@ -375,7 +394,7 @@ EOF
 
 # Add version suffix to man pages and move them to mandir.
 mkdir -p %{buildroot}/%{_mandir}/man1
-for f in `ls %{build_install_prefix}/share/man/man1/*`; do
+for f in %{build_install_prefix}/share/man/man1/*; do
   filename=`basename $f | cut -f 1 -d '.'`
   mv $f %{buildroot}%{_mandir}/man1/$filename%{exec_suffix}.1
 done
@@ -404,7 +423,7 @@ ninja check-all -C _build || \
 
 %postun devel
 if [ $1 -eq 0 ]; then
-  %{_sbindir}/update-alternatives --remove llvm-config %{_bindir}/llvm-config
+  %{_sbindir}/update-alternatives --remove llvm-config %{_bindir}/llvm-config-%{__isa_bits}
 fi
 
 %endif
@@ -415,6 +434,7 @@ fi
 %{_bindir}/*
 
 %if %{without compat_build}
+%exclude %{_bindir}/llvm-config
 %exclude %{_bindir}/llvm-config-%{__isa_bits}
 %exclude %{_bindir}/not
 %exclude %{_bindir}/count
@@ -449,6 +469,7 @@ fi
 
 %files devel
 %if %{without compat_build}
+%ghost %{_bindir}/llvm-config
 %{_bindir}/llvm-config-%{__isa_bits}
 %{_mandir}/man1/llvm-config*
 %{_includedir}/llvm
@@ -489,6 +510,8 @@ fi
 %{llvm_libdir}/unittests/
 %{_datadir}/llvm/src/unittests
 %{_datadir}/llvm/src/test.tar.gz
+%{_datadir}/llvm/src/%{_arch}.site.cfg.py
+%{_datadir}/llvm/src/%{_arch}.Unit.site.cfg.py
 %{_datadir}/llvm/lit.fedora.cfg.py
 %{_bindir}/not
 %{_bindir}/count
@@ -507,8 +530,20 @@ fi
 %endif
 
 %changelog
-* Tue May 26 2020 Josh Stone <jistone@redhat.com> - 9.0.1-5
-- Fix big-endian miscompilation in rustc, rhbz#1840304
+* Wed Aug 19 2020 Tom Stellard <tstellar@redhat.com> - 10.0.1-3
+- Fix rust crash on ppc64le compiling firefox
+
+* Fri Jul 31 2020 sguelton@redhat.com - 10.0.1-2
+- Fix llvm-config alternative handling, see rhbz#1859996
+
+* Fri Jul 24 2020 sguelton@redhat.com - 10.0.1-1
+- 10.0.1 Release
+
+* Wed Jun 24 2020 sguelton@redhat.com - 10.0.0-2
+- Reproducible build of test.tar.gz, see rhbz#1820319
+
+* Tue Apr 7 2020 sguelton@redhat.com - 10.0.0-1
+- 10.0.0 Release
 
 * Thu Feb 27 2020 Josh Stone <jistone@redhat.com> - 9.0.1-4
 - Fix a codegen bug for Rust