Update prebuilt Clang to r416183b from Android.

https://android.googlesource.com/platform/prebuilts/clang/host/
linux-x86/+/06a71ddac05c22edb2d10b590e1769b3f8619bef

clang 12.0.5 (based on r416183b) from build 7284624.

Change-Id: I277a316abcf47307562d8b748b84870f31a72866
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
diff --git a/linux-x64/clang/include/llvm/Analysis/MemoryLocation.h b/linux-x64/clang/include/llvm/Analysis/MemoryLocation.h
index 7c26353..3b188d7 100644
--- a/linux-x64/clang/include/llvm/Analysis/MemoryLocation.h
+++ b/linux-x64/clang/include/llvm/Analysis/MemoryLocation.h
@@ -17,20 +17,25 @@
 
 #include "llvm/ADT/DenseMapInfo.h"
 #include "llvm/ADT/Optional.h"
-#include "llvm/IR/Instructions.h"
 #include "llvm/IR/Metadata.h"
+#include "llvm/Support/TypeSize.h"
 
 namespace llvm {
 
+class CallBase;
+class Instruction;
 class LoadInst;
 class StoreInst;
 class MemTransferInst;
 class MemIntrinsic;
+class AtomicCmpXchgInst;
 class AtomicMemTransferInst;
 class AtomicMemIntrinsic;
+class AtomicRMWInst;
 class AnyMemTransferInst;
 class AnyMemIntrinsic;
 class TargetLibraryInfo;
+class VAArgInst;
 
 // Represents the size of a MemoryLocation. Logically, it's an
 // Optional<uint63_t> that also carries a bit to represent whether the integer
@@ -59,10 +64,11 @@
 // None.
 class LocationSize {
   enum : uint64_t {
-    Unknown = ~uint64_t(0),
+    BeforeOrAfterPointer = ~uint64_t(0),
+    AfterPointer = BeforeOrAfterPointer - 1,
+    MapEmpty = BeforeOrAfterPointer - 2,
+    MapTombstone = BeforeOrAfterPointer - 3,
     ImpreciseBit = uint64_t(1) << 63,
-    MapEmpty = Unknown - 1,
-    MapTombstone = Unknown - 2,
 
     // The maximum value we can represent without falling back to 'unknown'.
     MaxValue = (MapTombstone - 1) & ~ImpreciseBit,
@@ -76,7 +82,11 @@
 
   constexpr LocationSize(uint64_t Raw, DirectConstruction): Value(Raw) {}
 
-  static_assert(Unknown & ImpreciseBit, "Unknown is imprecise by definition.");
+  static_assert(AfterPointer & ImpreciseBit,
+                "AfterPointer is imprecise by definition.");
+  static_assert(BeforeOrAfterPointer & ImpreciseBit,
+                "BeforeOrAfterPointer is imprecise by definition.");
+
 public:
   // FIXME: Migrate all users to construct via either `precise` or `upperBound`,
   // to make it more obvious at the callsite the kind of size that they're
@@ -85,21 +95,39 @@
   // Since the overwhelming majority of users of this provide precise values,
   // this assumes the provided value is precise.
   constexpr LocationSize(uint64_t Raw)
-      : Value(Raw > MaxValue ? Unknown : Raw) {}
+      : Value(Raw > MaxValue ? AfterPointer : Raw) {}
 
   static LocationSize precise(uint64_t Value) { return LocationSize(Value); }
+  static LocationSize precise(TypeSize Value) {
+    if (Value.isScalable())
+      return afterPointer();
+    return precise(Value.getFixedSize());
+  }
 
   static LocationSize upperBound(uint64_t Value) {
     // You can't go lower than 0, so give a precise result.
     if (LLVM_UNLIKELY(Value == 0))
       return precise(0);
     if (LLVM_UNLIKELY(Value > MaxValue))
-      return unknown();
+      return afterPointer();
     return LocationSize(Value | ImpreciseBit, Direct);
   }
+  static LocationSize upperBound(TypeSize Value) {
+    if (Value.isScalable())
+      return afterPointer();
+    return upperBound(Value.getFixedSize());
+  }
 
-  constexpr static LocationSize unknown() {
-    return LocationSize(Unknown, Direct);
+  /// Any location after the base pointer (but still within the underlying
+  /// object).
+  constexpr static LocationSize afterPointer() {
+    return LocationSize(AfterPointer, Direct);
+  }
+
+  /// Any location before or after the base pointer (but still within the
+  /// underlying object).
+  constexpr static LocationSize beforeOrAfterPointer() {
+    return LocationSize(BeforeOrAfterPointer, Direct);
   }
 
   // Sentinel values, generally used for maps.
@@ -116,20 +144,24 @@
     if (Other == *this)
       return *this;
 
-    if (!hasValue() || !Other.hasValue())
-      return unknown();
+    if (Value == BeforeOrAfterPointer || Other.Value == BeforeOrAfterPointer)
+      return beforeOrAfterPointer();
+    if (Value == AfterPointer || Other.Value == AfterPointer)
+      return afterPointer();
 
     return upperBound(std::max(getValue(), Other.getValue()));
   }
 
-  bool hasValue() const { return Value != Unknown; }
+  bool hasValue() const {
+    return Value != AfterPointer && Value != BeforeOrAfterPointer;
+  }
   uint64_t getValue() const {
     assert(hasValue() && "Getting value from an unknown LocationSize!");
     return Value & ~ImpreciseBit;
   }
 
   // Returns whether or not this value is precise. Note that if a value is
-  // precise, it's guaranteed to not be `unknown()`.
+  // precise, it's guaranteed to not be unknown.
   bool isPrecise() const {
     return (Value & ImpreciseBit) == 0;
   }
@@ -137,6 +169,9 @@
   // Convenience method to check if this LocationSize's value is 0.
   bool isZero() const { return hasValue() && getValue() == 0; }
 
+  /// Whether accesses before the base pointer are possible.
+  bool mayBeBeforePointer() const { return Value == BeforeOrAfterPointer; }
+
   bool operator==(const LocationSize &Other) const {
     return Value == Other.Value;
   }
@@ -194,6 +229,8 @@
   /// member is null if that kind of information is unavailable).
   AAMDNodes AATags;
 
+  void print(raw_ostream &OS) const { OS << *Ptr << " " << Size << "\n"; }
+
   /// Return a location with information about the memory reference by the given
   /// instruction.
   static MemoryLocation get(const LoadInst *LI);
@@ -204,22 +241,7 @@
   static MemoryLocation get(const Instruction *Inst) {
     return *MemoryLocation::getOrNone(Inst);
   }
-  static Optional<MemoryLocation> getOrNone(const Instruction *Inst) {
-    switch (Inst->getOpcode()) {
-    case Instruction::Load:
-      return get(cast<LoadInst>(Inst));
-    case Instruction::Store:
-      return get(cast<StoreInst>(Inst));
-    case Instruction::VAArg:
-      return get(cast<VAArgInst>(Inst));
-    case Instruction::AtomicCmpXchg:
-      return get(cast<AtomicCmpXchgInst>(Inst));
-    case Instruction::AtomicRMW:
-      return get(cast<AtomicRMWInst>(Inst));
-    default:
-      return None;
-    }
-  }
+  static Optional<MemoryLocation> getOrNone(const Instruction *Inst);
 
   /// Return a location representing the source of a memory transfer.
   static MemoryLocation getForSource(const MemTransferInst *MTI);
@@ -240,8 +262,30 @@
     return getForArgument(Call, ArgIdx, &TLI);
   }
 
-  explicit MemoryLocation(const Value *Ptr = nullptr,
-                          LocationSize Size = LocationSize::unknown(),
+  /// Return a location that may access any location after Ptr, while remaining
+  /// within the underlying object.
+  static MemoryLocation getAfter(const Value *Ptr,
+                                 const AAMDNodes &AATags = AAMDNodes()) {
+    return MemoryLocation(Ptr, LocationSize::afterPointer(), AATags);
+  }
+
+  /// Return a location that may access any location before or after Ptr, while
+  /// remaining within the underlying object.
+  static MemoryLocation
+  getBeforeOrAfter(const Value *Ptr, const AAMDNodes &AATags = AAMDNodes()) {
+    return MemoryLocation(Ptr, LocationSize::beforeOrAfterPointer(), AATags);
+  }
+
+  // Return the exact size if the exact size is known at compiletime,
+  // otherwise return MemoryLocation::UnknownSize.
+  static uint64_t getSizeOrUnknown(const TypeSize &T) {
+    return T.isScalable() ? UnknownSize : T.getFixedSize();
+  }
+
+  MemoryLocation()
+      : Ptr(nullptr), Size(LocationSize::beforeOrAfterPointer()), AATags() {}
+
+  explicit MemoryLocation(const Value *Ptr, LocationSize Size,
                           const AAMDNodes &AATags = AAMDNodes())
       : Ptr(Ptr), Size(Size), AATags(AATags) {}