[clang] Resign function pointer (PR #98847)

Akira Hatanaka via cfe-commits cfe-commits at lists.llvm.org
Sun Jul 14 17:20:45 PDT 2024


https://github.com/ahatanak updated https://github.com/llvm/llvm-project/pull/98847

>From 938d8f030a12a18c1a316aaa8dbc5c24a2c69296 Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha <ahmed at bougacha.org>
Date: Mon, 27 Sep 2021 08:00:00 -0700
Subject: [PATCH 1/4] [clang][CodeGen] Teach RawAddress/Address about ptrauth.

---
 clang/lib/CodeGen/Address.h       | 43 ++++++++++++++++++++++++++---
 clang/lib/CodeGen/CGBlocks.cpp    |  4 +--
 clang/lib/CodeGen/CGBuilder.h     | 46 ++++++++++++++++++++++---------
 clang/lib/CodeGen/CGCall.cpp      | 13 +++++----
 clang/lib/CodeGen/CGException.cpp |  4 +--
 clang/lib/CodeGen/CGObjCMac.cpp   |  2 +-
 6 files changed, 85 insertions(+), 27 deletions(-)

diff --git a/clang/lib/CodeGen/Address.h b/clang/lib/CodeGen/Address.h
index 35ec370a139c9..3b677c9159e22 100644
--- a/clang/lib/CodeGen/Address.h
+++ b/clang/lib/CodeGen/Address.h
@@ -108,6 +108,22 @@ class RawAddress {
 
 /// Like RawAddress, an abstract representation of an aligned address, but the
 /// pointer contained in this class is possibly signed.
+///
+/// This is designed to be an IR-level abstraction, carrying just the
+/// information necessary to perform IR operations on an address like loads and
+/// stores.  In particular, it doesn't carry C type information or allow the
+/// representation of things like bit-fields; clients working at that level
+/// should generally be using `LValue`.
+///
+/// An address may be either *raw*, meaning that it's an ordinary machine
+/// pointer, or *signed*, meaning that the pointer carries an embedded
+/// pointer-authentication signature. Representing signed pointers directly in
+/// this abstraction allows the authentication to be delayed as long as possible
+/// without forcing IRGen to use totally different code paths for signed and
+/// unsigned values or to separately propagate signature information through
+/// every API that manipulates addresses. Pointer arithmetic on signed addresses
+/// (e.g. drilling down to a struct field) is accumulated into a separate offset
+/// which is applied when the address is finally accessed.
 class Address {
   friend class CGBuilderTy;
 
@@ -117,6 +133,10 @@ class Address {
   /// The expected IR type of the pointer. Carrying accurate element type
   /// information in Address makes it more convenient to work with Address
   /// values and allows frontend assertions to catch simple mistakes.
+  ///
+  /// When the address is a raw pointer, this is currently redundant with the
+  /// pointer's type, but for signed pointers it is useful if the pointer has
+  /// been offsetted or cast from the original type.
   llvm::Type *ElementType = nullptr;
 
   CharUnits Alignment;
@@ -153,6 +173,11 @@ class Address {
   static Address invalid() { return Address(nullptr); }
   bool isValid() const { return Pointer.getPointer() != nullptr; }
 
+  llvm::Value *getPointerIfNotSigned() const {
+    assert(isValid() && "pointer isn't valid");
+    return Pointer.getPointer();
+  }
+
   /// This function is used in situations where the caller is doing some sort of
   /// opaque "laundering" of the pointer.
   void replaceBasePointer(llvm::Value *P) {
@@ -172,6 +197,8 @@ class Address {
     return Pointer.getPointer();
   }
 
+  llvm::Value *getUnsignedPointer() const { return getBasePointer(); }
+
   /// Return the type of the pointer value.
   llvm::PointerType *getType() const {
     return llvm::PointerType::get(
@@ -211,6 +238,14 @@ class Address {
     return *this;
   }
 
+  /// Add a constant offset.
+  void addOffset(CharUnits V, llvm::Type *Ty, CGBuilderTy &Builder);
+
+  /// Add a variable offset.
+  /// \param V An llvm value holding a variable offset.
+  void addOffset(llvm::Value *V, llvm::Type *Ty, CGBuilderTy &Builder,
+                 CharUnits NewAlignment);
+
   bool hasOffset() const { return Offset; }
 
   llvm::Value *getOffset() const { return Offset; }
@@ -218,7 +253,7 @@ class Address {
   /// Return the pointer contained in this class after authenticating it and
   /// adding offset to it if necessary.
   llvm::Value *emitRawPointer(CodeGenFunction &CGF) const {
-    return getBasePointer();
+    return getUnsignedPointer();
   }
 
   /// Return address with different pointer, but same element type and
@@ -249,9 +284,9 @@ class Address {
 };
 
 inline RawAddress::RawAddress(Address Addr)
-    : PointerAndKnownNonNull(Addr.isValid() ? Addr.getBasePointer() : nullptr,
-                             Addr.isValid() ? Addr.isKnownNonNull()
-                                            : NotKnownNonNull),
+    : PointerAndKnownNonNull(
+          Addr.isValid() ? Addr.getUnsignedPointer() : nullptr,
+          Addr.isValid() ? Addr.isKnownNonNull() : NotKnownNonNull),
       ElementType(Addr.isValid() ? Addr.getElementType() : nullptr),
       Alignment(Addr.isValid() ? Addr.getAlignment() : CharUnits::Zero()) {}
 
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 066139b1c78c7..2affd93c6b9a2 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -1974,8 +1974,8 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
         // it. It's not quite worth the annoyance to avoid creating it in the
         // first place.
         if (!needsEHCleanup(captureType.isDestructedType()))
-          if (auto *I =
-                  cast_or_null<llvm::Instruction>(dstField.getBasePointer()))
+          if (auto *I = cast_or_null<llvm::Instruction>(
+                  dstField.getPointerIfNotSigned()))
             I->eraseFromParent();
       }
       break;
diff --git a/clang/lib/CodeGen/CGBuilder.h b/clang/lib/CodeGen/CGBuilder.h
index 0bc4fda62979c..752bfc6c0c058 100644
--- a/clang/lib/CodeGen/CGBuilder.h
+++ b/clang/lib/CodeGen/CGBuilder.h
@@ -15,6 +15,7 @@
 #include "llvm/Analysis/Utils/Local.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Module.h"
 #include "llvm/IR/Type.h"
 
 namespace clang {
@@ -56,7 +57,24 @@ class CGBuilderTy : public CGBuilderBaseTy {
   CodeGenFunction *getCGF() const { return getInserter().CGF; }
 
   llvm::Value *emitRawPointerFromAddress(Address Addr) const {
-    return Addr.getBasePointer();
+    return Addr.getUnsignedPointer();
+  }
+
+  /// Helper function to compute a GEP's offset and add it to Addr.
+  Address addGEPOffset(Address Addr, ArrayRef<llvm::Value *> IdxList,
+                       CharUnits Align, bool IsInBounds, const Twine &Name) {
+    typedef ArrayRef<llvm::Value *>::const_iterator IdxItTy;
+    typedef llvm::generic_gep_type_iterator<IdxItTy> GEPTypeIt;
+    const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
+    GEPTypeIt GTI = GEPTypeIt::begin(Addr.getElementType(), IdxList.begin());
+    IdxItTy IdxBegin = IdxList.begin(), IdxEnd = IdxList.end();
+    llvm::Type *GEPType = Addr.getType();
+    SmallString<12> Buffer;
+    StringRef GEPName = Name.toStringRef(Buffer);
+    std::pair<llvm::Value *, llvm::Type *> OffsetAndType = llvm::EmitGEPOffset(
+        this, DL, GTI, IdxBegin, IdxEnd, GEPType, GEPName, IsInBounds, false);
+    Addr.addOffset(OffsetAndType.first, OffsetAndType.second, *this, Align);
+    return Addr;
   }
 
   template <bool IsInBounds>
@@ -222,8 +240,8 @@ class CGBuilderTy : public CGBuilderBaseTy {
     const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
     auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
 
-    return Address(CreateStructGEP(Addr.getElementType(), Addr.getBasePointer(),
-                                   Index, Name),
+    return Address(CreateStructGEP(Addr.getElementType(),
+                                   Addr.getUnsignedPointer(), Index, Name),
                    ElTy->getElementType(Index),
                    Addr.getAlignment().alignmentAtOffset(Offset),
                    Addr.isKnownNonNull());
@@ -245,7 +263,7 @@ class CGBuilderTy : public CGBuilderBaseTy {
         CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy->getElementType()));
 
     return Address(
-        CreateInBoundsGEP(Addr.getElementType(), Addr.getBasePointer(),
+        CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
                           {getSize(CharUnits::Zero()), getSize(Index)}, Name),
         ElTy->getElementType(),
         Addr.getAlignment().alignmentAtOffset(Index * EltSize),
@@ -263,10 +281,10 @@ class CGBuilderTy : public CGBuilderBaseTy {
     const llvm::DataLayout &DL = BB->getDataLayout();
     CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
 
-    return Address(
-        CreateInBoundsGEP(ElTy, Addr.getBasePointer(), getSize(Index), Name),
-        ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize),
-        Addr.isKnownNonNull());
+    return Address(CreateInBoundsGEP(ElTy, Addr.getUnsignedPointer(),
+                                     getSize(Index), Name),
+                   ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize),
+                   Addr.isKnownNonNull());
   }
 
   /// Given
@@ -280,9 +298,10 @@ class CGBuilderTy : public CGBuilderBaseTy {
     const llvm::DataLayout &DL = BB->getDataLayout();
     CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
 
-    return Address(CreateGEP(ElTy, Addr.getBasePointer(), getSize(Index), Name),
-                   Addr.getElementType(),
-                   Addr.getAlignment().alignmentAtOffset(Index * EltSize));
+    return Address(
+        CreateGEP(ElTy, Addr.getUnsignedPointer(), getSize(Index), Name),
+        Addr.getElementType(),
+        Addr.getAlignment().alignmentAtOffset(Index * EltSize));
   }
 
   /// Create GEP with single dynamic index. The address alignment is reduced
@@ -305,7 +324,7 @@ class CGBuilderTy : public CGBuilderBaseTy {
                                      const llvm::Twine &Name = "") {
     assert(Addr.getElementType() == TypeCache.Int8Ty);
     return Address(
-        CreateInBoundsGEP(Addr.getElementType(), Addr.getBasePointer(),
+        CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
                           getSize(Offset), Name),
         Addr.getElementType(), Addr.getAlignment().alignmentAtOffset(Offset),
         Addr.isKnownNonNull());
@@ -314,7 +333,8 @@ class CGBuilderTy : public CGBuilderBaseTy {
   Address CreateConstByteGEP(Address Addr, CharUnits Offset,
                              const llvm::Twine &Name = "") {
     assert(Addr.getElementType() == TypeCache.Int8Ty);
-    return Address(CreateGEP(Addr.getElementType(), Addr.getBasePointer(),
+
+    return Address(CreateGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
                              getSize(Offset), Name),
                    Addr.getElementType(),
                    Addr.getAlignment().alignmentAtOffset(Offset));
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index a38484941ba24..333771160cabf 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -3508,7 +3508,8 @@ static llvm::Value *tryRemoveRetainOfSelf(CodeGenFunction &CGF,
   llvm::LoadInst *load =
     dyn_cast<llvm::LoadInst>(retainedValue->stripPointerCasts());
   if (!load || load->isAtomic() || load->isVolatile() ||
-      load->getPointerOperand() != CGF.GetAddrOfLocalVar(self).getBasePointer())
+      load->getPointerOperand() !=
+          CGF.GetAddrOfLocalVar(self).getPointerIfNotSigned())
     return nullptr;
 
   // Okay!  Burn it all down.  This relies for correctness on the
@@ -3545,7 +3546,8 @@ static llvm::Value *emitAutoreleaseOfResult(CodeGenFunction &CGF,
 
 /// Heuristically search for a dominating store to the return-value slot.
 static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) {
-  llvm::Value *ReturnValuePtr = CGF.ReturnValue.getBasePointer();
+  // This function shouldn't be called when ReturnValue is signed.
+  llvm::Value *ReturnValuePtr = CGF.ReturnValue.getUnsignedPointer();
 
   // Check if a User is a store which pointerOperand is the ReturnValue.
   // We are looking for stores to the ReturnValue, not for stores of the
@@ -4133,7 +4135,8 @@ static bool isProvablyNull(llvm::Value *addr) {
 }
 
 static bool isProvablyNonNull(Address Addr, CodeGenFunction &CGF) {
-  return llvm::isKnownNonZero(Addr.getBasePointer(), CGF.CGM.getDataLayout());
+  return llvm::isKnownNonZero(Addr.getUnsignedPointer(),
+                              CGF.CGM.getDataLayout());
 }
 
 /// Emit the actual writing-back of a writeback.
@@ -4141,7 +4144,7 @@ static void emitWriteback(CodeGenFunction &CGF,
                           const CallArgList::Writeback &writeback) {
   const LValue &srcLV = writeback.Source;
   Address srcAddr = srcLV.getAddress();
-  assert(!isProvablyNull(srcAddr.getBasePointer()) &&
+  assert(!isProvablyNull(srcAddr.getPointerIfNotSigned()) &&
          "shouldn't have writeback for provably null argument");
 
   llvm::BasicBlock *contBB = nullptr;
@@ -4258,7 +4261,7 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args,
       CGF.ConvertTypeForMem(CRE->getType()->getPointeeType());
 
   // If the address is a constant null, just pass the appropriate null.
-  if (isProvablyNull(srcAddr.getBasePointer())) {
+  if (isProvablyNull(srcAddr.getPointerIfNotSigned())) {
     args.add(RValue::get(llvm::ConstantPointerNull::get(destType)),
              CRE->getType());
     return;
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index bb2ed237ee9f3..2de85963437f5 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -1835,8 +1835,8 @@ Address CodeGenFunction::recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF,
                                                    llvm::Value *ParentFP) {
   llvm::CallInst *RecoverCall = nullptr;
   CGBuilderTy Builder(*this, AllocaInsertPt);
-  if (auto *ParentAlloca =
-          dyn_cast_or_null<llvm::AllocaInst>(ParentVar.getBasePointer())) {
+  if (auto *ParentAlloca = dyn_cast_or_null<llvm::AllocaInst>(
+          ParentVar.getPointerIfNotSigned())) {
     // Mark the variable escaped if nobody else referenced it and compute the
     // localescape index.
     auto InsertPair = ParentCGF.EscapedLocals.insert(
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 30f3911a8b03c..7395370259fe9 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -4425,7 +4425,7 @@ void FragileHazards::emitHazardsInNewBlocks() {
 
 static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, Address V) {
   if (V.isValid())
-    if (llvm::Value *Ptr = V.getBasePointer())
+    if (llvm::Value *Ptr = V.getPointerIfNotSigned())
       S.insert(Ptr);
 }
 

>From a147bcebdd879fec4f7e26339c20ed84dd012136 Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha <ahmed at bougacha.org>
Date: Wed, 15 May 2024 13:37:17 -0700
Subject: [PATCH 2/4] [clang][CodeGen] Set KnownNonNull in more places.

---
 clang/lib/CodeGen/CGExpr.cpp          | 15 ++++++++++----
 clang/lib/CodeGen/CGExprAgg.cpp       |  3 +++
 clang/lib/CodeGen/CGExprCXX.cpp       |  9 +++++----
 clang/lib/CodeGen/CGValue.h           | 10 ++-------
 clang/lib/CodeGen/CodeGenFunction.cpp | 29 ++++++++++++++++++---------
 clang/lib/CodeGen/CodeGenFunction.h   |  4 +++-
 clang/lib/CodeGen/ItaniumCXXABI.cpp   |  2 +-
 7 files changed, 45 insertions(+), 27 deletions(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index ddb82571f53d7..d5c3732a4e270 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1941,6 +1941,9 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
       Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV),
                               NotKnownNonNull);
 
+  if (!CGM.getCodeGenOpts().NullPointerIsValid)
+    Addr = Addr.setKnownNonNull();
+
   if (const auto *ClangVecTy = Ty->getAs<VectorType>()) {
     // Boolean vectors use `iN` as storage type.
     if (ClangVecTy->isExtVectorBoolType()) {
@@ -2090,6 +2093,9 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
       Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV),
                               NotKnownNonNull);
 
+  if (!CGM.getCodeGenOpts().NullPointerIsValid)
+    Addr = Addr.setKnownNonNull();
+
   llvm::Type *SrcTy = Value->getType();
   if (const auto *ClangVecTy = Ty->getAs<VectorType>()) {
     auto *VecTy = dyn_cast<llvm::FixedVectorType>(SrcTy);
@@ -2791,9 +2797,9 @@ CodeGenFunction::EmitLoadOfReference(LValue RefLVal,
   llvm::LoadInst *Load =
       Builder.CreateLoad(RefLVal.getAddress(), RefLVal.isVolatile());
   CGM.DecorateInstructionWithTBAA(Load, RefLVal.getTBAAInfo());
-  return makeNaturalAddressForPointer(Load, RefLVal.getType()->getPointeeType(),
-                                      CharUnits(), /*ForPointeeType=*/true,
-                                      PointeeBaseInfo, PointeeTBAAInfo);
+  return makeNaturalAddressForPointer(
+      Load, RefLVal.getType()->getPointeeType(), CharUnits(),
+      /*ForPointeeType=*/true, PointeeBaseInfo, PointeeTBAAInfo, KnownNonNull);
 }
 
 LValue CodeGenFunction::EmitLoadOfReferenceLValue(LValue RefLVal) {
@@ -4706,7 +4712,8 @@ LValue CodeGenFunction::EmitLValueForLambdaField(const FieldDecl *Field,
     }
   } else {
     QualType LambdaTagType = getContext().getTagDeclType(Field->getParent());
-    LambdaLV = MakeNaturalAlignAddrLValue(ThisValue, LambdaTagType);
+    LambdaLV = MakeNaturalAlignAddrLValue(ThisValue, LambdaTagType,
+                                          KnownNonNull);
   }
   return EmitLValueForField(LambdaLV, Field);
 }
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index c3c10e73ff05e..d70701f0856cf 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -253,6 +253,9 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
 void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
   LValue LV = CGF.EmitLValue(E);
 
+  if (!CGF.CGM.getCodeGenOpts().NullPointerIsValid)
+    LV = LV.setKnownNonNull();
+
   // If the type of the l-value is atomic, then do an atomic load.
   if (LV.getType()->isAtomicType() || CGF.LValueIsSuitableForInlineAtomic(LV)) {
     CGF.EmitAtomicLoad(LV, E->getExprLoc(), Dest);
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 8eb6ab7381acb..db4a70f5316f8 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -265,7 +265,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
   if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
     if (OCE->isAssignmentOp()) {
       if (TrivialAssignment) {
-        TrivialAssignmentRHS = EmitLValue(CE->getArg(1));
+        TrivialAssignmentRHS = EmitLValue(CE->getArg(1), KnownNonNull);
       } else {
         RtlArgs = &RtlArgStorage;
         EmitCallArgs(*RtlArgs, MD->getType()->castAs<FunctionProtoType>(),
@@ -279,11 +279,12 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
   if (IsArrow) {
     LValueBaseInfo BaseInfo;
     TBAAAccessInfo TBAAInfo;
-    Address ThisValue = EmitPointerWithAlignment(Base, &BaseInfo, &TBAAInfo);
+    Address ThisValue = EmitPointerWithAlignment(
+        Base, &BaseInfo, &TBAAInfo, KnownNonNull);
     This = MakeAddrLValue(ThisValue, Base->getType()->getPointeeType(),
                           BaseInfo, TBAAInfo);
   } else {
-    This = EmitLValue(Base);
+    This = EmitLValue(Base, KnownNonNull);
   }
 
   if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) {
@@ -316,7 +317,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
       // the RHS.
       LValue RHS = isa<CXXOperatorCallExpr>(CE)
                        ? TrivialAssignmentRHS
-                       : EmitLValue(*CE->arg_begin());
+                       : EmitLValue(*CE->arg_begin(), KnownNonNull);
       EmitAggregateAssign(This, RHS, CE->getType());
       return RValue::get(This.getPointer(*this));
     }
diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h
index f1ba3cf95ae59..6ed94bd9c7592 100644
--- a/clang/lib/CodeGen/CGValue.h
+++ b/clang/lib/CodeGen/CGValue.h
@@ -233,9 +233,6 @@ class LValue {
   // this lvalue.
   bool Nontemporal : 1;
 
-  // The pointer is known not to be null.
-  bool IsKnownNonNull : 1;
-
   LValueBaseInfo BaseInfo;
   TBAAAccessInfo TBAAInfo;
 
@@ -263,7 +260,6 @@ class LValue {
     this->ImpreciseLifetime = false;
     this->Nontemporal = false;
     this->ThreadLocalRef = false;
-    this->IsKnownNonNull = false;
     this->BaseIvarExp = nullptr;
   }
 
@@ -349,11 +345,9 @@ class LValue {
   LValueBaseInfo getBaseInfo() const { return BaseInfo; }
   void setBaseInfo(LValueBaseInfo Info) { BaseInfo = Info; }
 
-  KnownNonNull_t isKnownNonNull() const {
-    return (KnownNonNull_t)IsKnownNonNull;
-  }
+  KnownNonNull_t isKnownNonNull() const { return Addr.isKnownNonNull(); }
   LValue setKnownNonNull() {
-    IsKnownNonNull = true;
+    Addr.setKnownNonNull();
     return *this;
   }
 
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 26deeca95d326..a222bc05e8dab 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -195,34 +195,45 @@ CodeGenFunction::CGFPOptionsRAII::~CGFPOptionsRAII() {
   CGF.Builder.setDefaultConstrainedRounding(OldRounding);
 }
 
-static LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T,
-                                         bool ForPointeeType,
-                                         CodeGenFunction &CGF) {
+static LValue
+MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, bool ForPointeeType,
+                           bool MightBeSigned, CodeGenFunction &CGF,
+                           KnownNonNull_t IsKnownNonNull = NotKnownNonNull) {
   LValueBaseInfo BaseInfo;
   TBAAAccessInfo TBAAInfo;
   CharUnits Alignment =
       CGF.CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo, ForPointeeType);
-  Address Addr = Address(V, CGF.ConvertTypeForMem(T), Alignment);
+  Address Addr =
+      MightBeSigned
+          ? CGF.makeNaturalAddressForPointer(V, T, Alignment, false, nullptr,
+                                             nullptr, IsKnownNonNull)
+          : Address(V, CGF.ConvertTypeForMem(T), Alignment, IsKnownNonNull);
   return CGF.MakeAddrLValue(Addr, T, BaseInfo, TBAAInfo);
 }
 
-LValue CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) {
-  return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false, *this);
+LValue
+CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T,
+                                            KnownNonNull_t IsKnownNonNull) {
+  return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false,
+                                      /*IsSigned*/ true, *this, IsKnownNonNull);
 }
 
 LValue
 CodeGenFunction::MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T) {
-  return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true, *this);
+  return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true,
+                                      /*IsSigned*/ true, *this);
 }
 
 LValue CodeGenFunction::MakeNaturalAlignRawAddrLValue(llvm::Value *V,
                                                       QualType T) {
-  return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false, *this);
+  return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false,
+                                      /*IsSigned*/ false, *this);
 }
 
 LValue CodeGenFunction::MakeNaturalAlignPointeeRawAddrLValue(llvm::Value *V,
                                                              QualType T) {
-  return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true, *this);
+  return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true,
+                                      /*IsSigned*/ false, *this);
 }
 
 llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) {
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 13f12b5d878a6..5268cc7eda4a2 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -2728,7 +2728,9 @@ class CodeGenFunction : public CodeGenTypeCache {
   /// an l-value with the natural pointee alignment of T.
   LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T);
 
-  LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T);
+  LValue
+  MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T,
+                             KnownNonNull_t IsKnownNonNull = NotKnownNonNull);
 
   /// Same as MakeNaturalAlignPointeeAddrLValue except that the pointer is known
   /// to be unsigned.
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 6e5fa0faf73d7..1609ae19696c7 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -4711,7 +4711,7 @@ static void InitCatchParam(CodeGenFunction &CGF,
 
   // Cast that to the appropriate type.
   Address adjustedExn(CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy),
-                      LLVMCatchTy, caughtExnAlignment);
+                      LLVMCatchTy, caughtExnAlignment, KnownNonNull);
 
   // The copy expression is defined in terms of an OpaqueValueExpr.
   // Find it and map it to the adjusted expression.

>From 4110867a3b0a20a7685aeae9ceaa64d65c365f4f Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha <ahmed at bougacha.org>
Date: Thu, 27 Jun 2024 16:00:35 -0700
Subject: [PATCH 3/4] [clang] Resign type-discriminated function pointers on
 cast.

---
 clang/include/clang/AST/ASTContext.h          |   2 +-
 clang/include/clang/AST/Type.h                |   5 +-
 clang/lib/AST/ASTContext.cpp                  |  12 +-
 clang/lib/CodeGen/Address.h                   |  39 ++-
 clang/lib/CodeGen/CGBuilder.h                 |  94 ++++--
 clang/lib/CodeGen/CGBuiltin.cpp               |   3 +-
 clang/lib/CodeGen/CGCall.cpp                  |   6 +-
 clang/lib/CodeGen/CGExpr.cpp                  |  10 +-
 clang/lib/CodeGen/CGExprAgg.cpp               |   4 +-
 clang/lib/CodeGen/CGExprConstant.cpp          |  16 +-
 clang/lib/CodeGen/CGExprScalar.cpp            |  29 +-
 clang/lib/CodeGen/CGPointerAuth.cpp           | 318 ++++++++++++++++++
 clang/lib/CodeGen/CGValue.h                   |  29 +-
 clang/lib/CodeGen/CodeGenFunction.cpp         |  60 +++-
 clang/lib/CodeGen/CodeGenFunction.h           |  73 +++-
 clang/lib/CodeGen/CodeGenModule.h             |   3 +
 clang/lib/Headers/ptrauth.h                   |  15 +
 .../ptrauth-function-lvalue-cast-disc.c       |  55 +++
 ...ptrauth-function-type-discriminator-cast.c |  85 +++++
 clang/test/CodeGen/ptrauth.c                  |  77 +++++
 clang/test/Preprocessor/ptrauth_feature.c     |  10 +
 .../ptrauth-function-type-discriminatior.c    |  65 ++++
 22 files changed, 907 insertions(+), 103 deletions(-)
 create mode 100644 clang/test/CodeGen/ptrauth-function-lvalue-cast-disc.c
 create mode 100644 clang/test/CodeGen/ptrauth-function-type-discriminator-cast.c
 create mode 100644 clang/test/CodeGen/ptrauth.c
 create mode 100644 clang/test/Sema/ptrauth-function-type-discriminatior.c

diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 57022e75073fe..8ba0c943a9c86 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1284,7 +1284,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
   getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD);
 
   /// Return the "other" type-specific discriminator for the given type.
-  uint16_t getPointerAuthTypeDiscriminator(QualType T) const;
+  uint16_t getPointerAuthTypeDiscriminator(QualType T);
 
   /// Apply Objective-C protocol qualifiers to the given type.
   /// \param allowOnPointerType specifies if we can apply protocol
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 3aa0f05b0ab60..bf242debe479a 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2507,6 +2507,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
   bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); }
   bool isPointerType() const;
   bool isSignableType() const;
+  bool isSignablePointerType() const;
   bool isAnyPointerType() const;   // Any C pointer or ObjC object pointer
   bool isCountAttributedType() const;
   bool isBlockPointerType() const;
@@ -8002,7 +8003,9 @@ inline bool Type::isAnyPointerType() const {
   return isPointerType() || isObjCObjectPointerType();
 }
 
-inline bool Type::isSignableType() const { return isPointerType(); }
+inline bool Type::isSignableType() const { return isSignablePointerType(); }
+
+inline bool Type::isSignablePointerType() const { return isPointerType(); }
 
 inline bool Type::isBlockPointerType() const {
   return isa<BlockPointerType>(CanonicalType);
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 497579dcc56b6..18dfe51e167e0 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3400,7 +3400,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
   }
 }
 
-uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) const {
+uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) {
   assert(!T->isDependentType() &&
          "cannot compute type discriminator of a dependent type");
 
@@ -3410,11 +3410,13 @@ uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) const {
   if (T->isFunctionPointerType() || T->isFunctionReferenceType())
     T = T->getPointeeType();
 
-  if (T->isFunctionType())
+  if (T->isFunctionType()) {
     encodeTypeForFunctionPointerAuth(*this, Out, T);
-  else
-    llvm_unreachable(
-        "type discrimination of non-function type not implemented yet");
+  } else {
+    T = T.getUnqualifiedType();
+    std::unique_ptr<MangleContext> MC(createMangleContext());
+    MC->mangleCanonicalTypeName(T, Out);
+  }
 
   return llvm::getPointerAuthStableSipHash(Str);
 }
diff --git a/clang/lib/CodeGen/Address.h b/clang/lib/CodeGen/Address.h
index 3b677c9159e22..1d2c453f25523 100644
--- a/clang/lib/CodeGen/Address.h
+++ b/clang/lib/CodeGen/Address.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_LIB_CODEGEN_ADDRESS_H
 #define LLVM_CLANG_LIB_CODEGEN_ADDRESS_H
 
+#include "CGPointerAuthInfo.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/Type.h"
 #include "llvm/ADT/PointerIntPair.h"
@@ -141,7 +142,11 @@ class Address {
 
   CharUnits Alignment;
 
-  /// Offset from the base pointer.
+  /// The ptrauth information needed to authenticate the base pointer.
+  CGPointerAuthInfo PtrAuthInfo;
+
+  /// Offset from the base pointer. This is non-null only when the base
+  /// pointer is signed.
   llvm::Value *Offset = nullptr;
 
   llvm::Value *emitRawPointerSlow(CodeGenFunction &CGF) const;
@@ -160,12 +165,14 @@ class Address {
   }
 
   Address(llvm::Value *BasePtr, llvm::Type *ElementType, CharUnits Alignment,
-          llvm::Value *Offset, KnownNonNull_t IsKnownNonNull = NotKnownNonNull)
+          CGPointerAuthInfo PtrAuthInfo, llvm::Value *Offset,
+          KnownNonNull_t IsKnownNonNull = NotKnownNonNull)
       : Pointer(BasePtr, IsKnownNonNull), ElementType(ElementType),
-        Alignment(Alignment), Offset(Offset) {}
+        Alignment(Alignment), PtrAuthInfo(PtrAuthInfo), Offset(Offset) {}
 
   Address(RawAddress RawAddr)
-      : Pointer(RawAddr.isValid() ? RawAddr.getPointer() : nullptr),
+      : Pointer(RawAddr.isValid() ? RawAddr.getPointer() : nullptr,
+                RawAddr.isValid() ? RawAddr.isKnownNonNull() : NotKnownNonNull),
         ElementType(RawAddr.isValid() ? RawAddr.getElementType() : nullptr),
         Alignment(RawAddr.isValid() ? RawAddr.getAlignment()
                                     : CharUnits::Zero()) {}
@@ -175,7 +182,7 @@ class Address {
 
   llvm::Value *getPointerIfNotSigned() const {
     assert(isValid() && "pointer isn't valid");
-    return Pointer.getPointer();
+    return !isSigned() ? Pointer.getPointer() : nullptr;
   }
 
   /// This function is used in situations where the caller is doing some sort of
@@ -197,7 +204,10 @@ class Address {
     return Pointer.getPointer();
   }
 
-  llvm::Value *getUnsignedPointer() const { return getBasePointer(); }
+  llvm::Value *getUnsignedPointer() const {
+    assert(!isSigned() && "cannot call this function if pointer is signed");
+    return getBasePointer();
+  }
 
   /// Return the type of the pointer value.
   llvm::PointerType *getType() const {
@@ -219,6 +229,9 @@ class Address {
   /// Return the IR name of the pointer value.
   llvm::StringRef getName() const { return Pointer.getPointer()->getName(); }
 
+  const CGPointerAuthInfo &getPointerAuthInfo() const { return PtrAuthInfo; }
+  void setPointerAuthInfo(const CGPointerAuthInfo &Info) { PtrAuthInfo = Info; }
+
   // This function is called only in CGBuilderBaseTy::CreateElementBitCast.
   void setElementType(llvm::Type *Ty) {
     assert(hasOffset() &&
@@ -226,7 +239,8 @@ class Address {
     ElementType = Ty;
   }
 
-  /// Whether the pointer is known not to be null.
+  bool isSigned() const { return PtrAuthInfo.isSigned(); }
+
   KnownNonNull_t isKnownNonNull() const {
     assert(isValid());
     return (KnownNonNull_t)Pointer.getInt();
@@ -250,10 +264,15 @@ class Address {
 
   llvm::Value *getOffset() const { return Offset; }
 
+  Address getResignedAddress(const CGPointerAuthInfo &NewInfo,
+                             CodeGenFunction &CGF) const;
+
   /// Return the pointer contained in this class after authenticating it and
   /// adding offset to it if necessary.
   llvm::Value *emitRawPointer(CodeGenFunction &CGF) const {
-    return getUnsignedPointer();
+    if (!isSigned())
+      return getUnsignedPointer();
+    return emitRawPointerSlow(CGF);
   }
 
   /// Return address with different pointer, but same element type and
@@ -275,8 +294,8 @@ class Address {
   /// alignment.
   Address withElementType(llvm::Type *ElemTy) const {
     if (!hasOffset())
-      return Address(getBasePointer(), ElemTy, getAlignment(), nullptr,
-                     isKnownNonNull());
+      return Address(getBasePointer(), ElemTy, getAlignment(),
+                     getPointerAuthInfo(), nullptr, isKnownNonNull());
     Address A(*this);
     A.ElementType = ElemTy;
     return A;
diff --git a/clang/lib/CodeGen/CGBuilder.h b/clang/lib/CodeGen/CGBuilder.h
index 752bfc6c0c058..48b3067494062 100644
--- a/clang/lib/CodeGen/CGBuilder.h
+++ b/clang/lib/CodeGen/CGBuilder.h
@@ -57,7 +57,10 @@ class CGBuilderTy : public CGBuilderBaseTy {
   CodeGenFunction *getCGF() const { return getInserter().CGF; }
 
   llvm::Value *emitRawPointerFromAddress(Address Addr) const {
-    return Addr.getUnsignedPointer();
+    if (!Addr.isSigned())
+      return Addr.getUnsignedPointer();
+    assert(getCGF() && "CGF not set");
+    return Addr.emitRawPointerSlow(*getCGF());
   }
 
   /// Helper function to compute a GEP's offset and add it to Addr.
@@ -208,8 +211,8 @@ class CGBuilderTy : public CGBuilderBaseTy {
                               const llvm::Twine &Name = "") {
     if (!Addr.hasOffset())
       return Address(CreateAddrSpaceCast(Addr.getBasePointer(), Ty, Name),
-                     ElementTy, Addr.getAlignment(), nullptr,
-                     Addr.isKnownNonNull());
+                     ElementTy, Addr.getAlignment(), Addr.getPointerAuthInfo(),
+                     nullptr, Addr.isKnownNonNull());
     // Eagerly force a raw address if these is an offset.
     return RawAddress(
         CreateAddrSpaceCast(Addr.emitRawPointer(*getCGF()), Ty, Name),
@@ -240,11 +243,14 @@ class CGBuilderTy : public CGBuilderBaseTy {
     const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
     auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
 
-    return Address(CreateStructGEP(Addr.getElementType(),
-                                   Addr.getUnsignedPointer(), Index, Name),
-                   ElTy->getElementType(Index),
-                   Addr.getAlignment().alignmentAtOffset(Offset),
-                   Addr.isKnownNonNull());
+    if (!Addr.isSigned())
+      return Address(CreateStructGEP(Addr.getElementType(),
+                                     Addr.getUnsignedPointer(), Index, Name),
+                     ElTy->getElementType(Index),
+                     Addr.getAlignment().alignmentAtOffset(Offset),
+                     Addr.isKnownNonNull());
+    Addr.addOffset(Offset, ElTy->getTypeAtIndex(Index), *this);
+    return Addr;
   }
 
   /// Given
@@ -262,12 +268,15 @@ class CGBuilderTy : public CGBuilderBaseTy {
     CharUnits EltSize =
         CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy->getElementType()));
 
-    return Address(
-        CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
-                          {getSize(CharUnits::Zero()), getSize(Index)}, Name),
-        ElTy->getElementType(),
-        Addr.getAlignment().alignmentAtOffset(Index * EltSize),
-        Addr.isKnownNonNull());
+    if (!Addr.isSigned())
+      return Address(
+          CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
+                            {getSize(CharUnits::Zero()), getSize(Index)}, Name),
+          ElTy->getElementType(),
+          Addr.getAlignment().alignmentAtOffset(Index * EltSize),
+          Addr.isKnownNonNull());
+    Addr.addOffset(Index * EltSize, ElTy, *this);
+    return Addr;
   }
 
   /// Given
@@ -281,10 +290,14 @@ class CGBuilderTy : public CGBuilderBaseTy {
     const llvm::DataLayout &DL = BB->getDataLayout();
     CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
 
-    return Address(CreateInBoundsGEP(ElTy, Addr.getUnsignedPointer(),
-                                     getSize(Index), Name),
-                   ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize),
-                   Addr.isKnownNonNull());
+    if (!Addr.isSigned())
+      return Address(CreateInBoundsGEP(ElTy, Addr.getUnsignedPointer(),
+                                       getSize(Index), Name),
+                     ElTy,
+                     Addr.getAlignment().alignmentAtOffset(Index * EltSize),
+                     Addr.isKnownNonNull());
+    Addr.addOffset(Index * EltSize, ElTy, *this);
+    return Addr;
   }
 
   /// Given
@@ -298,10 +311,12 @@ class CGBuilderTy : public CGBuilderBaseTy {
     const llvm::DataLayout &DL = BB->getDataLayout();
     CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
 
-    return Address(
-        CreateGEP(ElTy, Addr.getUnsignedPointer(), getSize(Index), Name),
-        Addr.getElementType(),
-        Addr.getAlignment().alignmentAtOffset(Index * EltSize));
+    if (!Addr.isSigned())
+      return Address(
+          CreateGEP(ElTy, Addr.getUnsignedPointer(), getSize(Index), Name),
+          ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize));
+    Addr.addOffset(Index * EltSize, ElTy, *this);
+    return Addr;
   }
 
   /// Create GEP with single dynamic index. The address alignment is reduced
@@ -323,21 +338,28 @@ class CGBuilderTy : public CGBuilderBaseTy {
   Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset,
                                      const llvm::Twine &Name = "") {
     assert(Addr.getElementType() == TypeCache.Int8Ty);
-    return Address(
-        CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
-                          getSize(Offset), Name),
-        Addr.getElementType(), Addr.getAlignment().alignmentAtOffset(Offset),
-        Addr.isKnownNonNull());
+
+    if (!Addr.isSigned())
+      return Address(
+          CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
+                            getSize(Offset), Name),
+          Addr.getElementType(), Addr.getAlignment().alignmentAtOffset(Offset),
+          Addr.isKnownNonNull());
+    Addr.addOffset(Offset, TypeCache.Int8Ty, *this);
+    return Addr;
   }
 
   Address CreateConstByteGEP(Address Addr, CharUnits Offset,
                              const llvm::Twine &Name = "") {
     assert(Addr.getElementType() == TypeCache.Int8Ty);
 
-    return Address(CreateGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
-                             getSize(Offset), Name),
-                   Addr.getElementType(),
-                   Addr.getAlignment().alignmentAtOffset(Offset));
+    if (!Addr.isSigned())
+      return Address(CreateGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
+                               getSize(Offset), Name),
+                     Addr.getElementType(),
+                     Addr.getAlignment().alignmentAtOffset(Offset));
+    Addr.addOffset(Offset, TypeCache.Int8Ty, *this);
+    return Addr;
   }
 
   using CGBuilderBaseTy::CreateConstInBoundsGEP2_32;
@@ -364,10 +386,12 @@ class CGBuilderTy : public CGBuilderBaseTy {
   Address CreateInBoundsGEP(Address Addr, ArrayRef<llvm::Value *> IdxList,
                             llvm::Type *ElementType, CharUnits Align,
                             const Twine &Name = "") {
-    return RawAddress(CreateInBoundsGEP(Addr.getElementType(),
-                                        emitRawPointerFromAddress(Addr),
-                                        IdxList, Name),
-                      ElementType, Align, Addr.isKnownNonNull());
+    if (!Addr.isSigned())
+      return RawAddress(CreateInBoundsGEP(Addr.getElementType(),
+                                          emitRawPointerFromAddress(Addr),
+                                          IdxList, Name),
+                        ElementType, Align, Addr.isKnownNonNull());
+    return addGEPOffset(Addr, IdxList, Align, true, Name);
   }
 
   using CGBuilderBaseTy::CreateIsNull;
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 6cc0d9485720c..494891ce4740d 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2151,7 +2151,8 @@ RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) {
 
   // Ignore argument 1, the format string. It is not currently used.
   CallArgList Args;
-  Args.add(RValue::get(BufAddr.emitRawPointer(*this)), Ctx.VoidPtrTy);
+  Args.add(RValue::get(getAsNaturalPointerTo(BufAddr, Ctx.VoidTy)),
+           Ctx.VoidPtrTy);
 
   for (const auto &Item : Layout.Items) {
     int Size = Item.getSizeByte();
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 333771160cabf..b60f5b3a65868 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4135,8 +4135,8 @@ static bool isProvablyNull(llvm::Value *addr) {
 }
 
 static bool isProvablyNonNull(Address Addr, CodeGenFunction &CGF) {
-  return llvm::isKnownNonZero(Addr.getUnsignedPointer(),
-                              CGF.CGM.getDataLayout());
+  return !Addr.isSigned() && llvm::isKnownNonZero(Addr.getUnsignedPointer(),
+                                                  CGF.CGM.getDataLayout());
 }
 
 /// Emit the actual writing-back of a writeback.
@@ -5101,7 +5101,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
   llvm::Value *UnusedReturnSizePtr = nullptr;
   if (RetAI.isIndirect() || RetAI.isInAlloca() || RetAI.isCoerceAndExpand()) {
     if (!ReturnValue.isNull()) {
-      SRetPtr = ReturnValue.getAddress();
+      SRetPtr = ReturnValue.getValue();
     } else {
       SRetPtr = CreateMemTemp(RetTy, "tmp", &SRetAlloca);
       if (HaveInsertPoint() && ReturnValue.isUnused()) {
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d5c3732a4e270..c3bf7d960410a 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1311,7 +1311,8 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo,
         if (CE->getCastKind() == CK_AddressSpaceConversion)
           Addr = CGF.Builder.CreateAddrSpaceCast(
               Addr, CGF.ConvertType(E->getType()), ElemTy);
-        return Addr;
+        return CGF.AuthPointerToPointerCast(Addr, CE->getSubExpr()->getType(),
+                                            CE->getType());
       }
       break;
 
@@ -1785,8 +1786,11 @@ CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {
   }
 
   // Emit as a constant.
-  auto C = ConstantEmitter(*this).emitAbstract(refExpr->getLocation(),
-                                               result.Val, resultType);
+  // Try to emit as a constant.
+  llvm::Constant *C =
+      ConstantEmitter(*this).tryEmitAbstract(result.Val, resultType);
+  if (!C)
+    return ConstantEmission();
 
   // Make sure we emit a debug reference to the global variable.
   // This should probably fire even for
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index d70701f0856cf..14fee2eee8250 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -330,8 +330,8 @@ void AggExprEmitter::withReturnValueSlot(
   if (!UseTemp)
     return;
 
-  assert(Dest.isIgnored() || Dest.emitRawPointer(CGF) !=
-                                 Src.getAggregatePointer(E->getType(), CGF));
+  assert(Dest.getAddress().isSigned() || Dest.isIgnored() ||
+         Dest.emitRawPointer(CGF) != Src.getAggregatePointer(E->getType(), CGF));
   EmitFinalDestCopy(E->getType(), Src);
 
   if (!RequiresDestruction && LifetimeStartInst) {
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 00a5a7e6898a8..534f7c0407f61 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -2074,14 +2074,24 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
     if (D->hasAttr<WeakRefAttr>())
       return CGM.GetWeakRefReference(D).getPointer();
 
-    auto PtrAuthSign = [&](llvm::Constant *C) {
+    auto PtrAuthSign = [&](llvm::Constant *C, bool IsFunction) {
       CGPointerAuthInfo AuthInfo;
 
       if (EnablePtrAuthFunctionTypeDiscrimination)
         AuthInfo = CGM.getFunctionPointerAuthInfo(DestType);
+      else {
+        // FIXME: getPointerAuthInfoForType should be able to return the pointer
+        //        auth info of reference types.
+        if (auto *RT = DestType->getAs<ReferenceType>())
+          DestType = CGM.getContext().getPointerType(RT->getPointeeType());
+        // Don't emit a signed pointer if the destination is a function pointer
+        // type.
+        if (DestType->isSignableType() && !DestType->isFunctionPointerType())
+          AuthInfo = CGM.getPointerAuthInfoForType(DestType);
+      }
 
       if (AuthInfo) {
-        if (hasNonZeroOffset())
+        if (IsFunction && hasNonZeroOffset())
           return ConstantLValue(nullptr);
 
         C = applyOffset(C);
@@ -2095,7 +2105,7 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
     };
 
     if (const auto *FD = dyn_cast<FunctionDecl>(D))
-      return PtrAuthSign(CGM.getRawFunctionPointer(FD));
+      return PtrAuthSign(CGM.getRawFunctionPointer(FD), true);
 
     if (const auto *VD = dyn_cast<VarDecl>(D)) {
       // We can never refer to a variable with local storage.
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index f40f3c273206b..65acb3b067f91 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -2373,7 +2373,9 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
       DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo());
       return EmitLoadOfLValue(DestLV, CE->getExprLoc());
     }
-    return Builder.CreateBitCast(Src, DstTy);
+
+    llvm::Value *Result = Builder.CreateBitCast(Src, DstTy);
+    return CGF.AuthPointerToPointerCast(Result, E->getType(), DestTy);
   }
   case CK_AddressSpaceConversion: {
     Expr::EvalResult Result;
@@ -2523,6 +2525,8 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
       if (DestTy.mayBeDynamicClass())
         IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
     }
+
+    IntToPtr = CGF.AuthPointerToPointerCast(IntToPtr, E->getType(), DestTy);
     return IntToPtr;
   }
   case CK_PointerToIntegral: {
@@ -2538,6 +2542,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
         PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
     }
 
+    PtrExpr = CGF.AuthPointerToPointerCast(PtrExpr, E->getType(), DestTy);
     return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
   }
   case CK_ToVoid: {
@@ -2850,10 +2855,11 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
     Builder.SetInsertPoint(opBB);
     atomicPHI = Builder.CreatePHI(value->getType(), 2);
     atomicPHI->addIncoming(value, startBB);
-    value = atomicPHI;
+    value = CGF.EmitPointerAuthAuth(type->getPointeeType(), atomicPHI);
   } else {
     value = EmitLoadOfLValue(LV, E->getExprLoc());
     input = value;
+    value = CGF.EmitPointerAuthAuth(type->getPointeeType(), value);
   }
 
   // Special case of integer increment that we have to check first: bool++.
@@ -3095,6 +3101,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
   if (atomicPHI) {
     llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
     llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
+    value = CGF.EmitPointerAuthSign(type->getPointeeType(), value);
     auto Pair = CGF.EmitAtomicCompareExchange(
         LV, RValue::get(atomicPHI), RValue::get(value), E->getExprLoc());
     llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), type);
@@ -3106,6 +3113,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
   }
 
   // Store the updated result through the lvalue.
+  value = CGF.EmitPointerAuthSign(type->getPointeeType(), value);
   if (LV.isBitField()) {
     Value *Src = Previous ? Previous : value;
     CGF.EmitStoreThroughBitfieldLValue(RValue::get(value), LV, &value);
@@ -3966,6 +3974,10 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
     return CGF.Builder.CreateBitCast(result, pointer->getType());
   }
 
+  CGPointerAuthInfo PtrAuthInfo = CGF.CGM.getPointerAuthInfoForType(op.Ty);
+  if (PtrAuthInfo)
+    pointer = CGF.EmitPointerAuthAuth(PtrAuthInfo, pointer);
+
   QualType elementType = pointerType->getPointeeType();
   if (const VariableArrayType *vla
         = CGF.getContext().getAsVariableArrayType(elementType)) {
@@ -3986,7 +3998,8 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
           elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
           "add.ptr");
     }
-    return pointer;
+    return PtrAuthInfo ? CGF.EmitPointerAuthSign(PtrAuthInfo, pointer)
+                       : pointer;
   }
 
   // Explicitly handle GNU void* and function pointer arithmetic extensions. The
@@ -3999,11 +4012,13 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
     elemTy = CGF.ConvertTypeForMem(elementType);
 
   if (CGF.getLangOpts().isSignedOverflowDefined())
-    return CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
+    pointer = CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
+  else
+    pointer = CGF.EmitCheckedInBoundsGEP(elemTy, pointer, index, isSigned,
+                                         isSubtraction, op.E->getExprLoc(),
+                                         "add.ptr");
 
-  return CGF.EmitCheckedInBoundsGEP(
-      elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
-      "add.ptr");
+  return PtrAuthInfo ? CGF.EmitPointerAuthSign(PtrAuthInfo, pointer) : pointer;
 }
 
 // Construct an fmuladd intrinsic to represent a fused mul-add of MulOp and
diff --git a/clang/lib/CodeGen/CGPointerAuth.cpp b/clang/lib/CodeGen/CGPointerAuth.cpp
index 621d567dde721..c069b3fa72fba 100644
--- a/clang/lib/CodeGen/CGPointerAuth.cpp
+++ b/clang/lib/CodeGen/CGPointerAuth.cpp
@@ -15,6 +15,7 @@
 #include "CodeGenModule.h"
 #include "clang/CodeGen/CodeGenABITypes.h"
 #include "clang/CodeGen/ConstantInitBuilder.h"
+#include "llvm/Analysis/ValueTracking.h"
 #include "llvm/Support/SipHash.h"
 
 using namespace clang;
@@ -89,6 +90,7 @@ CGPointerAuthInfo CodeGenModule::getFunctionPointerAuthInfo(QualType T) {
                            Discriminator);
 }
 
+
 llvm::Value *
 CodeGenFunction::EmitPointerAuthBlendDiscriminator(llvm::Value *StorageAddress,
                                                    llvm::Value *Discriminator) {
@@ -165,6 +167,130 @@ CGPointerAuthInfo CodeGenModule::getPointerAuthInfoForType(QualType T) {
   return ::getPointerAuthInfoForType(*this, T);
 }
 
+Address CodeGenFunction::mergeAddressesInConditionalExpr(
+    Address LHS, Address RHS, llvm::BasicBlock *LHSBlock,
+    llvm::BasicBlock *RHSBlock, llvm::BasicBlock *MergeBlock,
+    QualType MergedType) {
+  CGPointerAuthInfo LHSInfo = LHS.getPointerAuthInfo();
+  CGPointerAuthInfo RHSInfo = RHS.getPointerAuthInfo();
+
+  if (LHSInfo || RHSInfo) {
+    if (LHSInfo != RHSInfo || LHS.getOffset() != RHS.getOffset() ||
+        LHS.getBasePointer()->getType() != RHS.getBasePointer()->getType()) {
+      // If the LHS and RHS have different signing information, offsets, or base
+      // pointer types, resign both sides and clear out the offsets.
+      CGPointerAuthInfo NewInfo =
+          CGM.getPointerAuthInfoForPointeeType(MergedType);
+      LHSBlock->getTerminator()->eraseFromParent();
+      Builder.SetInsertPoint(LHSBlock);
+      LHS = LHS.getResignedAddress(NewInfo, *this);
+      Builder.CreateBr(MergeBlock);
+      LHSBlock = Builder.GetInsertBlock();
+      RHSBlock->getTerminator()->eraseFromParent();
+      Builder.SetInsertPoint(RHSBlock);
+      RHS = RHS.getResignedAddress(NewInfo, *this);
+      Builder.CreateBr(MergeBlock);
+      RHSBlock = Builder.GetInsertBlock();
+    }
+
+    assert(LHS.getPointerAuthInfo() == RHS.getPointerAuthInfo() &&
+           LHS.getOffset() == RHS.getOffset() &&
+           LHS.getBasePointer()->getType() == RHS.getBasePointer()->getType() &&
+           "lhs and rhs must have the same signing information, offsets, and "
+           "base pointer types");
+  }
+
+  Builder.SetInsertPoint(MergeBlock);
+  llvm::PHINode *PtrPhi = Builder.CreatePHI(LHS.getType(), 2, "cond");
+  PtrPhi->addIncoming(LHS.getBasePointer(), LHSBlock);
+  PtrPhi->addIncoming(RHS.getBasePointer(), RHSBlock);
+  LHS.replaceBasePointer(PtrPhi);
+  LHS.setAlignment(std::min(LHS.getAlignment(), RHS.getAlignment()));
+  return LHS;
+}
+
+static bool isZeroConstant(llvm::Value *value) {
+  if (auto ci = dyn_cast<llvm::ConstantInt>(value))
+    return ci->isZero();
+  return false;
+}
+
+static bool equalAuthPolicies(const CGPointerAuthInfo &left,
+                              const CGPointerAuthInfo &right) {
+  if (left.isSigned() != right.isSigned())
+    return false;
+  assert(left.isSigned() && right.isSigned() &&
+         "should only be called with non-null auth policies");
+  return left.getKey() == right.getKey() &&
+         left.getAuthenticationMode() == right.getAuthenticationMode();
+}
+
+llvm::Value *CodeGenFunction::EmitPointerAuthResign(
+    llvm::Value *value, QualType type, const CGPointerAuthInfo &curAuthInfo,
+    const CGPointerAuthInfo &newAuthInfo, bool isKnownNonNull) {
+  // Fast path: if neither schema wants a signature, we're done.
+  if (!curAuthInfo && !newAuthInfo)
+    return value;
+
+  llvm::Value *null = nullptr;
+  // If the value is obviously null, we're done.
+  if (auto pointerValue = dyn_cast<llvm::PointerType>(value->getType())) {
+    null = CGM.getNullPointer(pointerValue, type);
+  } else {
+    assert(value->getType()->isIntegerTy());
+    null = llvm::ConstantInt::get(IntPtrTy, 0);
+  }
+  if (value == null) {
+    return value;
+  }
+
+  // If both schemas sign the same way, we're done.
+  if (equalAuthPolicies(curAuthInfo, newAuthInfo)) {
+    auto curD = curAuthInfo.getDiscriminator();
+    auto newD = newAuthInfo.getDiscriminator();
+    if (curD == newD)
+      return value;
+
+    if ((curD == nullptr && isZeroConstant(newD)) ||
+        (newD == nullptr && isZeroConstant(curD)))
+      return value;
+  }
+
+  llvm::BasicBlock *initBB = Builder.GetInsertBlock();
+  llvm::BasicBlock *resignBB = nullptr, *contBB = nullptr;
+
+  // Null pointers have to be mapped to null, and the ptrauth_resign
+  // intrinsic doesn't do that.
+  if (!isKnownNonNull && !llvm::isKnownNonZero(value, CGM.getDataLayout())) {
+    contBB = createBasicBlock("resign.cont");
+    resignBB = createBasicBlock("resign.nonnull");
+
+    auto isNonNull = Builder.CreateICmpNE(value, null);
+    Builder.CreateCondBr(isNonNull, resignBB, contBB);
+    EmitBlock(resignBB);
+  }
+
+  // Perform the auth/sign/resign operation.
+  if (!newAuthInfo) {
+    value = EmitPointerAuthAuth(curAuthInfo, value);
+  } else if (!curAuthInfo) {
+    value = EmitPointerAuthSign(newAuthInfo, value);
+  } else {
+    value = EmitPointerAuthResignCall(value, curAuthInfo, newAuthInfo);
+  }
+
+  // Clean up with a phi if we branched before.
+  if (contBB) {
+    EmitBlock(contBB);
+    auto phi = Builder.CreatePHI(value->getType(), 2);
+    phi->addIncoming(null, initBB);
+    phi->addIncoming(value, resignBB);
+    value = phi;
+  }
+
+  return value;
+}
+
 llvm::Constant *
 CodeGenModule::getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key,
                                         llvm::Constant *StorageAddress,
@@ -211,6 +337,16 @@ llvm::Constant *CodeGenModule::getConstantSignedPointer(
                                   OtherDiscriminator);
 }
 
+llvm::Constant *CodeGenModule::getConstantSignedPointer(llvm::Constant *Pointer,
+                                                        QualType PointeeType) {
+  CGPointerAuthInfo Info = getPointerAuthInfoForPointeeType(PointeeType);
+  if (!Info.shouldSign())
+    return Pointer;
+  return getConstantSignedPointer(
+      Pointer, Info.getKey(), nullptr,
+      cast<llvm::ConstantInt>(Info.getDiscriminator()));
+}
+
 /// If applicable, sign a given constant function pointer with the ABI rules for
 /// functionType.
 llvm::Constant *CodeGenModule::getFunctionPointer(llvm::Constant *Pointer,
@@ -351,3 +487,185 @@ CodeGenModule::getVTablePointerAuthInfo(CodeGenFunction *CGF,
                            /* IsIsaPointer */ false,
                            /* AuthenticatesNullValues */ false, Discriminator);
 }
+
+llvm::Value *CodeGenFunction::AuthPointerToPointerCast(llvm::Value *ResultPtr,
+                                                       QualType SourceType,
+                                                       QualType DestType) {
+  CGPointerAuthInfo CurAuthInfo, NewAuthInfo;
+  if (SourceType->isSignableType())
+    CurAuthInfo = getPointerAuthInfoForType(CGM, SourceType);
+
+  if (DestType->isSignableType())
+    NewAuthInfo = getPointerAuthInfoForType(CGM, DestType);
+
+  if (!CurAuthInfo && !NewAuthInfo)
+    return ResultPtr;
+
+  // If only one side of the cast is a function pointer, then we still need to
+  // resign to handle casts to/from opaque pointers.
+  if (!CurAuthInfo && DestType->isFunctionPointerType())
+    CurAuthInfo = CGM.getFunctionPointerAuthInfo(SourceType);
+
+  if (!NewAuthInfo && SourceType->isFunctionPointerType())
+    NewAuthInfo = CGM.getFunctionPointerAuthInfo(DestType);
+
+  return EmitPointerAuthResign(ResultPtr, DestType, CurAuthInfo, NewAuthInfo,
+                               /*IsKnownNonNull=*/false);
+}
+
+Address CodeGenFunction::AuthPointerToPointerCast(Address Ptr,
+                                                  QualType SourceType,
+                                                  QualType DestType) {
+  CGPointerAuthInfo CurAuthInfo, NewAuthInfo;
+  if (SourceType->isSignableType())
+    CurAuthInfo = getPointerAuthInfoForType(CGM, SourceType);
+
+  if (DestType->isSignableType())
+    NewAuthInfo = getPointerAuthInfoForType(CGM, DestType);
+
+  if (!CurAuthInfo && !NewAuthInfo)
+    return Ptr;
+
+  if (!CurAuthInfo && DestType->isFunctionPointerType()) {
+    // When casting a non-signed pointer to a function pointer, just set the
+    // auth info on Ptr to the assumed schema. The pointer will be resigned to
+    // the effective type when used.
+    Ptr.setPointerAuthInfo(CGM.getFunctionPointerAuthInfo(SourceType));
+    return Ptr;
+  }
+
+  if (!NewAuthInfo && SourceType->isFunctionPointerType()) {
+    NewAuthInfo = CGM.getFunctionPointerAuthInfo(DestType);
+    Ptr = Ptr.getResignedAddress(NewAuthInfo, *this);
+    Ptr.setPointerAuthInfo(CGPointerAuthInfo());
+    return Ptr;
+  }
+
+  return Ptr;
+}
+
+Address CodeGenFunction::EmitPointerAuthSign(Address Addr,
+                                             QualType PointeeType) {
+  CGPointerAuthInfo Info = getPointerAuthInfoForPointeeType(CGM, PointeeType);
+  llvm::Value *Ptr = EmitPointerAuthSign(Info, Addr.emitRawPointer(*this));
+  return Address(Ptr, Addr.getElementType(), Addr.getAlignment());
+}
+
+Address CodeGenFunction::EmitPointerAuthAuth(Address Addr,
+                                             QualType PointeeType) {
+  CGPointerAuthInfo Info = getPointerAuthInfoForPointeeType(CGM, PointeeType);
+  llvm::Value *Ptr = EmitPointerAuthAuth(Info, Addr.emitRawPointer(*this));
+  return Address(Ptr, Addr.getElementType(), Addr.getAlignment());
+}
+
+Address CodeGenFunction::getAsNaturalAddressOf(Address Addr,
+                                               QualType PointeeTy) {
+  CGPointerAuthInfo Info =
+      PointeeTy.isNull() ? CGPointerAuthInfo()
+                         : CGM.getPointerAuthInfoForPointeeType(PointeeTy);
+  return Addr.getResignedAddress(Info, *this);
+}
+
+Address Address::getResignedAddress(const CGPointerAuthInfo &NewInfo,
+                                    CodeGenFunction &CGF) const {
+  assert(isValid() && "pointer isn't valid");
+  CGPointerAuthInfo CurInfo = getPointerAuthInfo();
+  llvm::Value *Val;
+
+  // Nothing to do if neither the current or the new ptrauth info needs signing.
+  if (!CurInfo.isSigned() && !NewInfo.isSigned())
+    return Address(getUnsignedPointer(), getElementType(), getAlignment(),
+                   isKnownNonNull());
+
+  assert(ElementType && "Effective type has to be set");
+
+  // If the current and the new ptrauth infos are the same and the offset is
+  // null, just cast the base pointer to the effective type.
+  if (CurInfo == NewInfo && !hasOffset())
+    Val = getBasePointer();
+  else {
+    if (Offset) {
+      assert(isSigned() && "signed pointer expected");
+      // Authenticate the base pointer.
+      Val = CGF.EmitPointerAuthResign(getBasePointer(), QualType(), CurInfo,
+                                      CGPointerAuthInfo(), isKnownNonNull());
+
+      // Add offset to the authenticated pointer.
+      unsigned AS = cast<llvm::PointerType>(getBasePointer()->getType())
+                        ->getAddressSpace();
+      Val = CGF.Builder.CreateBitCast(Val,
+                                      llvm::PointerType::get(CGF.Int8Ty, AS));
+      Val = CGF.Builder.CreateGEP(CGF.Int8Ty, Val, Offset, "resignedgep");
+
+      // Sign the pointer using the new ptrauth info.
+      Val = CGF.EmitPointerAuthResign(Val, QualType(), CGPointerAuthInfo(),
+                                      NewInfo, isKnownNonNull());
+    } else {
+      Val = CGF.EmitPointerAuthResign(getBasePointer(), QualType(), CurInfo,
+                                      NewInfo, isKnownNonNull());
+    }
+  }
+
+  Val = CGF.Builder.CreateBitCast(Val, getType());
+  return Address(Val, getElementType(), getAlignment(), NewInfo, nullptr,
+                 isKnownNonNull());
+}
+
+void Address::addOffset(CharUnits V, llvm::Type *Ty, CGBuilderTy &Builder) {
+  assert(isSigned() &&
+         "shouldn't add an offset if the base pointer isn't signed");
+  Alignment = Alignment.alignmentAtOffset(V);
+  llvm::Value *FixedOffset =
+      llvm::ConstantInt::get(Builder.getCGF()->IntPtrTy, V.getQuantity());
+  addOffset(FixedOffset, Ty, Builder, Alignment);
+}
+
+void Address::addOffset(llvm::Value *V, llvm::Type *Ty, CGBuilderTy &Builder,
+                        CharUnits NewAlignment) {
+  assert(isSigned() &&
+         "shouldn't add an offset if the base pointer isn't signed");
+  ElementType = Ty;
+  Alignment = NewAlignment;
+
+  if (!Offset) {
+    Offset = V;
+    return;
+  }
+
+  Offset = Builder.CreateAdd(Offset, V, "add");
+}
+
+llvm::Value *Address::emitRawPointerSlow(CodeGenFunction &CGF) const {
+  return CGF.getAsNaturalPointerTo(*this, QualType());
+}
+
+llvm::Value *RValue::getAggregatePointer(QualType PointeeType,
+                                         CodeGenFunction &CGF) const {
+  return CGF.getAsNaturalPointerTo(getAggregateAddress(), PointeeType);
+}
+
+llvm::Value *LValue::getPointer(CodeGenFunction &CGF) const {
+  assert(isSimple());
+  return emitResignedPointer(getType(), CGF);
+}
+
+llvm::Value *LValue::emitResignedPointer(QualType PointeeTy,
+                                         CodeGenFunction &CGF) const {
+  assert(isSimple());
+  return CGF.getAsNaturalAddressOf(Addr, PointeeTy).getBasePointer();
+}
+
+llvm::Value *LValue::emitRawPointer(CodeGenFunction &CGF) const {
+  assert(isSimple());
+  return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr;
+}
+
+llvm::Value *AggValueSlot::getPointer(QualType PointeeTy,
+                                      CodeGenFunction &CGF) const {
+  Address SignedAddr = CGF.getAsNaturalAddressOf(Addr, PointeeTy);
+  return SignedAddr.getBasePointer();
+}
+
+llvm::Value *AggValueSlot::emitRawPointer(CodeGenFunction &CGF) const {
+  return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr;
+}
diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h
index 6ed94bd9c7592..27efcf6ac199b 100644
--- a/clang/lib/CodeGen/CGValue.h
+++ b/clang/lib/CodeGen/CGValue.h
@@ -15,6 +15,7 @@
 #define LLVM_CLANG_LIB_CODEGEN_CGVALUE_H
 
 #include "Address.h"
+#include "CGPointerAuthInfo.h"
 #include "CodeGenTBAA.h"
 #include "EHScopeStack.h"
 #include "clang/AST/ASTContext.h"
@@ -78,6 +79,8 @@ class RValue {
     return std::make_pair(Vals.first, Vals.second);
   }
 
+  bool isSignedAggregate() const { return AggregateAddr.isSigned(); }
+
   /// getAggregateAddr() - Return the Value* of the address of the aggregate.
   Address getAggregateAddress() const {
     assert(isAggregate() && "Not an aggregate!");
@@ -85,9 +88,7 @@ class RValue {
   }
 
   llvm::Value *getAggregatePointer(QualType PointeeType,
-                                   CodeGenFunction &CGF) const {
-    return getAggregateAddress().getBasePointer();
-  }
+                                   CodeGenFunction &CGF) const;
 
   static RValue getIgnored() {
     // FIXME: should we make this a more explicit state?
@@ -317,6 +318,8 @@ class LValue {
   bool isNontemporal() const { return Nontemporal; }
   void setNontemporal(bool Value) { Nontemporal = Value; }
 
+  bool isPointerSigned() const { return Addr.isSigned(); }
+
   bool isObjCWeak() const {
     return Quals.getObjCGCAttr() == Qualifiers::Weak;
   }
@@ -352,19 +355,19 @@ class LValue {
   }
 
   // simple lvalue
-  llvm::Value *getPointer(CodeGenFunction &CGF) const {
-    assert(isSimple());
-    return Addr.getBasePointer();
-  }
-  llvm::Value *emitRawPointer(CodeGenFunction &CGF) const {
-    assert(isSimple());
-    return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr;
-  }
+  llvm::Value *getPointer(CodeGenFunction &CGF) const;
+  llvm::Value *emitResignedPointer(QualType PointeeTy,
+                                   CodeGenFunction &CGF) const;
+  llvm::Value *emitRawPointer(CodeGenFunction &CGF) const;
 
   Address getAddress() const { return Addr; }
 
   void setAddress(Address address) { Addr = address; }
 
+  CGPointerAuthInfo getPointerAuthInfo() const {
+    return Addr.getPointerAuthInfo();
+  }
+
   // vector elt lvalue
   Address getVectorAddress() const {
     assert(isVectorElt());
@@ -636,9 +639,7 @@ class AggValueSlot {
 
   llvm::Value *getPointer(QualType PointeeTy, CodeGenFunction &CGF) const;
 
-  llvm::Value *emitRawPointer(CodeGenFunction &CGF) const {
-    return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr;
-  }
+  llvm::Value *emitRawPointer(CodeGenFunction &CGF) const;
 
   Address getAddress() const {
     return Addr;
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index a222bc05e8dab..9e29cddc6f858 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -18,6 +18,7 @@
 #include "CGDebugInfo.h"
 #include "CGHLSLRuntime.h"
 #include "CGOpenMPRuntime.h"
+#include "CGRecordLayout.h"
 #include "CodeGenModule.h"
 #include "CodeGenPGO.h"
 #include "TargetInfo.h"
@@ -558,8 +559,11 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
     ReturnBlock.getBlock()->eraseFromParent();
   }
   if (ReturnValue.isValid()) {
+    // This only matters when ReturnValue isn't signed. ReturnValue is possibly
+    // signed only when the return is Indirect or InAlloca. In that case, a
+    // temporary alloca to store the return value isn't created.
     auto *RetAlloca =
-        dyn_cast<llvm::AllocaInst>(ReturnValue.emitRawPointer(*this));
+        dyn_cast_or_null<llvm::AllocaInst>(ReturnValue.getPointerIfNotSigned());
     if (RetAlloca && RetAlloca->use_empty()) {
       RetAlloca->eraseFromParent();
       ReturnValue = Address::invalid();
@@ -3137,3 +3141,57 @@ CodeGenFunction::EmitPointerAuthAuth(const CGPointerAuthInfo &PointerAuth,
   return EmitPointerAuthCommon(*this, PointerAuth, Pointer,
                                llvm::Intrinsic::ptrauth_auth);
 }
+
+llvm::Value *CodeGenFunction::EmitPointerAuthSign(QualType pointeeType,
+                                                  llvm::Value *pointer) {
+  CGPointerAuthInfo pointerAuth =
+      CGM.getPointerAuthInfoForPointeeType(pointeeType);
+  return EmitPointerAuthSign(pointerAuth, pointer);
+}
+
+llvm::Value *CodeGenFunction::EmitPointerAuthAuth(QualType pointeeType,
+                                                  llvm::Value *pointer) {
+  CGPointerAuthInfo pointerAuth =
+      CGM.getPointerAuthInfoForPointeeType(pointeeType);
+  return EmitPointerAuthAuth(pointerAuth, pointer);
+}
+
+llvm::Value *
+CodeGenFunction::EmitPointerAuthResignCall(llvm::Value *value,
+                                           const CGPointerAuthInfo &curAuth,
+                                           const CGPointerAuthInfo &newAuth) {
+  assert(curAuth && newAuth);
+
+  if (curAuth.getAuthenticationMode() !=
+          PointerAuthenticationMode::SignAndAuth ||
+      newAuth.getAuthenticationMode() !=
+          PointerAuthenticationMode::SignAndAuth) {
+    auto authedValue = EmitPointerAuthAuth(curAuth, value);
+    return EmitPointerAuthSign(newAuth, authedValue);
+  }
+  // Convert the pointer to intptr_t before signing it.
+  auto origType = value->getType();
+  value = Builder.CreatePtrToInt(value, IntPtrTy);
+
+  auto curKey = Builder.getInt32(curAuth.getKey());
+  auto newKey = Builder.getInt32(newAuth.getKey());
+
+  llvm::Value *curDiscriminator = curAuth.getDiscriminator();
+  if (!curDiscriminator)
+    curDiscriminator = Builder.getSize(0);
+
+  llvm::Value *newDiscriminator = newAuth.getDiscriminator();
+  if (!newDiscriminator)
+    newDiscriminator = Builder.getSize(0);
+
+  // call i64 @llvm.ptrauth.resign(i64 %pointer,
+  //                               i32 %curKey, i64 %curDiscriminator,
+  //                               i32 %newKey, i64 %newDiscriminator)
+  auto intrinsic = CGM.getIntrinsic(llvm::Intrinsic::ptrauth_resign);
+  value = EmitRuntimeCall(
+      intrinsic, {value, curKey, curDiscriminator, newKey, newDiscriminator});
+
+  // Convert back to the original type.
+  value = Builder.CreateIntToPtr(value, origType);
+  return value;
+}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 5268cc7eda4a2..2ce28f3e4681f 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -185,6 +185,11 @@ template <> struct DominatingValue<Address> {
     DominatingLLVMValue::saved_type BasePtr;
     llvm::Type *ElementType;
     CharUnits Alignment;
+    unsigned PtrAuthKey : 28;
+    PointerAuthenticationMode PtrAuthMode : 2;
+    bool IsIsaPointer : 1;
+    bool AuthenticatesNullValues : 1;
+    DominatingLLVMValue::saved_type PtrAuthDiscriminator;
     DominatingLLVMValue::saved_type Offset;
     llvm::PointerType *EffectiveType;
   };
@@ -193,16 +198,36 @@ template <> struct DominatingValue<Address> {
     if (DominatingLLVMValue::needsSaving(value.getBasePointer()) ||
         DominatingLLVMValue::needsSaving(value.getOffset()))
       return true;
+    CGPointerAuthInfo info = value.getPointerAuthInfo();
+    if (info.isSigned() &&
+        DominatingLLVMValue::needsSaving(info.getDiscriminator()))
+      return true;
     return false;
   }
   static saved_type save(CodeGenFunction &CGF, type value) {
+    bool isSigned = value.getPointerAuthInfo().isSigned();
     return {DominatingLLVMValue::save(CGF, value.getBasePointer()),
-            value.getElementType(), value.getAlignment(),
-            DominatingLLVMValue::save(CGF, value.getOffset()), value.getType()};
+            value.getElementType(),
+            value.getAlignment(),
+            isSigned ? value.getPointerAuthInfo().getKey() : 0,
+            value.getPointerAuthInfo().getAuthenticationMode(),
+            value.getPointerAuthInfo().isIsaPointer(),
+            value.getPointerAuthInfo().authenticatesNullValues(),
+            isSigned ? DominatingLLVMValue::save(
+                           CGF, value.getPointerAuthInfo().getDiscriminator())
+                     : DominatingLLVMValue::saved_type(),
+            DominatingLLVMValue::save(CGF, value.getOffset()),
+            value.getType()};
   }
   static type restore(CodeGenFunction &CGF, saved_type value) {
+    CGPointerAuthInfo info;
+    if (value.PtrAuthMode != PointerAuthenticationMode::None)
+      info = CGPointerAuthInfo{
+          value.PtrAuthKey, value.PtrAuthMode, value.IsIsaPointer,
+          value.AuthenticatesNullValues,
+          DominatingLLVMValue::restore(CGF, value.PtrAuthDiscriminator)};
     return Address(DominatingLLVMValue::restore(CGF, value.BasePtr),
-                   value.ElementType, value.Alignment,
+                   value.ElementType, value.Alignment, info,
                    DominatingLLVMValue::restore(CGF, value.Offset));
   }
 };
@@ -2665,15 +2690,7 @@ class CodeGenFunction : public CodeGenTypeCache {
                                           llvm::BasicBlock *LHSBlock,
                                           llvm::BasicBlock *RHSBlock,
                                           llvm::BasicBlock *MergeBlock,
-                                          QualType MergedType) {
-    Builder.SetInsertPoint(MergeBlock);
-    llvm::PHINode *PtrPhi = Builder.CreatePHI(LHS.getType(), 2, "cond");
-    PtrPhi->addIncoming(LHS.getBasePointer(), LHSBlock);
-    PtrPhi->addIncoming(RHS.getBasePointer(), RHSBlock);
-    LHS.replaceBasePointer(PtrPhi);
-    LHS.setAlignment(std::min(LHS.getAlignment(), RHS.getAlignment()));
-    return LHS;
-  }
+                                          QualType MergedType);
 
   /// Construct an address with the natural alignment of T. If a pointer to T
   /// is expected to be signed, the pointer passed to this function must have
@@ -2687,7 +2704,8 @@ class CodeGenFunction : public CodeGenTypeCache {
     if (Alignment.isZero())
       Alignment =
           CGM.getNaturalTypeAlignment(T, BaseInfo, TBAAInfo, ForPointeeType);
-    return Address(Ptr, ConvertTypeForMem(T), Alignment, nullptr,
+    return Address(Ptr, ConvertTypeForMem(T), Alignment,
+                   CGM.getPointerAuthInfoForPointeeType(T), nullptr,
                    IsKnownNonNull);
   }
 
@@ -4423,10 +4441,6 @@ class CodeGenFunction : public CodeGenTypeCache {
                                                CXXDtorType Type,
                                                const CXXRecordDecl *RD);
 
-  llvm::Value *getAsNaturalPointerTo(Address Addr, QualType PointeeType) {
-    return Addr.getBasePointer();
-  }
-
   bool isPointerKnownNonNull(const Expr *E);
 
   /// Create the discriminator from the storage address and the entity hash.
@@ -4436,16 +4450,41 @@ class CodeGenFunction : public CodeGenTypeCache {
                                         llvm::Value *StorageAddress,
                                         GlobalDecl SchemaDecl,
                                         QualType SchemaType);
+
   llvm::Value *EmitPointerAuthSign(QualType PointeeType, llvm::Value *Pointer);
   llvm::Value *EmitPointerAuthSign(const CGPointerAuthInfo &Info,
                                    llvm::Value *Pointer);
+
+  llvm::Value *EmitPointerAuthAuth(QualType PointeeType, llvm::Value *Pointer);
   llvm::Value *EmitPointerAuthAuth(const CGPointerAuthInfo &Info,
                                    llvm::Value *Pointer);
 
+  llvm::Value *EmitPointerAuthResign(llvm::Value *Pointer, QualType PointerType,
+                                     const CGPointerAuthInfo &CurAuthInfo,
+                                     const CGPointerAuthInfo &NewAuthInfo,
+                                     bool IsKnownNonNull);
+  llvm::Value *EmitPointerAuthResignCall(llvm::Value *Pointer,
+                                         const CGPointerAuthInfo &CurInfo,
+                                         const CGPointerAuthInfo &NewInfo);
+
   void EmitPointerAuthOperandBundle(
       const CGPointerAuthInfo &Info,
       SmallVectorImpl<llvm::OperandBundleDef> &Bundles);
 
+  llvm::Value *AuthPointerToPointerCast(llvm::Value *ResultPtr,
+                                        QualType SourceType, QualType DestType);
+  Address AuthPointerToPointerCast(Address Ptr, QualType SourceType,
+                                   QualType DestType);
+
+  Address EmitPointerAuthSign(Address Addr, QualType PointeeType);
+  Address EmitPointerAuthAuth(Address Addr, QualType PointeeType);
+
+  Address getAsNaturalAddressOf(Address Addr, QualType PointeeTy);
+
+  llvm::Value *getAsNaturalPointerTo(Address Addr, QualType PointeeType) {
+    return getAsNaturalAddressOf(Addr, PointeeType).getBasePointer();
+  }
+
   // Return the copy constructor name with the prefix "__copy_constructor_"
   // removed.
   static std::string getNonTrivialCopyConstructorStr(QualType QT,
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index caa3786c033b5..7c6078df0af82 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -986,6 +986,9 @@ class CodeGenModule : public CodeGenTypeCache {
                                            GlobalDecl SchemaDecl,
                                            QualType SchemaType);
 
+  llvm::Constant *getConstantSignedPointer(llvm::Constant *Pointer,
+                                           QualType PointeeType);
+
   llvm::Constant *
   getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key,
                            llvm::Constant *StorageAddress,
diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h
index 40ac6dcac2ab8..e0bc8c4f9acf7 100644
--- a/clang/lib/Headers/ptrauth.h
+++ b/clang/lib/Headers/ptrauth.h
@@ -58,6 +58,21 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
 /* Authenticating a pointer that was not signed with the given key
    and extra-data value will (likely) fail by trapping. */
 
+/* The null function pointer is always the all-zero bit pattern.
+   Signing an all-zero bit pattern will embed a (likely) non-zero
+   signature in the result, and so the result will not seem to be
+   a null function pointer.  Authenticating this value will yield
+   a null function pointer back.  However, authenticating an
+   all-zero bit pattern will probably fail, because the
+   authentication will expect a (likely) non-zero signature to
+   embedded in the value.
+
+   Because of this, if a pointer may validly be null, you should
+   check for null before attempting to authenticate it with one
+   of these intrinsics.  This is not necessary when using the
+   __ptrauth qualifier; the compiler will perform this check
+   automatically. */
+
 #if __has_feature(ptrauth_intrinsics)
 
 /* Strip the signature from a value without authenticating it.
diff --git a/clang/test/CodeGen/ptrauth-function-lvalue-cast-disc.c b/clang/test/CodeGen/ptrauth-function-lvalue-cast-disc.c
new file mode 100644
index 0000000000000..6712a6cf417b9
--- /dev/null
+++ b/clang/test/CodeGen/ptrauth-function-lvalue-cast-disc.c
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 %s -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics -emit-llvm -o-  -fptrauth-function-pointer-type-discrimination | FileCheck %s
+
+typedef void (*fptr_t)(void);
+
+char *cptr;
+void (*fptr)(void);
+
+// CHECK-LABEL: define void @test1
+void test1() {
+  // CHECK: [[LOAD:%.*]] = load ptr, ptr @cptr
+  // CHECK: [[TOINT:%.*]] = ptrtoint ptr [[LOAD]] to i64
+  // CHECK: call i64 @llvm.ptrauth.resign(i64 [[TOINT]], i32 0, i64 0, i32 0, i64 18983)
+  // CHECK: call void {{.*}}() [ "ptrauth"(i32 0, i64 18983) ]
+
+  (*(fptr_t)cptr)();
+}
+
+// CHECK-LABEL: define i8 @test2
+char test2() {
+  return *(char *)fptr;
+
+  // CHECK: [[LOAD:%.*]] = load ptr, ptr @fptr
+  // CHECK: [[CMP:%.*]] = icmp ne ptr [[LOAD]], null
+
+  // CHECK: [[TOINT:%.*]] = ptrtoint ptr [[LOAD]] to i64
+  // CHECK: call i64 @llvm.ptrauth.resign(i64 [[TOINT]], i32 0, i64 18983, i32 0, i64 0)
+}
+
+// CHECK-LABEL: define void @test4
+void test4() {
+  (*((fptr_t)(&*((char *)(&*(fptr_t)cptr)))))();
+
+  // CHECK: [[LOAD:%.*]] = load ptr, ptr @cptr
+  // CHECK-NEXT: [[CAST4:%.*]] = ptrtoint ptr [[LOAD]] to i64
+  // CHECK-NEXT: [[RESIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[CAST4]], i32 0, i64 0, i32 0, i64 18983)
+  // CHECK-NEXT: [[CAST5:%.*]] = inttoptr i64 [[RESIGN]] to ptr
+  // CHECK-NEXT: call void [[CAST5]]() [ "ptrauth"(i32 0, i64 18983) ]
+}
+
+void *vptr;
+void test5() {
+  vptr = &*(char *)fptr;
+
+  // CHECK: [[LOAD:%.*]] = load ptr, ptr @fptr
+  // CHECK-NEXT: [[CMP]] = icmp ne ptr [[LOAD]], null
+  // CHECK-NEXT: br i1 [[CMP]], label %[[NONNULL:.*]], label %[[CONT:.*]]
+
+  // CHECK: [[NONNULL]]:
+  // CHECK: [[RESIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 {{.*}}, i32 0, i64 18983, i32 0, i64 0)
+  // CHECK: [[CAST:%.*]] = inttoptr i64 [[RESIGN]] to ptr
+
+  // CHECK: [[CONT]]:
+  // CHECK: [[PHI:%.*]] = phi ptr [ null, {{.*}} ], [ [[CAST]], %[[NONNULL]] ]
+  // CHECK: store ptr [[PHI]], ptr @vptr
+}
diff --git a/clang/test/CodeGen/ptrauth-function-type-discriminator-cast.c b/clang/test/CodeGen/ptrauth-function-type-discriminator-cast.c
new file mode 100644
index 0000000000000..fa12e2c7ec19c
--- /dev/null
+++ b/clang/test/CodeGen/ptrauth-function-type-discriminator-cast.c
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 %s       -fptrauth-function-pointer-type-discrimination -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics -disable-llvm-passes -emit-llvm -o- | FileCheck %s
+// RUN: %clang_cc1 -xc++ %s -fptrauth-function-pointer-type-discrimination -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics -disable-llvm-passes -emit-llvm -o- | FileCheck %s --check-prefixes=CHECK,CHECKCXX
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void f(void);
+void f2(int);
+void (*fptr)(void);
+void *opaque;
+unsigned long uintptr;
+
+#ifdef __cplusplus
+struct ptr_member {
+  void (*fptr_)(int) = 0;
+};
+ptr_member pm;
+void (*test_member)() = (void (*)())pm.fptr_;
+
+// CHECKCXX-LABEL: define internal void @__cxx_global_var_init
+// CHECKCXX: call i64 @llvm.ptrauth.resign(i64 {{.*}}, i32 0, i64 2712, i32 0, i64 18983)
+#endif
+
+
+// CHECK-LABEL: define void @test_cast_to_opaque
+void test_cast_to_opaque() {
+  opaque = (void *)f;
+
+  // CHECK: [[RESIGN_VAL:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @f, i32 0, i64 18983) to i64), i32 0, i64 18983, i32 0, i64 0)
+  // CHECK: [[RESIGN_PTR:%.*]] = inttoptr i64 [[RESIGN_VAL]] to ptr
+}
+
+// CHECK-LABEL: define void @test_cast_from_opaque
+void test_cast_from_opaque() {
+  fptr = (void (*)(void))opaque;
+
+  // CHECK: [[LOAD:%.*]] = load ptr, ptr @opaque
+  // CHECK: [[CMP:%.*]] = icmp ne ptr [[LOAD]], null
+  // CHECK: br i1 [[CMP]], label %[[RESIGN_LAB:.*]], label
+
+  // CHECK: [[RESIGN_LAB]]:
+  // CHECK: [[INT:%.*]] = ptrtoint ptr [[LOAD]] to i64
+  // CHECK: [[RESIGN_INT:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[INT]], i32 0, i64 0, i32 0, i64 18983)
+}
+
+// CHECK-LABEL: define void @test_cast_to_intptr
+void test_cast_to_intptr() {
+  uintptr = (unsigned long)fptr;
+
+  // CHECK: [[ENTRY:.*]]:
+  // CHECK: [[LOAD:%.*]] = load ptr, ptr @fptr
+  // CHECK: [[CMP:%.*]] = icmp ne ptr [[LOAD]], null
+  // CHECK: br i1 [[CMP]], label %[[RESIGN_LAB:.*]], label %[[RESIGN_CONT:.*]]
+
+  // CHECK: [[RESIGN_LAB]]:
+  // CHECK: [[INT:%.*]] = ptrtoint ptr [[LOAD]] to i64
+  // CHECK: [[RESIGN_INT:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[INT]], i32 0, i64 18983, i32 0, i64 0)
+  // CHECK: [[RESIGN:%.*]] = inttoptr i64 [[RESIGN_INT]] to ptr
+  // CHECK: br label %[[RESIGN_CONT]]
+
+  // CHECK: [[RESIGN_CONT]]:
+  // CHECK: phi ptr [ null, %[[ENTRY]] ], [ [[RESIGN]], %[[RESIGN_LAB]] ]
+}
+
+// CHECK-LABEL: define void @test_function_to_function_cast
+void test_function_to_function_cast() {
+  void (*fptr2)(int) = (void (*)(int))fptr;
+  // CHECK: call i64 @llvm.ptrauth.resign(i64 {{.*}}, i32 0, i64 18983, i32 0, i64 2712)
+}
+
+// CHECK-LABEL: define void @test_call_lvalue_cast
+void test_call_lvalue_cast() {
+  (*(void (*)(int))f)(42);
+
+  // CHECK: entry:
+  // CHECK-NEXT: [[RESIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @f, i32 0, i64 18983) to i64), i32 0, i64 18983, i32 0, i64 2712)
+  // CHECK-NEXT: [[RESIGN_INT:%.*]] = inttoptr i64 [[RESIGN]] to ptr
+  // CHECK-NEXT: call void [[RESIGN_INT]](i32 noundef 42) [ "ptrauth"(i32 0, i64 2712) ]
+}
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/clang/test/CodeGen/ptrauth.c b/clang/test/CodeGen/ptrauth.c
new file mode 100644
index 0000000000000..dff6dbeb8508a
--- /dev/null
+++ b/clang/test/CodeGen/ptrauth.c
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm %s  -o - | FileCheck -check-prefix=CHECK -check-prefix=NOPCH %s
+// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-pch %s -o %t.ast
+// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -x ast -o - %t.ast | FileCheck -check-prefix=CHECK -check-prefix=PCH %s
+
+#define FNPTRKEY 0
+
+void (*fnptr)(void);
+long discriminator;
+
+extern void external_function(void);
+// CHECK: @fptr1 = global ptr ptrauth (ptr @external_function, i32 0, i64 18983)
+void (*fptr1)(void) = external_function;
+// CHECK: @fptr2 = global ptr ptrauth (ptr @external_function, i32 0, i64 18983)
+void (*fptr2)(void) = &external_function;
+
+// CHECK: @fptr3 = global ptr ptrauth (ptr @external_function, i32 2, i64 26)
+void (*fptr3)(void) = __builtin_ptrauth_sign_constant(&external_function, 2, 26);
+
+// CHECK: @fptr4 = global ptr ptrauth (ptr @external_function, i32 2, i64 26, ptr @fptr4)
+void (*fptr4)(void) = __builtin_ptrauth_sign_constant(&external_function, 2, __builtin_ptrauth_blend_discriminator(&fptr4, 26));
+
+// CHECK-LABEL: define void @test_call()
+void test_call() {
+  // CHECK:      [[T0:%.*]] = load ptr, ptr @fnptr,
+  // CHECK-NEXT: call void [[T0]]() [ "ptrauth"(i32 0, i64 18983) ]
+  fnptr();
+}
+
+// CHECK-LABEL: define void @test_direct_call()
+void test_direct_call() {
+  // CHECK: call void @test_call(){{$}}
+  test_call();
+}
+
+void abort();
+// CHECK-LABEL: define void @test_direct_builtin_call()
+void test_direct_builtin_call() {
+  // CHECK: call void @abort() {{#[0-9]+$}}
+  abort();
+}
+
+// CHECK-LABEL: define ptr @test_function_pointer()
+// CHECK:  ret ptr ptrauth (ptr @external_function, i32 0, i64 18983)
+void (*test_function_pointer())(void) {
+  return external_function;
+}
+
+struct InitiallyIncomplete;
+extern struct InitiallyIncomplete returns_initially_incomplete(void);
+// CHECK-LABEL: define void @use_while_incomplete()
+void use_while_incomplete() {
+  // NOPCH:      [[VAR:%.*]] = alloca ptr,
+  // NOPCH-NEXT: store ptr ptrauth (ptr @returns_initially_incomplete, i32 0, i64 25106), ptr [[VAR]]
+  // PCH:        [[VAR:%.*]] = alloca ptr,
+  // PCH-NEXT:   store ptr ptrauth (ptr @returns_initially_incomplete, i32 0, i64 25106), ptr [[VAR]]
+  struct InitiallyIncomplete (*fnptr)(void) = &returns_initially_incomplete;
+}
+struct InitiallyIncomplete { int x; };
+// CHECK-LABEL: define void @use_while_complete()
+void use_while_complete() {
+  // CHECK:      [[VAR:%.*]] = alloca ptr,
+  // CHECK-NEXT: store ptr ptrauth (ptr @returns_initially_incomplete, i32 0, i64 25106), ptr [[VAR]]
+  // CHECK-NEXT: ret void
+  struct InitiallyIncomplete (*fnptr)(void) = &returns_initially_incomplete;
+}
+
+// CHECK-LABEL: define void @test_memcpy_inline(
+// CHECK-NOT: call{{.*}}memcpy
+
+extern inline __attribute__((__always_inline__))
+void *memcpy(void *d, const void *s, unsigned long) {
+  return 0;
+}
+
+void test_memcpy_inline(char *d, char *s) {
+  memcpy(d, s, 4);
+}
diff --git a/clang/test/Preprocessor/ptrauth_feature.c b/clang/test/Preprocessor/ptrauth_feature.c
index 88b6982c01657..c19ac21d42139 100644
--- a/clang/test/Preprocessor/ptrauth_feature.c
+++ b/clang/test/Preprocessor/ptrauth_feature.c
@@ -65,6 +65,16 @@
 // RUN:   FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,NOINITFINI,FUNC
 
 
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN:   -fptrauth-intrinsics \
+// RUN:   -fptrauth-calls \
+// RUN:   -fptrauth-returns \
+// RUN:   -fptrauth-vtable-pointer-address-discrimination \
+// RUN:   -fptrauth-vtable-pointer-type-discrimination \
+// RUN:   -fptrauth-function-pointer-type-discrimination | \
+// RUN:   FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,NOINITFINI,FUNC
+
+
 #if __has_feature(ptrauth_intrinsics)
 // INTRIN: has_ptrauth_intrinsics
 void has_ptrauth_intrinsics() {}
diff --git a/clang/test/Sema/ptrauth-function-type-discriminatior.c b/clang/test/Sema/ptrauth-function-type-discriminatior.c
new file mode 100644
index 0000000000000..0dacdf35f2038
--- /dev/null
+++ b/clang/test/Sema/ptrauth-function-type-discriminatior.c
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 %s -triple arm64e-apple-ios13 -verify -xobjective-c -fblocks
+// RUN: %clang_cc1 %s -triple arm64e-apple-ios13 -verify -xc
+// RUN: %clang_cc1 %s -triple arm64e-apple-ios13 -verify -xc++
+
+// expected-no-diagnostics
+
+#define discm(x) __builtin_ptrauth_type_discriminator(x)
+
+struct Complete {};
+struct Incomplete;
+
+#ifndef __cplusplus
+enum EIncomplete;
+#endif
+
+enum EComplete { enumerator };
+
+_Static_assert(discm(void(void)) == 18983, "");
+_Static_assert(discm(void()) == discm(void(void)), "");
+_Static_assert(discm(void(int *)) == discm(void(float *)), "");
+_Static_assert(discm(void(int *)) == discm(void(struct Incomplete *)), "");
+_Static_assert(discm(void(struct Complete *)) == discm(void(struct Incomplete *)), "");
+_Static_assert(discm(void(int *)) != discm(void(int)), "");
+_Static_assert(discm(void(int)) != discm(void(int, ...)), "");
+_Static_assert(discm(_Atomic(int *)()) == discm(int *()), "");
+#ifndef __cplusplus
+_Static_assert(discm(enum EIncomplete()) == discm(int()), "");
+#endif
+_Static_assert(discm(enum EComplete()) == discm(int()), "");
+_Static_assert(discm(unsigned long()) == discm(int()), "");
+_Static_assert(discm(char()) == discm(int()), "");
+_Static_assert(discm(int(int (*)[10])) == discm(int(int (*)[9])), "");
+_Static_assert(discm(void (int[10])) == discm(void (int *)), "");
+_Static_assert(discm(void (int[*])) == discm(void (int *)), "");
+_Static_assert(discm(void (void ())) == discm(void (void (*))), "");
+
+#ifndef __cplusplus
+typedef struct {} foo;
+struct foo {};
+_Static_assert(discm(void(foo)) == discm(void(struct foo)), "");
+#endif
+
+#ifdef __OBJC__
+ at interface I @end
+_Static_assert(discm(id()) == discm(I*()), "");
+_Static_assert(discm(id()) == discm(void*()), "");
+_Static_assert(discm(id()) == discm(Class()), "");
+_Static_assert(discm(void(^())()) == discm(id()), "");
+#endif
+
+#ifdef __cplusplus
+_Static_assert(discm(void(Complete &)) != discm(void(Complete *)), "");
+_Static_assert(discm(void(Complete &)) != discm(void(Complete &&)), "");
+_Static_assert(discm(void(Incomplete &)) != discm(void(Incomplete &&)), "");
+/* Descend into array and function types when using references. */
+_Static_assert(discm(void(void (&)())) != discm(void (void (&)(int))), "");
+_Static_assert(discm(void(void (&)())) != discm(void (int (&)())), "");
+_Static_assert(discm(void(int (&)[10])) == discm(void(int (&)[9])), "");
+_Static_assert(discm(void(int (&)[10])) == discm(void(int (&)[])), "");
+_Static_assert(discm(void(int (&)[10])) != discm(void(float (&)[10])), "");
+#endif
+
+typedef __attribute__((ext_vector_type(4))) float vec4;
+typedef __attribute__((ext_vector_type(16))) char char_vec16;
+_Static_assert(discm(void (vec4)) == discm(void (char_vec16)), "");

>From d7ad33a22780ba8edd1bf53ca2096a4ecf278385 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka <ahatanak at gmail.com>
Date: Sun, 14 Jul 2024 15:58:04 -0700
Subject: [PATCH 4/4] revert unneeded changes

---
 clang/include/clang/AST/ASTContext.h  |   2 +-
 clang/include/clang/AST/Type.h        |   5 +-
 clang/lib/AST/ASTContext.cpp          |  12 ++-
 clang/lib/CodeGen/Address.h           |  28 +------
 clang/lib/CodeGen/CGBlocks.cpp        |   4 +-
 clang/lib/CodeGen/CGBuilder.h         | 108 ++++++++------------------
 clang/lib/CodeGen/CGBuiltin.cpp       |   3 +-
 clang/lib/CodeGen/CGCall.cpp          |  15 ++--
 clang/lib/CodeGen/CGException.cpp     |   4 +-
 clang/lib/CodeGen/CGExpr.cpp          |  22 ++----
 clang/lib/CodeGen/CGExprAgg.cpp       |   7 +-
 clang/lib/CodeGen/CGExprCXX.cpp       |   9 +--
 clang/lib/CodeGen/CGExprConstant.cpp  |  16 +---
 clang/lib/CodeGen/CGExprScalar.cpp    |  22 ++----
 clang/lib/CodeGen/CGObjCMac.cpp       |   2 +-
 clang/lib/CodeGen/CGPointerAuth.cpp   |  88 +--------------------
 clang/lib/CodeGen/CGValue.h           |  12 +--
 clang/lib/CodeGen/CodeGenFunction.cpp |   6 +-
 clang/lib/CodeGen/CodeGenFunction.h   |  41 +++-------
 clang/lib/CodeGen/CodeGenModule.h     |   3 -
 clang/lib/CodeGen/ItaniumCXXABI.cpp   |   2 +-
 21 files changed, 97 insertions(+), 314 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 8ba0c943a9c86..57022e75073fe 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1284,7 +1284,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
   getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD);
 
   /// Return the "other" type-specific discriminator for the given type.
-  uint16_t getPointerAuthTypeDiscriminator(QualType T);
+  uint16_t getPointerAuthTypeDiscriminator(QualType T) const;
 
   /// Apply Objective-C protocol qualifiers to the given type.
   /// \param allowOnPointerType specifies if we can apply protocol
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index bf242debe479a..3aa0f05b0ab60 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2507,7 +2507,6 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
   bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); }
   bool isPointerType() const;
   bool isSignableType() const;
-  bool isSignablePointerType() const;
   bool isAnyPointerType() const;   // Any C pointer or ObjC object pointer
   bool isCountAttributedType() const;
   bool isBlockPointerType() const;
@@ -8003,9 +8002,7 @@ inline bool Type::isAnyPointerType() const {
   return isPointerType() || isObjCObjectPointerType();
 }
 
-inline bool Type::isSignableType() const { return isSignablePointerType(); }
-
-inline bool Type::isSignablePointerType() const { return isPointerType(); }
+inline bool Type::isSignableType() const { return isPointerType(); }
 
 inline bool Type::isBlockPointerType() const {
   return isa<BlockPointerType>(CanonicalType);
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 18dfe51e167e0..497579dcc56b6 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3400,7 +3400,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
   }
 }
 
-uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) {
+uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) const {
   assert(!T->isDependentType() &&
          "cannot compute type discriminator of a dependent type");
 
@@ -3410,13 +3410,11 @@ uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) {
   if (T->isFunctionPointerType() || T->isFunctionReferenceType())
     T = T->getPointeeType();
 
-  if (T->isFunctionType()) {
+  if (T->isFunctionType())
     encodeTypeForFunctionPointerAuth(*this, Out, T);
-  } else {
-    T = T.getUnqualifiedType();
-    std::unique_ptr<MangleContext> MC(createMangleContext());
-    MC->mangleCanonicalTypeName(T, Out);
-  }
+  else
+    llvm_unreachable(
+        "type discrimination of non-function type not implemented yet");
 
   return llvm::getPointerAuthStableSipHash(Str);
 }
diff --git a/clang/lib/CodeGen/Address.h b/clang/lib/CodeGen/Address.h
index 1d2c453f25523..17232772ce8e1 100644
--- a/clang/lib/CodeGen/Address.h
+++ b/clang/lib/CodeGen/Address.h
@@ -180,11 +180,6 @@ class Address {
   static Address invalid() { return Address(nullptr); }
   bool isValid() const { return Pointer.getPointer() != nullptr; }
 
-  llvm::Value *getPointerIfNotSigned() const {
-    assert(isValid() && "pointer isn't valid");
-    return !isSigned() ? Pointer.getPointer() : nullptr;
-  }
-
   /// This function is used in situations where the caller is doing some sort of
   /// opaque "laundering" of the pointer.
   void replaceBasePointer(llvm::Value *P) {
@@ -204,11 +199,6 @@ class Address {
     return Pointer.getPointer();
   }
 
-  llvm::Value *getUnsignedPointer() const {
-    assert(!isSigned() && "cannot call this function if pointer is signed");
-    return getBasePointer();
-  }
-
   /// Return the type of the pointer value.
   llvm::PointerType *getType() const {
     return llvm::PointerType::get(
@@ -252,14 +242,6 @@ class Address {
     return *this;
   }
 
-  /// Add a constant offset.
-  void addOffset(CharUnits V, llvm::Type *Ty, CGBuilderTy &Builder);
-
-  /// Add a variable offset.
-  /// \param V An llvm value holding a variable offset.
-  void addOffset(llvm::Value *V, llvm::Type *Ty, CGBuilderTy &Builder,
-                 CharUnits NewAlignment);
-
   bool hasOffset() const { return Offset; }
 
   llvm::Value *getOffset() const { return Offset; }
@@ -270,9 +252,7 @@ class Address {
   /// Return the pointer contained in this class after authenticating it and
   /// adding offset to it if necessary.
   llvm::Value *emitRawPointer(CodeGenFunction &CGF) const {
-    if (!isSigned())
-      return getUnsignedPointer();
-    return emitRawPointerSlow(CGF);
+    return getBasePointer();
   }
 
   /// Return address with different pointer, but same element type and
@@ -303,9 +283,9 @@ class Address {
 };
 
 inline RawAddress::RawAddress(Address Addr)
-    : PointerAndKnownNonNull(
-          Addr.isValid() ? Addr.getUnsignedPointer() : nullptr,
-          Addr.isValid() ? Addr.isKnownNonNull() : NotKnownNonNull),
+    : PointerAndKnownNonNull(Addr.isValid() ? Addr.getBasePointer() : nullptr,
+                             Addr.isValid() ? Addr.isKnownNonNull()
+                                            : NotKnownNonNull),
       ElementType(Addr.isValid() ? Addr.getElementType() : nullptr),
       Alignment(Addr.isValid() ? Addr.getAlignment() : CharUnits::Zero()) {}
 
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 2affd93c6b9a2..066139b1c78c7 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -1974,8 +1974,8 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
         // it. It's not quite worth the annoyance to avoid creating it in the
         // first place.
         if (!needsEHCleanup(captureType.isDestructedType()))
-          if (auto *I = cast_or_null<llvm::Instruction>(
-                  dstField.getPointerIfNotSigned()))
+          if (auto *I =
+                  cast_or_null<llvm::Instruction>(dstField.getBasePointer()))
             I->eraseFromParent();
       }
       break;
diff --git a/clang/lib/CodeGen/CGBuilder.h b/clang/lib/CodeGen/CGBuilder.h
index 48b3067494062..6625c662e041f 100644
--- a/clang/lib/CodeGen/CGBuilder.h
+++ b/clang/lib/CodeGen/CGBuilder.h
@@ -15,7 +15,6 @@
 #include "llvm/Analysis/Utils/Local.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Module.h"
 #include "llvm/IR/Type.h"
 
 namespace clang {
@@ -57,27 +56,7 @@ class CGBuilderTy : public CGBuilderBaseTy {
   CodeGenFunction *getCGF() const { return getInserter().CGF; }
 
   llvm::Value *emitRawPointerFromAddress(Address Addr) const {
-    if (!Addr.isSigned())
-      return Addr.getUnsignedPointer();
-    assert(getCGF() && "CGF not set");
-    return Addr.emitRawPointerSlow(*getCGF());
-  }
-
-  /// Helper function to compute a GEP's offset and add it to Addr.
-  Address addGEPOffset(Address Addr, ArrayRef<llvm::Value *> IdxList,
-                       CharUnits Align, bool IsInBounds, const Twine &Name) {
-    typedef ArrayRef<llvm::Value *>::const_iterator IdxItTy;
-    typedef llvm::generic_gep_type_iterator<IdxItTy> GEPTypeIt;
-    const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
-    GEPTypeIt GTI = GEPTypeIt::begin(Addr.getElementType(), IdxList.begin());
-    IdxItTy IdxBegin = IdxList.begin(), IdxEnd = IdxList.end();
-    llvm::Type *GEPType = Addr.getType();
-    SmallString<12> Buffer;
-    StringRef GEPName = Name.toStringRef(Buffer);
-    std::pair<llvm::Value *, llvm::Type *> OffsetAndType = llvm::EmitGEPOffset(
-        this, DL, GTI, IdxBegin, IdxEnd, GEPType, GEPName, IsInBounds, false);
-    Addr.addOffset(OffsetAndType.first, OffsetAndType.second, *this, Align);
-    return Addr;
+    return Addr.getBasePointer();
   }
 
   template <bool IsInBounds>
@@ -243,14 +222,11 @@ class CGBuilderTy : public CGBuilderBaseTy {
     const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
     auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
 
-    if (!Addr.isSigned())
-      return Address(CreateStructGEP(Addr.getElementType(),
-                                     Addr.getUnsignedPointer(), Index, Name),
-                     ElTy->getElementType(Index),
-                     Addr.getAlignment().alignmentAtOffset(Offset),
-                     Addr.isKnownNonNull());
-    Addr.addOffset(Offset, ElTy->getTypeAtIndex(Index), *this);
-    return Addr;
+    return Address(CreateStructGEP(Addr.getElementType(), Addr.getBasePointer(),
+                                   Index, Name),
+                   ElTy->getElementType(Index),
+                   Addr.getAlignment().alignmentAtOffset(Offset),
+                   Addr.isKnownNonNull());
   }
 
   /// Given
@@ -268,15 +244,12 @@ class CGBuilderTy : public CGBuilderBaseTy {
     CharUnits EltSize =
         CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy->getElementType()));
 
-    if (!Addr.isSigned())
-      return Address(
-          CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
-                            {getSize(CharUnits::Zero()), getSize(Index)}, Name),
-          ElTy->getElementType(),
-          Addr.getAlignment().alignmentAtOffset(Index * EltSize),
-          Addr.isKnownNonNull());
-    Addr.addOffset(Index * EltSize, ElTy, *this);
-    return Addr;
+    return Address(
+        CreateInBoundsGEP(Addr.getElementType(), Addr.getBasePointer(),
+                          {getSize(CharUnits::Zero()), getSize(Index)}, Name),
+        ElTy->getElementType(),
+        Addr.getAlignment().alignmentAtOffset(Index * EltSize),
+        Addr.isKnownNonNull());
   }
 
   /// Given
@@ -290,14 +263,10 @@ class CGBuilderTy : public CGBuilderBaseTy {
     const llvm::DataLayout &DL = BB->getDataLayout();
     CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
 
-    if (!Addr.isSigned())
-      return Address(CreateInBoundsGEP(ElTy, Addr.getUnsignedPointer(),
-                                       getSize(Index), Name),
-                     ElTy,
-                     Addr.getAlignment().alignmentAtOffset(Index * EltSize),
-                     Addr.isKnownNonNull());
-    Addr.addOffset(Index * EltSize, ElTy, *this);
-    return Addr;
+    return Address(
+        CreateInBoundsGEP(ElTy, Addr.getBasePointer(), getSize(Index), Name),
+        ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize),
+        Addr.isKnownNonNull());
   }
 
   /// Given
@@ -311,12 +280,9 @@ class CGBuilderTy : public CGBuilderBaseTy {
     const llvm::DataLayout &DL = BB->getDataLayout();
     CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
 
-    if (!Addr.isSigned())
-      return Address(
-          CreateGEP(ElTy, Addr.getUnsignedPointer(), getSize(Index), Name),
-          ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize));
-    Addr.addOffset(Index * EltSize, ElTy, *this);
-    return Addr;
+    return Address(CreateGEP(ElTy, Addr.getBasePointer(), getSize(Index), Name),
+                   Addr.getElementType(),
+                   Addr.getAlignment().alignmentAtOffset(Index * EltSize));
   }
 
   /// Create GEP with single dynamic index. The address alignment is reduced
@@ -338,28 +304,20 @@ class CGBuilderTy : public CGBuilderBaseTy {
   Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset,
                                      const llvm::Twine &Name = "") {
     assert(Addr.getElementType() == TypeCache.Int8Ty);
-
-    if (!Addr.isSigned())
-      return Address(
-          CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
-                            getSize(Offset), Name),
-          Addr.getElementType(), Addr.getAlignment().alignmentAtOffset(Offset),
-          Addr.isKnownNonNull());
-    Addr.addOffset(Offset, TypeCache.Int8Ty, *this);
-    return Addr;
+    return Address(
+        CreateInBoundsGEP(Addr.getElementType(), Addr.getBasePointer(),
+                          getSize(Offset), Name),
+        Addr.getElementType(), Addr.getAlignment().alignmentAtOffset(Offset),
+        Addr.isKnownNonNull());
   }
 
   Address CreateConstByteGEP(Address Addr, CharUnits Offset,
                              const llvm::Twine &Name = "") {
     assert(Addr.getElementType() == TypeCache.Int8Ty);
-
-    if (!Addr.isSigned())
-      return Address(CreateGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
-                               getSize(Offset), Name),
-                     Addr.getElementType(),
-                     Addr.getAlignment().alignmentAtOffset(Offset));
-    Addr.addOffset(Offset, TypeCache.Int8Ty, *this);
-    return Addr;
+    return Address(CreateGEP(Addr.getElementType(), Addr.getBasePointer(),
+                             getSize(Offset), Name),
+                   Addr.getElementType(),
+                   Addr.getAlignment().alignmentAtOffset(Offset));
   }
 
   using CGBuilderBaseTy::CreateConstInBoundsGEP2_32;
@@ -386,12 +344,10 @@ class CGBuilderTy : public CGBuilderBaseTy {
   Address CreateInBoundsGEP(Address Addr, ArrayRef<llvm::Value *> IdxList,
                             llvm::Type *ElementType, CharUnits Align,
                             const Twine &Name = "") {
-    if (!Addr.isSigned())
-      return RawAddress(CreateInBoundsGEP(Addr.getElementType(),
-                                          emitRawPointerFromAddress(Addr),
-                                          IdxList, Name),
-                        ElementType, Align, Addr.isKnownNonNull());
-    return addGEPOffset(Addr, IdxList, Align, true, Name);
+    return RawAddress(CreateInBoundsGEP(Addr.getElementType(),
+                                        emitRawPointerFromAddress(Addr),
+                                        IdxList, Name),
+                      ElementType, Align, Addr.isKnownNonNull());
   }
 
   using CGBuilderBaseTy::CreateIsNull;
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 494891ce4740d..6cc0d9485720c 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2151,8 +2151,7 @@ RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) {
 
   // Ignore argument 1, the format string. It is not currently used.
   CallArgList Args;
-  Args.add(RValue::get(getAsNaturalPointerTo(BufAddr, Ctx.VoidTy)),
-           Ctx.VoidPtrTy);
+  Args.add(RValue::get(BufAddr.emitRawPointer(*this)), Ctx.VoidPtrTy);
 
   for (const auto &Item : Layout.Items) {
     int Size = Item.getSizeByte();
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index b60f5b3a65868..a38484941ba24 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -3508,8 +3508,7 @@ static llvm::Value *tryRemoveRetainOfSelf(CodeGenFunction &CGF,
   llvm::LoadInst *load =
     dyn_cast<llvm::LoadInst>(retainedValue->stripPointerCasts());
   if (!load || load->isAtomic() || load->isVolatile() ||
-      load->getPointerOperand() !=
-          CGF.GetAddrOfLocalVar(self).getPointerIfNotSigned())
+      load->getPointerOperand() != CGF.GetAddrOfLocalVar(self).getBasePointer())
     return nullptr;
 
   // Okay!  Burn it all down.  This relies for correctness on the
@@ -3546,8 +3545,7 @@ static llvm::Value *emitAutoreleaseOfResult(CodeGenFunction &CGF,
 
 /// Heuristically search for a dominating store to the return-value slot.
 static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) {
-  // This function shouldn't be called when ReturnValue is signed.
-  llvm::Value *ReturnValuePtr = CGF.ReturnValue.getUnsignedPointer();
+  llvm::Value *ReturnValuePtr = CGF.ReturnValue.getBasePointer();
 
   // Check if a User is a store which pointerOperand is the ReturnValue.
   // We are looking for stores to the ReturnValue, not for stores of the
@@ -4135,8 +4133,7 @@ static bool isProvablyNull(llvm::Value *addr) {
 }
 
 static bool isProvablyNonNull(Address Addr, CodeGenFunction &CGF) {
-  return !Addr.isSigned() && llvm::isKnownNonZero(Addr.getUnsignedPointer(),
-                                                  CGF.CGM.getDataLayout());
+  return llvm::isKnownNonZero(Addr.getBasePointer(), CGF.CGM.getDataLayout());
 }
 
 /// Emit the actual writing-back of a writeback.
@@ -4144,7 +4141,7 @@ static void emitWriteback(CodeGenFunction &CGF,
                           const CallArgList::Writeback &writeback) {
   const LValue &srcLV = writeback.Source;
   Address srcAddr = srcLV.getAddress();
-  assert(!isProvablyNull(srcAddr.getPointerIfNotSigned()) &&
+  assert(!isProvablyNull(srcAddr.getBasePointer()) &&
          "shouldn't have writeback for provably null argument");
 
   llvm::BasicBlock *contBB = nullptr;
@@ -4261,7 +4258,7 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args,
       CGF.ConvertTypeForMem(CRE->getType()->getPointeeType());
 
   // If the address is a constant null, just pass the appropriate null.
-  if (isProvablyNull(srcAddr.getPointerIfNotSigned())) {
+  if (isProvablyNull(srcAddr.getBasePointer())) {
     args.add(RValue::get(llvm::ConstantPointerNull::get(destType)),
              CRE->getType());
     return;
@@ -5101,7 +5098,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
   llvm::Value *UnusedReturnSizePtr = nullptr;
   if (RetAI.isIndirect() || RetAI.isInAlloca() || RetAI.isCoerceAndExpand()) {
     if (!ReturnValue.isNull()) {
-      SRetPtr = ReturnValue.getValue();
+      SRetPtr = ReturnValue.getAddress();
     } else {
       SRetPtr = CreateMemTemp(RetTy, "tmp", &SRetAlloca);
       if (HaveInsertPoint() && ReturnValue.isUnused()) {
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index 2de85963437f5..bb2ed237ee9f3 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -1835,8 +1835,8 @@ Address CodeGenFunction::recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF,
                                                    llvm::Value *ParentFP) {
   llvm::CallInst *RecoverCall = nullptr;
   CGBuilderTy Builder(*this, AllocaInsertPt);
-  if (auto *ParentAlloca = dyn_cast_or_null<llvm::AllocaInst>(
-          ParentVar.getPointerIfNotSigned())) {
+  if (auto *ParentAlloca =
+          dyn_cast_or_null<llvm::AllocaInst>(ParentVar.getBasePointer())) {
     // Mark the variable escaped if nobody else referenced it and compute the
     // localescape index.
     auto InsertPair = ParentCGF.EscapedLocals.insert(
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index c3bf7d960410a..7ae5f0b1cf760 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1786,11 +1786,8 @@ CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {
   }
 
   // Emit as a constant.
-  // Try to emit as a constant.
-  llvm::Constant *C =
-      ConstantEmitter(*this).tryEmitAbstract(result.Val, resultType);
-  if (!C)
-    return ConstantEmission();
+  auto C = ConstantEmitter(*this).emitAbstract(refExpr->getLocation(),
+                                               result.Val, resultType);
 
   // Make sure we emit a debug reference to the global variable.
   // This should probably fire even for
@@ -1945,9 +1942,6 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
       Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV),
                               NotKnownNonNull);
 
-  if (!CGM.getCodeGenOpts().NullPointerIsValid)
-    Addr = Addr.setKnownNonNull();
-
   if (const auto *ClangVecTy = Ty->getAs<VectorType>()) {
     // Boolean vectors use `iN` as storage type.
     if (ClangVecTy->isExtVectorBoolType()) {
@@ -2097,9 +2091,6 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
       Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV),
                               NotKnownNonNull);
 
-  if (!CGM.getCodeGenOpts().NullPointerIsValid)
-    Addr = Addr.setKnownNonNull();
-
   llvm::Type *SrcTy = Value->getType();
   if (const auto *ClangVecTy = Ty->getAs<VectorType>()) {
     auto *VecTy = dyn_cast<llvm::FixedVectorType>(SrcTy);
@@ -2801,9 +2792,9 @@ CodeGenFunction::EmitLoadOfReference(LValue RefLVal,
   llvm::LoadInst *Load =
       Builder.CreateLoad(RefLVal.getAddress(), RefLVal.isVolatile());
   CGM.DecorateInstructionWithTBAA(Load, RefLVal.getTBAAInfo());
-  return makeNaturalAddressForPointer(
-      Load, RefLVal.getType()->getPointeeType(), CharUnits(),
-      /*ForPointeeType=*/true, PointeeBaseInfo, PointeeTBAAInfo, KnownNonNull);
+  return makeNaturalAddressForPointer(Load, RefLVal.getType()->getPointeeType(),
+                                      CharUnits(), /*ForPointeeType=*/true,
+                                      PointeeBaseInfo, PointeeTBAAInfo);
 }
 
 LValue CodeGenFunction::EmitLoadOfReferenceLValue(LValue RefLVal) {
@@ -4716,8 +4707,7 @@ LValue CodeGenFunction::EmitLValueForLambdaField(const FieldDecl *Field,
     }
   } else {
     QualType LambdaTagType = getContext().getTagDeclType(Field->getParent());
-    LambdaLV = MakeNaturalAlignAddrLValue(ThisValue, LambdaTagType,
-                                          KnownNonNull);
+    LambdaLV = MakeNaturalAlignAddrLValue(ThisValue, LambdaTagType);
   }
   return EmitLValueForField(LambdaLV, Field);
 }
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 14fee2eee8250..c3c10e73ff05e 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -253,9 +253,6 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
 void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
   LValue LV = CGF.EmitLValue(E);
 
-  if (!CGF.CGM.getCodeGenOpts().NullPointerIsValid)
-    LV = LV.setKnownNonNull();
-
   // If the type of the l-value is atomic, then do an atomic load.
   if (LV.getType()->isAtomicType() || CGF.LValueIsSuitableForInlineAtomic(LV)) {
     CGF.EmitAtomicLoad(LV, E->getExprLoc(), Dest);
@@ -330,8 +327,8 @@ void AggExprEmitter::withReturnValueSlot(
   if (!UseTemp)
     return;
 
-  assert(Dest.getAddress().isSigned() || Dest.isIgnored() ||
-         Dest.emitRawPointer(CGF) != Src.getAggregatePointer(E->getType(), CGF));
+  assert(Dest.isIgnored() || Dest.emitRawPointer(CGF) !=
+                                 Src.getAggregatePointer(E->getType(), CGF));
   EmitFinalDestCopy(E->getType(), Src);
 
   if (!RequiresDestruction && LifetimeStartInst) {
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index db4a70f5316f8..8eb6ab7381acb 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -265,7 +265,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
   if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
     if (OCE->isAssignmentOp()) {
       if (TrivialAssignment) {
-        TrivialAssignmentRHS = EmitLValue(CE->getArg(1), KnownNonNull);
+        TrivialAssignmentRHS = EmitLValue(CE->getArg(1));
       } else {
         RtlArgs = &RtlArgStorage;
         EmitCallArgs(*RtlArgs, MD->getType()->castAs<FunctionProtoType>(),
@@ -279,12 +279,11 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
   if (IsArrow) {
     LValueBaseInfo BaseInfo;
     TBAAAccessInfo TBAAInfo;
-    Address ThisValue = EmitPointerWithAlignment(
-        Base, &BaseInfo, &TBAAInfo, KnownNonNull);
+    Address ThisValue = EmitPointerWithAlignment(Base, &BaseInfo, &TBAAInfo);
     This = MakeAddrLValue(ThisValue, Base->getType()->getPointeeType(),
                           BaseInfo, TBAAInfo);
   } else {
-    This = EmitLValue(Base, KnownNonNull);
+    This = EmitLValue(Base);
   }
 
   if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) {
@@ -317,7 +316,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
       // the RHS.
       LValue RHS = isa<CXXOperatorCallExpr>(CE)
                        ? TrivialAssignmentRHS
-                       : EmitLValue(*CE->arg_begin(), KnownNonNull);
+                       : EmitLValue(*CE->arg_begin());
       EmitAggregateAssign(This, RHS, CE->getType());
       return RValue::get(This.getPointer(*this));
     }
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 534f7c0407f61..00a5a7e6898a8 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -2074,24 +2074,14 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
     if (D->hasAttr<WeakRefAttr>())
       return CGM.GetWeakRefReference(D).getPointer();
 
-    auto PtrAuthSign = [&](llvm::Constant *C, bool IsFunction) {
+    auto PtrAuthSign = [&](llvm::Constant *C) {
       CGPointerAuthInfo AuthInfo;
 
       if (EnablePtrAuthFunctionTypeDiscrimination)
         AuthInfo = CGM.getFunctionPointerAuthInfo(DestType);
-      else {
-        // FIXME: getPointerAuthInfoForType should be able to return the pointer
-        //        auth info of reference types.
-        if (auto *RT = DestType->getAs<ReferenceType>())
-          DestType = CGM.getContext().getPointerType(RT->getPointeeType());
-        // Don't emit a signed pointer if the destination is a function pointer
-        // type.
-        if (DestType->isSignableType() && !DestType->isFunctionPointerType())
-          AuthInfo = CGM.getPointerAuthInfoForType(DestType);
-      }
 
       if (AuthInfo) {
-        if (IsFunction && hasNonZeroOffset())
+        if (hasNonZeroOffset())
           return ConstantLValue(nullptr);
 
         C = applyOffset(C);
@@ -2105,7 +2095,7 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
     };
 
     if (const auto *FD = dyn_cast<FunctionDecl>(D))
-      return PtrAuthSign(CGM.getRawFunctionPointer(FD), true);
+      return PtrAuthSign(CGM.getRawFunctionPointer(FD));
 
     if (const auto *VD = dyn_cast<VarDecl>(D)) {
       // We can never refer to a variable with local storage.
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 65acb3b067f91..14ca9341c5148 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -2855,11 +2855,10 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
     Builder.SetInsertPoint(opBB);
     atomicPHI = Builder.CreatePHI(value->getType(), 2);
     atomicPHI->addIncoming(value, startBB);
-    value = CGF.EmitPointerAuthAuth(type->getPointeeType(), atomicPHI);
+    value = atomicPHI;
   } else {
     value = EmitLoadOfLValue(LV, E->getExprLoc());
     input = value;
-    value = CGF.EmitPointerAuthAuth(type->getPointeeType(), value);
   }
 
   // Special case of integer increment that we have to check first: bool++.
@@ -3101,7 +3100,6 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
   if (atomicPHI) {
     llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
     llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
-    value = CGF.EmitPointerAuthSign(type->getPointeeType(), value);
     auto Pair = CGF.EmitAtomicCompareExchange(
         LV, RValue::get(atomicPHI), RValue::get(value), E->getExprLoc());
     llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), type);
@@ -3113,7 +3111,6 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
   }
 
   // Store the updated result through the lvalue.
-  value = CGF.EmitPointerAuthSign(type->getPointeeType(), value);
   if (LV.isBitField()) {
     Value *Src = Previous ? Previous : value;
     CGF.EmitStoreThroughBitfieldLValue(RValue::get(value), LV, &value);
@@ -3974,10 +3971,6 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
     return CGF.Builder.CreateBitCast(result, pointer->getType());
   }
 
-  CGPointerAuthInfo PtrAuthInfo = CGF.CGM.getPointerAuthInfoForType(op.Ty);
-  if (PtrAuthInfo)
-    pointer = CGF.EmitPointerAuthAuth(PtrAuthInfo, pointer);
-
   QualType elementType = pointerType->getPointeeType();
   if (const VariableArrayType *vla
         = CGF.getContext().getAsVariableArrayType(elementType)) {
@@ -3998,8 +3991,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
           elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
           "add.ptr");
     }
-    return PtrAuthInfo ? CGF.EmitPointerAuthSign(PtrAuthInfo, pointer)
-                       : pointer;
+    return pointer;
   }
 
   // Explicitly handle GNU void* and function pointer arithmetic extensions. The
@@ -4012,13 +4004,11 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
     elemTy = CGF.ConvertTypeForMem(elementType);
 
   if (CGF.getLangOpts().isSignedOverflowDefined())
-    pointer = CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
-  else
-    pointer = CGF.EmitCheckedInBoundsGEP(elemTy, pointer, index, isSigned,
-                                         isSubtraction, op.E->getExprLoc(),
-                                         "add.ptr");
+    return CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
 
-  return PtrAuthInfo ? CGF.EmitPointerAuthSign(PtrAuthInfo, pointer) : pointer;
+  return CGF.EmitCheckedInBoundsGEP(
+      elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
+      "add.ptr");
 }
 
 // Construct an fmuladd intrinsic to represent a fused mul-add of MulOp and
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 7395370259fe9..30f3911a8b03c 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -4425,7 +4425,7 @@ void FragileHazards::emitHazardsInNewBlocks() {
 
 static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, Address V) {
   if (V.isValid())
-    if (llvm::Value *Ptr = V.getPointerIfNotSigned())
+    if (llvm::Value *Ptr = V.getBasePointer())
       S.insert(Ptr);
 }
 
diff --git a/clang/lib/CodeGen/CGPointerAuth.cpp b/clang/lib/CodeGen/CGPointerAuth.cpp
index c069b3fa72fba..7651dd936016e 100644
--- a/clang/lib/CodeGen/CGPointerAuth.cpp
+++ b/clang/lib/CodeGen/CGPointerAuth.cpp
@@ -90,7 +90,6 @@ CGPointerAuthInfo CodeGenModule::getFunctionPointerAuthInfo(QualType T) {
                            Discriminator);
 }
 
-
 llvm::Value *
 CodeGenFunction::EmitPointerAuthBlendDiscriminator(llvm::Value *StorageAddress,
                                                    llvm::Value *Discriminator) {
@@ -167,48 +166,6 @@ CGPointerAuthInfo CodeGenModule::getPointerAuthInfoForType(QualType T) {
   return ::getPointerAuthInfoForType(*this, T);
 }
 
-Address CodeGenFunction::mergeAddressesInConditionalExpr(
-    Address LHS, Address RHS, llvm::BasicBlock *LHSBlock,
-    llvm::BasicBlock *RHSBlock, llvm::BasicBlock *MergeBlock,
-    QualType MergedType) {
-  CGPointerAuthInfo LHSInfo = LHS.getPointerAuthInfo();
-  CGPointerAuthInfo RHSInfo = RHS.getPointerAuthInfo();
-
-  if (LHSInfo || RHSInfo) {
-    if (LHSInfo != RHSInfo || LHS.getOffset() != RHS.getOffset() ||
-        LHS.getBasePointer()->getType() != RHS.getBasePointer()->getType()) {
-      // If the LHS and RHS have different signing information, offsets, or base
-      // pointer types, resign both sides and clear out the offsets.
-      CGPointerAuthInfo NewInfo =
-          CGM.getPointerAuthInfoForPointeeType(MergedType);
-      LHSBlock->getTerminator()->eraseFromParent();
-      Builder.SetInsertPoint(LHSBlock);
-      LHS = LHS.getResignedAddress(NewInfo, *this);
-      Builder.CreateBr(MergeBlock);
-      LHSBlock = Builder.GetInsertBlock();
-      RHSBlock->getTerminator()->eraseFromParent();
-      Builder.SetInsertPoint(RHSBlock);
-      RHS = RHS.getResignedAddress(NewInfo, *this);
-      Builder.CreateBr(MergeBlock);
-      RHSBlock = Builder.GetInsertBlock();
-    }
-
-    assert(LHS.getPointerAuthInfo() == RHS.getPointerAuthInfo() &&
-           LHS.getOffset() == RHS.getOffset() &&
-           LHS.getBasePointer()->getType() == RHS.getBasePointer()->getType() &&
-           "lhs and rhs must have the same signing information, offsets, and "
-           "base pointer types");
-  }
-
-  Builder.SetInsertPoint(MergeBlock);
-  llvm::PHINode *PtrPhi = Builder.CreatePHI(LHS.getType(), 2, "cond");
-  PtrPhi->addIncoming(LHS.getBasePointer(), LHSBlock);
-  PtrPhi->addIncoming(RHS.getBasePointer(), RHSBlock);
-  LHS.replaceBasePointer(PtrPhi);
-  LHS.setAlignment(std::min(LHS.getAlignment(), RHS.getAlignment()));
-  return LHS;
-}
-
 static bool isZeroConstant(llvm::Value *value) {
   if (auto ci = dyn_cast<llvm::ConstantInt>(value))
     return ci->isZero();
@@ -337,16 +294,6 @@ llvm::Constant *CodeGenModule::getConstantSignedPointer(
                                   OtherDiscriminator);
 }
 
-llvm::Constant *CodeGenModule::getConstantSignedPointer(llvm::Constant *Pointer,
-                                                        QualType PointeeType) {
-  CGPointerAuthInfo Info = getPointerAuthInfoForPointeeType(PointeeType);
-  if (!Info.shouldSign())
-    return Pointer;
-  return getConstantSignedPointer(
-      Pointer, Info.getKey(), nullptr,
-      cast<llvm::ConstantInt>(Info.getDiscriminator()));
-}
-
 /// If applicable, sign a given constant function pointer with the ABI rules for
 /// functionType.
 llvm::Constant *CodeGenModule::getFunctionPointer(llvm::Constant *Pointer,
@@ -574,7 +521,7 @@ Address Address::getResignedAddress(const CGPointerAuthInfo &NewInfo,
 
   // Nothing to do if neither the current or the new ptrauth info needs signing.
   if (!CurInfo.isSigned() && !NewInfo.isSigned())
-    return Address(getUnsignedPointer(), getElementType(), getAlignment(),
+    return Address(getBasePointer(), getElementType(), getAlignment(),
                    isKnownNonNull());
 
   assert(ElementType && "Effective type has to be set");
@@ -611,39 +558,10 @@ Address Address::getResignedAddress(const CGPointerAuthInfo &NewInfo,
                  isKnownNonNull());
 }
 
-void Address::addOffset(CharUnits V, llvm::Type *Ty, CGBuilderTy &Builder) {
-  assert(isSigned() &&
-         "shouldn't add an offset if the base pointer isn't signed");
-  Alignment = Alignment.alignmentAtOffset(V);
-  llvm::Value *FixedOffset =
-      llvm::ConstantInt::get(Builder.getCGF()->IntPtrTy, V.getQuantity());
-  addOffset(FixedOffset, Ty, Builder, Alignment);
-}
-
-void Address::addOffset(llvm::Value *V, llvm::Type *Ty, CGBuilderTy &Builder,
-                        CharUnits NewAlignment) {
-  assert(isSigned() &&
-         "shouldn't add an offset if the base pointer isn't signed");
-  ElementType = Ty;
-  Alignment = NewAlignment;
-
-  if (!Offset) {
-    Offset = V;
-    return;
-  }
-
-  Offset = Builder.CreateAdd(Offset, V, "add");
-}
-
 llvm::Value *Address::emitRawPointerSlow(CodeGenFunction &CGF) const {
   return CGF.getAsNaturalPointerTo(*this, QualType());
 }
 
-llvm::Value *RValue::getAggregatePointer(QualType PointeeType,
-                                         CodeGenFunction &CGF) const {
-  return CGF.getAsNaturalPointerTo(getAggregateAddress(), PointeeType);
-}
-
 llvm::Value *LValue::getPointer(CodeGenFunction &CGF) const {
   assert(isSimple());
   return emitResignedPointer(getType(), CGF);
@@ -665,7 +583,3 @@ llvm::Value *AggValueSlot::getPointer(QualType PointeeTy,
   Address SignedAddr = CGF.getAsNaturalAddressOf(Addr, PointeeTy);
   return SignedAddr.getBasePointer();
 }
-
-llvm::Value *AggValueSlot::emitRawPointer(CodeGenFunction &CGF) const {
-  return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr;
-}
diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h
index 27efcf6ac199b..c4ec8d207d2e3 100644
--- a/clang/lib/CodeGen/CGValue.h
+++ b/clang/lib/CodeGen/CGValue.h
@@ -79,8 +79,6 @@ class RValue {
     return std::make_pair(Vals.first, Vals.second);
   }
 
-  bool isSignedAggregate() const { return AggregateAddr.isSigned(); }
-
   /// getAggregateAddr() - Return the Value* of the address of the aggregate.
   Address getAggregateAddress() const {
     assert(isAggregate() && "Not an aggregate!");
@@ -88,7 +86,9 @@ class RValue {
   }
 
   llvm::Value *getAggregatePointer(QualType PointeeType,
-                                   CodeGenFunction &CGF) const;
+                                   CodeGenFunction &CGF) const {
+    return getAggregateAddress().getBasePointer();
+  }
 
   static RValue getIgnored() {
     // FIXME: should we make this a more explicit state?
@@ -318,8 +318,6 @@ class LValue {
   bool isNontemporal() const { return Nontemporal; }
   void setNontemporal(bool Value) { Nontemporal = Value; }
 
-  bool isPointerSigned() const { return Addr.isSigned(); }
-
   bool isObjCWeak() const {
     return Quals.getObjCGCAttr() == Qualifiers::Weak;
   }
@@ -639,7 +637,9 @@ class AggValueSlot {
 
   llvm::Value *getPointer(QualType PointeeTy, CodeGenFunction &CGF) const;
 
-  llvm::Value *emitRawPointer(CodeGenFunction &CGF) const;
+  llvm::Value *emitRawPointer(CodeGenFunction &CGF) const {
+    return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr;
+  }
 
   Address getAddress() const {
     return Addr;
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 9e29cddc6f858..fab3091f0581c 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -18,7 +18,6 @@
 #include "CGDebugInfo.h"
 #include "CGHLSLRuntime.h"
 #include "CGOpenMPRuntime.h"
-#include "CGRecordLayout.h"
 #include "CodeGenModule.h"
 #include "CodeGenPGO.h"
 #include "TargetInfo.h"
@@ -559,11 +558,8 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
     ReturnBlock.getBlock()->eraseFromParent();
   }
   if (ReturnValue.isValid()) {
-    // This only matters when ReturnValue isn't signed. ReturnValue is possibly
-    // signed only when the return is Indirect or InAlloca. In that case, a
-    // temporary alloca to store the return value isn't created.
     auto *RetAlloca =
-        dyn_cast_or_null<llvm::AllocaInst>(ReturnValue.getPointerIfNotSigned());
+        dyn_cast<llvm::AllocaInst>(ReturnValue.emitRawPointer(*this));
     if (RetAlloca && RetAlloca->use_empty()) {
       RetAlloca->eraseFromParent();
       ReturnValue = Address::invalid();
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 2ce28f3e4681f..4a85153cd7830 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -185,11 +185,6 @@ template <> struct DominatingValue<Address> {
     DominatingLLVMValue::saved_type BasePtr;
     llvm::Type *ElementType;
     CharUnits Alignment;
-    unsigned PtrAuthKey : 28;
-    PointerAuthenticationMode PtrAuthMode : 2;
-    bool IsIsaPointer : 1;
-    bool AuthenticatesNullValues : 1;
-    DominatingLLVMValue::saved_type PtrAuthDiscriminator;
     DominatingLLVMValue::saved_type Offset;
     llvm::PointerType *EffectiveType;
   };
@@ -198,36 +193,16 @@ template <> struct DominatingValue<Address> {
     if (DominatingLLVMValue::needsSaving(value.getBasePointer()) ||
         DominatingLLVMValue::needsSaving(value.getOffset()))
       return true;
-    CGPointerAuthInfo info = value.getPointerAuthInfo();
-    if (info.isSigned() &&
-        DominatingLLVMValue::needsSaving(info.getDiscriminator()))
-      return true;
     return false;
   }
   static saved_type save(CodeGenFunction &CGF, type value) {
-    bool isSigned = value.getPointerAuthInfo().isSigned();
     return {DominatingLLVMValue::save(CGF, value.getBasePointer()),
-            value.getElementType(),
-            value.getAlignment(),
-            isSigned ? value.getPointerAuthInfo().getKey() : 0,
-            value.getPointerAuthInfo().getAuthenticationMode(),
-            value.getPointerAuthInfo().isIsaPointer(),
-            value.getPointerAuthInfo().authenticatesNullValues(),
-            isSigned ? DominatingLLVMValue::save(
-                           CGF, value.getPointerAuthInfo().getDiscriminator())
-                     : DominatingLLVMValue::saved_type(),
-            DominatingLLVMValue::save(CGF, value.getOffset()),
-            value.getType()};
+            value.getElementType(), value.getAlignment(),
+            DominatingLLVMValue::save(CGF, value.getOffset()), value.getType()};
   }
   static type restore(CodeGenFunction &CGF, saved_type value) {
-    CGPointerAuthInfo info;
-    if (value.PtrAuthMode != PointerAuthenticationMode::None)
-      info = CGPointerAuthInfo{
-          value.PtrAuthKey, value.PtrAuthMode, value.IsIsaPointer,
-          value.AuthenticatesNullValues,
-          DominatingLLVMValue::restore(CGF, value.PtrAuthDiscriminator)};
     return Address(DominatingLLVMValue::restore(CGF, value.BasePtr),
-                   value.ElementType, value.Alignment, info,
+                   value.ElementType, value.Alignment, CGPointerAuthInfo(),
                    DominatingLLVMValue::restore(CGF, value.Offset));
   }
 };
@@ -2690,7 +2665,15 @@ class CodeGenFunction : public CodeGenTypeCache {
                                           llvm::BasicBlock *LHSBlock,
                                           llvm::BasicBlock *RHSBlock,
                                           llvm::BasicBlock *MergeBlock,
-                                          QualType MergedType);
+                                          QualType MergedType) {
+    Builder.SetInsertPoint(MergeBlock);
+    llvm::PHINode *PtrPhi = Builder.CreatePHI(LHS.getType(), 2, "cond");
+    PtrPhi->addIncoming(LHS.getBasePointer(), LHSBlock);
+    PtrPhi->addIncoming(RHS.getBasePointer(), RHSBlock);
+    LHS.replaceBasePointer(PtrPhi);
+    LHS.setAlignment(std::min(LHS.getAlignment(), RHS.getAlignment()));
+    return LHS;
+  }
 
   /// Construct an address with the natural alignment of T. If a pointer to T
   /// is expected to be signed, the pointer passed to this function must have
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 7c6078df0af82..caa3786c033b5 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -986,9 +986,6 @@ class CodeGenModule : public CodeGenTypeCache {
                                            GlobalDecl SchemaDecl,
                                            QualType SchemaType);
 
-  llvm::Constant *getConstantSignedPointer(llvm::Constant *Pointer,
-                                           QualType PointeeType);
-
   llvm::Constant *
   getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key,
                            llvm::Constant *StorageAddress,
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 1609ae19696c7..6e5fa0faf73d7 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -4711,7 +4711,7 @@ static void InitCatchParam(CodeGenFunction &CGF,
 
   // Cast that to the appropriate type.
   Address adjustedExn(CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy),
-                      LLVMCatchTy, caughtExnAlignment, KnownNonNull);
+                      LLVMCatchTy, caughtExnAlignment);
 
   // The copy expression is defined in terms of an OpaqueValueExpr.
   // Find it and map it to the adjusted expression.



More information about the cfe-commits mailing list