[clang] [compiler-rt] [libcxx] [llvm] [polly] Backport for #203715 on llvm 23 (PR #211219)

via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 22 02:56:36 PDT 2026


=?utf-8?b?6ZmI5a2Q5piC?= <2802328816 at qq.com>,Karthika Devi C
 <kartc at qti.qualcomm.com>,Karthika Devi C <kartc at qti.qualcomm.com>,Amy Kwan
 <amy.kwan1 at ibm.com>,Erich Keane <ekeane at nvidia.com>,Tom Stellard
 <tstellar at redhat.com>,Pawan Nirpal <pnirpal at qti.qualcomm.com>,hev
 <wangrui at loongson.cn>,Daniel Kiss <daniel.kiss at arm.com>,Ikhlas Ajbar
 <iajbar at quicinc.com>,maflcko <6399679+maflcko at users.noreply.github.com>,Nikita
 Popov <npopov at redhat.com>,cqwrteur <oyzawqgcfc at gmail.com>,Jacek Caban
 <jacek at codeweavers.com>,Nikita Popov <npopov at redhat.com>,Tom Stellard
 <tstellar at redhat.com>,Douglas Yung <douglas.yung at sony.com>,Douglas Yung
 <douglas.yung at sony.com>,Tom Stellard <tstellar at redhat.com>,Tom Stellard
 <tstellar at redhat.com>,Louis Dionne <ldionne.2 at gmail.com>,Tom Stellard
 <tstellar at redhat.com>,Ajay Wakodikar <ajaywakodikarsocial at gmail.com>,Ajay
 Wakodikar <ajaywakodikarsocial at gmail.com>
Message-ID: <llvm.org/llvm/llvm-project/pull/211219 at github.com>
In-Reply-To:


https://github.com/arrowten created https://github.com/llvm/llvm-project/pull/211219

None

>From f0777c1f997c0a95897dbaba2919bb96236849b2 Mon Sep 17 00:00:00 2001
From: Douglas Yung <douglas.yung at sony.com>
Date: Tue, 14 Jul 2026 13:24:57 +0000
Subject: [PATCH 01/35] Bump version to 23.1.0git

---
 cmake/Modules/LLVMVersion.cmake          | 2 +-
 libcxx/include/__config                  | 2 +-
 llvm/utils/gn/secondary/llvm/version.gni | 2 +-
 llvm/utils/lit/lit/__init__.py           | 2 +-
 llvm/utils/mlgo-utils/mlgo/__init__.py   | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/cmake/Modules/LLVMVersion.cmake b/cmake/Modules/LLVMVersion.cmake
index fa1b0997cd3e8..ed3dfebf7548a 100644
--- a/cmake/Modules/LLVMVersion.cmake
+++ b/cmake/Modules/LLVMVersion.cmake
@@ -4,7 +4,7 @@ if(NOT DEFINED LLVM_VERSION_MAJOR)
   set(LLVM_VERSION_MAJOR 23)
 endif()
 if(NOT DEFINED LLVM_VERSION_MINOR)
-  set(LLVM_VERSION_MINOR 0)
+  set(LLVM_VERSION_MINOR 1)
 endif()
 if(NOT DEFINED LLVM_VERSION_PATCH)
   set(LLVM_VERSION_PATCH 0)
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 3f271ff504767..d6caacef6691d 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -36,7 +36,7 @@
 // _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM.
 // Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 17.0.1 == 17.00.01), _LIBCPP_VERSION is
 // defined to XXYYZZ.
-#  define _LIBCPP_VERSION 230000
+#  define _LIBCPP_VERSION 230100
 
 #  if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME)
 #    define _LIBCPP_ABI_VCRUNTIME
diff --git a/llvm/utils/gn/secondary/llvm/version.gni b/llvm/utils/gn/secondary/llvm/version.gni
index d772c1ec3f0b8..8420f988572e3 100644
--- a/llvm/utils/gn/secondary/llvm/version.gni
+++ b/llvm/utils/gn/secondary/llvm/version.gni
@@ -1,4 +1,4 @@
 llvm_version_major = 23
-llvm_version_minor = 0
+llvm_version_minor = 1
 llvm_version_patch = 0
 llvm_version = "$llvm_version_major.$llvm_version_minor.$llvm_version_patch"
diff --git a/llvm/utils/lit/lit/__init__.py b/llvm/utils/lit/lit/__init__.py
index 8356da6ef9502..d6c6d64cbe234 100644
--- a/llvm/utils/lit/lit/__init__.py
+++ b/llvm/utils/lit/lit/__init__.py
@@ -2,7 +2,7 @@
 
 __author__ = "Daniel Dunbar"
 __email__ = "daniel at minormatter.com"
-__versioninfo__ = (23, 0, 0)
+__versioninfo__ = (23, 1, 0)
 __version__ = ".".join(str(v) for v in __versioninfo__) + "dev"
 
 __all__ = []
diff --git a/llvm/utils/mlgo-utils/mlgo/__init__.py b/llvm/utils/mlgo-utils/mlgo/__init__.py
index 6ed46bc3aa56a..f0e5c8b214ff6 100644
--- a/llvm/utils/mlgo-utils/mlgo/__init__.py
+++ b/llvm/utils/mlgo-utils/mlgo/__init__.py
@@ -4,7 +4,7 @@
 
 from datetime import timezone, datetime
 
-__versioninfo__ = (23, 0, 0)
+__versioninfo__ = (23, 1, 0)
 __version__ = (
     ".".join(str(v) for v in __versioninfo__)
     + "dev"

>From a589eb4f8e64689afe2b0844a63879b7b4865ff3 Mon Sep 17 00:00:00 2001
From: Felipe de Azevedo Piovezan <fpiovezan at apple.com>
Date: Tue, 14 Jul 2026 18:12:19 +0100
Subject: [PATCH 02/35] Revert "[libc++][NFC] Inline std::function members into
 the class body" (#209555)

Reverts llvm/llvm-project#209461

This is breaking LLDB testing bots and it also failed pre-merge CI.

(cherry picked from commit 7618426138aae95561da676a1d1e10ee0392bf78)
---
 libcxx/include/__functional/function.h | 141 ++++++++++++++++++-------
 1 file changed, 104 insertions(+), 37 deletions(-)

diff --git a/libcxx/include/__functional/function.h b/libcxx/include/__functional/function.h
index 0adc336424e2e..90072e9528484 100644
--- a/libcxx/include/__functional/function.h
+++ b/libcxx/include/__functional/function.h
@@ -340,7 +340,7 @@ template <typename _Fun>
 struct __use_small_storage
     : public integral_constant<
           bool,
-          sizeof(_Fun) <= sizeof(__policy_storage) && _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) &&
+          sizeof(_Fun) <= sizeof(__policy_storage)&& _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) &&
               is_trivially_copy_constructible<_Fun>::value && is_trivially_destructible<_Fun>::value> {};
 
 // Policy contains information about how to copy, destroy, and move the
@@ -628,10 +628,10 @@ class function<_Rp(_ArgTypes...)>
   // construct/copy/destroy:
   _LIBCPP_HIDE_FROM_ABI function() _NOEXCEPT {}
   _LIBCPP_HIDE_FROM_ABI function(nullptr_t) _NOEXCEPT {}
-  _LIBCPP_HIDE_FROM_ABI function(const function&)      = default;
-  _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT = default;
+  _LIBCPP_HIDE_FROM_ABI function(const function&);
+  _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT;
   template <class _Fp, class = _EnableIfLValueCallable<_Fp>>
-  _LIBCPP_HIDE_FROM_ABI function(_Fp __f) : __f_(std::move(__f)) {}
+  _LIBCPP_HIDE_FROM_ABI function(_Fp);
 
 #  if _LIBCPP_STD_VER <= 14
   template <class _Alloc>
@@ -639,35 +639,23 @@ class function<_Rp(_ArgTypes...)>
   template <class _Alloc>
   _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {}
   template <class _Alloc>
-  _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function& __f) : __f_(__f.__f_) {}
+  _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function&);
   template <class _Alloc>
-  _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&& __f) : __f_(std::move(__f.__f_)) {}
+  _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&&);
   template <class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>>
-  _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, _Fp __f) : __f_(std::move(__f)) {}
+  _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc& __a, _Fp __f);
 #  endif
 
-  _LIBCPP_HIDE_FROM_ABI function& operator=(const function& __f) {
-    function(__f).swap(*this);
-    return *this;
-  }
-
-  _LIBCPP_HIDE_FROM_ABI function& operator=(function&& __f) _NOEXCEPT = default;
-
-  _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT {
-    __f_ = nullptr;
-    return *this;
-  }
-
+  _LIBCPP_HIDE_FROM_ABI function& operator=(const function&);
+  _LIBCPP_HIDE_FROM_ABI function& operator=(function&&) _NOEXCEPT;
+  _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT;
   template <class _Fp, class = _EnableIfLValueCallable<__decay_t<_Fp>>>
-  _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&& __f) {
-    function(std::forward<_Fp>(__f)).swap(*this);
-    return *this;
-  }
+  _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&&);
 
-  _LIBCPP_HIDE_FROM_ABI ~function() = default;
+  _LIBCPP_HIDE_FROM_ABI ~function();
 
   // function modifiers:
-  _LIBCPP_HIDE_FROM_ABI void swap(function& __f) _NOEXCEPT { __f_.swap(__f.__f_); }
+  _LIBCPP_HIDE_FROM_ABI void swap(function&) _NOEXCEPT;
 
 #  if _LIBCPP_STD_VER <= 14
   template <class _Fp, class _Alloc>
@@ -689,23 +677,15 @@ class function<_Rp(_ArgTypes...)>
 
 public:
   // function invocation:
-  _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes... __args) const { return __f_(std::forward<_ArgTypes>(__args)...); }
+  _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const;
 
 #  if _LIBCPP_HAS_RTTI
   // function target access:
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT {
-    return __f_.target_type();
-  }
-
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT;
   template <typename _Tp>
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT {
-    return (_Tp*)(__f_.template target<_Tp>());
-  }
-
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT;
   template <typename _Tp>
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT {
-    return __f_.template target<_Tp>();
-  }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT;
 #  endif // _LIBCPP_HAS_RTTI
 };
 
@@ -717,6 +697,93 @@ template <class _Fp, class _Stripped = __strip_signature_t<decltype(&_Fp::operat
 function(_Fp) -> function<_Stripped>;
 #  endif // _LIBCPP_STD_VER >= 17
 
+template <class _Rp, class... _ArgTypes>
+function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {}
+
+#  if _LIBCPP_STD_VER <= 14
+template <class _Rp, class... _ArgTypes>
+template <class _Alloc>
+function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, const function& __f) : __f_(__f.__f_) {}
+#  endif
+
+template <class _Rp, class... _ArgTypes>
+function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT : __f_(std::move(__f.__f_)) {}
+
+#  if _LIBCPP_STD_VER <= 14
+template <class _Rp, class... _ArgTypes>
+template <class _Alloc>
+function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, function&& __f) : __f_(std::move(__f.__f_)) {}
+#  endif
+
+template <class _Rp, class... _ArgTypes>
+template <class _Fp, class>
+function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(std::move(__f)) {}
+
+#  if _LIBCPP_STD_VER <= 14
+template <class _Rp, class... _ArgTypes>
+template <class _Fp, class _Alloc, class>
+function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, _Fp __f) : __f_(std::move(__f)) {}
+#  endif
+
+template <class _Rp, class... _ArgTypes>
+function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(const function& __f) {
+  function(__f).swap(*this);
+  return *this;
+}
+
+template <class _Rp, class... _ArgTypes>
+function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT {
+  __f_ = std::move(__f.__f_);
+  return *this;
+}
+
+template <class _Rp, class... _ArgTypes>
+function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT {
+  __f_ = nullptr;
+  return *this;
+}
+
+template <class _Rp, class... _ArgTypes>
+template <class _Fp, class>
+function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) {
+  function(std::forward<_Fp>(__f)).swap(*this);
+  return *this;
+}
+
+template <class _Rp, class... _ArgTypes>
+function<_Rp(_ArgTypes...)>::~function() {}
+
+template <class _Rp, class... _ArgTypes>
+void function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT {
+  __f_.swap(__f.__f_);
+}
+
+template <class _Rp, class... _ArgTypes>
+_Rp function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const {
+  return __f_(std::forward<_ArgTypes>(__arg)...);
+}
+
+#  if _LIBCPP_HAS_RTTI
+
+template <class _Rp, class... _ArgTypes>
+const std::type_info& function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT {
+  return __f_.target_type();
+}
+
+template <class _Rp, class... _ArgTypes>
+template <typename _Tp>
+_Tp* function<_Rp(_ArgTypes...)>::target() _NOEXCEPT {
+  return (_Tp*)(__f_.template target<_Tp>());
+}
+
+template <class _Rp, class... _ArgTypes>
+template <typename _Tp>
+const _Tp* function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT {
+  return __f_.template target<_Tp>();
+}
+
+#  endif // _LIBCPP_HAS_RTTI
+
 template <class _Rp, class... _ArgTypes>
 inline _LIBCPP_HIDE_FROM_ABI bool operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {
   return !__f;

>From 38e1487f6b61e326330aa0467ec37b1287deaf69 Mon Sep 17 00:00:00 2001
From: Douglas Yung <douglas.yung at sony.com>
Date: Tue, 14 Jul 2026 12:47:31 -0400
Subject: [PATCH 03/35] Fix test that had a check embedded which depended on
 the current LLVM version number. (#209530)

When the test was refactored, it embedded the current LLVM version
number in one of the check strings so that when I bumped the LLVM
version to 24, the test failed since it was expecting 23 but the
compiler was now generating 23.

Fix this issue by changing the check to a regex so it doesn't need
updating after every LLVM version change.

(cherry picked from commit 1a072b5f008321f22e61f744b7474fe52f0ee48c)
---
 llvm/test/CodeGen/SystemZ/zos-ppa2.ll | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/SystemZ/zos-ppa2.ll b/llvm/test/CodeGen/SystemZ/zos-ppa2.ll
index a4c1d50df5543..b1d8d47356b97 100644
--- a/llvm/test/CodeGen/SystemZ/zos-ppa2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-ppa2.ll
@@ -21,9 +21,10 @@
 ; CHECK:  DC XL2'0000'
 ; CHECK: L#DVS DS 0H
 ; CHECK:  DC XL14'F1F9F7F0F0F1F0F1F0F0F0F0F0F0'
-; CHECK:  DC XL6'F2F3F0F0F0F0'
+; CHECK:  DC XL6'{{((F[[:digit:]]){6})}}'
 ; CHECK:  DC XL2'0000'
 
+
 ; CHECK: C_@@QPPA2 CATTR ALIGN(3),FILL(0),NOTEXECUTABLE,READONLY,RMODE(64),PART(.
 ; CHECK:                .&ppa2)
 ; CHECK: .&ppa2 XATTR LINKAGE(OS),REFERENCE(DATA),SCOPE(SECTION)

>From b9c1e158337a9f3975f868c493cf902406d13954 Mon Sep 17 00:00:00 2001
From: Jordan Rupprecht <rupprecht at google.com>
Date: Tue, 14 Jul 2026 15:01:26 -0500
Subject: [PATCH 04/35] [clang][test] Avoid relying on `-fuse-ld=ld` default
 value for marm64x test (#209597)

Test case added in #209324

(cherry picked from commit 0b908e100f3d88232aa3b0190e23e41ca327edf1)
---
 clang/test/Driver/msvc-link.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/test/Driver/msvc-link.c b/clang/test/Driver/msvc-link.c
index e78e457442c66..fc7a18014da73 100644
--- a/clang/test/Driver/msvc-link.c
+++ b/clang/test/Driver/msvc-link.c
@@ -45,10 +45,10 @@
 // RUN: %clang_cl -arm64EC -marm64x -fuse-ld=link -### -- %s 2>&1 | FileCheck --check-prefix=ARM64X %s
 // ARM64X: "-machine:arm64x"
 
-// RUN: %clang --target=arm64ec-pc-windows-msvc -marm64x -### %s 2>&1 | FileCheck --check-prefix=ARM64X-LLD %s
-// RUN: %clang --target=aarch64-pc-windows-msvc -marm64x -### %s 2>&1 | FileCheck --check-prefix=ARM64X-LLD %s
-// RUN: %clang_cl -marm64x -### -- %s 2>&1 | FileCheck --check-prefix=ARM64X-LLD %s
-// RUN: %clang_cl -arm64EC -marm64x -### -- %s 2>&1 | FileCheck --check-prefix=ARM64X-LLD %s
+// RUN: %clang -fuse-ld= --target=arm64ec-pc-windows-msvc -marm64x -### %s 2>&1 | FileCheck --check-prefix=ARM64X-LLD %s
+// RUN: %clang -fuse-ld= --target=aarch64-pc-windows-msvc -marm64x -### %s 2>&1 | FileCheck --check-prefix=ARM64X-LLD %s
+// RUN: %clang_cl -fuse-ld= -marm64x -### -- %s 2>&1 | FileCheck --check-prefix=ARM64X-LLD %s
+// RUN: %clang_cl -fuse-ld= -arm64EC -marm64x -### -- %s 2>&1 | FileCheck --check-prefix=ARM64X-LLD %s
 // ARM64X-LLD: lld-link
 // ARM64X-LLD-SAME: "-machine:arm64x"
 

>From 5100381e4719316bb4f00419bb52e260dc32f2e6 Mon Sep 17 00:00:00 2001
From: Garvit Gupta <garvgupt at qti.qualcomm.com>
Date: Tue, 14 Jul 2026 23:11:07 +0530
Subject: [PATCH 05/35] [RISCV] Fold 26-bit frame-index offsets into
 Xqcilo/Xqcilia load/store/addi (#209315)

Extend frame-index addressing such that the sp-relative offset resolved for a stack access that fits within 26-bit and not 12-bits; folds directly into the wide Xqcilo/Xqcilia instructions. This is achieved by adding the support for the following:

- Adding support for stack accesses to complex pattern `SelectAddrRegImm26` for 26-bit loads and stores
- Adding support for frame index operand to qc.e.addi instruction
- Allowing 26-bit offsets to fold into the loads and store instructions from qcilo/qcilia extension

(cherry picked from commit 79d1db7e00932407c4aa1028632f2c188d14cac8)
---
 llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp   |   6 +
 llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td   |   7 ++
 llvm/lib/Target/RISCV/RISCVInstrPredicates.td |  22 ++++
 llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp   |   6 +
 .../RISCV/xqcilo-xqcilia-frame-index.ll       | 113 ++++++++++++++++++
 5 files changed, 154 insertions(+)
 create mode 100644 llvm/test/CodeGen/RISCV/xqcilo-xqcilia-frame-index.ll

diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index c86926e075c99..8d9c2d519274c 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -3579,6 +3579,10 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
 /// compressible) standard load/store instructions.
 bool RISCVDAGToDAGISel::SelectAddrRegImm26(SDValue Addr, SDValue &Base,
                                            SDValue &Offset) {
+
+  if (SelectAddrFrameIndex(Addr, Base, Offset))
+    return true;
+
   SDLoc DL(Addr);
   MVT VT = Addr.getSimpleValueType();
 
@@ -3588,6 +3592,8 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm26(SDValue Addr, SDValue &Base,
     // load/store.
     if (isInt<26>(CVal) && !isInt<12>(CVal)) {
       Base = Addr.getOperand(0);
+      if (auto *FIN = dyn_cast<FrameIndexSDNode>(Base))
+        Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), VT);
       Offset = CurDAG->getSignedTargetConstant(CVal, DL, VT);
       return true;
     }
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index bb7b2bf08644e..ea3c5927f1da8 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -1635,6 +1635,13 @@ def : PatGprNoX0Simm26NoSimm12<or, QC_E_ORI>;
 def : PatGprNoX0Simm26NoSimm12<xor, QC_E_XORI>;
 } // Predicates = [HasVendorXqcilia, IsRV32]
 
+/// FrameIndex calculations
+
+let Predicates = [HasVendorXqcilia, IsRV32] in {
+  def : Pat<(riscv_add_like frameindex:$fi, simm26_nosimm12:$offset),
+            (QC_E_ADDI (iPTR (to_tframeindex $fi)), simm26_nosimm12:$offset)>;
+} // Predicates = [HasVendorXqcilia, IsRV32]
+
 /// Load/Store operations
 
 let Predicates = [HasVendorXqcilo, IsRV32], AddedComplexity = 2 in {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrPredicates.td b/llvm/lib/Target/RISCV/RISCVInstrPredicates.td
index 367f91bb9902f..cff834150cfeb 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrPredicates.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrPredicates.td
@@ -242,3 +242,25 @@ def isBaseStore
                        SH,
                        SB,
                      ]>>>;
+
+// Xqcilo 26-bit offset Loads (qc.e.lb, qc.e.lbu, qc.e.lh, qc.e.lhu, qc.e.lw)
+def isBaseQCLoad
+    : TIIPredicate<"isBaseQCLoad",
+                   MCReturnStatement<
+                     CheckOpcode<[
+                       QC_E_LB,
+                       QC_E_LBU,
+                       QC_E_LH,
+                       QC_E_LHU,
+                       QC_E_LW
+                     ]>>>;
+
+// Xqcilo 26-bit offset Stores (qc.e.sb, qc.e.sh, qc.e.sw)
+def isBaseQCStore
+    : TIIPredicate<"isBaseQCStore",
+                   MCReturnStatement<
+                     CheckOpcode<[
+                       QC_E_SB,
+                       QC_E_SH,
+                       QC_E_SW
+                     ]>>>;
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
index 7dbdc881ea6c0..3311841505685 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
@@ -588,6 +588,7 @@ bool RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
   if (!IsRVVSpill) {
     int64_t Val = Offset.getFixed();
     int64_t Lo12 = SignExtend64<12>(Val);
+    int64_t Lo26 = SignExtend64<26>(Val);
     unsigned Opc = MI.getOpcode();
 
     if (Opc == RISCV::ADDI && !isInt<12>(Val)) {
@@ -614,6 +615,11 @@ bool RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
       // instruction will add 4 to the immediate. If that would overflow 12
       // bits, we can't fold the offset.
       MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);
+    } else if (Opc == RISCV::QC_E_ADDI || RISCVInstrInfo::isBaseQCLoad(MI) ||
+               RISCVInstrInfo::isBaseQCStore(MI)) {
+      MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Lo26);
+      Offset = StackOffset::get((uint64_t)Val - (uint64_t)Lo26,
+                                Offset.getScalable());
     } else {
       // We can encode an add with 12 bit signed immediate in the immediate
       // operand of our user instruction.  As a result, the remaining
diff --git a/llvm/test/CodeGen/RISCV/xqcilo-xqcilia-frame-index.ll b/llvm/test/CodeGen/RISCV/xqcilo-xqcilia-frame-index.ll
new file mode 100644
index 0000000000000..eaf5b78f30ff2
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/xqcilo-xqcilia-frame-index.ll
@@ -0,0 +1,113 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; Frame-index addressing for the Qualcomm Xqcilo/Xqcilia large-offset
+; instructions (qc.e.lw/qc.e.sw/qc.e.addi). Stack accesses whose resolved
+; sp-relative offset is a 26-bit (but not 12-bit) signed immediate fold the
+; offset directly into the wide instruction instead of materialising a base.
+;
+; RUN: llc < %s -mtriple=riscv32 -mattr=+xqcilo,+xqcilia -riscv-no-aliases \
+; RUN:   | FileCheck %s
+
+; Load variant: A load at a large (simm26, not simm12) offset off a stack slot
+; folds the resolved frame offset into a single qc.e.lw. The offset-0 access
+; keeps the alloca live.
+define i32 @stack_fi_load(i32 %x) nounwind {
+; CHECK-LABEL: stack_fi_load:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    qc.e.addi sp, sp, -4000016
+; CHECK-NEXT:    qc.e.lw a1, 3000016(sp)
+; CHECK-NEXT:    c.mv a2, a0
+; CHECK-NEXT:    c.mv a0, a1
+; CHECK-NEXT:    c.swsp a2, 16(sp)
+; CHECK-NEXT:    qc.e.addi sp, sp, 4000016
+; CHECK-NEXT:    c.jr ra
+entry:
+  %arr = alloca [4000000 x i8], align 4
+  %p0 = getelementptr inbounds [4000000 x i8], ptr %arr, i32 0, i32 0
+  store i32 %x, ptr %p0, align 4
+  %p1 = getelementptr inbounds [4000000 x i8], ptr %arr, i32 0, i32 3000000
+  %v = load i32, ptr %p1, align 4
+  ret i32 %v
+}
+
+; Store variant: a store at a large (simm26, not simm12) offset off a stack slot
+; folds into a single qc.e.sw.
+define void @stack_fi_store(i32 %x) nounwind {
+; CHECK-LABEL: stack_fi_store:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    qc.e.addi sp, sp, -4000016
+; CHECK-NEXT:    qc.e.sw a0, 3000016(sp)
+; CHECK-NEXT:    c.swsp a0, 16(sp)
+; CHECK-NEXT:    qc.e.addi sp, sp, 4000016
+; CHECK-NEXT:    c.jr ra
+entry:
+  %arr = alloca [4000000 x i8], align 4
+  %p1 = getelementptr inbounds [4000000 x i8], ptr %arr, i32 0, i32 3000000
+  store i32 %x, ptr %p1, align 4
+  %p0 = getelementptr inbounds [4000000 x i8], ptr %arr, i32 0, i32 0
+  store i32 %x, ptr %p0, align 4
+  ret void
+}
+
+; The address of a large-offset stack element escapes via a call, so it must be
+; materialised as a value. The (frameindex + simm26) computation selects
+; QC_E_ADDI and folds the resolved 26-bit frame offset into it.
+declare void @use(ptr)
+define void @fi_addr_escapes(i32 %x) nounwind {
+; CHECK-LABEL: fi_addr_escapes:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    c.addi16sp sp, -256
+; CHECK-NEXT:    c.swsp ra, 252(sp) # 4-byte Folded Spill
+; CHECK-NEXT:    qc.e.addi sp, sp, -3999760
+; CHECK-NEXT:    qc.e.addi a0, sp, 3000012
+; CHECK-NEXT:    call use
+; CHECK-NEXT:    c.addi4spn a0, sp, 12
+; CHECK-NEXT:    call use
+; CHECK-NEXT:    qc.e.addi sp, sp, 3999760
+; CHECK-NEXT:    c.lwsp ra, 252(sp) # 4-byte Folded Reload
+; CHECK-NEXT:    c.addi16sp sp, 256
+; CHECK-NEXT:    c.jr ra
+  %arr = alloca [4000000 x i8], align 4
+  %p1 = getelementptr inbounds [4000000 x i8], ptr %arr, i32 0, i32 3000000
+  call void @use(ptr %p1)
+  %p0 = getelementptr inbounds [4000000 x i8], ptr %arr, i32 0, i32 0
+  call void @use(ptr %p0)
+  ret void
+}
+
+; A bare frame index (offset 0) whose slot resolves to a large (simm26, not
+; simm12) sp-relative offset. The small alloca is placed first so the allocator
+; lays it out high in the frame (sp + ~8204).
+define i32 @bare_fi_high_frame() nounwind {
+; CHECK-LABEL: bare_fi_high_frame:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    qc.e.addi sp, sp, -8208
+; CHECK-NEXT:    c.li a0, 1
+; CHECK-NEXT:    c.swsp a0, 12(sp)
+; CHECK-NEXT:    qc.e.lw a0, 8204(sp)
+; CHECK-NEXT:    qc.e.addi sp, sp, 8208
+; CHECK-NEXT:    c.jr ra
+  %small = alloca i32
+  %big = alloca [8192 x i8], align 4
+  %pb = getelementptr [8192 x i8], ptr %big, i32 0, i32 0
+  store volatile i32 1, ptr %pb
+  %v = load i32, ptr %small
+  ret i32 %v
+}
+
+; Store variant of the bare-frame-index case.
+define void @bare_fi_high_frame_store(i32 %x) nounwind {
+; CHECK-LABEL: bare_fi_high_frame_store:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    qc.e.addi sp, sp, -8208
+; CHECK-NEXT:    c.li a1, 1
+; CHECK-NEXT:    c.swsp a1, 12(sp)
+; CHECK-NEXT:    qc.e.sw a0, 8204(sp)
+; CHECK-NEXT:    qc.e.addi sp, sp, 8208
+; CHECK-NEXT:    c.jr ra
+  %small = alloca i32
+  %big = alloca [8192 x i8], align 4
+  %pb = getelementptr [8192 x i8], ptr %big, i32 0, i32 0
+  store volatile i32 1, ptr %pb
+  store i32 %x, ptr %small
+  ret void
+}

>From 6e708e7d66bb2c8daee1334068190c3138ca20ee Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at hanshq.net>
Date: Tue, 14 Jul 2026 22:10:27 +0200
Subject: [PATCH 06/35] Revert "[Clang] Allow devirtualization involving array
 subscripts with constant indices when the pointee type is known [CWG1504]
 (#207540) (#209596)

It caused miscompiles, see discussion on the PR.

This reverts commit ee24ac00d874ce82eaf36431f9aeb2ad744bc3b8.

(cherry picked from commit 04aa50715cafa5f205b44bc88a6f721d296ec91c)
---
 clang/lib/AST/DeclCXX.cpp                     | 35 ----------------
 clang/test/CXX/drs/cwg15xx.cpp                | 19 ---------
 .../devirtualize-virtual-function-calls.cpp   | 42 +------------------
 clang/www/cxx_dr_status.html                  |  2 +-
 4 files changed, 3 insertions(+), 95 deletions(-)

diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index ef7e58536202b..0573cdf95952a 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -2600,41 +2600,6 @@ CXXMethodDecl *CXXMethodDecl::getDevirtualizedMethod(const Expr *Base,
     }
   }
 
-  // By CWG1504 / C++11 [expr.add]p6, pointer arithmetic on a base pointer into
-  // an array of derived objects is undefined behavior when the element type and
-  // pointee type are not similar. This means we can devirtualize calls on
-  // objects accessed through array subscripts or pointer arithmetic with
-  // non-zero offsets, since the dynamic type must match the static type.
-  //
-  // A single object is considered to be an array of one element, so p[0]
-  // could still be a derived object, but p[N] for N != 0 cannot.
-  const Expr *Inner = Base->IgnoreParenImpCasts();
-  if (const auto *UO = dyn_cast<UnaryOperator>(Inner))
-    if (UO->getOpcode() == UO_Deref)
-      Inner = UO->getSubExpr()->IgnoreParenImpCasts();
-
-  // Handle p[N].f() (dot syntax with array subscript).
-  if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(Inner)) {
-    Expr::EvalResult Result;
-    if (ASE->getIdx()->EvaluateAsInt(Result, getASTContext()) &&
-        !Result.Val.getInt().isZero())
-      return DevirtualizedMethod;
-  }
-
-  // Handle (p + N)->f() (arrow syntax with pointer arithmetic).
-  if (const auto *BO = dyn_cast<BinaryOperator>(Inner)) {
-    if (BO->getOpcode() == BO_Add || BO->getOpcode() == BO_Sub) {
-      // Identify the integer operand (the offset).
-      const Expr *IdxExpr = BO->getLHS()->getType()->isPointerType()
-                                ? BO->getRHS()
-                                : BO->getLHS();
-      Expr::EvalResult Result;
-      if (IdxExpr->EvaluateAsInt(Result, getASTContext()) &&
-          !Result.Val.getInt().isZero())
-        return DevirtualizedMethod;
-    }
-  }
-
   // We can't devirtualize the call.
   return nullptr;
 }
diff --git a/clang/test/CXX/drs/cwg15xx.cpp b/clang/test/CXX/drs/cwg15xx.cpp
index 53f262740eae2..5a9b80ed028c4 100644
--- a/clang/test/CXX/drs/cwg15xx.cpp
+++ b/clang/test/CXX/drs/cwg15xx.cpp
@@ -11,25 +11,6 @@
 // cxx98-error at -1 {{variadic macros are a C99 feature}}
 #endif
 
-namespace cwg1504 { // cwg1504: 23
-#if __cplusplus >= 201103L
-  // CWG1504: Pointer arithmetic after derived-base conversion
-  struct Base { int x; };
-  struct Derived : Base { int y; };
-  constexpr Derived arr[2] = {};
-
-  // Pointer arithmetic on a base pointer into a derived array is UB,
-  // and the constexpr evaluator must diagnose it.
-  constexpr int test(int n) {
-    return ((const Base*)arr)[n].x; // #cwg1504-x
-  }
-  constexpr int bad = test(1);
-  // since-cxx11-error at -1 {{constexpr variable 'bad' must be initialized by a constant expression}}
-  // since-cxx11-note@#cwg1504-x {{cannot access field of pointer past the end of object}}
-  // since-cxx11-note at -3 {{in call to 'test(1)'}}
-#endif
-} // namespace cwg1504
-
 namespace cwg1512 { // cwg1512: 4
   void f(char *p) {
     if (p > 0) {}
diff --git a/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp b/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
index 32a887e8fbcc9..b50881db63e05 100644
--- a/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
+++ b/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
@@ -92,48 +92,10 @@ void fd(D d, XD xd, D *p) {
   // CHECK: call void %
   p[0].f();
 
-  // We can devirtualize this, by CWG1504 / [expr.add]/6 (if the array
+  // FIXME: We can devirtualize this, by C++1z [expr.add]/6 (if the array
   // element type and the pointee type are not similar, behavior is undefined).
-  // CHECK: call void @_ZN1A1fEv
-  p[1].f();
-
-  // Negative indices are also UB for the same reason.
-  // CHECK: call void @_ZN1A1fEv
-  p[-1].f();
-
-  // Pointer arithmetic with arrow syntax: (p + N)->f()
-  // CHECK: call void @_ZN1A1fEv
-  (p + 1)->f();
-
-  // Pointer subtraction with arrow syntax: (p - N)->f()
-  // CHECK: call void @_ZN1A1fEv
-  (p - 1)->f();
-
-  // Can't devirtualize with non-constant index; we can't prove N != 0.
-  int n = 1;
-  // CHECK: call void %
-  p[n].f();
-
-  // Zero through expression: p[1-1] evaluates to 0, can't devirtualize.
-  // CHECK: call void %
-  p[1-1].f();
-
-  // (p + 0)->f() also can't be devirtualized (same as *p).
   // CHECK: call void %
-  (p + 0)->f();
-
-  // 1 + p is legal pointer arithmetic too.
-  // CHECK: call void @_ZN1A1fEv
-  (1 + p)->f();
-
-  // Constant variables are evaluated.
-  const int N = 1;
-  // CHECK: call void @_ZN1A1fEv
-  p[N].f();
-
-  // Pointer arithmetic with deref: *(p + 1)
-  // CHECK: call void @_ZN1A1fEv
-  (*(p + 1)).f();
+  p[1].f();
 }
 
 struct B {
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 73c8be98e7848..af91ac559d274 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -10309,7 +10309,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
     <td>[<a href="https://wg21.link/expr.add">expr.add</a>]</td>
     <td>CD3</td>
     <td>Pointer arithmetic after derived-base conversion</td>
-    <td class="full" align="center">Clang 23</td>
+    <td class="unknown" align="center">Unknown</td>
   </tr>
   <tr id="1505">
     <td><a href="https://cplusplus.github.io/CWG/issues/1505.html">1505</a></td>

>From 8cc33c0fec099662f6e9ecb9e0a0c792b3643967 Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Tue, 14 Jul 2026 09:32:11 -0700
Subject: [PATCH 07/35] [Clang] Require x86 target for some tests (#209532)

These tests assert behavior about the always-inliner which now requires
a target to be present to check function attribute compatibility for
inlining.

Fix forward for 37b8e765ce4837a7577e6f762bcdffe4b232759c.

(cherry picked from commit 97f76580cdb0893d0b4edc7adf703162a23c0a67)
---
 clang/test/CodeGen/memcmp-inline-builtin-to-asm.c | 2 ++
 clang/test/CodeGen/memcpy-inline-builtin.c        | 2 ++
 clang/test/CodeGen/pr9614.c                       | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/clang/test/CodeGen/memcmp-inline-builtin-to-asm.c b/clang/test/CodeGen/memcmp-inline-builtin-to-asm.c
index 1dae1d8f0143d..e1347bd36d17b 100644
--- a/clang/test/CodeGen/memcmp-inline-builtin-to-asm.c
+++ b/clang/test/CodeGen/memcmp-inline-builtin-to-asm.c
@@ -1,5 +1,7 @@
 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
 
+// REQUIRES: x86-registered-target
+
 // RUN: %clang_cc1 -triple x86_64 -emit-llvm -o - %s | opt -S -passes=verify | FileCheck %s
 //
 // Verifies that clang detects memcmp inline version and uses it instead of the builtin.
diff --git a/clang/test/CodeGen/memcpy-inline-builtin.c b/clang/test/CodeGen/memcpy-inline-builtin.c
index d287ce361f571..bb86eb6515349 100644
--- a/clang/test/CodeGen/memcpy-inline-builtin.c
+++ b/clang/test/CodeGen/memcpy-inline-builtin.c
@@ -1,5 +1,7 @@
 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
 
+// REQUIRES: x86-registered-target
+
 // RUN: %clang_cc1 -triple x86_64 -emit-llvm -o - %s | FileCheck %s
 //
 // Verifies that clang detects memcpy inline version and uses it instead of the builtin.
diff --git a/clang/test/CodeGen/pr9614.c b/clang/test/CodeGen/pr9614.c
index 394af32fd6cb3..d8a7a1add5f7c 100644
--- a/clang/test/CodeGen/pr9614.c
+++ b/clang/test/CodeGen/pr9614.c
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -triple x86_64-pc-linux -emit-llvm %s -o - | FileCheck %s
 
+// REQUIRES: x86-registered-target
+
 extern void foo_alias (void) __asm ("foo");
 inline void foo (void) {
   return foo_alias ();

>From a431e974f000a55eef4936a92965034eb1f5acaf Mon Sep 17 00:00:00 2001
From: Krisitan Erik Olsen <kristian.erik at outlook.com>
Date: Wed, 15 Jul 2026 02:18:18 -0700
Subject: [PATCH 08/35] [X86] Skip debug instructions in tile copy lowering
 (#209640)

X86LowerTileCopy iterates over instructions in reverse to track live
registers, calling LiveRegUnits::stepBackward on every instruction
unconditionally. Since commit 16b2ef32 added an assertion that
stepBackward must not receive debug instructions, functions containing
debug info hit the assertion during tile copy lowering.
This patch skips debug instructions early in the loop, matching the
guard pattern used in RegisterScavenging.cpp and X86FixupBWInsts.cpp.

Fixes #209512

(cherry picked from commit 3e4160fdc3d5bb0ed86480604bdfcd3130e7dd37)
---
 llvm/lib/Target/X86/X86LowerTileCopy.cpp |  2 ++
 llvm/test/CodeGen/X86/AMX/pr209512.ll    | 28 ++++++++++++++++++++++++
 2 files changed, 30 insertions(+)
 create mode 100644 llvm/test/CodeGen/X86/AMX/pr209512.ll

diff --git a/llvm/lib/Target/X86/X86LowerTileCopy.cpp b/llvm/lib/Target/X86/X86LowerTileCopy.cpp
index e5a374dfcc0b6..628f691279600 100644
--- a/llvm/lib/Target/X86/X86LowerTileCopy.cpp
+++ b/llvm/lib/Target/X86/X86LowerTileCopy.cpp
@@ -87,6 +87,8 @@ static bool lowerTileCopy(MachineFunction &MF) {
     LiveRegUnits UsedRegs(*TRI);
     UsedRegs.addLiveOuts(MBB);
     for (MachineInstr &MI : llvm::make_early_inc_range(reverse(MBB))) {
+      if (MI.isDebugInstr())
+        continue;
       UsedRegs.stepBackward(MI);
       if (!MI.isCopy())
         continue;
diff --git a/llvm/test/CodeGen/X86/AMX/pr209512.ll b/llvm/test/CodeGen/X86/AMX/pr209512.ll
new file mode 100644
index 0000000000000..975aa5c1e5f6c
--- /dev/null
+++ b/llvm/test/CodeGen/X86/AMX/pr209512.ll
@@ -0,0 +1,28 @@
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+amx-int8 -mattr=+avx512f -verify-machineinstrs -o /dev/null
+
+define void @test_debug_instr(ptr %arg) #0 !dbg !4 {
+  #dbg_declare(ptr %arg, !12, !DIExpression(), !15)
+  %1 = call x86_amx @llvm.x86.cast.vector.to.tile.v1024i8(<1024 x i8> zeroinitializer)
+  %2 = call x86_amx @llvm.x86.tdpbssd.internal(i16 0, i16 0, i16 0, x86_amx %1, x86_amx %1, x86_amx %1)
+  ret void
+}
+
+declare x86_amx @llvm.x86.cast.vector.to.tile.v1024i8(<1024 x i8>) #1
+declare x86_amx @llvm.x86.tdpbssd.internal(i16, i16, i16, x86_amx, x86_amx, x86_amx) #2
+
+attributes #0 = { "target-features"="+amx-int8" }
+attributes #1 = { nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #2 = { nounwind }
+
+!llvm.module.flags = !{!0}
+!llvm.dbg.cu = !{!1}
+
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DICompileUnit(language: DW_LANG_C11, file: !2, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, nameTableKind: None)
+!2 = !DIFile(filename: "test.c", directory: "/tmp")
+!3 = !{}
+!4 = distinct !DISubprogram(name: "test_debug_instr", linkageName: "test_debug_instr", scope: !2, file: !2, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !1, retainedNodes: !3)
+!9 = distinct !DISubroutineType(types: !3)
+!12 = distinct !DILocalVariable(name: "a", arg: 1, scope: !4, file: !2, line: 1, type: !13)
+!13 = !DICompositeType(tag: DW_TAG_structure_type, name: "__tile1024i", scope: !4, file: !2, size: 16384, align: 8192, flags: DIFlagPublic, elements: !3, identifier: "__tile1024i")
+!15 = !DILocation(line: 1, column: 1, scope: !4)

>From ed334243b371778ed994f6bec07b49bb33379d4a Mon Sep 17 00:00:00 2001
From: Lukacma <Marian.Lukac at arm.com>
Date: Wed, 15 Jul 2026 13:25:07 +0100
Subject: [PATCH 09/35] [AArch64] Remove HCX feature flag from backend
 (#209477)

This patch removes +hcx option from the llvm and removes guarding of
HCRX_EL2 system register on it.

(cherry picked from commit f48200029bf6277d4fe3915b480a5c87c8f172c9)
---
 .../Driver/print-enabled-extensions/aarch64-ampere1b.c |  1 -
 .../Driver/print-enabled-extensions/aarch64-ampere1c.c |  1 -
 .../print-enabled-extensions/aarch64-apple-a16.c       |  1 -
 .../print-enabled-extensions/aarch64-apple-a17.c       |  1 -
 .../Driver/print-enabled-extensions/aarch64-apple-m4.c |  1 -
 .../Driver/print-enabled-extensions/aarch64-apple-m5.c |  1 -
 .../print-enabled-extensions/aarch64-armv8.7-a.c       |  1 -
 .../print-enabled-extensions/aarch64-armv8.8-a.c       |  1 -
 .../print-enabled-extensions/aarch64-armv8.9-a.c       |  1 -
 .../print-enabled-extensions/aarch64-armv9.2-a.c       |  1 -
 .../print-enabled-extensions/aarch64-armv9.3-a.c       |  1 -
 .../print-enabled-extensions/aarch64-armv9.4-a.c       |  1 -
 .../print-enabled-extensions/aarch64-armv9.5-a.c       |  1 -
 .../Driver/print-enabled-extensions/aarch64-c1-nano.c  |  1 -
 .../print-enabled-extensions/aarch64-c1-premium.c      |  1 -
 .../Driver/print-enabled-extensions/aarch64-c1-pro.c   |  1 -
 .../Driver/print-enabled-extensions/aarch64-c1-ultra.c |  1 -
 .../print-enabled-extensions/aarch64-cortex-a320.c     |  2 --
 .../print-enabled-extensions/aarch64-cortex-a520.c     |  1 -
 .../print-enabled-extensions/aarch64-cortex-a520ae.c   |  1 -
 .../print-enabled-extensions/aarch64-cortex-a720.c     |  1 -
 .../print-enabled-extensions/aarch64-cortex-a720ae.c   |  1 -
 .../print-enabled-extensions/aarch64-cortex-a725.c     |  1 -
 .../print-enabled-extensions/aarch64-cortex-x4.c       |  1 -
 .../print-enabled-extensions/aarch64-cortex-x925.c     |  1 -
 .../print-enabled-extensions/aarch64-fujitsu-monaka.c  |  1 -
 .../Driver/print-enabled-extensions/aarch64-gb10.c     |  1 -
 .../Driver/print-enabled-extensions/aarch64-hip12.c    |  1 -
 .../print-enabled-extensions/aarch64-neoverse-n3.c     |  1 -
 .../print-enabled-extensions/aarch64-neoverse-v3.c     |  1 -
 .../print-enabled-extensions/aarch64-neoverse-v3ae.c   |  1 -
 .../Driver/print-enabled-extensions/aarch64-olympus.c  |  1 -
 .../Driver/print-enabled-extensions/aarch64-rigel.c    |  1 -
 llvm/lib/Target/AArch64/AArch64Features.td             |  5 +----
 llvm/lib/Target/AArch64/AArch64Processors.td           | 10 ++++------
 llvm/lib/Target/AArch64/AArch64SystemOperands.td       |  4 +---
 llvm/test/MC/AArch64/armv8.7a-hcx.s                    |  7 +------
 llvm/test/MC/Disassembler/AArch64/armv8.7a-hcx.txt     |  6 +-----
 38 files changed, 8 insertions(+), 58 deletions(-)

diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-ampere1b.c b/clang/test/Driver/print-enabled-extensions/aarch64-ampere1b.c
index 444ac4526200f..dc5e5de05e1e5 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-ampere1b.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-ampere1b.c
@@ -27,7 +27,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-ampere1c.c b/clang/test/Driver/print-enabled-extensions/aarch64-ampere1c.c
index d3c1e7ebefd9e..8ec11dea30f23 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-ampere1c.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-ampere1c.c
@@ -30,7 +30,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-apple-a16.c b/clang/test/Driver/print-enabled-extensions/aarch64-apple-a16.c
index 6f417c1592b06..81c21942638e4 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-apple-a16.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-apple-a16.c
@@ -26,7 +26,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-apple-a17.c b/clang/test/Driver/print-enabled-extensions/aarch64-apple-a17.c
index 39e5b70c25d88..75ff0c59a4bbe 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-apple-a17.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-apple-a17.c
@@ -26,7 +26,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-apple-m4.c b/clang/test/Driver/print-enabled-extensions/aarch64-apple-m4.c
index b410124527322..07fd1caea0e22 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-apple-m4.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-apple-m4.c
@@ -26,7 +26,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-apple-m5.c b/clang/test/Driver/print-enabled-extensions/aarch64-apple-m5.c
index ae8923287b2e3..a7eee80014dad 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-apple-m5.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-apple-m5.c
@@ -28,7 +28,6 @@
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
 // CHECK-NEXT:     FEAT_HBC                                               Enable Armv8.8-A Hinted Conditional Branches Extension
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-armv8.7-a.c b/clang/test/Driver/print-enabled-extensions/aarch64-armv8.7-a.c
index 4a8e18b23aac8..9fca36fbdcf46 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-armv8.7-a.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-armv8.7-a.c
@@ -24,7 +24,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-armv8.8-a.c b/clang/test/Driver/print-enabled-extensions/aarch64-armv8.8-a.c
index 160acb524df5c..1db92c1ca9afa 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-armv8.8-a.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-armv8.8-a.c
@@ -25,7 +25,6 @@
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
 // CHECK-NEXT:     FEAT_HBC                                               Enable Armv8.8-A Hinted Conditional Branches Extension
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-armv8.9-a.c b/clang/test/Driver/print-enabled-extensions/aarch64-armv8.9-a.c
index 04bd8fc06049b..58b8242f28560 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-armv8.9-a.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-armv8.9-a.c
@@ -28,7 +28,6 @@
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
 // CHECK-NEXT:     FEAT_HBC                                               Enable Armv8.8-A Hinted Conditional Branches Extension
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-armv9.2-a.c b/clang/test/Driver/print-enabled-extensions/aarch64-armv9.2-a.c
index d3b26122dc6db..6329363ca29bd 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-armv9.2-a.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-armv9.2-a.c
@@ -25,7 +25,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-armv9.3-a.c b/clang/test/Driver/print-enabled-extensions/aarch64-armv9.3-a.c
index 61894f0fcefa5..e2b93c9e89557 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-armv9.3-a.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-armv9.3-a.c
@@ -26,7 +26,6 @@
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
 // CHECK-NEXT:     FEAT_HBC                                               Enable Armv8.8-A Hinted Conditional Branches Extension
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-armv9.4-a.c b/clang/test/Driver/print-enabled-extensions/aarch64-armv9.4-a.c
index 1cfda6c996b9e..31826357172ae 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-armv9.4-a.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-armv9.4-a.c
@@ -29,7 +29,6 @@
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
 // CHECK-NEXT:     FEAT_HBC                                               Enable Armv8.8-A Hinted Conditional Branches Extension
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-armv9.5-a.c b/clang/test/Driver/print-enabled-extensions/aarch64-armv9.5-a.c
index 76c8b34a56b75..4eb48de4206a6 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-armv9.5-a.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-armv9.5-a.c
@@ -31,7 +31,6 @@
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
 // CHECK-NEXT:     FEAT_HBC                                               Enable Armv8.8-A Hinted Conditional Branches Extension
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-c1-nano.c b/clang/test/Driver/print-enabled-extensions/aarch64-c1-nano.c
index 33112527c9add..ebf84aa612d9a 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-c1-nano.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-c1-nano.c
@@ -30,7 +30,6 @@
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
 // CHECK-NEXT:     FEAT_HBC                                               Enable Armv8.8-A Hinted Conditional Branches Extension
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-c1-premium.c b/clang/test/Driver/print-enabled-extensions/aarch64-c1-premium.c
index 3b146e36f81a2..63fc83641191d 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-c1-premium.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-c1-premium.c
@@ -30,7 +30,6 @@
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
 // CHECK-NEXT:     FEAT_HBC                                               Enable Armv8.8-A Hinted Conditional Branches Extension
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-c1-pro.c b/clang/test/Driver/print-enabled-extensions/aarch64-c1-pro.c
index d31a598463267..833a67d0035e2 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-c1-pro.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-c1-pro.c
@@ -30,7 +30,6 @@
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
 // CHECK-NEXT:     FEAT_HBC                                               Enable Armv8.8-A Hinted Conditional Branches Extension
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-c1-ultra.c b/clang/test/Driver/print-enabled-extensions/aarch64-c1-ultra.c
index d3ab7d92eca92..85e609fd13f27 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-c1-ultra.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-c1-ultra.c
@@ -30,7 +30,6 @@
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
 // CHECK-NEXT:     FEAT_HBC                                               Enable Armv8.8-A Hinted Conditional Branches Extension
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a320.c b/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a320.c
index eed89039f3a19..71338d4f679ae 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a320.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a320.c
@@ -26,7 +26,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
@@ -57,4 +56,3 @@
 // CHECK-NEXT:     FEAT_VHE                                               Enable Armv8.1-A Virtual Host extension
 // CHECK-NEXT:     FEAT_WFxT                                              Enable Armv8.7-A WFET and WFIT instruction
 // CHECK-NEXT:     FEAT_XS                                                Enable Armv8.7-A limited-TLB-maintenance instruction
-
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a520.c b/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a520.c
index 5c5f9ba81b5b8..a31428fb9fd5b 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a520.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a520.c
@@ -27,7 +27,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a520ae.c b/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a520ae.c
index d68fc6e744a29..1d82d4548bd09 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a520ae.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a520ae.c
@@ -27,7 +27,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a720.c b/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a720.c
index b7f0ae500ee5e..380586b69fcaf 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a720.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a720.c
@@ -27,7 +27,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a720ae.c b/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a720ae.c
index 8f7139afeca67..dcb9301e339b4 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a720ae.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a720ae.c
@@ -27,7 +27,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a725.c b/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a725.c
index 7c5e7c3624f69..2d531ed1b1dd6 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a725.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-cortex-a725.c
@@ -27,7 +27,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-cortex-x4.c b/clang/test/Driver/print-enabled-extensions/aarch64-cortex-x4.c
index 09ed3f285481b..c846604a340f4 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-cortex-x4.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-cortex-x4.c
@@ -27,7 +27,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-cortex-x925.c b/clang/test/Driver/print-enabled-extensions/aarch64-cortex-x925.c
index 3969c0922c894..31667440c25ec 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-cortex-x925.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-cortex-x925.c
@@ -27,7 +27,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-fujitsu-monaka.c b/clang/test/Driver/print-enabled-extensions/aarch64-fujitsu-monaka.c
index e0802b3866cc8..119e24dee559c 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-fujitsu-monaka.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-fujitsu-monaka.c
@@ -35,7 +35,6 @@
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
 // CHECK-NEXT:     FEAT_HBC                                               Enable Armv8.8-A Hinted Conditional Branches Extension
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-gb10.c b/clang/test/Driver/print-enabled-extensions/aarch64-gb10.c
index f482a1bd1a31e..4b1d0013094c6 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-gb10.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-gb10.c
@@ -28,7 +28,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-hip12.c b/clang/test/Driver/print-enabled-extensions/aarch64-hip12.c
index 6370303909839..8494b01967bc6 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-hip12.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-hip12.c
@@ -30,7 +30,6 @@
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
 // CHECK-NEXT:     FEAT_HBC                                               Enable Armv8.8-A Hinted Conditional Branches Extension
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-neoverse-n3.c b/clang/test/Driver/print-enabled-extensions/aarch64-neoverse-n3.c
index 9819a8388f039..ac695755c36f2 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-neoverse-n3.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-neoverse-n3.c
@@ -27,7 +27,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-neoverse-v3.c b/clang/test/Driver/print-enabled-extensions/aarch64-neoverse-v3.c
index f400d5bc3596e..3dfa448a99161 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-neoverse-v3.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-neoverse-v3.c
@@ -28,7 +28,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-neoverse-v3ae.c b/clang/test/Driver/print-enabled-extensions/aarch64-neoverse-v3ae.c
index 67d8377e95227..f8a6596305c8d 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-neoverse-v3ae.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-neoverse-v3ae.c
@@ -29,7 +29,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-olympus.c b/clang/test/Driver/print-enabled-extensions/aarch64-olympus.c
index c50c0b130307b..6eb255c2202ab 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-olympus.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-olympus.c
@@ -35,7 +35,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-rigel.c b/clang/test/Driver/print-enabled-extensions/aarch64-rigel.c
index a8a85a74445e7..c39825c0fb988 100644
--- a/clang/test/Driver/print-enabled-extensions/aarch64-rigel.c
+++ b/clang/test/Driver/print-enabled-extensions/aarch64-rigel.c
@@ -35,7 +35,6 @@
 // CHECK-NEXT:     FEAT_FRINTTS                                           Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int
 // CHECK-NEXT:     FEAT_FlagM                                             Enable Armv8.4-A Flag Manipulation instructions
 // CHECK-NEXT:     FEAT_FlagM2                                            Enable alternative NZCV format for floating point comparisons
-// CHECK-NEXT:     FEAT_HCX                                               Enable Armv8.7-A HCRX_EL2 system register
 // CHECK-NEXT:     FEAT_I8MM                                              Enable Matrix Multiply Int8 Extension
 // CHECK-NEXT:     FEAT_JSCVT                                             Enable Armv8.3-A JavaScript FP conversion instructions
 // CHECK-NEXT:     FEAT_LOR                                               Enable Armv8.1-A Limited Ordering Regions extension
diff --git a/llvm/lib/Target/AArch64/AArch64Features.td b/llvm/lib/Target/AArch64/AArch64Features.td
index 7cb7cd32f673b..59e841792155d 100644
--- a/llvm/lib/Target/AArch64/AArch64Features.td
+++ b/llvm/lib/Target/AArch64/AArch64Features.td
@@ -303,9 +303,6 @@ def FeatureXS : Extension<"xs", "XS", "FEAT_XS",
 def FeatureWFxT : ExtensionWithMArch<"wfxt", "WFxT", "FEAT_WFxT",
   "Enable Armv8.7-A WFET and WFIT instruction">;
 
-def FeatureHCX : Extension<"hcx", "HCX", "FEAT_HCX",
-  "Enable Armv8.7-A HCRX_EL2 system register">;
-
 def FeatureLS64 : ExtensionWithMArch<"ls64", "LS64",
   "FEAT_LS64, FEAT_LS64_V, FEAT_LS64_ACCDATA",
   "Enable Armv8.7-A LD64B/ST64B Accelerator Extension">;
@@ -1065,7 +1062,7 @@ def HasV8_6aOps : Architecture64<8, 6, "a", "v8.6a",
     FeatureEnhancedCounterVirtualization, FeatureMatMulInt8],
   !listconcat(HasV8_5aOps.DefaultExts, [FeatureBF16, FeatureMatMulInt8])>;
 def HasV8_7aOps : Architecture64<8, 7, "a", "v8.7a",
-  [HasV8_6aOps, FeatureXS, FeatureWFxT, FeatureHCX],
+  [HasV8_6aOps, FeatureXS, FeatureWFxT],
   !listconcat(HasV8_6aOps.DefaultExts, [FeatureWFxT, FeatureSPE_EEF])>;
 def HasV8_8aOps : Architecture64<8, 8, "a", "v8.8a",
   [HasV8_7aOps, FeatureHBC, FeatureMOPS, FeatureNMI],
diff --git a/llvm/lib/Target/AArch64/AArch64Processors.td b/llvm/lib/Target/AArch64/AArch64Processors.td
index f8b344c61ba1e..e71aa4d2779e6 100644
--- a/llvm/lib/Target/AArch64/AArch64Processors.td
+++ b/llvm/lib/Target/AArch64/AArch64Processors.td
@@ -835,7 +835,7 @@ def ProcessorFeatures {
                                    FeatureRAS, FeatureSEL2, FeatureTRACEV8_4,
                                    FeatureAltFPCmp, FeatureFRInt3264,
                                    FeatureMTE, FeatureFineGrainedTraps,
-                                   FeatureHCX, FeatureRCPC3, FeatureETE,
+                                   FeatureRCPC3, FeatureETE,
                                    FeatureSVEBitPerm, FeatureSVE2, FeatureTRBE,
                                    FeatureSME, FeatureSME2];
   list<SubtargetFeature> A65  = [HasV8_2aOps, FeatureSHA2, FeatureAES, FeatureFPARMv8,
@@ -917,7 +917,7 @@ def ProcessorFeatures {
                                   FeatureAM, FeatureRAS, FeatureSEL2,
                                   FeatureTRACEV8_4, FeatureAltFPCmp,
                                   FeatureFRInt3264, FeatureMTE,
-                                  FeatureFineGrainedTraps, FeatureHCX,
+                                  FeatureFineGrainedTraps,
                                   FeatureSPE_EEF, FeatureRCPC3, FeatureETE,
                                   FeatureSVEBitPerm, FeatureSVE2, FeatureTRBE,
                                   FeatureSME, FeatureSME2];
@@ -992,7 +992,7 @@ def ProcessorFeatures {
                                       FeatureRAS, FeatureSEL2, FeatureTRACEV8_4,
                                       FeatureAltFPCmp, FeatureFRInt3264,
                                       FeatureMTE, FeatureFineGrainedTraps,
-                                      FeatureHCX, FeatureSPE_EEF, FeatureRCPC3,
+                                      FeatureSPE_EEF, FeatureRCPC3,
                                       FeatureETE, FeatureSVEBitPerm,
                                       FeatureSVE2, FeatureTRBE, FeatureSME,
                                       FeatureSME2];
@@ -1007,7 +1007,7 @@ def ProcessorFeatures {
                                     FeatureSEL2, FeatureTRACEV8_4,
                                     FeatureAltFPCmp, FeatureFRInt3264,
                                     FeatureMTE, FeatureFineGrainedTraps,
-                                    FeatureHCX, FeatureSPE_EEF, FeatureRCPC3,
+                                    FeatureSPE_EEF, FeatureRCPC3,
                                     FeatureETE, FeatureSVEBitPerm, FeatureSVE2,
                                     FeatureTRBE, FeatureSME, FeatureSME2];
   list<SubtargetFeature> A64FX    = [HasV8_2aOps, FeatureFPARMv8, FeatureNEON,
@@ -1069,7 +1069,6 @@ def ProcessorFeatures {
   list<SubtargetFeature> AppleA16 = [HasV8_6aOps, FeatureSHA2, FeatureAES, FeatureFPARMv8,
                                      FeatureNEON, FeaturePerfMon, FeatureSHA3,
                                      FeatureFullFP16, FeatureFP16FML,
-                                     FeatureHCX,
                                      FeatureComplxNum, FeatureCRC, FeatureJS,
                                      FeatureLSE, FeaturePAuth, FeatureFPAC,
                                      FeatureRAS, FeatureRCPC, FeatureRDM,
@@ -1077,7 +1076,6 @@ def ProcessorFeatures {
   list<SubtargetFeature> AppleA17 = [HasV8_6aOps, FeatureSHA2, FeatureAES, FeatureFPARMv8,
                                      FeatureNEON, FeaturePerfMon, FeatureSHA3,
                                      FeatureFullFP16, FeatureFP16FML,
-                                     FeatureHCX,
                                      FeatureComplxNum, FeatureCRC, FeatureJS,
                                      FeatureLSE, FeaturePAuth, FeatureFPAC,
                                      FeatureRAS, FeatureRCPC, FeatureRDM,
diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index b394cd1eca38a..bbe6c39a562c4 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -1257,9 +1257,7 @@ def : RWSysReg<"ACTLR_EL12",         0b11, 0b101, 0b0001, 0b0000, 0b001>;
 def : RWSysReg<"ACTLR_EL2",          0b11, 0b100, 0b0001, 0b0000, 0b001>;
 def : RWSysReg<"ACTLR_EL3",          0b11, 0b110, 0b0001, 0b0000, 0b001>;
 def : RWSysReg<"HCR_EL2",            0b11, 0b100, 0b0001, 0b0001, 0b000>;
-def : RWSysReg<"HCRX_EL2",           0b11, 0b100, 0b0001, 0b0010, 0b010> {
-  let Requires = [{ {AArch64::FeatureHCX} }];
-}
+def : RWSysReg<"HCRX_EL2",           0b11, 0b100, 0b0001, 0b0010, 0b010>;
 def : RWSysReg<"SCR_EL3",            0b11, 0b110, 0b0001, 0b0001, 0b000>;
 def : RWSysReg<"MDCR_EL2",           0b11, 0b100, 0b0001, 0b0001, 0b001>;
 def : RWSysReg<"SDER32_EL3",         0b11, 0b110, 0b0001, 0b0001, 0b001>;
diff --git a/llvm/test/MC/AArch64/armv8.7a-hcx.s b/llvm/test/MC/AArch64/armv8.7a-hcx.s
index d89d6af7b54b8..35086793ace38 100644
--- a/llvm/test/MC/AArch64/armv8.7a-hcx.s
+++ b/llvm/test/MC/AArch64/armv8.7a-hcx.s
@@ -1,12 +1,7 @@
-// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+hcx < %s 2>%t | FileCheck %s
-// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.7a < %s 2>%t | FileCheck %s
-// RUN: not llvm-mc -triple aarch64-none-linux-gnu < %s 2> %t
-// RUN: FileCheck --check-prefix=CHECK-NO-HCX-ERR %s < %t
+// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding < %s | FileCheck %s
 
   mrs x2, HCRX_EL2
 // CHECK: mrs x2, HCRX_EL2              // encoding: [0x42,0x12,0x3c,0xd5]
-// CHECK-NO-HCX-ERR: [[@LINE-2]]:11: error: expected readable system register
 
   msr HCRX_EL2, x3
 // CHECK: msr HCRX_EL2, x3              // encoding: [0x43,0x12,0x1c,0xd5]
-// CHECK-NO-HCX-ERR: [[@LINE-2]]:7: error: expected writable system register
diff --git a/llvm/test/MC/Disassembler/AArch64/armv8.7a-hcx.txt b/llvm/test/MC/Disassembler/AArch64/armv8.7a-hcx.txt
index 9582131e6fdf2..ef68349f2c505 100644
--- a/llvm/test/MC/Disassembler/AArch64/armv8.7a-hcx.txt
+++ b/llvm/test/MC/Disassembler/AArch64/armv8.7a-hcx.txt
@@ -1,11 +1,7 @@
-# RUN: llvm-mc -triple=aarch64 -mattr=+hcx -disassemble %s | FileCheck %s
-# RUN: llvm-mc -triple=aarch64 -mattr=+v8.7a -disassemble %s | FileCheck %s
-# RUN: llvm-mc -triple=aarch64 -disassemble %s | FileCheck --check-prefix=CHECK-NO-HCX %s
+# RUN: llvm-mc -triple=aarch64 -disassemble %s | FileCheck %s
 
 [0x42,0x12,0x3c,0xd5]
 # CHECK: mrs x2, HCRX_EL2
-# CHECK-NO-HCX: mrs x2, S3_4_C1_C2_2
 
 [0x43,0x12,0x1c,0xd5]
 # CHECK: msr HCRX_EL2, x3
-# CHECK-NO-HCX: msr S3_4_C1_C2_2, x3

>From fc48c7e574f87f478ed17cee143afae350f7be88 Mon Sep 17 00:00:00 2001
From: Mel Chen <mel.chen at sifive.com>
Date: Wed, 15 Jul 2026 19:19:38 +0800
Subject: [PATCH 10/35] [VPlan] Fix nowrap flags for strided access pointers
 from SCEV (#209453)

This patch addresses two things. First, the offset calculation
(canonical IV * stride) should not reuse the NSW flag of the add
recurrence. The NSW property from SCEV for the original scalar
recurrence does not necessarily hold for the reconstructed
multiplication using the vector canonical IV. The NUW flag, however, can
still be safely propagated.
Second, because vputils::getGEPFlagsForPtr currently doesn't support
recipes other than VPInstruction, and to avoid relying on LLVM IR
function (like calling stripPointerCasts()), we change
VPVectorPointerRecipe's GEP flags to use the add recurrence's flags to
prevent propagating unprovable GEP flags like inbounds.

(cherry picked from commit 1d4148821bf96bef23ea77952031e3e7bec26d3a)
---
 llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp  | 14 +++++++-------
 .../LoopVectorize/RISCV/strided-accesses-unroll.ll |  4 +---
 .../LoopVectorize/RISCV/strided-accesses.ll        | 10 +++++-----
 3 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index 4da74c5146c52..f37d61f8464fa 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -7787,16 +7787,16 @@ void VPlanTransforms::convertToStridedAccesses(VPlan &Plan,
       auto *AddRecPtr = cast<SCEVAddRecExpr>(PtrSCEV);
       auto *Offset = Builder.createOverflowingOp(
           Instruction::Mul, {CanIV, StrideInBytes},
-          {AddRecPtr->hasNoUnsignedWrap(), AddRecPtr->hasNoSignedWrap()});
-      auto *BasePtr = Builder.createNoWrapPtrAdd(
-          StartVPV, Offset,
-          AddRecPtr->hasNoUnsignedWrap() ? GEPNoWrapFlags::noUnsignedWrap()
-                                         : GEPNoWrapFlags::none());
+          {AddRecPtr->hasNoUnsignedWrap(), /*HasNSW=*/false});
+      GEPNoWrapFlags NWFlags = AddRecPtr->hasNoUnsignedWrap()
+                                   ? GEPNoWrapFlags::noUnsignedWrap()
+                                   : GEPNoWrapFlags::none();
+      VPValue *BasePtr = Builder.createNoWrapPtrAdd(StartVPV, Offset, NWFlags);
 
       // Create a new vector pointer for strided access.
       VPValue *NewPtr = Builder.createVectorPointer(
-          BasePtr, Type::getInt8Ty(Plan.getContext()), StrideInBytes,
-          Ptr->getGEPNoWrapFlags(), Ptr->getDebugLoc());
+          BasePtr, Type::getInt8Ty(Plan.getContext()), StrideInBytes, NWFlags,
+          Ptr->getDebugLoc());
 
       VPValue *Mask = LoadR->getMask();
       if (!Mask)
diff --git a/llvm/test/Transforms/LoopVectorize/RISCV/strided-accesses-unroll.ll b/llvm/test/Transforms/LoopVectorize/RISCV/strided-accesses-unroll.ll
index c4727847d244f..8a53e298af869 100644
--- a/llvm/test/Transforms/LoopVectorize/RISCV/strided-accesses-unroll.ll
+++ b/llvm/test/Transforms/LoopVectorize/RISCV/strided-accesses-unroll.ll
@@ -1,8 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --filter-out-after "^scalar.ph" --version 6
 ; RUN: opt < %s -S -p loop-vectorize -mtriple riscv64 -mattr=+v -force-vector-interleave=2 | FileCheck %s
 
-; FIXME: the second part of the strided load's gep shouldn't have nuw.
-
 define void @negative_stride_nuw(ptr noalias %src, ptr noalias %dst) {
 ; CHECK-LABEL: define void @negative_stride_nuw(
 ; CHECK-SAME: ptr noalias [[SRC:%.*]], ptr noalias [[DST:%.*]]) #[[ATTR0:[0-9]+]] {
@@ -26,7 +24,7 @@ define void @negative_stride_nuw(ptr noalias %src, ptr noalias %dst) {
 ; CHECK-NEXT:    [[TMP8:%.*]] = mul i64 [[INDEX]], -8
 ; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP7]], i64 [[TMP8]]
 ; CHECK-NEXT:    [[TMP10:%.*]] = mul i64 [[TMP2]], -8
-; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr nuw i8, ptr [[TMP9]], i64 [[TMP10]]
+; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr i8, ptr [[TMP9]], i64 [[TMP10]]
 ; CHECK-NEXT:    [[TMP12:%.*]] = call <vscale x 4 x i32> @llvm.experimental.vp.strided.load.nxv4i32.p0.i64(ptr align 4 [[TMP9]], i64 -8, <vscale x 4 x i1> splat (i1 true), i32 [[TMP6]])
 ; CHECK-NEXT:    [[TMP13:%.*]] = call <vscale x 4 x i32> @llvm.experimental.vp.strided.load.nxv4i32.p0.i64(ptr align 4 [[TMP11]], i64 -8, <vscale x 4 x i1> splat (i1 true), i32 [[TMP6]])
 ; CHECK-NEXT:    [[TMP14:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[INDEX]]
diff --git a/llvm/test/Transforms/LoopVectorize/RISCV/strided-accesses.ll b/llvm/test/Transforms/LoopVectorize/RISCV/strided-accesses.ll
index 673d26a02e036..1062ba477bdce 100644
--- a/llvm/test/Transforms/LoopVectorize/RISCV/strided-accesses.ll
+++ b/llvm/test/Transforms/LoopVectorize/RISCV/strided-accesses.ll
@@ -1262,13 +1262,13 @@ define void @double_stride_ptr_iv(ptr %p, ptr %p2, i64 %stride) {
 ; STRIDED-UF2-NEXT:    br i1 [[CMP_N]], label %[[EXIT:.*]], label %[[SCALAR_PH]]
 ; STRIDED-UF2:       [[SCALAR_PH]]:
 ; STRIDED-UF2-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ], [ 0, %[[VECTOR_MEMCHECK]] ]
-; STRIDED-UF2-NEXT:    [[BC_RESUME_VAL16:%.*]] = phi ptr [ [[TMP11]], %[[MIDDLE_BLOCK]] ], [ [[P]], %[[ENTRY]] ], [ [[P]], %[[VECTOR_MEMCHECK]] ]
-; STRIDED-UF2-NEXT:    [[BC_RESUME_VAL17:%.*]] = phi ptr [ [[TMP12]], %[[MIDDLE_BLOCK]] ], [ [[P2]], %[[ENTRY]] ], [ [[P2]], %[[VECTOR_MEMCHECK]] ]
+; STRIDED-UF2-NEXT:    [[BC_RESUME_VAL15:%.*]] = phi ptr [ [[TMP11]], %[[MIDDLE_BLOCK]] ], [ [[P]], %[[ENTRY]] ], [ [[P]], %[[VECTOR_MEMCHECK]] ]
+; STRIDED-UF2-NEXT:    [[BC_RESUME_VAL16:%.*]] = phi ptr [ [[TMP12]], %[[MIDDLE_BLOCK]] ], [ [[P2]], %[[ENTRY]] ], [ [[P2]], %[[VECTOR_MEMCHECK]] ]
 ; STRIDED-UF2-NEXT:    br label %[[LOOP:.*]]
 ; STRIDED-UF2:       [[LOOP]]:
 ; STRIDED-UF2-NEXT:    [[I:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[NEXTI:%.*]], %[[LOOP]] ]
-; STRIDED-UF2-NEXT:    [[PTR:%.*]] = phi ptr [ [[BC_RESUME_VAL16]], %[[SCALAR_PH]] ], [ [[PTR_NEXT:%.*]], %[[LOOP]] ]
-; STRIDED-UF2-NEXT:    [[PTR2:%.*]] = phi ptr [ [[BC_RESUME_VAL17]], %[[SCALAR_PH]] ], [ [[PTR2_NEXT:%.*]], %[[LOOP]] ]
+; STRIDED-UF2-NEXT:    [[PTR:%.*]] = phi ptr [ [[BC_RESUME_VAL15]], %[[SCALAR_PH]] ], [ [[PTR_NEXT:%.*]], %[[LOOP]] ]
+; STRIDED-UF2-NEXT:    [[PTR2:%.*]] = phi ptr [ [[BC_RESUME_VAL16]], %[[SCALAR_PH]] ], [ [[PTR2_NEXT:%.*]], %[[LOOP]] ]
 ; STRIDED-UF2-NEXT:    [[X0:%.*]] = load i32, ptr [[PTR]], align 4
 ; STRIDED-UF2-NEXT:    [[Y0:%.*]] = add i32 [[X0]], 1
 ; STRIDED-UF2-NEXT:    store i32 [[Y0]], ptr [[PTR2]], align 4
@@ -1356,7 +1356,7 @@ define void @constant_stride_reinterpret(ptr noalias %in, ptr noalias %out) {
 ; CHECK-UF2-NEXT:    [[TMP5:%.*]] = shl nuw i64 [[INDEX]], 2
 ; CHECK-UF2-NEXT:    [[TMP6:%.*]] = getelementptr nuw i8, ptr [[IN]], i64 [[TMP5]]
 ; CHECK-UF2-NEXT:    [[TMP7:%.*]] = mul i64 [[TMP3]], 4
-; CHECK-UF2-NEXT:    [[TMP13:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP6]], i64 [[TMP7]]
+; CHECK-UF2-NEXT:    [[TMP13:%.*]] = getelementptr nuw i8, ptr [[TMP6]], i64 [[TMP7]]
 ; CHECK-UF2-NEXT:    [[WIDE_MASKED_GATHER:%.*]] = call <vscale x 2 x i64> @llvm.experimental.vp.strided.load.nxv2i64.p0.i64(ptr align 8 [[TMP6]], i64 4, <vscale x 2 x i1> splat (i1 true), i32 [[TMP12]])
 ; CHECK-UF2-NEXT:    [[WIDE_MASKED_GATHER1:%.*]] = call <vscale x 2 x i64> @llvm.experimental.vp.strided.load.nxv2i64.p0.i64(ptr align 8 [[TMP13]], i64 4, <vscale x 2 x i1> splat (i1 true), i32 [[TMP12]])
 ; CHECK-UF2-NEXT:    [[TMP8:%.*]] = getelementptr inbounds nuw i64, ptr [[OUT]], i64 [[INDEX]]

>From ce6af707aac85db6e176ad0faa3bfe608e1a68f5 Mon Sep 17 00:00:00 2001
From: Erich Keane <ekeane at nvidia.com>
Date: Wed, 15 Jul 2026 09:25:25 -0700
Subject: [PATCH 11/35] Create a Template member to be the MemberSpec of a
 failed TemplVarDecl (#209604)

Patch #200092 changed to no longer check the previous var template when
setting whether the current one is a member specialization. However, if
the previous one was actually an error case (see the example here and in
the report), we ended up trying to do that anyway, which caused an
assertion.

This patch puts in a 'fake' declaration for the not-found declaration after we
emit the 'not found' error for the purposes of allowing our diagnostics to
continue evaluating these without causing problems.

Fixes: #209432
(cherry picked from commit 2c2e43675910603bab1b163655786e4850569d74)
---
 clang/lib/Sema/SemaDecl.cpp                   | 15 +++++++++++++
 .../test/SemaTemplate/class-template-spec.cpp | 21 +++++++++++++++++++
 2 files changed, 36 insertions(+)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 7e1b23c971a9c..c5920f03ed6e1 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -8374,6 +8374,21 @@ NamedDecl *Sema::ActOnVariableDeclarator(
         << Name << computeDeclContext(D.getCXXScopeSpec(), true)
         << D.getCXXScopeSpec().getRange();
       NewVD->setInvalidDecl();
+
+      // if this is a member specialization, we don't have any primary template
+      // to be instantiated from. We set ourselves to a 'fake' clone of this so
+      // that anything that attempts to refer to this invalid declaration can
+      // act as if there IS a primary instantiation.
+      if (NewTemplate && IsMemberSpecialization) {
+        VarDecl *FakeVD =
+            VarDecl::Create(Context, DC, D.getBeginLoc(), D.getIdentifierLoc(),
+                            II, R, TInfo, SC);
+        FakeVD->setInvalidDecl();
+        VarTemplateDecl *FakeInstantiatedFrom = VarTemplateDecl::Create(
+            Context, DC, D.getIdentifierLoc(), Name, TemplateParams, FakeVD);
+        FakeInstantiatedFrom->setInvalidDecl();
+        NewTemplate->setInstantiatedFromMemberTemplate(FakeInstantiatedFrom);
+      }
     }
 
     if (!IsPlaceholderVariable)
diff --git a/clang/test/SemaTemplate/class-template-spec.cpp b/clang/test/SemaTemplate/class-template-spec.cpp
index e2486f912e2c4..e60763feb2e1f 100644
--- a/clang/test/SemaTemplate/class-template-spec.cpp
+++ b/clang/test/SemaTemplate/class-template-spec.cpp
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-linux-gnu -verify=expected,cxx14 -std=c++14 %s
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++26 %s
 
 template<typename T, typename U = int> struct A; // expected-note {{template is declared here}} \
@@ -251,4 +252,24 @@ namespace VarTemplateMismatch {
   template<> template<int> const int A<short>::x = 0;
   // expected-error at -1 {{template non-type parameter has a different type 'int' in template redeclaration}}
 } // namespace VarTemplateMismatch
+
+namespace VarTemplateNoMember {
+  template<typename T> struct S {};
+  // expected-error at +1{{no member named 'foo' in 'VarTemplateNoMember::S<long>'}}
+  template<> template<typename U> constexpr int S<long>::foo;
+  // In C++14, these are definitions, not declarations, so they get a
+  // redefinition error.
+  // cxx14-error at +2{{redefinition of 'foo'}}
+  // cxx14-note at -4{{previous definition is here}}
+  template<> template<typename U> constexpr int S<long>::foo;
+  // cxx14-error at +2{{redefinition of 'foo'}}
+  // cxx14-note at -2{{previous definition is here}}
+  template<> template<typename U> constexpr int S<long>::foo;
+  // cxx14-error at +2{{redefinition of 'foo'}}
+  // cxx14-note at -2{{previous definition is here}}
+  template<> template<typename U> constexpr int S<long>::foo;
+  // cxx14-error at +2{{redefinition of 'foo'}}
+  // cxx14-note at -2{{previous definition is here}}
+  template<> template<typename U> constexpr int S<long>::foo;
+} // namespace VarTemplateNoMember
 #endif

>From f54355e08d91e1f4c87337505936e9299a9ffb99 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=99=88=E5=AD=90=E6=98=82?= <2802328816 at qq.com>
Date: Thu, 16 Jul 2026 00:13:11 +0800
Subject: [PATCH 12/35] [LoopUnroll] Invalidate SCEV after full unrolling
 (#208874)

Full unrolling may leave stale ScalarEvolution loop and disposition
caches around the loop pass boundary. A later IndVars pass can then use
stale exit count information and incorrectly fold reachable exits.

Invalidate SCEV loop and disposition caches after successful full
unrolling before preserving `ScalarEvolutionAnalysis.`

Fixes #207744.

(cherry picked from commit 42c2980c7c632d7a45776d3e2c51627100f6e763)
---
 llvm/lib/Transforms/Utils/LoopUnroll.cpp      |  4 ++
 .../full-unroll-scev-invalidation.ll          | 55 +++++++++++++++++++
 2 files changed, 59 insertions(+)
 create mode 100644 llvm/test/Transforms/LoopUnroll/full-unroll-scev-invalidation.ll

diff --git a/llvm/lib/Transforms/Utils/LoopUnroll.cpp b/llvm/lib/Transforms/Utils/LoopUnroll.cpp
index d00de52e1cb0b..1f9f340a9cb31 100644
--- a/llvm/lib/Transforms/Utils/LoopUnroll.cpp
+++ b/llvm/lib/Transforms/Utils/LoopUnroll.cpp
@@ -1284,6 +1284,10 @@ llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
   // Loop over the PHI nodes in the original block, setting incoming values.
   for (PHINode *PN : OrigPHINode) {
     if (CompletelyUnroll) {
+      // The RAUW below disconnects the original PHI from its users.
+      // Invalidate cached SCEVs while the def-use chain is still intact.
+      if (SE)
+        SE->forgetValue(PN);
       PN->replaceAllUsesWith(PN->getIncomingValueForBlock(Preheader));
       PN->eraseFromParent();
     } else if (ULO.Count > 1) {
diff --git a/llvm/test/Transforms/LoopUnroll/full-unroll-scev-invalidation.ll b/llvm/test/Transforms/LoopUnroll/full-unroll-scev-invalidation.ll
new file mode 100644
index 0000000000000..a9f7a1df0328a
--- /dev/null
+++ b/llvm/test/Transforms/LoopUnroll/full-unroll-scev-invalidation.ll
@@ -0,0 +1,55 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes='loop(indvars,loop-unroll-full)' %s | FileCheck %s
+
+ at __chk = external global i64
+
+define void @f4(i64 %0) {
+; CHECK-LABEL: define void @f4(
+; CHECK-SAME: i64 [[TMP0:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    br label %[[LBL_B5:.*]]
+; CHECK:       [[LBL_B5]]:
+; CHECK-NEXT:    br label %[[LBL_B10:.*]]
+; CHECK:       [[LBL_B10]]:
+; CHECK-NEXT:    [[CONV1:%.*]] = trunc i64 [[TMP0]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[CONV1]])
+; CHECK-NEXT:    [[TOBOOL4_NOT:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    br i1 [[TOBOOL4_NOT]], label %[[COMMON_RET1:.*]], label %[[IF_THEN8:.*]]
+; CHECK:       [[IF_THEN8]]:
+; CHECK-NEXT:    store i64 5, ptr @__chk, align 4
+; CHECK-NEXT:    ret void
+; CHECK:       [[COMMON_RET1]]:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %lbl_b5
+
+lbl_b5:
+  br label %lbl_b10
+
+lbl_b10:
+  %1 = phi i8 [ 0, %lbl_b5 ], [ 1, %lbl_b10 ]
+  %2 = phi i64 [ %0, %lbl_b5 ], [ 0, %lbl_b10 ]
+  %bb13.1 = phi i32 [ 0, %lbl_b5 ], [ %3, %lbl_b10 ]
+  %conv1 = trunc i64 %2 to i32
+  %3 = call i32 @llvm.ctpop.i32(i32 %conv1)
+  %loadedv = trunc i8 %1 to i1
+  br i1 %loadedv, label %if.then3, label %lbl_b10
+
+if.then3:
+  %tobool4.not = icmp eq i32 %bb13.1, 0
+  br i1 %tobool4.not, label %common.ret, label %if.then8
+
+if.then8:
+  br i1 true, label %if.then10, label %lbl_b5
+
+common.ret:
+  ret void
+
+if.then10:
+  %.lcssa.lcssa34 = phi i32 [ %3, %if.then8 ]
+  store i64 5, ptr @__chk
+  ret void
+}
+
+declare i32 @llvm.ctpop.i32(i32)

>From a2520c9f136c302b05b501c05222e0f605897b32 Mon Sep 17 00:00:00 2001
From: Karthika Devi C <kartc at qti.qualcomm.com>
Date: Wed, 15 Jul 2026 15:51:38 +0530
Subject: [PATCH 13/35] [Polly] Skip vectorize.enable for FP loops with dist=1
 dependences (#205756)

When -polly-annotate-metadata-vectorize is active, Polly marks its
generated loops with llvm.loop.vectorize.enable=true. This is harmful
for loops with a loop-carried dependence of distance 1 that involve
floating-point operations: the Loop Vectorizer reorders FP operations
(e.g. scalar reduction like q = factor*q), producing results that differ
from the sequential scalar reference and causing correctness failures.

Two changes are made:

1. IslAst.cpp: add PollyVectorizeMetadata to the PerformParallelTest
gate so that dependence-distance computation is performed whenever
-polly-annotate-metadata-vectorize is passed, not only when
-polly-parallel or a vectorizer is active.

2. IslNodeBuilder.cpp / LoopGenerators.cpp: when a loop has a dist=1
dependence involving FP operations, omit the vectorize.enable annotation
entirely. This lets the Loop Vectorizer apply its own cost model and
legality checks decide.

(cherry picked from commit df1838f5d961f9587ca4f90d992bef81cc6155db)
---
 polly/include/polly/CodeGen/LoopGenerators.h  |  6 +-
 polly/lib/CodeGen/IslAst.cpp                  |  5 +-
 polly/lib/CodeGen/IslNodeBuilder.cpp          | 47 +++++++++++++++-
 polly/lib/CodeGen/LoopGenerators.cpp          | 12 ++--
 .../CodeGen/Metadata/basic_vec_annotate.ll    |  4 +-
 .../Metadata/skip_vec_annotate_fp_dist1.ll    | 56 +++++++++++++++++++
 6 files changed, 118 insertions(+), 12 deletions(-)
 create mode 100644 polly/test/CodeGen/Metadata/skip_vec_annotate_fp_dist1.ll

diff --git a/polly/include/polly/CodeGen/LoopGenerators.h b/polly/include/polly/CodeGen/LoopGenerators.h
index 6076e5951fb0a..39a5bcfe44ec5 100644
--- a/polly/include/polly/CodeGen/LoopGenerators.h
+++ b/polly/include/polly/CodeGen/LoopGenerators.h
@@ -70,13 +70,17 @@ extern int PollyChunkSize;
 ///                           assume it.
 /// @param LoopVectDisabled   If the Loop vectorizer should be disabled for this
 ///                           loop.
+/// @param SkipVectorizeEnableMetadata
+///                           If Polly should avoid setting
+///                           llvm.loop.vectorize.enable=true for this loop.
 ///
 /// @return Value*    The newly created induction variable for this loop.
 Value *createLoop(Value *LowerBound, Value *UpperBound, Value *Stride,
                   PollyIRBuilder &Builder, LoopInfo &LI, DominatorTree &DT,
                   BasicBlock *&ExitBlock, ICmpInst::Predicate Predicate,
                   ScopAnnotator *Annotator = nullptr, bool Parallel = false,
-                  bool UseGuard = true, bool LoopVectDisabled = false);
+                  bool UseGuard = true, bool LoopVectDisabled = false,
+                  bool SkipVectorizeEnableMetadata = false);
 
 /// Create a DebugLoc representing generated instructions.
 ///
diff --git a/polly/lib/CodeGen/IslAst.cpp b/polly/lib/CodeGen/IslAst.cpp
index 0ea14ae2fc2e0..20b6440ebffb5 100644
--- a/polly/lib/CodeGen/IslAst.cpp
+++ b/polly/lib/CodeGen/IslAst.cpp
@@ -81,6 +81,8 @@ static cl::opt<bool> DetectParallel("polly-ast-detect-parallel",
                                     cl::desc("Detect parallelism"), cl::Hidden,
                                     cl::cat(PollyCategory));
 
+extern cl::opt<bool> PollyVectorizeMetadata;
+
 static cl::opt<bool>
     PollyPrintAst("polly-print-ast",
                   cl::desc("Print the ISL abstract syntax tree"),
@@ -501,7 +503,8 @@ IslAst::IslAst(IslAst &&O)
 
 void IslAst::init(const Dependences &D) {
   bool PerformParallelTest = PollyParallel || DetectParallel ||
-                             PollyVectorizerChoice != VECTORIZER_NONE;
+                             PollyVectorizerChoice != VECTORIZER_NONE ||
+                             PollyVectorizeMetadata;
   auto ScheduleTree = S.getScheduleTree();
 
   // Skip AST and code generation if there was no benefit achieved.
diff --git a/polly/lib/CodeGen/IslNodeBuilder.cpp b/polly/lib/CodeGen/IslNodeBuilder.cpp
index 924f6533b0a81..7e395fd4cbd31 100644
--- a/polly/lib/CodeGen/IslNodeBuilder.cpp
+++ b/polly/lib/CodeGen/IslNodeBuilder.cpp
@@ -28,7 +28,6 @@
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/PostOrderIterator.h"
 #include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Analysis/AssumptionCache.h"
 #include "llvm/Analysis/LoopInfo.h"
@@ -75,6 +74,9 @@
 using namespace llvm;
 using namespace polly;
 
+// Declared in LoopGenerators.cpp
+extern llvm::cl::opt<bool> PollyVectorizeMetadata;
+
 #define DEBUG_TYPE "polly-codegen"
 
 STATISTIC(VersionedScops, "Number of SCoPs that required versioning.");
@@ -434,6 +436,34 @@ static bool IsLoopVectorizerDisabled(isl::ast_node_for Node) {
   return false;
 }
 
+/// Returns true if the loop has a dist=1 dependence involving FP operations
+/// (array-carried RAW/WAW or scalar FP reduction). In that case we omit the
+/// vectorize.enable annotation and let the Loop Vectorizer decide.
+static bool hasLoopCarriedDependence(isl::ast_node_for For, const Scop &S) {
+  isl::pw_aff PwaDist = IslAstInfo::getMinimalDependenceDistance(For);
+  if (PwaDist.is_null())
+    return false;
+
+  isl::set Dist = isl::manage(isl_pw_aff_domain(PwaDist.copy()));
+  isl::pw_aff PwaOne = isl::pw_aff(Dist, isl::val::one(S.getIslCtx()));
+  if (isl_pw_aff_is_equal(PwaDist.get(), PwaOne.get()) != isl_bool_true)
+    return false;
+
+  // dist=1: suppress forced vectorization if the body has FP operations.
+  for (isl::set StmtSet :
+       IslAstInfo::getSchedule(For).domain().get_set_list()) {
+    auto *Stmt = static_cast<ScopStmt *>(StmtSet.get_tuple_id().get_user());
+    for (Instruction *Inst : Stmt->getInstructions()) {
+      if (Inst->getType()->isFloatingPointTy() ||
+          (Inst->getNumOperands() > 0 &&
+           Inst->getOperand(0)->getType()->isFloatingPointTy()))
+        return true;
+    }
+  }
+
+  return false;
+}
+
 void IslNodeBuilder::createForSequential(isl::ast_node_for For,
                                          bool MarkParallel) {
   Value *ValueLB, *ValueUB, *ValueInc;
@@ -478,9 +508,22 @@ void IslNodeBuilder::createForSequential(isl::ast_node_for For,
   // omit the GuardBB in front of the loop.
   bool UseGuardBB = !GenSE->isKnownPredicate(Predicate, GenSE->getSCEV(ValueLB),
                                              GenSE->getSCEV(ValueUB));
+
+  // FIXME: This is a workaround for
+  // https://github.com/llvm/llvm-project/issues/198726.
+  // llvm.loop.vectorize.enable=true has an additional property beyond
+  // requesting vectorization — it implicitly allows FP operation reordering.
+  // This is a limitation of the metadata format: there is no way to separate
+  // the request for vectorization from the request for reassociating FP ops.
+  // Once LoopVectorize is fixed to not reorder FP ops without explicit
+  // permission, this workaround can be removed.
+  // For now, skip vectorize.enable for dist=1 FP loops to avoid correctness
+  // failures from FP reassociation.
+  bool SkipVectorizeEnableMetadata = hasLoopCarriedDependence(For, S);
+
   IV = createLoop(ValueLB, ValueUB, ValueInc, Builder, *GenLI, *GenDT,
                   ExitBlock, Predicate, &Annotator, MarkParallel, UseGuardBB,
-                  LoopVectorizerDisabled);
+                  LoopVectorizerDisabled, SkipVectorizeEnableMetadata);
   IDToValue[IteratorID.get()] = IV;
 
   create(Body.release());
diff --git a/polly/lib/CodeGen/LoopGenerators.cpp b/polly/lib/CodeGen/LoopGenerators.cpp
index 57e0cb6377b92..df6fd9df1294d 100644
--- a/polly/lib/CodeGen/LoopGenerators.cpp
+++ b/polly/lib/CodeGen/LoopGenerators.cpp
@@ -90,7 +90,8 @@ Value *polly::createLoop(Value *LB, Value *UB, Value *Stride,
                          DominatorTree &DT, BasicBlock *&ExitBB,
                          ICmpInst::Predicate Predicate,
                          ScopAnnotator *Annotator, bool Parallel, bool UseGuard,
-                         bool LoopVectDisabled) {
+                         bool LoopVectDisabled,
+                         bool SkipVectorizeEnableMetadata) {
   Function *F = Builder.GetInsertBlock()->getParent();
   LLVMContext &Context = F->getContext();
 
@@ -165,15 +166,14 @@ Value *polly::createLoop(Value *LB, Value *UB, Value *Stride,
   // Create the loop latch and annotate it as such.
   CondBrInst *B = Builder.CreateCondBr(LoopCondition, HeaderBB, ExitBB);
 
-  // Don't annotate vectorize metadata when both LoopVectDisabled and
-  // PollyVectorizeMetadata are disabled. Annotate vectorize metadata to false
-  // when LoopVectDisabled is true. Otherwise we annotate the vectorize metadata
-  // to true.
+  // Emit vectorize.enable=false only for explicit user disable
+  // (LoopVectDisabled). For dist=1 FP loops (SkipVectorizeEnableMetadata), omit
+  // the annotation and let the Loop Vectorizer decide.
   if (Annotator) {
     std::optional<bool> EnableVectorizeMetadata;
     if (LoopVectDisabled)
       EnableVectorizeMetadata = false;
-    else if (PollyVectorizeMetadata)
+    else if (PollyVectorizeMetadata && !SkipVectorizeEnableMetadata)
       EnableVectorizeMetadata = true;
     Annotator->annotateLoopLatch(B, Parallel, EnableVectorizeMetadata);
   }
diff --git a/polly/test/CodeGen/Metadata/basic_vec_annotate.ll b/polly/test/CodeGen/Metadata/basic_vec_annotate.ll
index 344a6d0990837..e059fea707321 100644
--- a/polly/test/CodeGen/Metadata/basic_vec_annotate.ll
+++ b/polly/test/CodeGen/Metadata/basic_vec_annotate.ll
@@ -14,8 +14,8 @@
 ; CHECK: br {{.*}} !llvm.loop [[POLLY_LOOP:![0-9]+]]
 ; CHECK: [[LOOP]] = distinct !{[[LOOP]], [[META2:![0-9]+]], [[META3:![0-9]+]]}
 ; CHECK: [[META3]] = !{!"llvm.loop.vectorize.enable", i32 0}
-; CHECK: [[POLLY_LOOP]] = distinct !{[[POLLY_LOOP]], [[META2:![0-9]+]], [[META3:![0-9]+]]}
-; CHECK: [[META3]] = !{!"llvm.loop.vectorize.enable", i1 true}
+; CHECK: [[POLLY_LOOP]] = distinct !{[[POLLY_LOOP]], {{.*}}}
+; CHECK-DAG: !{!"llvm.loop.vectorize.enable", i1 true}
 
 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"
 target triple = "aarch64-unknown-linux-gnu"
diff --git a/polly/test/CodeGen/Metadata/skip_vec_annotate_fp_dist1.ll b/polly/test/CodeGen/Metadata/skip_vec_annotate_fp_dist1.ll
new file mode 100644
index 0000000000000..6ed41b1f64cbd
--- /dev/null
+++ b/polly/test/CodeGen/Metadata/skip_vec_annotate_fp_dist1.ll
@@ -0,0 +1,56 @@
+; RUN: opt %loadNPMPolly -S '-passes=polly<no-default-opts>' -polly-annotate-metadata-vectorize < %s | FileCheck %s
+
+; Verify that vectorize.enable metadata is NOT added for a loop with a dist=1
+; dependence involving floating-point operations. This is a workaround for
+; https://github.com/llvm/llvm-project/issues/198726 where vectorize.enable
+; implicitly allows FP reassociation causing correctness failures.
+
+; void scale(double *A, double factor, int n) {
+;   for (int i = 1; i < n; i++)
+;     A[i] = factor * A[i - 1];
+; }
+
+; The Polly-generated loop should NOT have vectorize.enable metadata.
+; CHECK: polly.stmt.for.body:
+; CHECK: br {{.*}} !llvm.loop [[POLLY_LOOP:![0-9]+]]
+; CHECK: [[POLLY_LOOP]] = distinct !{[[POLLY_LOOP]],
+; CHECK-NOT: !"llvm.loop.vectorize.enable", i1 true
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"
+target triple = "aarch64-unknown-linux-gnu"
+
+define dso_local void @scale(ptr nocapture noundef %A, double noundef %factor, i32 noundef %n) local_unnamed_addr #0 {
+entry:
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  %cmp5 = icmp sgt i32 %n, 1
+  br i1 %cmp5, label %for.body.preheader, label %for.cond.cleanup
+
+for.body.preheader:                               ; preds = %entry.split
+  %wide.trip.count = zext nneg i32 %n to i64
+  br label %for.body
+
+for.cond.cleanup.loopexit:                        ; preds = %for.body
+  br label %for.cond.cleanup
+
+for.cond.cleanup:                                 ; preds = %for.cond.cleanup.loopexit, %entry.split
+  ret void
+
+for.body:                                         ; preds = %for.body.preheader, %for.body
+  %indvars.iv = phi i64 [ 1, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
+  %0 = add nsw i64 %indvars.iv, -1
+  %arrayidx = getelementptr inbounds double, ptr %A, i64 %0
+  %1 = load double, ptr %arrayidx, align 8
+  %mul = fmul double %factor, %1
+  %arrayidx2 = getelementptr inbounds double, ptr %A, i64 %indvars.iv
+  store double %mul, ptr %arrayidx2, align 8
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+  %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count
+  br i1 %exitcond.not, label %for.cond.cleanup.loopexit, label %for.body, !llvm.loop !0
+}
+
+attributes #0 = { nofree norecurse nosync nounwind memory(argmem: readwrite) uwtable "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-a57" "target-features"="+aes,+crc,+fp-armv8,+neon,+outline-atomics,+perfmon,+sha2,+v8a,-fmv" }
+
+!0 = distinct !{!0, !1}
+!1 = !{!"llvm.loop.mustprogress"}

>From 23780df286c2e5914014d002206f1bfde7d0f1b9 Mon Sep 17 00:00:00 2001
From: Karthika Devi C <kartc at qti.qualcomm.com>
Date: Wed, 15 Jul 2026 23:36:45 +0530
Subject: [PATCH 14/35] [Polly] Fix codegen assertions to account for
 DefinedBehaviorContext (#209188)

DeLICM may produce new read access relations whose domain is restricted
to the DefinedBehaviorContext (e.g., only valid when a parameter ensures
no UB). The validation in setNewAccessRelation already accounts for
this, but the debug assertions in createNewAccesses and
generateScalarLoads did not, causing false assertion failures during
code generation.

Intersect the checked domains with getBestKnownDefinedBehaviorContext()
to match the contract that DeLICM relies on.

Fixes #205732

(cherry picked from commit ea612545644d1e3f238ac4cd053758f569f9bf3b)
---
 polly/lib/CodeGen/BlockGenerators.cpp |  5 ++++
 polly/lib/CodeGen/IslNodeBuilder.cpp  | 12 ++++++--
 polly/test/CodeGen/issue205732.ll     | 40 +++++++++++++++++++++++++++
 3 files changed, 55 insertions(+), 2 deletions(-)
 create mode 100644 polly/test/CodeGen/issue205732.ll

diff --git a/polly/lib/CodeGen/BlockGenerators.cpp b/polly/lib/CodeGen/BlockGenerators.cpp
index be01f24f562b2..877bb48ad650a 100644
--- a/polly/lib/CodeGen/BlockGenerators.cpp
+++ b/polly/lib/CodeGen/BlockGenerators.cpp
@@ -555,6 +555,11 @@ void BlockGenerator::generateScalarLoads(
 #ifndef NDEBUG
     auto StmtDom =
         Stmt.getDomain().intersect_params(Stmt.getParent()->getContext());
+    // Restrict to defined behavior context to match DeLICM's contract:
+    // new read accesses are only required to cover the defined-behavior
+    // subset of the domain.
+    StmtDom = StmtDom.intersect_params(
+        Stmt.getParent()->getBestKnownDefinedBehaviorContext());
     auto AccDom = MA->getAccessRelation().domain();
     assert(!StmtDom.is_subset(AccDom).is_false() &&
            "Scalar must be loaded in all statement instances");
diff --git a/polly/lib/CodeGen/IslNodeBuilder.cpp b/polly/lib/CodeGen/IslNodeBuilder.cpp
index 7e395fd4cbd31..93822e5c61615 100644
--- a/polly/lib/CodeGen/IslNodeBuilder.cpp
+++ b/polly/lib/CodeGen/IslNodeBuilder.cpp
@@ -846,9 +846,17 @@ IslNodeBuilder::createNewAccesses(ScopStmt *Stmt,
                                      Stmt->getParent()->getContext().release());
       SchedDom = isl_set_intersect_params(
           SchedDom, Stmt->getParent()->getContext().release());
-      assert(isl_set_is_subset(SchedDom, AccDom) &&
+      // Restrict to defined behavior context to match DeLICM's contract:
+      // new read accesses are only required to cover the defined-behavior
+      // subset of the domain.
+      auto *DefinedBehavior =
+          Stmt->getParent()->getBestKnownDefinedBehaviorContext().release();
+      SchedDom =
+          isl_set_intersect_params(SchedDom, isl_set_copy(DefinedBehavior));
+      Dom = isl_set_intersect_params(Dom, DefinedBehavior);
+      assert(isl_set_is_subset(SchedDom, AccDom) != isl_bool_false &&
              "Access relation not defined on full schedule domain");
-      assert(isl_set_is_subset(Dom, AccDom) &&
+      assert(isl_set_is_subset(Dom, AccDom) != isl_bool_false &&
              "Access relation not defined on full domain");
       isl_set_free(AccDom);
       isl_set_free(SchedDom);
diff --git a/polly/test/CodeGen/issue205732.ll b/polly/test/CodeGen/issue205732.ll
new file mode 100644
index 0000000000000..35dc786df1c4b
--- /dev/null
+++ b/polly/test/CodeGen/issue205732.ll
@@ -0,0 +1,40 @@
+; RUN: opt %loadNPMPolly -passes=polly -S %s | FileCheck %s
+;
+; https://github.com/llvm/llvm-project/issues/205732
+; When DeLICM maps a scalar to an array element, the new access relation
+; may only be valid within the DefinedBehaviorContext (i.e., for parameter
+; values where the original program has no undefined behavior). Code
+; generation must not assert failure for such partial-domain read accesses.
+;
+; CHECK: polly.start:
+
+define void @foo(i32 %w, ptr %dst, i64 %n) {
+entry:
+  br label %for.outer
+
+for.outer:
+  %i = phi i64 [ %i.next, %for.mid.exit ], [ 0, %entry ]
+  br label %for.mid
+
+for.mid:
+  br label %for.inner
+
+for.inner:
+  %0 = phi i32 [ 0, %for.mid ], [ 1, %for.inner ]
+  %1 = load i16, ptr null, align 2
+  %cond1 = icmp eq i32 0, %w
+  br i1 %cond1, label %for.inner.exit, label %for.inner
+
+for.inner.exit:
+  br i1 true, label %for.mid.exit, label %for.mid
+
+for.mid.exit:
+  %ptr = getelementptr [4 x i8], ptr %dst, i64 %i
+  store i32 %0, ptr %ptr, align 4
+  %i.next = add i64 %i, 1
+  %cond2 = icmp eq i64 %i, %n
+  br i1 %cond2, label %for.outer.exit, label %for.outer
+
+for.outer.exit:
+  ret void
+}

>From 88c69e55f3da48bcebdb425f54431f80ce457c8d Mon Sep 17 00:00:00 2001
From: Amy Kwan <amy.kwan1 at ibm.com>
Date: Wed, 15 Jul 2026 15:42:46 -0400
Subject: [PATCH 15/35] [Object][GOFF] Recognize RLD and LEN records (#207118)

This patch adds explicit cases for RT_RLD and RT_LEN records when
parsing GOFF objects. These record types are not handled yet, but
recognizing them allows us to diagnose them and avoids teating them as
unexpected records.

(cherry picked from commit c40401dd8d28e88519433531c041b0b7e5ada8a9)
---
 llvm/lib/Object/GOFFObjectFile.cpp | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Object/GOFFObjectFile.cpp b/llvm/lib/Object/GOFFObjectFile.cpp
index 4ee51a61c14fa..057d3fc208c9b 100644
--- a/llvm/lib/Object/GOFFObjectFile.cpp
+++ b/llvm/lib/Object/GOFFObjectFile.cpp
@@ -170,6 +170,12 @@ GOFFObjectFile::GOFFObjectFile(MemoryBufferRef Object, Error &Err)
       TextPtrs.emplace_back(I);
       LLVM_DEBUG(dbgs() << "  --  TXT\n");
       break;
+    case GOFF::RT_RLD:
+      LLVM_DEBUG(dbgs() << "  --  RLD (GOFF record type) unhandled\n");
+      break;
+    case GOFF::RT_LEN:
+      LLVM_DEBUG(dbgs() << "  --  LEN (GOFF record type) unhandled\n");
+      break;
     case GOFF::RT_END:
       LLVM_DEBUG(dbgs() << "  --  END (GOFF record type) unhandled\n");
       break;
@@ -177,7 +183,10 @@ GOFFObjectFile::GOFFObjectFile(MemoryBufferRef Object, Error &Err)
       LLVM_DEBUG(dbgs() << "  --  HDR (GOFF record type) unhandled\n");
       break;
     default:
-      llvm_unreachable("Unknown record type");
+      Err = createStringError(object_error::parse_failed,
+                              "record %zu has unknown record type 0x%02" PRIX8,
+                              RecordNum, RecordType);
+      return;
     }
     PrevRecordType = RecordType;
     PrevContinuationBits = I[1] & 0x03;

>From c7280675cd04a97c958bcf46db8042e33ab35fc9 Mon Sep 17 00:00:00 2001
From: Erich Keane <ekeane at nvidia.com>
Date: Wed, 15 Jul 2026 06:57:31 -0700
Subject: [PATCH 16/35] Fix references to complete types in attribute
 references (#209537)

This is a regression from #197215.

Attributes are not REALLY in the body of a function (though the name of
said function is... awkwardly inaccurate at best), but still need to pay
attention to the completeness of their references. As a result, we
weren't marking the expression as invalid, but were also trying to
evaluate it.

This patch fixes this in 2 ways. First, we re-add the
CXXThisTypeOverride check, but except constant substitution, since that
has some additional 'this' behavior from #197215. x

Secondly, we also make the constant evaluator give up on incomplete
types when handling an L value member. This stops us from trying to
evaluate the value if it is incomplete during template instantiation,
when the type is incomplete. We don't diagnose, since it is still
potentially a constant expression, but isn't currently one.

Fixes: #199527
(cherry picked from commit 0d93f2aec0b4847761bd8458b7847ce37b85cf03)
---
 clang/lib/AST/ExprConstant.cpp   | 13 +++++++++--
 clang/lib/Sema/SemaExprCXX.cpp   |  8 +++++++
 clang/test/SemaCXX/enable_if.cpp | 39 ++++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 7d9dba8cd33fc..120af89a93b09 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -3212,8 +3212,17 @@ static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal,
                                const FieldDecl *FD,
                                const ASTRecordLayout *RL = nullptr) {
   if (!RL) {
-    if (FD->getParent()->isInvalidDecl()) return false;
-    RL = &Info.Ctx.getASTRecordLayout(FD->getParent());
+    const RecordDecl *RD = FD->getParent();
+    if (RD->isInvalidDecl())
+      return false;
+    // There are some cases where the base is not yet complete but we haven't
+    // disagnosed (such as in a template instantation of an attribute that
+    // references the expression, ala enable_if).  These aren't necessarily
+    // constant expressions so we return 'false', but they might be, so we don't
+    // diagnose.
+    if (!RD->isCompleteDefinition())
+      return false;
+    RL = &Info.Ctx.getASTRecordLayout(RD);
   }
 
   unsigned I = FD->getFieldIndex();
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 5f22cd409dc01..538604aa2e64b 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1487,6 +1487,14 @@ void Sema::MarkThisReferenced(CXXThisExpr *This) {
 }
 
 bool Sema::isThisOutsideMemberFunctionBody(QualType BaseType) {
+  // If we're outside the body of a member function, then we'll have a specified
+  // type for 'this'. Constraint substitution is the exception: a concept is
+  // evaluated in its own declaration context (see GH#197215), so it loses the
+  // enclosing '*this' even though it may legitimately name a member of the
+  // class currently being instantiated.
+  if (CXXThisTypeOverride.isNull() && !inConstraintSubstitution())
+    return false;
+
   // Determine whether we're looking into a class that's currently being
   // defined.
   CXXRecordDecl *Class = BaseType->getAsCXXRecordDecl();
diff --git a/clang/test/SemaCXX/enable_if.cpp b/clang/test/SemaCXX/enable_if.cpp
index a34b87064b49d..4af0922fee5ac 100644
--- a/clang/test/SemaCXX/enable_if.cpp
+++ b/clang/test/SemaCXX/enable_if.cpp
@@ -646,6 +646,45 @@ void Substitute(Arg) __attribute__((enable_if(PlaceholderBitmask, ""))) {
 
 }
 
+namespace GH199527 {
+struct S { // expected-note {{definition of 'GH199527::S' is not complete until the closing '}'}}
+  ~S() {}
+  bool b;
+  // expected-error at +1{{member access into incomplete type 'S'}}
+  void foo(S b) __attribute__((enable_if(b.b, "")));
+};
+
+template<typename T>
+struct S2 {
+  bool b;
+  void foo(S2 b) const __attribute__((enable_if(b.b, "templ_foo_disabled"))); // #FOO
+};
+
+void use() {
+  S2<int> s_whatever;
+  S2<int> s_true{true};
+  S2<int> s_false{false};
+
+
+  // Both fail because this isn't a constexpr.
+  // expected-error at +2{{no matching member function for call to 'foo'}}
+  // expected-note@#FOO{{candidate disabled: templ_foo_disabled}}
+  s_whatever.foo(s_true);
+  // expected-error at +2{{no matching member function for call to 'foo'}}
+  // expected-note@#FOO{{candidate disabled: templ_foo_disabled}}
+  s_whatever.foo(s_false);
+
+  constexpr S2<int> ce_s_whatever{};
+  constexpr S2<int> ce_s_true{true};
+  constexpr S2<int> ce_s_false{false};
+
+  ce_s_whatever.foo(ce_s_true);
+  // expected-error at +2{{no matching member function for call to 'foo'}}
+  // expected-note@#FOO{{candidate disabled: templ_foo_disabled}}
+  ce_s_whatever.foo(ce_s_false);
+}
+}
+
 namespace DefaultArgs {
   void f(int n = __builtin_LINE()) __attribute__((enable_if(n == 12345, "only callable on line 12345"))); // expected-note {{only callable on line 12345}}
   void g() { f(); } // expected-error {{no matching function}}

>From a885d62292d8f02cac5eeeb739305dc58cf23abf Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Thu, 16 Jul 2026 09:37:06 -0700
Subject: [PATCH 17/35] workflows/llvm-abi-tests: Fix typo (#209917)

Introduced by 9bd8bbb2b76c55ca83ddb6e0aa8a3a79b65706d4.

(cherry picked from commit 16c6374250a465204e067b518577a2b4fd655f93)
---
 .github/workflows/llvm-abi-tests.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/llvm-abi-tests.yml b/.github/workflows/llvm-abi-tests.yml
index 1ad4b5c868bc4..ae9b7cc40d79a 100644
--- a/.github/workflows/llvm-abi-tests.yml
+++ b/.github/workflows/llvm-abi-tests.yml
@@ -122,7 +122,7 @@ jobs:
           else
             touch llvm.symbols
           fi
-          abi-dumper $EXTRA_ARGS -lver $REF -skip-cxx -public-headers ./install/include/$ABI_HEADERS -o $$REF.abi ./install/lib/libLLVM.so
+          abi-dumper $EXTRA_ARGS -lver $REF -skip-cxx -public-headers ./install/include/$ABI_HEADERS -o $REF.abi ./install/lib/libLLVM.so
           # Remove symbol versioning from dumps, so we can compare across major versions.
           sed -i "s/LLVM_$LLVM_VERSION_MAJOR/LLVM_NOVERSION/" $REF.abi
       - name: Upload ABI file

>From 5aa15abead01fef21fee4706aa01f39e8ac18829 Mon Sep 17 00:00:00 2001
From: Pawan Nirpal <pnirpal at qti.qualcomm.com>
Date: Wed, 15 Jul 2026 01:40:31 +0530
Subject: [PATCH 18/35] [ARM] - Fix Thumb1InstrInfo::copyPhysReg crash on debug
 instructions during liveness walk. (#209478)

clang asserts when compiling with -mthumb -mcpu=arm926ej-s -O0 -g
(pre-v6 Thumb1, debug info enabled). The crash occurs in
LiveRegUnits::stepBackward which unconditionally asserts that it must
never be called on a debug instruction, but Thumb1InstrInfo::copyPhysReg
walks the basic block backward without skipping DBG_VALUE instructions.

Fixes: https://github.com/llvm/llvm-project/issues/209475
(cherry picked from commit 73615e792dc3116d5c66cb8175039dd6d4840f31)
---
 llvm/lib/Target/ARM/Thumb1InstrInfo.cpp       |  8 ++++--
 .../thumb1-copy-physreg-dbg-value-crash.ll    | 25 +++++++++++++++++++
 2 files changed, 31 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/CodeGen/ARM/thumb1-copy-physreg-dbg-value-crash.ll

diff --git a/llvm/lib/Target/ARM/Thumb1InstrInfo.cpp b/llvm/lib/Target/ARM/Thumb1InstrInfo.cpp
index c2345f588b937..ef67e1116af72 100644
--- a/llvm/lib/Target/ARM/Thumb1InstrInfo.cpp
+++ b/llvm/lib/Target/ARM/Thumb1InstrInfo.cpp
@@ -62,10 +62,14 @@ void Thumb1InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
     UsedRegs.addLiveOuts(MBB);
 
     auto InstUpToI = MBB.end();
-    while (InstUpToI != I)
+    while (InstUpToI != I) {
       // The pre-decrement is on purpose here.
       // We want to have the liveness right before I.
-      UsedRegs.stepBackward(*--InstUpToI);
+      --InstUpToI;
+      if (InstUpToI->isDebugInstr())
+        continue;
+      UsedRegs.stepBackward(*InstUpToI);
+    }
 
     if (UsedRegs.available(ARM::CPSR)) {
       BuildMI(MBB, I, DL, get(ARM::tMOVSr), DestReg)
diff --git a/llvm/test/CodeGen/ARM/thumb1-copy-physreg-dbg-value-crash.ll b/llvm/test/CodeGen/ARM/thumb1-copy-physreg-dbg-value-crash.ll
new file mode 100644
index 0000000000000..0ff18f1f56d3c
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/thumb1-copy-physreg-dbg-value-crash.ll
@@ -0,0 +1,25 @@
+; RUN: llc < %s -mtriple=thumbv5e-none-linux-gnueabi --float-abi=soft -verify-machineinstrs -o /dev/null
+; This used to crash in Thumb1InstrInfo::copyPhysReg when computing liveness
+; for a pre-v6 low GPR copy. The backward liveness walk from MBB.end() to the
+; COPY instruction was calling LiveRegUnits::stepBackward on DBG_VALUE
+; instructions, which asserts that debug instructions must not affect liveness
+; calculation.
+
+define void @foo(ptr %res) !dbg !3 {
+entry:
+  #dbg_declare(ptr %res, !4, !DIExpression(), !5)
+  call void @llvm.memcpy.p0.p0.i32(ptr %res, ptr null, i32 1, i1 false)
+  ret void
+}
+
+declare void @llvm.memcpy.p0.p0.i32(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i32, i1 immarg)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, emissionKind: FullDebug)
+!1 = !DIFile(filename: "t.c", directory: "")
+!2 = !{i32 2, !"Debug Info Version", i32 3}
+!3 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, type: !DISubroutineType(types: !{}), unit: !0)
+!4 = !DILocalVariable(scope: !3)
+!5 = !DILocation(line: 1, scope: !3)

>From 66ba3bdaa25418fed2e74cd39576f236498bf289 Mon Sep 17 00:00:00 2001
From: hev <wangrui at loongson.cn>
Date: Fri, 17 Jul 2026 10:23:52 +0800
Subject: [PATCH 19/35] [LoongArch] Fix invalid VEXTH combines for unsupported
 type extensions (#209725)

`performEXTENDCombine` could form `VEXTH`/`VEXTH_U` nodes for
unsupported type combinations, such as extending `v8i8` to `v8i32` or
`v2i64` to `v2i128`. These illegal nodes would later reach instruction
selection and trigger backend failures:

* `Cannot select: LoongArchISD::VEXTH`
* `Don't know how to legalize this operation`

Prevent these combines from firing by verifying that the destination
type is legal and has exactly twice the total bit width of the source
before forming a `VEXTH`/`VEXTH_U` node.

Apply the same checks to `performSHLCombine` for consistency.

Fixes
https://github.com/llvm/llvm-project/pull/207316#issuecomment-4978234865
Fixes
https://github.com/llvm/llvm-project/pull/207316#issuecomment-4979233899

(cherry picked from commit 4a75259134c72d8be7fa3ea36c9dc7bfc02640ac)
---
 .../LoongArch/LoongArchISelLowering.cpp       | 21 ++---
 .../CodeGen/LoongArch/lasx/issue207316.ll     | 18 +++++
 llvm/test/CodeGen/LoongArch/lasx/xvexth.ll    | 80 ++++++++++++++++++-
 llvm/test/CodeGen/LoongArch/lsx/vexth.ll      | 58 +++++++++++++-
 4 files changed, 160 insertions(+), 17 deletions(-)
 create mode 100644 llvm/test/CodeGen/LoongArch/lasx/issue207316.ll

diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 4c5bb28a5e42f..d6189ff6b988d 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -6504,9 +6504,6 @@ static SDValue matchHalfOf128BitLanes(SDValue N, bool isLow) {
 static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
                                  TargetLowering::DAGCombinerInfo &DCI,
                                  const LoongArchSubtarget &Subtarget) {
-  if (!Subtarget.hasExtLSX())
-    return SDValue();
-
   assert(N->getOpcode() == ISD::SHL && "Unexpected opcode");
 
   EVT VT = N->getValueType(0);
@@ -6527,6 +6524,10 @@ static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
   if (!LHS.hasOneUse())
     return SDValue();
 
+  if (!DAG.getTargetLoweringInfo().isTypeLegal(VT) ||
+      N->getValueSizeInBits(0) != LHS->getOperand(0).getValueSizeInBits() * 2)
+    return SDValue();
+
   SDValue Vec = matchHalfOf128BitLanes(LHS.getOperand(0), /*isLow=*/true);
   if (!Vec)
     return SDValue();
@@ -6534,16 +6535,6 @@ static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
   EVT SrcVT = Vec.getValueType();
   EVT SrcEltVT = SrcVT.getVectorElementType();
   EVT DstEltVT = VT.getVectorElementType();
-
-  if (!SrcVT.isVector() || !VT.isVector())
-    return SDValue();
-  if (SrcVT.getSizeInBits() != VT.getSizeInBits())
-    return SDValue();
-  if (DstEltVT.getSizeInBits() != SrcEltVT.getSizeInBits() * 2)
-    return SDValue();
-  if (!SrcEltVT.isInteger() || SrcEltVT.getSizeInBits() > 32)
-    return SDValue();
-
   APInt Imm;
   if (!isConstantSplatVector(RHS, Imm, DstEltVT.getSizeInBits()))
     return SDValue();
@@ -8512,6 +8503,10 @@ static SDValue performEXTENDCombine(SDNode *N, SelectionDAG &DAG,
     if (SDValue R = PromoteMaskArithmetic(SDValue(N, 0), DL, DAG, Subtarget))
       return R;
 
+    if (!DAG.getTargetLoweringInfo().isTypeLegal(VT) ||
+        N->getValueSizeInBits(0) != N->getOperand(0).getValueSizeInBits() * 2)
+      return SDValue();
+
     if (SDValue R = matchHalfOf128BitLanes(N->getOperand(0), /*isLow=*/false)) {
       if (N->getOpcode() == ISD::SIGN_EXTEND)
         return DAG.getNode(LoongArchISD::VEXTH, DL, VT, R);
diff --git a/llvm/test/CodeGen/LoongArch/lasx/issue207316.ll b/llvm/test/CodeGen/LoongArch/lasx/issue207316.ll
new file mode 100644
index 0000000000000..1012918abde30
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/lasx/issue207316.ll
@@ -0,0 +1,18 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc --mtriple=loongarch32 --mattr=+32s,+lasx < %s | FileCheck %s
+; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s
+
+;; https://github.com/llvm/llvm-project/pull/207316#issuecomment-4978234865
+define void @exth_wu_bu() nounwind {
+; CHECK-LABEL: exth_wu_bu:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xvrepli.b $xr0, 0
+; CHECK-NEXT:    xvst $xr0, $zero, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = shufflevector <16 x i8> zeroinitializer, <16 x i8> zeroinitializer,
+                     <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+  %1 = zext <8 x i8> %0 to <8 x i32>
+  store <8 x i32> %1, ptr null
+  ret void
+}
diff --git a/llvm/test/CodeGen/LoongArch/lasx/xvexth.ll b/llvm/test/CodeGen/LoongArch/lasx/xvexth.ll
index db3a4c9c66368..e8d0cd4e2a297 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/xvexth.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/xvexth.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; RUN: llc --mtriple=loongarch32 --mattr=+32s,+lasx < %s | FileCheck %s
-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s
+; RUN: llc --mtriple=loongarch32 --mattr=+32s,+lasx < %s | FileCheck %s --check-prefixes=CHECK,LA32
+; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s --check-prefixes=CHECK,LA64
 
 define void @xvexth_h_b(ptr %a, ptr %r) nounwind {
 ; CHECK-LABEL: xvexth_h_b:
@@ -100,6 +100,47 @@ entry:
   ret void
 }
 
+define void @xvexth_q_d(ptr %a, ptr %r) nounwind {
+; LA32-LABEL: xvexth_q_d:
+; LA32:       # %bb.0: # %entry
+; LA32-NEXT:    xvld $xr0, $a0, 0
+; LA32-NEXT:    xvpickve2gr.w $a0, $xr0, 2
+; LA32-NEXT:    xvpickve2gr.w $a2, $xr0, 6
+; LA32-NEXT:    xvpickve2gr.w $a3, $xr0, 7
+; LA32-NEXT:    xvpickve2gr.w $a4, $xr0, 3
+; LA32-NEXT:    srai.w $a5, $a4, 31
+; LA32-NEXT:    srai.w $a6, $a3, 31
+; LA32-NEXT:    st.w $a3, $a1, 20
+; LA32-NEXT:    st.w $a2, $a1, 16
+; LA32-NEXT:    st.w $a4, $a1, 4
+; LA32-NEXT:    st.w $a0, $a1, 0
+; LA32-NEXT:    st.w $a6, $a1, 28
+; LA32-NEXT:    st.w $a6, $a1, 24
+; LA32-NEXT:    st.w $a5, $a1, 12
+; LA32-NEXT:    st.w $a5, $a1, 8
+; LA32-NEXT:    ret
+;
+; LA64-LABEL: xvexth_q_d:
+; LA64:       # %bb.0: # %entry
+; LA64-NEXT:    xvld $xr0, $a0, 0
+; LA64-NEXT:    xvpickve2gr.d $a0, $xr0, 3
+; LA64-NEXT:    xvpickve2gr.d $a2, $xr0, 1
+; LA64-NEXT:    srai.d $a2, $a2, 63
+; LA64-NEXT:    srai.d $a0, $a0, 63
+; LA64-NEXT:    xvstelm.d $xr0, $a1, 16, 3
+; LA64-NEXT:    xvstelm.d $xr0, $a1, 0, 1
+; LA64-NEXT:    st.d $a0, $a1, 24
+; LA64-NEXT:    st.d $a2, $a1, 8
+; LA64-NEXT:    ret
+entry:
+  %0 = load <4 x i64>, ptr %a
+  %1 = shufflevector <4 x i64> %0, <4 x i64> poison,
+                     <2 x i32> <i32 1, i32 3>
+  %2 = sext <2 x i64> %1 to <2 x i128>
+  store <2 x i128> %2, ptr %r
+  ret void
+}
+
 define void @xvexth_hu_bu(ptr %a, ptr %r) nounwind {
 ; CHECK-LABEL: xvexth_hu_bu:
 ; CHECK:       # %bb.0: # %entry
@@ -182,6 +223,41 @@ entry:
   ret void
 }
 
+define void @xvexth_qu_du(ptr %a, ptr %r) nounwind {
+; LA32-LABEL: xvexth_qu_du:
+; LA32:       # %bb.0: # %entry
+; LA32-NEXT:    xvld $xr0, $a0, 0
+; LA32-NEXT:    xvpickve2gr.w $a0, $xr0, 2
+; LA32-NEXT:    xvpickve2gr.w $a2, $xr0, 3
+; LA32-NEXT:    xvpickve2gr.w $a3, $xr0, 6
+; LA32-NEXT:    xvpickve2gr.w $a4, $xr0, 7
+; LA32-NEXT:    st.w $zero, $a1, 28
+; LA32-NEXT:    st.w $zero, $a1, 24
+; LA32-NEXT:    st.w $zero, $a1, 12
+; LA32-NEXT:    st.w $zero, $a1, 8
+; LA32-NEXT:    st.w $a4, $a1, 20
+; LA32-NEXT:    st.w $a3, $a1, 16
+; LA32-NEXT:    st.w $a2, $a1, 4
+; LA32-NEXT:    st.w $a0, $a1, 0
+; LA32-NEXT:    ret
+;
+; LA64-LABEL: xvexth_qu_du:
+; LA64:       # %bb.0: # %entry
+; LA64-NEXT:    xvld $xr0, $a0, 0
+; LA64-NEXT:    st.d $zero, $a1, 24
+; LA64-NEXT:    xvstelm.d $xr0, $a1, 16, 3
+; LA64-NEXT:    st.d $zero, $a1, 8
+; LA64-NEXT:    xvstelm.d $xr0, $a1, 0, 1
+; LA64-NEXT:    ret
+entry:
+  %0 = load <4 x i64>, ptr %a
+  %1 = shufflevector <4 x i64> %0, <4 x i64> poison,
+                     <2 x i32> <i32 1, i32 3>
+  %2 = zext <2 x i64> %1 to <2 x i128>
+  store <2 x i128> %2, ptr %r
+  ret void
+}
+
 define void @xvexth_du_wu_poison(ptr %a, ptr %r) nounwind {
 ; CHECK-LABEL: xvexth_du_wu_poison:
 ; CHECK:       # %bb.0: # %entry
diff --git a/llvm/test/CodeGen/LoongArch/lsx/vexth.ll b/llvm/test/CodeGen/LoongArch/lsx/vexth.ll
index d85c4eb7fa1ac..b8e87a0ccd058 100644
--- a/llvm/test/CodeGen/LoongArch/lsx/vexth.ll
+++ b/llvm/test/CodeGen/LoongArch/lsx/vexth.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; RUN: llc --mtriple=loongarch32 --mattr=+32s,+lsx < %s | FileCheck %s
-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s
+; RUN: llc --mtriple=loongarch32 --mattr=+32s,+lsx < %s | FileCheck %s --check-prefixes=CHECK,LA32
+; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s --check-prefixes=CHECK,LA64
 
 define void @vexth_h_b(ptr %a, ptr %r) nounwind {
 ; CHECK-LABEL: vexth_h_b:
@@ -94,6 +94,34 @@ entry:
   ret void
 }
 
+define void @vexth_q_d(ptr %a, ptr %r) nounwind {
+; LA32-LABEL: vexth_q_d:
+; LA32:       # %bb.0: # %entry
+; LA32-NEXT:    vld $vr0, $a0, 0
+; LA32-NEXT:    vpickve2gr.w $a0, $vr0, 2
+; LA32-NEXT:    vpickve2gr.w $a2, $vr0, 3
+; LA32-NEXT:    srai.w $a3, $a2, 31
+; LA32-NEXT:    st.w $a2, $a1, 4
+; LA32-NEXT:    st.w $a0, $a1, 0
+; LA32-NEXT:    st.w $a3, $a1, 12
+; LA32-NEXT:    st.w $a3, $a1, 8
+; LA32-NEXT:    ret
+;
+; LA64-LABEL: vexth_q_d:
+; LA64:       # %bb.0: # %entry
+; LA64-NEXT:    ld.d $a0, $a0, 8
+; LA64-NEXT:    srai.d $a2, $a0, 63
+; LA64-NEXT:    st.d $a0, $a1, 0
+; LA64-NEXT:    st.d $a2, $a1, 8
+; LA64-NEXT:    ret
+entry:
+  %0 = load <2 x i64>, ptr %a
+  %1 = shufflevector <2 x i64> %0, <2 x i64> poison, <1 x i32> <i32 1>
+  %2 = sext <1 x i64> %1 to <1 x i128>
+  store <1 x i128> %2, ptr %r
+  ret void
+}
+
 define void @vexth_hu_bu(ptr %a, ptr %r) nounwind {
 ; CHECK-LABEL: vexth_hu_bu:
 ; CHECK:       # %bb.0: # %entry
@@ -185,3 +213,29 @@ entry:
   store <2 x i64> %2, ptr %r
   ret void
 }
+
+define void @vexth_qu_du(ptr %a, ptr %r) nounwind {
+; LA32-LABEL: vexth_qu_du:
+; LA32:       # %bb.0: # %entry
+; LA32-NEXT:    vld $vr0, $a0, 0
+; LA32-NEXT:    vpickve2gr.w $a0, $vr0, 2
+; LA32-NEXT:    vpickve2gr.w $a2, $vr0, 3
+; LA32-NEXT:    st.w $zero, $a1, 12
+; LA32-NEXT:    st.w $zero, $a1, 8
+; LA32-NEXT:    st.w $a2, $a1, 4
+; LA32-NEXT:    st.w $a0, $a1, 0
+; LA32-NEXT:    ret
+;
+; LA64-LABEL: vexth_qu_du:
+; LA64:       # %bb.0: # %entry
+; LA64-NEXT:    ld.d $a0, $a0, 8
+; LA64-NEXT:    st.d $zero, $a1, 8
+; LA64-NEXT:    st.d $a0, $a1, 0
+; LA64-NEXT:    ret
+entry:
+  %0 = load <2 x i64>, ptr %a
+  %1 = shufflevector <2 x i64> %0, <2 x i64> poison, <1 x i32> <i32 1>
+  %2 = zext <1 x i64> %1 to <1 x i128>
+  store <1 x i128> %2, ptr %r
+  ret void
+}

>From 47e2df730a099583f16fc6fe64f0d2ffc5b7a16a Mon Sep 17 00:00:00 2001
From: Daniel Kiss <daniel.kiss at arm.com>
Date: Fri, 17 Jul 2026 06:04:26 +0900
Subject: [PATCH 20/35] [AArch64][COFF] Branch-protection=standard/pac-ret
 means "b-key" on Windows (#203989)

On AArch64 Windows the `B-key` is the only supported key for userspace,
let's make "standard" and "pac-ret" options generate "b-key".

Fixes: #203852
(cherry picked from commit 68f703f3e58a52c41b39dfc654a675560b6c5614)
---
 clang/docs/ReleaseNotes.md                    |  3 +
 clang/docs/UsersManual.md                     | 30 ++++++++
 clang/lib/Basic/Targets/AArch64.cpp           |  3 +-
 clang/lib/Basic/Targets/ARM.cpp               |  2 +-
 clang/lib/Driver/ToolChains/Clang.cpp         |  2 +-
 .../CodeGen/AArch64/branch-protection-attr.c  |  6 ++
 .../CodeGen/AArch64/sign-return-address.c     | 15 ++++
 clang/test/Driver/aarch64-security-options.c  |  4 ++
 .../Preprocessor/aarch64-target-features.c    |  4 ++
 llvm/docs/ReleaseNotes.md                     |  2 +
 .../llvm/TargetParser/ARMTargetParserCommon.h |  4 +-
 .../AArch64/AArch64MachineFunctionInfo.cpp    |  7 ++
 .../lib/Target/AArch64/AArch64PointerAuth.cpp |  4 ++
 .../TargetParser/ARMTargetParserCommon.cpp    |  8 ++-
 .../CodeGen/AArch64/sign-return-address.ll    | 71 +++----------------
 .../AArch64/windows-pac-invalid-a-key.ll      | 11 +++
 llvm/test/CodeGen/AArch64/wineh-bti.ll        |  2 +-
 17 files changed, 112 insertions(+), 66 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/windows-pac-invalid-a-key.ll

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 9063e54b3e692..5216f8a97af66 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -1041,6 +1041,9 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the
   - Hisilicon hip12 core (hip12).
   - NVIDIA Rigel core (rigel).
 
+- On AArch64 Windows targets, `-mbranch-protection=standard` and `-mbranch-protection=pac-ret`
+  now uses the B-key by default.
+
 #### Android Support
 
 #### Windows Support
diff --git a/clang/docs/UsersManual.md b/clang/docs/UsersManual.md
index 756f2784dc076..9bccf8e175298 100644
--- a/clang/docs/UsersManual.md
+++ b/clang/docs/UsersManual.md
@@ -2774,6 +2774,36 @@ are listed below.
    only. This only applies to the AArch64 architecture.
 ```
 
+```{eval-rst}
+.. option:: -mbranch-protection=features
+
+   Select the branch protection features to use for ARM and AArch64 targets.
+   ``features`` can be ``none``, ``standard``, or a ``+``-separated list of
+   ``bti``, ``gcs``, and ``pac-ret`` with optional ``pac-ret`` modifiers.
+
+   ``none`` is the default and turns off all types of branch protection.
+
+   ``standard`` turns on all branch protection features that are valid for the
+   target platform. If a feature has additional tuning options, ``standard``
+   sets them to their standard level.
+
+   ``pac-ret`` turns on return address signing to its standard level: signing
+   functions that save the return address to memory (non-leaf functions
+   practically always do this) using the A-key. On AArch64 Windows targets,
+   ``pac-ret`` uses the B-key by default.
+
+   ``+leaf`` extends the ``pac-ret`` signing to include leaf functions.
+
+   ``+b-key`` can be used to sign functions with the B-key instead of the A-key
+   on AArch64. ``b-key`` is accepted but ignored for ARM targets.
+
+   ``+pc`` enables the PAuth-LR form of return address signing.
+
+   ``bti`` turns on the Branch Target Identification mechanism.
+
+   ``gcs`` turns on Guarded Control Stack compatible code generation.
+```
+
 ```{eval-rst}
 .. option:: -mcompact-branches=[values]
 
diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index debf3ecf589e3..d531e26ade84a 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -254,7 +254,8 @@ bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,
                                                  const LangOptions &LO,
                                                  StringRef &Err) const {
   llvm::ARM::ParsedBranchProtection PBP;
-  if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err, HasPAuthLR))
+  if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err, getTriple(),
+                                        HasPAuthLR))
     return false;
 
   // GCS is currently untested with ptrauth-returns, but enabling this could be
diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp
index b9744ff9009ca..f963ce38352c2 100644
--- a/clang/lib/Basic/Targets/ARM.cpp
+++ b/clang/lib/Basic/Targets/ARM.cpp
@@ -375,7 +375,7 @@ bool ARMTargetInfo::validateBranchProtection(StringRef Spec, StringRef Arch,
                                              const LangOptions &LO,
                                              StringRef &Err) const {
   llvm::ARM::ParsedBranchProtection PBP;
-  if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err))
+  if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err, getTriple()))
     return false;
 
   if (!isBranchProtectionSupportedArch(Arch))
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 1d6877ffbd8a7..db7893c547ee7 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1445,7 +1445,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
       if (llvm::any_of(CmdArgs, isPAuthLR))
         EnablePAuthLR = true;
     }
-    if (!llvm::ARM::parseBranchProtection(A->getValue(), PBP, DiagMsg,
+    if (!llvm::ARM::parseBranchProtection(A->getValue(), PBP, DiagMsg, Triple,
                                           EnablePAuthLR))
       D.Diag(diag::err_drv_unsupported_option_argument)
           << A->getSpelling() << DiagMsg;
diff --git a/clang/test/CodeGen/AArch64/branch-protection-attr.c b/clang/test/CodeGen/AArch64/branch-protection-attr.c
index c66bce1bee6d3..d3fa2743ef626 100644
--- a/clang/test/CodeGen/AArch64/branch-protection-attr.c
+++ b/clang/test/CodeGen/AArch64/branch-protection-attr.c
@@ -13,6 +13,8 @@
 // RUN:                               | FileCheck %s --check-prefix=CHECK
 // RUN: %clang_cc1 -triple aarch64 -emit-llvm  -target-cpu generic -target-feature +v8.5a -mguarded-control-stack -mbranch-target-enforce -mbranch-protection-pauth-lr -msign-return-address=all -msign-return-address-key=a_key %s -o - \
 // RUN:                               | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -triple aarch64-windows-msvc -emit-llvm -target-cpu generic -target-feature +v8.5a %s -o - \
+// RUN:                               | FileCheck %s --check-prefix=WIN
 
 __attribute__ ((target("branch-protection=none")))
 void none() {}
@@ -21,6 +23,7 @@ void none() {}
   __attribute__ ((target("branch-protection=standard")))
 void std() {}
 // CHECK: define{{.*}} void @std() #[[#STD:]]
+// WIN: define{{.*}} void @std() #[[#WINSTD:]]
 
 __attribute__ ((target("branch-protection=bti")))
 void btionly() {}
@@ -29,6 +32,7 @@ void btionly() {}
 __attribute__ ((target("branch-protection=pac-ret")))
 void paconly() {}
 // CHECK: define{{.*}} void @paconly() #[[#PAC:]]
+// WIN: define{{.*}} void @paconly() #[[#WINPAC:]]
 
 __attribute__ ((target("branch-protection=pac-ret+bti")))
 void pacbti0() {}
@@ -82,10 +86,12 @@ void gcs() {}
 // CHECK-DAG: attributes #[[#NONE]] = { {{.*}}
 
 // CHECK-DAG: attributes #[[#STD]] = { {{.*}} "branch-target-enforcement" "guarded-control-stack" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key"
+// WIN-DAG: attributes #[[#WINSTD]] = { {{.*}} "branch-target-enforcement" "guarded-control-stack" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="b_key"
 
 // CHECK-DAG: attributes #[[#BTI]] = { {{.*}} "branch-target-enforcement"
 
 // CHECK-DAG: attributes #[[#PAC]] = { {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key"
+// WIN-DAG: attributes #[[#WINPAC]] = { {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="b_key"
 
 // CHECK-DAG: attributes #[[#PACLEAF]] = { {{.*}} "sign-return-address"="all" "sign-return-address-key"="a_key"
 
diff --git a/clang/test/CodeGen/AArch64/sign-return-address.c b/clang/test/CodeGen/AArch64/sign-return-address.c
index 2b505de339054..c617b45c21317 100644
--- a/clang/test/CodeGen/AArch64/sign-return-address.c
+++ b/clang/test/CodeGen/AArch64/sign-return-address.c
@@ -6,6 +6,8 @@
 // RUN: %clang -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=pac-ret+leaf  %s | FileCheck %s --check-prefix=CHECK --check-prefix=ALL
 // RUN: %clang -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key %s | FileCheck %s --check-prefix=CHECK --check-prefix=B-KEY
 // RUN: %clang -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=bti %s           | FileCheck %s --check-prefix=CHECK --check-prefix=BTE
+// RUN: %clang -target aarch64-windows-msvc -S -emit-llvm -o - -mbranch-protection=pac-ret %s | FileCheck %s --check-prefix=CHECK --check-prefix=WIN-PAC
+// RUN: %clang -target aarch64-windows-msvc -S -emit-llvm -o - -mbranch-protection=standard %s | FileCheck %s --check-prefix=CHECK --check-prefix=WIN-STD
 
 // REQUIRES: aarch64-registered-target
 
@@ -21,6 +23,8 @@
 // PART:  attributes #[[#ATTR]] = { {{.*}} "sign-return-address-key"="a_key"
 // B-KEY: attributes #[[#ATTR]] = { {{.*}} "sign-return-address-key"="b_key"
 // BTE:   attributes #[[#ATTR]] = { {{.*}} "branch-target-enforcement"
+// WIN-PAC: attributes #[[#ATTR]] = { {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="b_key"
+// WIN-STD: attributes #[[#ATTR]] = { {{.*}} "branch-target-enforcement" {{.*}} "guarded-control-stack" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="b_key"
 
 
 // Check module attributes
@@ -30,23 +34,34 @@
 // PART-NOT:  !"branch-target-enforcement"
 // BTE:       !{i32 8, !"branch-target-enforcement", i32 2}
 // B-KEY-NOT: !"branch-target-enforcement"
+// WIN-PAC-NOT: !"branch-target-enforcement"
+// WIN-STD:   !{i32 8, !"branch-target-enforcement", i32 2}
+
+// WIN-PAC-NOT: !"guarded-control-stack"
+// WIN-STD: !{i32 8, !"guarded-control-stack", i32 2}
 
 // NONE-NOT:  !"sign-return-address"
 // ALL:   !{i32 8, !"sign-return-address", i32 2}
 // PART:  !{i32 8, !"sign-return-address", i32 2}
 // BTE-NOT:   !"sign-return-address"
 // B-KEY: !{i32 8, !"sign-return-address", i32 2}
+// WIN-PAC: !{i32 8, !"sign-return-address", i32 2}
+// WIN-STD: !{i32 8, !"sign-return-address", i32 2}
 
 // NONE-NOT:  !"sign-return-address-all"
 // ALL:   !{i32 8, !"sign-return-address-all", i32 2}
 // PART-NOT:  !"sign-return-address-all"
 // BTE-NOT:   !"sign-return-address-all"
 // B-KEY-NOT: !"sign-return-address-all"
+// WIN-PAC-NOT: !"sign-return-address-all"
+// WIN-STD-NOT: !"sign-return-address-all"
 
 // NONE-NOT:  !"sign-return-address-with-bkey"
 // ALL-NOT:   !"sign-return-address-with-bkey"
 // PART-NOT:  !"sign-return-address-with-bkey"
 // BTE-NOT:   !"sign-return-address-with-bkey"
 // B-KEY: !{i32 8, !"sign-return-address-with-bkey", i32 2}
+// WIN-PAC: !{i32 8, !"sign-return-address-with-bkey", i32 2}
+// WIN-STD: !{i32 8, !"sign-return-address-with-bkey", i32 2}
 
 void foo() {}
diff --git a/clang/test/Driver/aarch64-security-options.c b/clang/test/Driver/aarch64-security-options.c
index 146add2d1cf70..967a6122a333d 100644
--- a/clang/test/Driver/aarch64-security-options.c
+++ b/clang/test/Driver/aarch64-security-options.c
@@ -13,6 +13,9 @@
 // RUN: %clang --target=aarch64 -c %s -### -mbranch-protection=standard                                2>&1 | \
 // RUN: FileCheck %s --check-prefix=RA-NON-LEAF --check-prefix=KEY-A --check-prefix=BTE-ON --check-prefix=GCS-ON --check-prefix=WARN
 
+// RUN: %clang --target=aarch64-windows-msvc -c %s -### -mbranch-protection=standard                  2>&1 | \
+// RUN: FileCheck %s --check-prefix=RA-NON-LEAF --check-prefix=KEY-B --check-prefix=BTE-ON --check-prefix=GCS-ON --check-prefix=WARN
+
 // If the -msign-return-address and -mbranch-protection are both used, the
 // right-most one controls return address signing.
 // RUN: %clang --target=aarch64 -c %s -### -msign-return-address=non-leaf -mbranch-protection=none     2>&1 | \
@@ -37,6 +40,7 @@
 // RA-ALL: "-msign-return-address=all"
 
 // KEY-A: "-msign-return-address-key=a_key"
+// KEY-B: "-msign-return-address-key=b_key"
 // KEY-NOT: "-msign-return-address-key"
 
 // BTE-OFF-NOT: "-mbranch-target-enforce"
diff --git a/clang/test/Preprocessor/aarch64-target-features.c b/clang/test/Preprocessor/aarch64-target-features.c
index 70b7c705ead79..a3ded91d5695f 100644
--- a/clang/test/Preprocessor/aarch64-target-features.c
+++ b/clang/test/Preprocessor/aarch64-target-features.c
@@ -541,6 +541,7 @@
 // RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret+b-key -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-BKEY %s
 // RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret+leaf -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-ALL %s
 // RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret+leaf+b-key -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-BKEY-ALL %s
+// RUN: %clang -target aarch64-windows-msvc -march=armv8-a -mbranch-protection=standard -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BRANCH-PROTECTION-STANDARD-WINDOWS %s
 //
 // Note: PAUTH-OFF - pac-ret is disabled
 //       CPU-NOPAUTH - FEAT_PAUTH support is disabled (but pac-ret can still use HINT-encoded instructions)
@@ -553,6 +554,9 @@
 // CHECK-PAUTH-BKEY-ALL:  #define __ARM_FEATURE_PAC_DEFAULT 6
 // CHECK-CPU-PAUTH:       #define __ARM_FEATURE_PAUTH 1
 // CHECK-CPU-NOPAUTH-NOT: __ARM_FEATURE_PAUTH
+// CHECK-BRANCH-PROTECTION-STANDARD-WINDOWS-DAG: #define __ARM_FEATURE_BTI_DEFAULT 1
+// CHECK-BRANCH-PROTECTION-STANDARD-WINDOWS-DAG: #define __ARM_FEATURE_GCS_DEFAULT 1
+// CHECK-BRANCH-PROTECTION-STANDARD-WINDOWS-DAG: #define __ARM_FEATURE_PAC_DEFAULT 2
 
 // ================== Check Branch Target Identification (BTI).
 // RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI-OFF %s
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index b186fbefb9e87..a878e6e68c24a 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -203,6 +203,8 @@ Makes programs 10x faster by doing Special New Thing.
   instead of the ABI names FP and LR. Note that LLVM IR produced by Clang
   always uses the ABI names, but other frontends may not.
   ([#167783](https://github.com/llvm/llvm-project/pull/167783))
+* On AArch64 Windows targets, return address signing now uses the B-key by
+  default because Windows unwind information only supports B-key signing.
 
 ### Changes to the AMDGPU Backend
 
diff --git a/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h b/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h
index 7c8030dd5576a..1df9740fde8b5 100644
--- a/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h
+++ b/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h
@@ -15,6 +15,7 @@
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
 
 namespace llvm {
 namespace ARM {
@@ -47,7 +48,8 @@ struct ParsedBranchProtection {
 };
 
 LLVM_ABI bool parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
-                                    StringRef &Err, bool EnablePAuthLR = false);
+                                    StringRef &Err, const llvm::Triple &Triple,
+                                    bool EnablePAuthLR = false);
 
 } // namespace ARM
 } // namespace llvm
diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
index 90dbd7304ec85..29aea3694497f 100644
--- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
@@ -18,6 +18,7 @@
 #include "AArch64Subtarget.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/IR/Constants.h"
+#include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Module.h"
 #include "llvm/MC/MCAsmInfo.h"
@@ -93,6 +94,12 @@ static bool ShouldSignWithBKey(const Function &F, const AArch64Subtarget &STI) {
   const StringRef Key =
       F.getFnAttribute("sign-return-address-key").getValueAsString();
   assert(Key == "a_key" || Key == "b_key");
+  if (STI.getTargetTriple().isOSWindows() && Key == "a_key" &&
+      GetSignReturnAddress(F) != SignReturnAddress::None) {
+    F.getContext().diagnose(DiagnosticInfoUnsupported{
+        F, "A-key return address signing is unsupported on AArch64 Windows"});
+    return true;
+  }
   return Key == "b_key";
 }
 
diff --git a/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp b/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp
index 5372ffe869e1f..6be02ba0dc38b 100644
--- a/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp
+++ b/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp
@@ -175,6 +175,8 @@ void AArch64PointerAuthImpl::signLR(MachineFunction &MF,
   }
 
   if (!EmitCFI && NeedsWinCFI) {
+    assert(UseBKey &&
+           "Windows SEH PAC unwind info only supports B-key signing");
     BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PACSignLR))
         .setMIFlag(MachineInstr::FrameSetup);
   }
@@ -336,6 +338,8 @@ void AArch64PointerAuthImpl::authenticateLR(
   }
 
   if (NeedsWinCFI) {
+    assert(UseBKey &&
+           "Windows SEH PAC unwind info only supports B-key signing");
     BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PACSignLR))
         .setMIFlag(MachineInstr::FrameDestroy);
   }
diff --git a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
index 15ba1ebd0c037..6d824c78cab97 100644
--- a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
+++ b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
@@ -141,7 +141,8 @@ ARM::EndianKind ARM::parseArchEndian(StringRef Arch) {
 // returned in `PBP`. Returns false in error, with `Err` containing
 // an erroneous part of the spec.
 bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
-                                StringRef &Err, bool EnablePAuthLR) {
+                                StringRef &Err, const llvm::Triple &Triple,
+                                bool EnablePAuthLR) {
   PBP = {"none", "a_key", false, false, false};
   if (Spec == "none")
     return true; // defaults are ok
@@ -151,6 +152,8 @@ bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
     PBP.BranchTargetEnforcement = true;
     PBP.GuardedControlStack = true;
     PBP.BranchProtectionPAuthLR = EnablePAuthLR;
+    if (Triple.isAArch64() && Triple.isOSWindows())
+      PBP.Key = "b_key";
     return true;
   }
 
@@ -164,6 +167,9 @@ bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
     }
     if (Opt == "pac-ret") {
       PBP.Scope = "non-leaf";
+      if (Triple.isAArch64() && Triple.isOSWindows())
+        PBP.Key = "b_key";
+
       for (; I + 1 != E; ++I) {
         StringRef PACOpt = Opts[I + 1].trim();
         if (PACOpt == "leaf")
diff --git a/llvm/test/CodeGen/AArch64/sign-return-address.ll b/llvm/test/CodeGen/AArch64/sign-return-address.ll
index 7267ce0e3afbf..755ba860c7ccc 100644
--- a/llvm/test/CodeGen/AArch64/sign-return-address.ll
+++ b/llvm/test/CodeGen/AArch64/sign-return-address.ll
@@ -5,14 +5,21 @@
 ; v9.5-A is not expected to change codegen without -mbranch-protection=+pc, so reuse DWARFCFI-V83A.
 ; RUN: llc -mtriple=aarch64 -mattr=v9.5a < %s | FileCheck --check-prefixes=CHECK,DWARFCFI,DWARFCFI-V83A %s
 
-; RUN: llc -mtriple=aarch64-windows              < %s | FileCheck --check-prefixes=CHECK,WINCFI,WINCFI-COMPAT %s
-; RUN: llc -mtriple=aarch64-windows -mattr=v8.3a < %s | FileCheck --check-prefixes=CHECK,WINCFI,WINCFI-V83A %s
+; RUN: sed -e '/^define i32 @leaf_sign_all_a_key(/,/^}/d' -e '/^define i32 @leaf_sign_all_a_key_bti(/,/^}/d' %s > %t.win-valid.ll
+; RUN: llc -mtriple=aarch64-windows              < %t.win-valid.ll | FileCheck --check-prefixes=CHECK,WINCFI,WINCFI-COMPAT %s
+; RUN: llc -mtriple=aarch64-windows -mattr=v8.3a < %t.win-valid.ll | FileCheck --check-prefixes=CHECK,WINCFI,WINCFI-V83A %s
+
+; RUN: sed -n -e '/^define i32 @leaf_sign_all_a_key(/,/^}/p' %s | not llc -mtriple=aarch64-windows -filetype=null 2>&1 | FileCheck --check-prefix=ERR-AKEY %s
 
 ; Make sure no errors are detected when emitting SEH opcodes.
 ; Errors are only checked for when generating a binary, so emit a dummy object
 ; file and make sure llc produces zero exit code.
-; RUN: llc -mtriple=aarch64-windows              -o %t.dummy.o --filetype=obj < %s
-; RUN: llc -mtriple=aarch64-windows -mattr=v8.3a -o %t.dummy.o --filetype=obj < %s
+; RUN: llc -mtriple=aarch64-windows              -o %t.dummy.o --filetype=obj < %t.win-valid.ll
+; RUN: llc -mtriple=aarch64-windows -mattr=v8.3a -o %t.dummy.o --filetype=obj < %t.win-valid.ll
+
+; ERR-AKEY: error:
+; ERR-AKEY-SAME: in function leaf_sign_all_a_key
+; ERR-AKEY-SAME: A-key return address signing is unsupported on AArch64 Windows
 
 define i32 @leaf(i32 %x) {
 ; CHECK-LABEL: leaf:
@@ -649,34 +656,6 @@ define i32 @leaf_sign_all_a_key(i32 %x) "sign-return-address"="all" "sign-return
 ; DWARFCFI-V83A-NEXT:    paciasp
 ; DWARFCFI-V83A-NEXT:    .cfi_negate_ra_state
 ; DWARFCFI-V83A-NEXT:    retaa
-;
-; WINCFI-COMPAT-LABEL: leaf_sign_all_a_key:
-; WINCFI-COMPAT:       .seh_proc leaf_sign_all_a_key
-; WINCFI-COMPAT-NEXT:  // %bb.0:
-; WINCFI-COMPAT-NEXT:    hint #25
-; WINCFI-COMPAT-NEXT:    .seh_pac_sign_lr
-; WINCFI-COMPAT-NEXT:    .seh_endprologue
-; WINCFI-COMPAT-NEXT:    .seh_startepilogue
-; WINCFI-COMPAT-NEXT:    hint #29
-; WINCFI-COMPAT-NEXT:    .seh_pac_sign_lr
-; WINCFI-COMPAT-NEXT:    .seh_endepilogue
-; WINCFI-COMPAT-NEXT:    ret
-; WINCFI-COMPAT-NEXT:    .seh_endfunclet
-; WINCFI-COMPAT-NEXT:    .seh_endproc
-;
-; WINCFI-V83A-LABEL: leaf_sign_all_a_key:
-; WINCFI-V83A:       .seh_proc leaf_sign_all_a_key
-; WINCFI-V83A-NEXT:  // %bb.0:
-; WINCFI-V83A-NEXT:    paciasp
-; WINCFI-V83A-NEXT:    .seh_pac_sign_lr
-; WINCFI-V83A-NEXT:    .seh_endprologue
-; WINCFI-V83A-NEXT:    .seh_startepilogue
-; WINCFI-V83A-NEXT:    autiasp
-; WINCFI-V83A-NEXT:    .seh_pac_sign_lr
-; WINCFI-V83A-NEXT:    .seh_endepilogue
-; WINCFI-V83A-NEXT:    ret
-; WINCFI-V83A-NEXT:    .seh_endfunclet
-; WINCFI-V83A-NEXT:    .seh_endproc
   ret i32 %x
 }
 
@@ -764,34 +743,6 @@ define i32 @leaf_sign_all_a_key_bti(i32 %x) "sign-return-address"="all" "sign-re
 ; DWARFCFI-V83A-NEXT:    paciasp
 ; DWARFCFI-V83A-NEXT:    .cfi_negate_ra_state
 ; DWARFCFI-V83A-NEXT:    retaa
-;
-; WINCFI-COMPAT-LABEL: leaf_sign_all_a_key_bti:
-; WINCFI-COMPAT:       .seh_proc leaf_sign_all_a_key_bti
-; WINCFI-COMPAT-NEXT:  // %bb.0:
-; WINCFI-COMPAT-NEXT:    hint #25
-; WINCFI-COMPAT-NEXT:    .seh_pac_sign_lr
-; WINCFI-COMPAT-NEXT:    .seh_endprologue
-; WINCFI-COMPAT-NEXT:    .seh_startepilogue
-; WINCFI-COMPAT-NEXT:    hint #29
-; WINCFI-COMPAT-NEXT:    .seh_pac_sign_lr
-; WINCFI-COMPAT-NEXT:    .seh_endepilogue
-; WINCFI-COMPAT-NEXT:    ret
-; WINCFI-COMPAT-NEXT:    .seh_endfunclet
-; WINCFI-COMPAT-NEXT:    .seh_endproc
-;
-; WINCFI-V83A-LABEL: leaf_sign_all_a_key_bti:
-; WINCFI-V83A:       .seh_proc leaf_sign_all_a_key_bti
-; WINCFI-V83A-NEXT:  // %bb.0:
-; WINCFI-V83A-NEXT:    paciasp
-; WINCFI-V83A-NEXT:    .seh_pac_sign_lr
-; WINCFI-V83A-NEXT:    .seh_endprologue
-; WINCFI-V83A-NEXT:    .seh_startepilogue
-; WINCFI-V83A-NEXT:    autiasp
-; WINCFI-V83A-NEXT:    .seh_pac_sign_lr
-; WINCFI-V83A-NEXT:    .seh_endepilogue
-; WINCFI-V83A-NEXT:    ret
-; WINCFI-V83A-NEXT:    .seh_endfunclet
-; WINCFI-V83A-NEXT:    .seh_endproc
   ret i32 %x
 }
 
diff --git a/llvm/test/CodeGen/AArch64/windows-pac-invalid-a-key.ll b/llvm/test/CodeGen/AArch64/windows-pac-invalid-a-key.ll
new file mode 100644
index 0000000000000..7203e10e4b200
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/windows-pac-invalid-a-key.ll
@@ -0,0 +1,11 @@
+; RUN: not llc -mtriple=aarch64-windows-msvc -filetype=null %s 2>&1 | FileCheck %s
+
+; CHECK: error:
+; CHECK-SAME: A-key return address signing is unsupported on AArch64 Windows
+
+define void @a_key() "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" {
+  call void @callee()
+  ret void
+}
+
+declare void @callee()
diff --git a/llvm/test/CodeGen/AArch64/wineh-bti.ll b/llvm/test/CodeGen/AArch64/wineh-bti.ll
index 86555a7f64366..ce565bd16e880 100644
--- a/llvm/test/CodeGen/AArch64/wineh-bti.ll
+++ b/llvm/test/CodeGen/AArch64/wineh-bti.ll
@@ -1,6 +1,6 @@
 ; RUN: llc < %s -mtriple=aarch64-windows -aarch64-min-jump-table-entries=4 | FileCheck %s
 
-define dso_local i32 @func(i32 %in) "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" "branch-target-enforcement" {
+define dso_local i32 @func(i32 %in) "sign-return-address"="non-leaf" "sign-return-address-key"="b_key" "branch-target-enforcement" {
 entry:
   call void asm sideeffect "", "~{x19}"()
   switch i32 %in, label %def [

>From 033aa122e399ba23d216fa3e469ee62721b1b8e7 Mon Sep 17 00:00:00 2001
From: Ikhlas Ajbar <iajbar at quicinc.com>
Date: Thu, 16 Jul 2026 14:18:20 -0500
Subject: [PATCH 21/35] [Hexagon] Fix HexagonRDFOpt hang during live-in
 recomputation (#209986)

After HexagonRDFOpt, the compiler recomputed live-in registers for every
block in one batch. On large inputs (e.g. kernel builds) this was slow,
and on some functions each pass changed the live-in values of other
blocks, triggering more passes until the compiler hung (PR #207422).

Fix: process blocks one at a time in post-order (successors before
predecessors) and stop as soon as nothing changes. Add a pass limit as a
safety net to keep compile time bounded in all cases.

(cherry picked from commit da6f3e6cc2565e4c6cf720931845c8eee132ce86)
---
 llvm/lib/Target/Hexagon/HexagonRDFOpt.cpp     |  26 +-
 .../CodeGen/Hexagon/rdfopt-liveins-hang.mir   | 541 ++++++++++++++++++
 2 files changed, 562 insertions(+), 5 deletions(-)
 create mode 100644 llvm/test/CodeGen/Hexagon/rdfopt-liveins-hang.mir

diff --git a/llvm/lib/Target/Hexagon/HexagonRDFOpt.cpp b/llvm/lib/Target/Hexagon/HexagonRDFOpt.cpp
index 10aeb5381d694..cd367a88ed68e 100644
--- a/llvm/lib/Target/Hexagon/HexagonRDFOpt.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonRDFOpt.cpp
@@ -14,6 +14,7 @@
 #include "RDFCopy.h"
 #include "RDFDeadCode.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PostOrderIterator.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/CodeGen/LivePhysRegs.h"
@@ -426,11 +427,26 @@ bool HexagonRDFOpt::runOnMachineFunction(MachineFunction &MF) {
     // lists. Skip:
     //   - the entry block: handled above from the RDF LiveMap;
     //   - EH pads: exception pointer/selector are runtime-established.
-    SmallVector<MachineBasicBlock *, 16> Blocks;
-    for (MachineBasicBlock &B : MF)
-      if (!B.isEntryBlock() && !B.isEHPad())
-        Blocks.push_back(&B);
-    fullyRecomputeLiveIns(Blocks);
+    //
+    // Recompute live-ins one block at a time, visiting successors before
+    // predecessors (post-order). This way each block already has fresh
+    // live-in info from its successors when it is processed.
+    SmallVector<MachineBasicBlock *, 16> Candidates;
+    for (MachineBasicBlock *MBB : post_order(&MF))
+      if (!MBB->isEntryBlock() && !MBB->isEHPad())
+        Candidates.push_back(MBB);
+
+    // One pass is usually enough. If any block's live-ins changed, repeat
+    // because its predecessors may need updating too. Stop after
+    // MaxLiveInSweeps passes to keep compile time bounded.
+    constexpr unsigned MaxLiveInSweeps = 8;
+    for (unsigned Sweep = 0; Sweep != MaxLiveInSweeps; ++Sweep) {
+      bool AnyChanged = false;
+      for (MachineBasicBlock *MBB : Candidates)
+        AnyChanged |= recomputeLiveIns(*MBB);
+      if (!AnyChanged)
+        break;
+    }
 
     // Recompute kill flags against the updated live-in lists.
     LV.resetKills();
diff --git a/llvm/test/CodeGen/Hexagon/rdfopt-liveins-hang.mir b/llvm/test/CodeGen/Hexagon/rdfopt-liveins-hang.mir
new file mode 100644
index 0000000000000..51e4c315d3a72
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/rdfopt-liveins-hang.mir
@@ -0,0 +1,541 @@
+# RUN: llc -mtriple=hexagon-unknown-linux-musl -run-pass=hexagon-rdf-opt \
+# RUN:     -verify-machineinstrs -o /dev/null %s
+#
+# Regression test for a HexagonRDFOpt compile-time hang.
+#
+# The pass used to recompute live-in registers for every block in one
+# big batch. On some functions the live-in values never stopped changing,
+# causing the compiler to hang
+#
+# The fix processes blocks one at a time in post-order and stops as
+# soon as nothing changes, with a pass limit as a safety net.
+# This test should finish in well under a second.
+
+--- |
+  target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
+  target triple = "hexagon-unknown-linux-musl"
+
+  %struct.folio = type { %struct.page }
+  %struct.page = type { %struct.memdesc_flags_t, %struct.anon, i32, ptr, i32, i32, i32, i32 }
+  %struct.memdesc_flags_t = type { i32 }
+  %struct.anon = type { %struct.list_head }
+  %struct.list_head = type { ptr, ptr }
+  %struct.dnode_of_data = type { ptr, %struct.folio, ptr, i32, i32 }
+
+  @data_blkaddr_node_folio = dso_local global %struct.folio zeroinitializer, align 4
+  @data_blkaddr_folio = dso_local local_unnamed_addr global ptr @data_blkaddr_node_folio, align 4
+  @f2fs_seek_block_folio = dso_local global %struct.folio zeroinitializer, align 4
+  @f2fs_seek_block___trans_tmp_8 = dso_local local_unnamed_addr global ptr @f2fs_seek_block_folio, align 4
+  @f2fs_seek_block_maxbytes = dso_local local_unnamed_addr global i32 2, align 4
+  @mem_map = dso_local local_unnamed_addr global ptr null, align 4
+  @__phys_offset = dso_local local_unnamed_addr global i32 0, align 4
+  @f2fs_seek_block_pgofs = dso_local local_unnamed_addr global i32 0, align 4
+  @f2fs_seek_block___trans_tmp_7 = dso_local local_unnamed_addr global ptr null, align 4
+  @f2fs_seek_block___trans_tmp_9 = dso_local local_unnamed_addr global i8 0, align 1
+  @f2fs_seek_block___trans_tmp_1 = dso_local local_unnamed_addr global i8 0, align 1
+  @f2fs_seek_block___trans_tmp_14 = dso_local local_unnamed_addr global i32 0, align 4
+  @f2fs_seek_block_end_offset = dso_local local_unnamed_addr global i32 0, align 4
+
+  declare i32 @get_inline_xattr_addrs(ptr noundef) local_unnamed_addr #0
+
+  ; Function Attrs: nounwind
+  define dso_local void @f2fs_seek_block(ptr noundef %file, i32 noundef %whence) local_unnamed_addr #1 {
+  entry:
+    %dn = alloca %struct.dnode_of_data, align 4
+    %0 = load ptr, ptr %file, align 4, !tbaa !9
+    %1 = load ptr, ptr %0, align 4, !tbaa !13
+    call void @llvm.lifetime.start.p0(ptr nonnull %dn) #4
+    call void @llvm.memset.p0.i32(ptr noundef nonnull align 4 dereferenceable(52) %dn, i8 -1, i32 52, i1 false), !annotation !16
+    %call = tail call i64 @i_size_read(ptr noundef %1) #4
+    %cmp = icmp slt i64 %call, 1
+    br i1 %cmp, label %fail, label %for.cond.preheader
+
+  for.cond.preheader:                               ; preds = %entry
+    %conv = trunc i64 %call to i32
+    br label %for.body
+
+  for.body:                                         ; preds = %for.inc34.thread, %for.inc34, %for.cond.preheader
+    %conv374 = phi i64 [ 0, %for.cond.preheader ], [ 2, %for.inc34 ], [ 2, %for.inc34.thread ]
+    %2 = icmp eq i32 %conv, 0
+    store ptr %1, ptr %dn, align 4, !tbaa !17
+    %sunkaddr = getelementptr inbounds i8, ptr %dn, i32 40
+    store ptr null, ptr %sunkaddr, align 4, !tbaa !27
+    %sunkaddr99 = getelementptr inbounds i8, ptr %dn, i32 44
+    store i32 0, ptr %sunkaddr99, align 4, !tbaa !28
+    %3 = load i32, ptr @f2fs_seek_block_pgofs, align 4, !tbaa !29
+    call void @f2fs_get_dnode_of_data(ptr noundef nonnull %dn, i32 noundef %3, i32 noundef 1) #4
+    br i1 %2, label %if.end11, label %if.then6
+
+  if.then6:                                         ; preds = %for.body
+    %4 = icmp eq i32 %whence, 0
+    br i1 %4, label %found, label %for.inc34.thread
+
+  if.end11:                                         ; preds = %for.body
+    %5 = load ptr, ptr @mem_map, align 4, !tbaa !30
+    %sub.ptr.rhs.cast.i = ptrtoint ptr %5 to i32
+    %sub.ptr.sub.i = sub i32 0, %sub.ptr.rhs.cast.i
+    %sub.ptr.div.i = sdiv exact i32 %sub.ptr.sub.i, 36
+    %6 = load i32, ptr @__phys_offset, align 4, !tbaa !32
+    %add1.i = shl i32 %sub.ptr.div.i, 12
+    %shr2.i = add i32 %add1.i, %6
+    %shl.i = and i32 %shr2.i, -4096
+    %7 = inttoptr i32 %shl.i to ptr
+    store ptr %7, ptr @f2fs_seek_block___trans_tmp_7, align 4, !tbaa !33
+    %cgep96 = getelementptr inbounds i8, ptr %7, i32 4
+    %p.sroa.5.0.copyload = load i16, ptr %cgep96, align 4, !tbaa !35
+    %tobool13 = icmp ne i16 %p.sroa.5.0.copyload, 0
+    %storedv = zext i1 %tobool13 to i8
+    store i8 %storedv, ptr @f2fs_seek_block___trans_tmp_9, align 1, !tbaa !37
+    store i8 %storedv, ptr @f2fs_seek_block___trans_tmp_1, align 1, !tbaa !37
+    br i1 %tobool13, label %cond.true, label %cond.end
+
+  cond.true:                                        ; preds = %if.end11
+    %call19 = call i32 @get_inline_xattr_addrs(ptr noundef %1) #4
+    br label %cond.end
+
+  cond.end:                                         ; preds = %cond.true, %if.end11
+    %cond = phi i32 [ %call19, %cond.true ], [ 2, %if.end11 ]
+    store i32 %cond, ptr @f2fs_seek_block___trans_tmp_14, align 4, !tbaa !32
+    store i32 %cond, ptr @f2fs_seek_block_end_offset, align 4, !tbaa !29
+    %cgep95 = getelementptr inbounds i8, ptr %dn, i32 48
+    %8 = load i32, ptr %cgep95, align 4, !tbaa !39
+    %cmp2173 = icmp ult i32 %8, %cond
+    br i1 %cmp2173, label %for.body23, label %for.inc34
+
+  for.body23:                                       ; preds = %for.inc, %cond.end
+    %9 = phi i32 [ %23, %for.inc ], [ %8, %cond.end ]
+    %10 = load ptr, ptr %dn, align 4, !tbaa !17
+    %11 = load ptr, ptr @mem_map, align 4, !tbaa !30
+    %12 = load i32, ptr @__phys_offset, align 4, !tbaa !32
+    %tobool.not.i.i = icmp eq ptr %10, null
+    br i1 %tobool.not.i.i, label %f2fs_data_blkaddr.exit, label %cond.true.i.i
+
+  cond.true.i.i:                                    ; preds = %for.body23
+    %13 = load i32, ptr %10, align 4, !tbaa !40
+    br label %f2fs_data_blkaddr.exit
+
+  f2fs_data_blkaddr.exit:                           ; preds = %cond.true.i.i, %for.body23
+    %cond.i.i = phi i32 [ %13, %cond.true.i.i ], [ 0, %for.body23 ]
+    %sub.ptr.rhs.cast.i.i.i = ptrtoint ptr %11 to i32
+    %sub.ptr.sub.i.i.i = sub i32 0, %sub.ptr.rhs.cast.i.i.i
+    %sub.ptr.div.i.i.i = sdiv exact i32 %sub.ptr.sub.i.i.i, 36
+    %add1.i.i.i = shl i32 %sub.ptr.div.i.i.i, 12
+    %shr2.i.i.i = add i32 %add1.i.i.i, %12
+    %shl.i.i.i = and i32 %shr2.i.i.i, -4096
+    %14 = inttoptr i32 %shl.i.i.i to ptr
+    %cgep97 = getelementptr inbounds [2 x i8], ptr %14, i32 %cond.i.i
+    %15 = load i16, ptr %cgep97, align 2, !tbaa !35
+    %conv.i.i = sext i16 %15 to i32
+    %add.i.i = sub nsw i32 0, %conv.i.i
+    %tobool25.not = icmp eq i32 %9, %add.i.i
+    br i1 %tobool25.not, label %for.inc, label %land.lhs.true
+
+  land.lhs.true:                                    ; preds = %f2fs_data_blkaddr.exit
+    %call26 = call i32 @F2FS_I_SB(ptr noundef %1) #4
+    %tobool27.not = icmp eq i32 %call26, 0
+    %sunkaddr100 = getelementptr inbounds i8, ptr %dn, i32 48
+    %.pre78 = load i32, ptr %sunkaddr100, align 4, !tbaa !32
+    br i1 %tobool27.not, label %for.inc, label %if.then28
+
+  if.then28:                                        ; preds = %land.lhs.true
+    %16 = load ptr, ptr %file, align 4, !tbaa !9
+    %__trans_tmp_18.sroa.0.0.copyload.i = load ptr, ptr %dn, align 4, !tbaa !42
+    %17 = load ptr, ptr @mem_map, align 4, !tbaa !30
+    %18 = load i32, ptr @__phys_offset, align 4, !tbaa !32
+    %tobool.not.i.i56 = icmp eq ptr %__trans_tmp_18.sroa.0.0.copyload.i, null
+    br i1 %tobool.not.i.i56, label %__found_offset.exit, label %cond.true.i.i57
+
+  cond.true.i.i57:                                  ; preds = %if.then28
+    %19 = load i32, ptr %__trans_tmp_18.sroa.0.0.copyload.i, align 4, !tbaa !40
+    br label %__found_offset.exit
+
+  __found_offset.exit:                              ; preds = %cond.true.i.i57, %if.then28
+    %cond.i.i58 = phi i32 [ %19, %cond.true.i.i57 ], [ 0, %if.then28 ]
+    %sub.ptr.rhs.cast.i.i.i59 = ptrtoint ptr %17 to i32
+    %sub.ptr.sub.i.i.i60 = sub i32 0, %sub.ptr.rhs.cast.i.i.i59
+    %sub.ptr.div.i.i.i61 = sdiv exact i32 %sub.ptr.sub.i.i.i60, 36
+    %add1.i.i.i62 = shl i32 %sub.ptr.div.i.i.i61, 12
+    %shr2.i.i.i63 = add i32 %add1.i.i.i62, %18
+    %shl.i.i.i64 = and i32 %shr2.i.i.i63, -4096
+    %20 = inttoptr i32 %shl.i.i.i64 to ptr
+    %cgep98 = getelementptr inbounds [2 x i8], ptr %20, i32 %cond.i.i58
+    %21 = load i16, ptr %cgep98, align 2, !tbaa !35
+    %conv.i.i66 = sext i16 %21 to i32
+    %22 = load ptr, ptr %16, align 4, !tbaa !13
+    %call3.i = call i32 @get_inline_xattr_addrs(ptr noundef %22) #4
+    %add.i.i67 = sub nsw i32 0, %conv.i.i66
+    %tobool4.not.i = icmp ne i32 %.pre78, %add.i.i67
+    %tobool.i = icmp ne i32 %call3.i, 0
+    %retval.0.i = select i1 %tobool4.not.i, i1 %tobool.i, i1 false
+    br i1 %retval.0.i, label %found, label %__found_offset.exit.for.inc_crit_edge
+
+  __found_offset.exit.for.inc_crit_edge:            ; preds = %__found_offset.exit
+    %sunkaddr101 = getelementptr inbounds i8, ptr %dn, i32 48
+    %.pre = load i32, ptr %sunkaddr101, align 4, !tbaa !39
+    br label %for.inc
+
+  for.inc:                                          ; preds = %__found_offset.exit.for.inc_crit_edge, %land.lhs.true, %f2fs_data_blkaddr.exit
+    %23 = phi i32 [ %.pre, %__found_offset.exit.for.inc_crit_edge ], [ %9, %f2fs_data_blkaddr.exit ], [ %.pre78, %land.lhs.true ]
+    %24 = load i32, ptr @f2fs_seek_block_pgofs, align 4, !tbaa !29
+    %inc = add nsw i32 %24, 1
+    store i32 %inc, ptr @f2fs_seek_block_pgofs, align 4, !tbaa !29
+    %25 = load i32, ptr @f2fs_seek_block_end_offset, align 4, !tbaa !29
+    %cmp21 = icmp ult i32 %23, %25
+    br i1 %cmp21, label %for.body23, label %for.inc34, !llvm.loop !43
+
+  for.inc34:                                        ; preds = %for.inc, %cond.end
+    %26 = icmp ugt i64 %call, 2
+    br i1 %26, label %for.body, label %for.end35, !llvm.loop !45
+
+  for.inc34.thread:                                 ; preds = %if.then6
+    %27 = icmp ugt i64 %call, 2
+    %28 = load i32, ptr @f2fs_seek_block_pgofs, align 4, !tbaa !29
+    %call9 = call i32 @f2fs_get_next_page_offset(ptr noundef nonnull %dn, i32 noundef %28) #4
+    store i32 %call9, ptr @f2fs_seek_block_pgofs, align 4, !tbaa !29
+    br i1 %27, label %for.body, label %found, !llvm.loop !45
+
+  for.end35:                                        ; preds = %for.inc34
+    %29 = icmp eq i32 %whence, 0
+    br i1 %29, label %fail, label %found
+
+  found:                                            ; preds = %for.end35, %for.inc34.thread, %__found_offset.exit, %if.then6
+    %conv372 = phi i64 [ %conv374, %__found_offset.exit ], [ 2, %for.end35 ], [ 2, %for.inc34.thread ], [ %conv374, %if.then6 ]
+    %30 = load i32, ptr @f2fs_seek_block_maxbytes, align 4, !tbaa !29
+    %call39 = call i32 @vfs_setpos(ptr noundef nonnull %file, i64 noundef %conv372, i32 noundef %30) #4
+    br label %fail
+
+  fail:                                             ; preds = %found, %for.end35, %entry
+    %call41 = call i32 @inode_unlock_shared(ptr noundef %1) #4
+    call void @llvm.lifetime.end.p0(ptr nonnull %dn) #4
+    ret void
+  }
+
+  declare i64 @i_size_read(ptr noundef) local_unnamed_addr #0
+
+  declare void @f2fs_get_dnode_of_data(ptr noundef, i32 noundef, i32 noundef) local_unnamed_addr #0
+
+  declare i32 @f2fs_get_next_page_offset(ptr noundef, i32 noundef) local_unnamed_addr #0
+
+  declare i32 @F2FS_I_SB(ptr noundef) local_unnamed_addr #0
+
+  declare i32 @vfs_setpos(ptr noundef, i64 noundef, i32 noundef) local_unnamed_addr #0
+
+  declare i32 @inode_unlock_shared(ptr noundef) local_unnamed_addr #0
+
+  ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
+  declare void @llvm.lifetime.end.p0(ptr captures(none)) #2
+
+  ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
+  declare void @llvm.lifetime.start.p0(ptr captures(none)) #2
+
+  ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: write)
+  declare void @llvm.memset.p0.i32(ptr writeonly captures(none), i8, i32, i1 immarg) #3
+
+  attributes #0 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="hexagonv68" "target-features"="+reserved-r19,+v68,-long-calls" }
+  attributes #1 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="hexagonv68" "target-features"="+reserved-r19,+v68,-long-calls" }
+  attributes #2 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+  attributes #3 = { nocallback nofree nosync nounwind willreturn memory(argmem: write) }
+  attributes #4 = { nounwind }
+
+  !llvm.module.flags = !{!0, !1, !2}
+  !llvm.ident = !{!3}
+  !llvm.errno.tbaa = !{!4}
+
+  !0 = !{i32 8, !"PIC Level", i32 2}
+  !1 = !{i32 7, !"PIE Level", i32 2}
+  !2 = !{i32 7, !"frame-pointer", i32 2}
+  !3 = !{!"clang version 23.0.0git (https://github.com/llvm/llvm-project.git 46c2e1fb7698776e97028f6e1aba5b942390249d)"}
+  !4 = !{!5, !6, i64 0}
+  !5 = !{!"__libc_errno", !6, i64 0}
+  !6 = !{!"int", !7, i64 0}
+  !7 = !{!"omnipotent char", !8, i64 0}
+  !8 = !{!"Simple C/C++ TBAA"}
+  !9 = !{!10, !11, i64 0}
+  !10 = !{!"file", !11, i64 0}
+  !11 = !{!"p1 _ZTS13address_space", !12, i64 0}
+  !12 = !{!"any pointer", !7, i64 0}
+  !13 = !{!14, !15, i64 0}
+  !14 = !{!"address_space", !15, i64 0}
+  !15 = !{!"p1 int", !12, i64 0}
+  !16 = !{!"auto-init"}
+  !17 = !{!18, !15, i64 0}
+  !18 = !{!"dnode_of_data", !15, i64 0, !19, i64 4, !26, i64 40, !6, i64 44, !6, i64 48}
+  !19 = !{!"folio", !20, i64 0}
+  !20 = !{!"page", !21, i64 0, !23, i64 4, !22, i64 12, !11, i64 16, !22, i64 20, !6, i64 24, !6, i64 28, !6, i64 32}
+  !21 = !{!"", !22, i64 0}
+  !22 = !{!"long", !7, i64 0}
+  !23 = !{!"", !24, i64 0}
+  !24 = !{!"list_head", !25, i64 0, !25, i64 4}
+  !25 = !{!"p1 _ZTS9list_head", !12, i64 0}
+  !26 = !{!"p1 _ZTS5folio", !12, i64 0}
+  !27 = !{!18, !26, i64 40}
+  !28 = !{!18, !6, i64 44}
+  !29 = !{!22, !22, i64 0}
+  !30 = !{!31, !31, i64 0}
+  !31 = !{!"p1 _ZTS4page", !12, i64 0}
+  !32 = !{!6, !6, i64 0}
+  !33 = !{!34, !34, i64 0}
+  !34 = !{!"p1 _ZTS9f2fs_node", !12, i64 0}
+  !35 = !{!36, !36, i64 0}
+  !36 = !{!"short", !7, i64 0}
+  !37 = !{!38, !38, i64 0}
+  !38 = !{!"_Bool", !7, i64 0}
+  !39 = !{!18, !6, i64 48}
+  !40 = !{!41, !6, i64 0}
+  !41 = !{!"f2fs_inode_info", !6, i64 0}
+  !42 = !{!15, !15, i64 0}
+  !43 = distinct !{!43, !44}
+  !44 = !{!"llvm.loop.mustprogress"}
+  !45 = distinct !{!45, !44}
+...
+---
+name:            f2fs_seek_block
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+failedISel:      false
+tracksRegLiveness: true
+hasWinCFI:       false
+noPhis:          true
+isSSA:           false
+noVRegs:         true
+hasFakeUses:     false
+callsEHReturn:   false
+callsUnwindInit: false
+hasEHContTarget: false
+hasEHScopes:     false
+hasEHFunclets:   false
+isOutlined:      false
+debugInstrRef:   false
+failsVerification: false
+tracksDebugUserValues: true
+registers:       []
+liveins:         []
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    8
+  adjustsStack:    true
+  hasCalls:        true
+  framePointerPolicy: all
+  stackProtector:  ''
+  functionContext: ''
+  maxCallFrameSize: 4294967295
+  cvBytesOfCalleeSavedRegisters: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  hasTailCall:     false
+  isCalleeSavedInfoValid: false
+  localFrameSize:  0
+fixedStack:      []
+stack:
+  - { id: 0, name: '', type: default, offset: 0, size: 52, alignment: 8,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 1, name: '', type: spill-slot, offset: 0, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 2, name: '', type: spill-slot, offset: 0, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 3, name: '', type: spill-slot, offset: 0, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 4, name: '', type: spill-slot, offset: 0, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 5, name: '', type: spill-slot, offset: 0, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 6, name: '', type: spill-slot, offset: 0, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 7, name: '', type: spill-slot, offset: 0, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 8, name: '', type: spill-slot, offset: 0, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 9, name: '', type: spill-slot, offset: 0, size: 8, alignment: 8,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+entry_values:    []
+callSites:       []
+debugValueSubstitutions: []
+constants:       []
+machineFunctionInfo:
+  stackAlignBaseReg: ''
+body:             |
+  bb.0:
+    successors: %bb.23(0x30000000), %bb.1(0x50000000)
+    liveins: $r0, $r1
+
+    ADJCALLSTACKDOWN 0, 0, implicit-def $r29, implicit-def dead $r30, implicit $r31, implicit $r30, implicit $r29
+    ADJCALLSTACKUP 0, 0, implicit-def dead $r29, implicit-def dead $r30, implicit-def dead $r31, implicit $r29
+    J2_jumpt killed undef renamable $p0, %bb.23, implicit-def dead $pc
+    J2_jump %bb.1, implicit-def dead $pc
+
+  bb.1:
+    successors: %bb.2(0x80000000)
+    liveins: $d10:0x0000000000000003, $r17, $r18
+
+  bb.2:
+    successors: %bb.4(0x30000000), %bb.3(0x50000000)
+    liveins: $d2:0x0000000000000003, $d10:0x0000000000000003, $d11, $r17, $r24, $r25, $r26, $r27, $r18
+
+    ADJCALLSTACKDOWN 0, 0, implicit-def $r29, implicit-def dead $r30, implicit $r31, implicit $r30, implicit $r29
+    ADJCALLSTACKUP 0, 0, implicit-def dead $r29, implicit-def dead $r30, implicit-def dead $r31, implicit $r29
+    J2_jumpt killed undef renamable $p0, %bb.4, implicit-def dead $pc
+    J2_jump %bb.3, implicit-def dead $pc
+
+  bb.3:
+    successors: %bb.22(0x04000000), %bb.20(0x7c000000)
+    liveins: $d10:0x0000000000000003, $d11, $r16, $r24, $r25, $r26, $r27, $r18
+
+    J2_jumpt killed undef renamable $p0, %bb.22, implicit-def dead $pc
+    J2_jump %bb.20, implicit-def dead $pc
+
+  bb.4:
+    successors: %bb.5(0x50000000), %bb.6(0x30000000)
+    liveins: $d11, $r16, $r24, $r25, $r26, $r27, $r18
+
+    J2_jumpt killed undef renamable $p0, %bb.6, implicit-def dead $pc
+    J2_jump %bb.5, implicit-def dead $pc
+
+  bb.5:
+    successors: %bb.6(0x80000000)
+    liveins: $d11, $r17, $r18, $r24, $r25, $r26, $r27
+
+    ADJCALLSTACKDOWN 0, 0, implicit-def $r29, implicit-def dead $r30, implicit $r31, implicit $r30, implicit $r29
+    ADJCALLSTACKUP 0, 0, implicit-def dead $r29, implicit-def dead $r30, implicit-def dead $r31, implicit $r29
+
+  bb.6:
+    successors: %bb.7(0x40000000), %bb.19(0x40000000)
+    liveins: $d2:0x0000000000000003, $d11, $r0, $r17, $r18, $r24, $r25, $r26, $r27
+
+    renamable $r16 = L2_loadri_io %stack.4, 0 :: (load (s32) from %stack.4)
+    J2_jumpf killed undef renamable $p0, %bb.19, implicit-def dead $pc
+    J2_jump %bb.7, implicit-def dead $pc
+
+  bb.7:
+    successors: %bb.9(0x30000000), %bb.8(0x50000000)
+    liveins: $d2:0x0000000000000003, $d11, $r16, $r17, $r18, $r20, $r24, $r25, $r26, $r27
+
+    J2_jumpt killed undef renamable $p0, %bb.9, implicit-def dead $pc
+    J2_jump %bb.8, implicit-def dead $pc
+
+  bb.8:
+    successors: %bb.9(0x80000000)
+    liveins: $d2:0x0000000000000003, $d11, $r0, $r2, $r16, $r17, $r18, $r20, $r24, $r25, $r26, $r27
+
+  bb.9:
+    successors: %bb.18(0x40000000), %bb.10(0x40000000)
+    liveins: $d2:0x0000000000000003, $d11, $r0, $r1, $r16, $r17, $r18, $r20, $r24, $r25, $r26, $r27
+
+    J2_jumpt killed undef renamable $p0, %bb.18, implicit-def dead $pc
+    J2_jump %bb.10, implicit-def dead $pc
+
+  bb.10:
+    successors: %bb.11(0x30000000), %bb.12(0x50000000)
+    liveins: $d11, $r16, $r17, $r18, $r24, $r25, $r26, $r27
+
+    ADJCALLSTACKDOWN 0, 0, implicit-def $r29, implicit-def dead $r30, implicit $r31, implicit $r30, implicit $r29
+    ADJCALLSTACKUP 0, 0, implicit-def dead $r29, implicit-def dead $r30, implicit-def dead $r31, implicit $r29
+    J2_jumpf killed undef renamable $p0, %bb.12, implicit-def $pc
+
+  bb.11:
+    successors: %bb.18(0x80000000)
+    liveins: $d11, $r16, $r17, $r18, $r20, $r24, $r25, $r26, $r27
+
+    J2_jump %bb.18, implicit-def $pc
+
+  bb.12:
+    successors: %bb.14(0x30000000), %bb.13(0x50000000)
+    liveins: $d11, $r16, $r17, $r18, $r20, $r24, $r25, $r26, $r27
+
+    J2_jumpt killed undef renamable $p0, %bb.14, implicit-def dead $pc
+    J2_jump %bb.13, implicit-def dead $pc
+
+  bb.13:
+    successors: %bb.14(0x80000000)
+    liveins: $d11, $r0, $r2, $r16, $r17, $r18, $r20, $r24, $r25, $r26, $r27
+
+  bb.14:
+    successors: %bb.15(0x42000000), %bb.17(0x3e000000)
+    liveins: $d11, $r0, $r1, $r16, $r17, $r18, $r20, $r24, $r25, $r26, $r27
+
+    renamable $r4 = L2_loadri_io renamable $r16, 0 :: (load (s32), !tbaa !9)
+    ADJCALLSTACKDOWN 0, 0, implicit-def $r29, implicit-def dead $r30, implicit $r31, implicit $r30, implicit $r29
+    renamable $r0 = L2_loadri_io killed renamable $r4, 0 :: (load (s32), !tbaa !13)
+    ADJCALLSTACKUP 0, 0, implicit-def dead $r29, implicit-def dead $r30, implicit-def dead $r31, implicit $r29
+    J2_jumpt killed undef renamable $p0, %bb.17, implicit-def dead $pc
+    J2_jump %bb.15, implicit-def dead $pc
+
+  bb.15:
+    successors: %bb.16(0x07c1f07c), %bb.17(0x783e0f84)
+    liveins: $d11, $r0, $r16, $r17, $r18, $r24, $r25, $r26, $r27
+
+    renamable $p0 = C2_cmpeqi killed renamable $r0, 0
+    J2_jumpt killed renamable $p0, %bb.17, implicit-def $pc
+
+  bb.16:
+    successors: %bb.22(0x80000000)
+    liveins: $d11, $r17
+
+    J2_jump %bb.22, implicit-def $pc
+
+  bb.17:
+    successors: %bb.18(0x80000000)
+    liveins: $d11, $r16, $r17, $r18, $r24, $r25, $r26, $r27
+
+  bb.18:
+    successors: %bb.7(0x7c000000), %bb.19(0x04000000)
+    liveins: $d2:0x0000000000000003, $d11, $r16, $r17, $r18, $r20, $r24, $r25, $r26, $r27
+
+    J2_jumpt killed undef renamable $p0, %bb.7, implicit-def dead $pc
+    J2_jump %bb.19, implicit-def dead $pc
+
+  bb.19:
+    successors: %bb.2(0x7c000000), %bb.21(0x04000000)
+    liveins: $d2:0x0000000000000003, $r17, $r24, $r25, $r26, $r27, $r18
+
+    J2_jumpt killed undef renamable $p0, %bb.2, implicit-def dead $pc
+    J2_jump %bb.21, implicit-def dead $pc
+
+  bb.20:
+    successors: %bb.2(0x7c000000), %bb.22(0x04000000)
+    liveins: $d10:0x0000000000000003, $r17, $r24, $r25, $r26, $r27, $r18
+
+    ADJCALLSTACKDOWN 0, 0, implicit-def $r29, implicit-def dead $r30, implicit $r31, implicit $r30, implicit $r29
+    ADJCALLSTACKUP 0, 0, implicit-def dead $r29, implicit-def dead $r30, implicit-def dead $r31, implicit $r29
+    J2_jumpt killed undef renamable $p0, %bb.2, implicit-def dead $pc
+    J2_jump %bb.22, implicit-def dead $pc
+
+  bb.21:
+    successors: %bb.23(0x30000000), %bb.22(0x50000000)
+    liveins: $r17
+
+    J2_jumpt killed undef renamable $p0, %bb.23, implicit-def dead $pc
+    J2_jump %bb.22, implicit-def dead $pc
+
+  bb.22:
+    successors: %bb.23(0x80000000)
+    liveins: $d11, $r17
+
+    ADJCALLSTACKDOWN 0, 0, implicit-def $r29, implicit-def dead $r30, implicit $r31, implicit $r30, implicit $r29
+    ADJCALLSTACKUP 0, 0, implicit-def dead $r29, implicit-def dead $r30, implicit-def dead $r31, implicit $r29
+
+  bb.23:
+    liveins: $r17
+
+    ADJCALLSTACKDOWN 0, 0, implicit-def $r29, implicit-def dead $r30, implicit $r31, implicit $r30, implicit $r29
+    ADJCALLSTACKUP 0, 0, implicit-def dead $r29, implicit-def dead $r30, implicit-def dead $r31, implicit $r29
+    PS_jmpret $r31, implicit-def dead $pc
+...

>From 52cbf59a5085bff2083a03a71bfbd82b882b024a Mon Sep 17 00:00:00 2001
From: maflcko <6399679+maflcko at users.noreply.github.com>
Date: Fri, 17 Jul 2026 07:42:16 +0200
Subject: [PATCH 22/35] [compiler-rt][ubsan] Fix suppressions for inlined
 functions (#206735)

Align suppression PC handling with getCallerLocation(), so function
suppressions identify the inlined function that caused a report.

Intentionally match only the innermost inline frame.

Extend suppressions-nested-calls.c coverage to -O1.

Fixes https://github.com/llvm/llvm-project/issues/209501

---------

Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^_ at 721217.xyz>
(cherry picked from commit a376783e2ed3a44f63991c97513711faad09525b)
---
 compiler-rt/lib/ubsan/ubsan_diag.cpp          |  6 +++++
 .../Integer/suppressions-nested-calls.c       | 22 +++++++++++++------
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/compiler-rt/lib/ubsan/ubsan_diag.cpp b/compiler-rt/lib/ubsan/ubsan_diag.cpp
index 6efd082a89934..d06af776b54e1 100644
--- a/compiler-rt/lib/ubsan/ubsan_diag.cpp
+++ b/compiler-rt/lib/ubsan/ubsan_diag.cpp
@@ -438,6 +438,9 @@ bool __ubsan::IsVptrCheckSuppressed(const char *TypeName) {
 bool __ubsan::IsPCSuppressed(ErrorType ET, uptr PC, const char *Filename) {
   InitAsStandaloneIfNecessary();
   CHECK(suppression_ctx);
+  // PC is the return address from the UBSan handler call. Symbolize the
+  // instruction that caused the call.
+  PC = StackTrace::GetPreviousInstructionPc(PC);
   const char *SuppType = ConvertTypeToFlagName(ET);
   // Fast path: don't symbolize PC if there is no suppressions for given UB
   // type.
@@ -453,6 +456,9 @@ bool __ubsan::IsPCSuppressed(ErrorType ET, uptr PC, const char *Filename) {
       return true;
   }
   // Suppress by function or source file name from debug info.
+  // The first frame is the innermost logical inline frame, if inline debug
+  // information is available. Do not search the rest of the chain: a
+  // suppression for an inline wrapper must not suppress an inlined callee.
   SymbolizedStackHolder Stack(Symbolizer::GetOrInit()->SymbolizePC(PC));
   const AddressInfo &AI = Stack.get()->info;
   return suppression_ctx->Match(AI.function, SuppType, &s) ||
diff --git a/compiler-rt/test/ubsan/TestCases/Integer/suppressions-nested-calls.c b/compiler-rt/test/ubsan/TestCases/Integer/suppressions-nested-calls.c
index 487d35eaa83f4..22ec6d4fe4642 100644
--- a/compiler-rt/test/ubsan/TestCases/Integer/suppressions-nested-calls.c
+++ b/compiler-rt/test/ubsan/TestCases/Integer/suppressions-nested-calls.c
@@ -3,28 +3,36 @@
 
 // # Test for UBSan suppressions with nested function calls
 //
-// RUN: %clang -fsanitize=integer -O0 -g %s -o %t.o0
 //
 // # Only the directly suppressed my_make_signed hit should disappear.
 // RUN: echo "implicit-integer-sign-change:my_make_signed" > %t.make_signed.name.supp
 // RUN: echo "implicit-integer-sign-change:Inputs/make_signed.h" > %t.make_signed.file.supp
 //
-// RUN: %env_ubsan_opts=suppressions='"%t.make_signed.name.supp"' %run %t.o0 2>&1 | FileCheck %s --check-prefix=CHECK-MAKE-SIGNED
-// RUN: %env_ubsan_opts=suppressions='"%t.make_signed.file.supp"' %run %t.o0 2>&1 | FileCheck %s --check-prefix=CHECK-MAKE-SIGNED
-//
 // # Only the suppressed wrapper-originated hit should disappear.
 // RUN: echo "implicit-integer-sign-change:my_wrapper_2" > %t.my_wrapper_2.name.supp
 // RUN: echo "implicit-integer-sign-change:Inputs/wrappers.h" > %t.wrappers.file.supp
 //
-// RUN: %env_ubsan_opts=suppressions='"%t.my_wrapper_2.name.supp"' %run %t.o0 2>&1 | FileCheck %s --check-prefix=CHECK-WRAPPERS
-// RUN: %env_ubsan_opts=suppressions='"%t.wrappers.file.supp"'     %run %t.o0 2>&1 | FileCheck %s --check-prefix=CHECK-WRAPPERS
-//
 // # Suppress both.
 // RUN: cat %t.make_signed.name.supp %t.my_wrapper_2.name.supp > %t.both.name.supp
 // RUN: cat %t.make_signed.file.supp %t.wrappers.file.supp > %t.both.file.supp
 //
+// # Compile and test each optimization level before the next compile. On
+// # Windows, the linker emits shared debug and auxiliary-file names here.
+// RUN: %clang -fsanitize=integer -O0 -g %s -o %t.o0
+// RUN: %env_ubsan_opts=suppressions='"%t.make_signed.name.supp"' %run %t.o0 2>&1 | FileCheck %s --check-prefix=CHECK-MAKE-SIGNED
+// RUN: %env_ubsan_opts=suppressions='"%t.make_signed.file.supp"' %run %t.o0 2>&1 | FileCheck %s --check-prefix=CHECK-MAKE-SIGNED
+// RUN: %env_ubsan_opts=suppressions='"%t.my_wrapper_2.name.supp"' %run %t.o0 2>&1 | FileCheck %s --check-prefix=CHECK-WRAPPERS
+// RUN: %env_ubsan_opts=suppressions='"%t.wrappers.file.supp"'     %run %t.o0 2>&1 | FileCheck %s --check-prefix=CHECK-WRAPPERS
 // RUN: %env_ubsan_opts=suppressions='"%t.both.name.supp"' %run %t.o0 2>&1 | FileCheck %s --allow-empty --check-prefix=CHECK-BOTH
 // RUN: %env_ubsan_opts=suppressions='"%t.both.file.supp"' %run %t.o0 2>&1 | FileCheck %s --allow-empty --check-prefix=CHECK-BOTH
+//
+// RUN: %clang -fsanitize=integer -O1 -g %s -o %t.o1
+// RUN: %env_ubsan_opts=suppressions='"%t.make_signed.name.supp"' %run %t.o1 2>&1 | FileCheck %s --check-prefix=CHECK-MAKE-SIGNED
+// RUN: %env_ubsan_opts=suppressions='"%t.make_signed.file.supp"' %run %t.o1 2>&1 | FileCheck %s --check-prefix=CHECK-MAKE-SIGNED
+// RUN: %env_ubsan_opts=suppressions='"%t.my_wrapper_2.name.supp"' %run %t.o1 2>&1 | FileCheck %s --check-prefix=CHECK-WRAPPERS
+// RUN: %env_ubsan_opts=suppressions='"%t.wrappers.file.supp"'     %run %t.o1 2>&1 | FileCheck %s --check-prefix=CHECK-WRAPPERS
+// RUN: %env_ubsan_opts=suppressions='"%t.both.name.supp"' %run %t.o1 2>&1 | FileCheck %s --allow-empty --check-prefix=CHECK-BOTH
+// RUN: %env_ubsan_opts=suppressions='"%t.both.file.supp"' %run %t.o1 2>&1 | FileCheck %s --allow-empty --check-prefix=CHECK-BOTH
 
 #include "Inputs/make_signed.h"
 #include "Inputs/wrappers.h"

>From 44addbd4e1fbf754092185cd74c08a1e283df80f Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 17 Jul 2026 09:51:47 +0200
Subject: [PATCH 23/35] [LTO] Sort DefinedGlobals in LTO cache key (#210025)

Sort the DefindeGlobals by GUID when computing the LTO cache key, to
avoid making the cache key dependent on the insertion order. This fixes
large compile-time regressions in rust incremental builds.

Alternatively one could make collectDefinedGVSummariesPerModule() work
on the sortedRange(), but as that is also used in other places, it
probably makes sense to sort locally.

The issue was introduced in 760bb06cb3cd98832f1e4e7a4eaebd98b66d2bdd.

(cherry picked from commit 90e31c46d005ae0a7f5968c38a9310bee499923c)
---
 llvm/lib/LTO/LTO.cpp                          | 11 +++++---
 .../X86/Inputs/cache-defined-globals-order.ll |  6 +++++
 .../X86/cache-defined-globals-order.ll        | 27 +++++++++++++++++++
 3 files changed, 41 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/ThinLTO/X86/Inputs/cache-defined-globals-order.ll
 create mode 100644 llvm/test/ThinLTO/X86/cache-defined-globals-order.ll

diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index b0fd1d77a2d66..c8c5b0880819a 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -304,9 +304,14 @@ std::string llvm::computeLTOCacheKey(
     }
   };
 
-  // Include the hash for the linkage type to reflect internalization and weak
-  // resolution, and collect any used type identifier resolutions.
-  for (auto &GS : DefinedGlobals) {
+  // Sort the defined globals by GUID to be independent of the insertion order,
+  // which may depend on the order that modules are added.
+  SmallVector<std::pair<GlobalValue::GUID, GlobalValueSummary *>>
+      SortedDefinedGlobals(DefinedGlobals.begin(), DefinedGlobals.end());
+  llvm::sort(SortedDefinedGlobals, llvm::less_first());
+  for (auto &GS : SortedDefinedGlobals) {
+    // Include the hash for the linkage type to reflect internalization and weak
+    // resolution, and collect any used type identifier resolutions.
     GlobalValue::LinkageTypes Linkage = GS.second->linkage();
     Hasher.update(
         ArrayRef<uint8_t>((const uint8_t *)&Linkage, sizeof(Linkage)));
diff --git a/llvm/test/ThinLTO/X86/Inputs/cache-defined-globals-order.ll b/llvm/test/ThinLTO/X86/Inputs/cache-defined-globals-order.ll
new file mode 100644
index 0000000000000..5a527c9bae924
--- /dev/null
+++ b/llvm/test/ThinLTO/X86/Inputs/cache-defined-globals-order.ll
@@ -0,0 +1,6 @@
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define linkonce_odr void @shared29() {
+  ret void
+}
diff --git a/llvm/test/ThinLTO/X86/cache-defined-globals-order.ll b/llvm/test/ThinLTO/X86/cache-defined-globals-order.ll
new file mode 100644
index 0000000000000..84f71f20f9e6d
--- /dev/null
+++ b/llvm/test/ThinLTO/X86/cache-defined-globals-order.ll
@@ -0,0 +1,27 @@
+; RUN: rm -rf %t && mkdir -p %t
+; RUN: opt -module-hash -module-summary %s -o %t/t.bc
+; RUN: opt -module-hash -module-summary %S/Inputs/cache-defined-globals-order.ll -o %t/a.bc
+
+; Tests that the LTO cache key is insensitive to the order of the modules.
+; The linkonce_odr function @shared29 is defined in both t.bc and a.bc, so
+; it gets a different position in the combined index depending on which
+; module is processed first, which results in a different insertion order
+; for DefinedGlobals.
+
+; RUN: llvm-lto2 run -cache-dir %t/cache -o %t.o %t/t.bc %t/a.bc -r=%t/t.bc,main,plx -r=%t/t.bc,shared29,plx -r=%t/a.bc,shared29,lx
+; RUN: ls %t/cache | count 2
+
+; RUN: llvm-lto2 run -cache-dir %t/cache -o %t.o %t/a.bc %t/t.bc -r=%t/t.bc,main,plx -r=%t/t.bc,shared29,plx -r=%t/a.bc,shared29,lx
+; RUN: ls %t/cache | count 2
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @main() {
+  call void @shared29()
+  ret void
+}
+
+define linkonce_odr void @shared29() {
+  ret void
+}

>From 28af770db4db6f04d047f52e7e135386fe7a6824 Mon Sep 17 00:00:00 2001
From: cqwrteur <oyzawqgcfc at gmail.com>
Date: Fri, 17 Jul 2026 17:11:45 +0800
Subject: [PATCH 24/35] [libcxx] avoid include Uppercase windows headers
 (#208903)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

We should use unknwn.h and windows.h instead of Unknwn.h and Windows.h
because Linux and other non‑Windows systems treat filenames as
case‑sensitive. Windows does not, so mixed‑case includes work there but
break elsewhere. Both mingw‑w64‑crt and windows‑msvc‑sysroot provide all
Windows headers in fully lowercase, so using the lowercase forms ensures
consistent cross‑platform builds.

Fixes #208901

(cherry picked from commit 2580624091e36b85c162439513eef8e752217a1d)
---
 libcxx/src/support/runtime/exception_pointer_msvc.ipp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/src/support/runtime/exception_pointer_msvc.ipp b/libcxx/src/support/runtime/exception_pointer_msvc.ipp
index 72360a2d791bd..3102d1ee93db2 100644
--- a/libcxx/src/support/runtime/exception_pointer_msvc.ipp
+++ b/libcxx/src/support/runtime/exception_pointer_msvc.ipp
@@ -14,8 +14,8 @@ _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmultichar")
 #include <cstdlib>
 #include <cstring>
 
-#include <Unknwn.h>
-#include <Windows.h>
+#include <unknwn.h>
+#include <windows.h>
 struct _ThrowInfo;
 #include <eh.h>
 #include <ehdata.h>

>From 44727f2bc6e66afccfc0e3e3f0d2e5f241924593 Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Fri, 17 Jul 2026 00:17:00 +0200
Subject: [PATCH 25/35] [clang][mingw] Try both native and ARM64EC triples when
 looking for a sysroot on the ARM64EC target (#210017)

Similarly to MSVC, a MinGW toolchain may provide support for both ARM64
and ARM64EC in a single sysroot. Structuring the toolchain this way has
the additional advantage of seamlessly supporting linking ARM64X images.

Support this configuration in findClangRelativeSysroot.

(cherry picked from commit 205a66201235c03b892e075ae548d6ea12f024a3)
---
 clang/lib/Driver/ToolChains/MinGW.cpp | 15 +++++++++++++++
 clang/test/Driver/mingw-sysroot.cpp   | 20 ++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp
index 7fe5be92012ee..65120931d8181 100644
--- a/clang/lib/Driver/ToolChains/MinGW.cpp
+++ b/clang/lib/Driver/ToolChains/MinGW.cpp
@@ -476,11 +476,26 @@ findClangRelativeSysroot(const Driver &D, const llvm::Triple &LiteralTriple,
                          const llvm::Triple &T, std::string &SubdirName) {
   llvm::SmallVector<llvm::SmallString<32>, 4> Subdirs;
   Subdirs.emplace_back(LiteralTriple.str());
+  // On ARM64EC targets, also try native aarch64 sysroot, which may contain
+  // support for both targets.
+  if (LiteralTriple.isWindowsArm64EC()) {
+    llvm::Triple NativeTriple(LiteralTriple);
+    NativeTriple.setArchName("aarch64");
+    Subdirs.emplace_back(NativeTriple.str());
+  }
   Subdirs.emplace_back(T.str());
   Subdirs.emplace_back(T.getArchName());
   Subdirs.back() += "-w64-mingw32";
   Subdirs.emplace_back(T.getArchName());
   Subdirs.back() += "-w64-mingw32ucrt";
+  if (T.isWindowsArm64EC()) {
+    llvm::Triple NativeTriple(T);
+    NativeTriple.setArchName("aarch64");
+    Subdirs.emplace_back(NativeTriple.str());
+
+    Subdirs.emplace_back("aarch64-w64-mingw32");
+    Subdirs.emplace_back("aarch64-w64-mingw32ucrt");
+  }
   StringRef ClangRoot = llvm::sys::path::parent_path(D.Dir);
   StringRef Sep = llvm::sys::path::get_separator();
   for (StringRef CandidateSubdir : Subdirs) {
diff --git a/clang/test/Driver/mingw-sysroot.cpp b/clang/test/Driver/mingw-sysroot.cpp
index 8e46d23c1782d..372df0509c8d9 100644
--- a/clang/test/Driver/mingw-sysroot.cpp
+++ b/clang/test/Driver/mingw-sysroot.cpp
@@ -10,8 +10,11 @@
 // RUN: rm -rf %t.dir/testroot-clang
 // RUN: mkdir -p %t.dir/testroot-clang/bin
 // RUN: ln -s %clang %t.dir/testroot-clang/bin/x86_64-w64-mingw32-clang
+// RUN: ln -s %clang %t.dir/testroot-clang/bin/aarch64-w64-mingw32-clang
+// RUN: ln -s %clang %t.dir/testroot-clang/bin/arm64ec-w64-mingw32-clang
 // RUN: ln -s %S/Inputs/mingw_ubuntu_posix_tree/usr/x86_64-w64-mingw32 %t.dir/testroot-clang/x86_64-w64-mingw32
 // RUN: ln -s %S/Inputs/mingw_arch_tree/usr/i686-w64-mingw32 %t.dir/testroot-clang/i686-w64-mingw32
+// RUN: ln -s %S/Inputs/mingw_ubuntu_posix_tree/usr/x86_64-w64-mingw32 %t.dir/testroot-clang/aarch64-w64-mingw32
 
 // RUN: rm -rf %t.dir/testroot-clang-native
 // RUN: mkdir -p %t.dir/testroot-clang-native/bin
@@ -23,6 +26,7 @@
 // RUN: mkdir -p %t.dir/testroot-custom-triple/bin
 // RUN: ln -s %clang %t.dir/testroot-custom-triple/bin/clang
 // RUN: ln -s %S/Inputs/mingw_ubuntu_posix_tree/usr/x86_64-w64-mingw32 %t.dir/testroot-custom-triple/x86_64-w64-mingw32foo
+// RUN: ln -s %S/Inputs/mingw_ubuntu_posix_tree/usr/x86_64-w64-mingw32 %t.dir/testroot-custom-triple/aarch64-w64-mingw32foo
 
 // If we find a gcc in the path with the right triplet prefix, pick that as
 // sysroot:
@@ -103,3 +107,19 @@
 
 // RUN: %t.dir/testroot-custom-triple/bin/clang -no-canonical-prefixes --target=x86_64-w64-mingw32foo -rtlib=compiler-rt -stdlib=libstdc++ --sysroot="" -c -### %s 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_CUSTOM_TRIPLE %s
 // CHECK_TESTROOT_CUSTOM_TRIPLE: "{{[^"]+}}/testroot-custom-triple{{/|\\\\}}x86_64-w64-mingw32foo{{/|\\\\}}include"
+
+// Check that the arm64ec target uses the aarch64 sysroot if a separate arm64ec sysroot is not found.
+
+// RUN: %t.dir/testroot-clang/bin/aarch64-w64-mingw32-clang -no-canonical-prefixes --target=aarch64-w64-mingw32 -rtlib=compiler-rt -stdlib=libstdc++ --sysroot="" -c -### %s 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_CLANG_AARCH64 %s
+// RUN: %t.dir/testroot-clang/bin/arm64ec-w64-mingw32-clang -no-canonical-prefixes --target=arm64ec-w64-mingw32 -rtlib=compiler-rt -stdlib=libstdc++ --sysroot="" -c -### %s 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_CLANG_AARCH64 %s
+// CHECK_TESTROOT_CLANG_AARCH64: "{{[^"]+}}/testroot-clang{{/|\\\\}}aarch64-w64-mingw32{{/|\\\\}}include"
+
+// RUN: %t.dir/testroot-custom-triple/bin/clang -no-canonical-prefixes --target=aarch64-w64-mingw32foo -rtlib=compiler-rt -stdlib=libstdc++ --sysroot="" -c -### %s 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_CUSTOM_TRIPLE_AARCH64 %s
+// RUN: %t.dir/testroot-custom-triple/bin/clang -no-canonical-prefixes --target=arm64ec-w64-mingw32foo -rtlib=compiler-rt -stdlib=libstdc++ --sysroot="" -c -### %s 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_CUSTOM_TRIPLE_AARCH64 %s
+// CHECK_TESTROOT_CUSTOM_TRIPLE_AARCH64: "{{[^"]+}}/testroot-custom-triple{{/|\\\\}}aarch64-w64-mingw32foo{{/|\\\\}}include"
+
+// Check that the arm64ec sysroot is still preferred when available.
+
+// RUN: ln -s %S/Inputs/mingw_ubuntu_posix_tree/usr/x86_64-w64-mingw32 %t.dir/testroot-custom-triple/arm64ec-w64-mingw32foo
+// RUN: %t.dir/testroot-custom-triple/bin/clang -no-canonical-prefixes --target=arm64ec-w64-mingw32foo -rtlib=compiler-rt -stdlib=libstdc++ --sysroot="" -c -### %s 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_CUSTOM_TRIPLE_ARM64EC %s
+// CHECK_TESTROOT_CUSTOM_TRIPLE_ARM64EC: "{{[^"]+}}/testroot-custom-triple{{/|\\\\}}arm64ec-w64-mingw32foo{{/|\\\\}}include"

>From f83ba9d97b34021e3d2ff2faf7b04a3001b2c7ca Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 17 Jul 2026 14:34:11 +0200
Subject: [PATCH 26/35] [X86] Fix assertion failure for tail call on i686+pic
 (#210302)

The pattern for TCRETURNmi has a IsNotPIC predicate, but the
checkTCRetEnoughRegs() predicate that's part of the X86tcret_enough_regs
PatFrag is evaluated first, so we can't assert that PIC is disabled
here. We should just return false in that case.

Fixes https://github.com/llvm/llvm-project/issues/210300.

(cherry picked from commit 23b0281d75a4320a4e6e3d837edf94911d98d252)
---
 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp    |  3 ++-
 llvm/test/CodeGen/X86/tailcall-i686-pic.ll | 14 ++++++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/CodeGen/X86/tailcall-i686-pic.ll

diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index b794567f6a047..9a0045367a8bf 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -3561,7 +3561,8 @@ bool X86DAGToDAGISel::checkTCRetEnoughRegs(SDNode *N) const {
       LoadGPRs -= 2; // Base is fixed index off ESP; no regs needed.
     } else if (BasePtr.getOpcode() == X86ISD::Wrapper &&
                isa<GlobalAddressSDNode>(BasePtr->getOperand(0))) {
-      assert(!getTargetMachine().isPositionIndependent());
+      if (getTargetMachine().isPositionIndependent())
+        return false;
       LoadGPRs -= 1; // Base is a global (immediate since this is non-PIC), no
                      // reg needed.
     }
diff --git a/llvm/test/CodeGen/X86/tailcall-i686-pic.ll b/llvm/test/CodeGen/X86/tailcall-i686-pic.ll
new file mode 100644
index 0000000000000..b8a4207451e8a
--- /dev/null
+++ b/llvm/test/CodeGen/X86/tailcall-i686-pic.ll
@@ -0,0 +1,14 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=i686-pc-windows-msvc -relocation-model=pic < %s | FileCheck %s
+
+ at fnptr = external global ptr
+
+define void @test() {
+; CHECK-LABEL: test:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl _fnptr, %eax
+; CHECK-NEXT:    jmpl *%eax # TAILCALL
+  %p = load ptr, ptr @fnptr
+  tail call void %p()
+  ret void
+}

>From 278c31bfb8ceb7ea17dbfd11a4fb21e6634af957 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Thu, 16 Jul 2026 21:06:59 -0700
Subject: [PATCH 27/35] workflows: Fixes for release-binaries and
 upload-release-artifact (#209246)

There were some bugs in upload-release-artifact workflow and
release-binaries was not including this action in its checkout.

(cherry picked from commit 963e226d9a6b923b10c8e328438838bd42e03d18)
---
 .github/workflows/release-binaries.yml                | 1 +
 .github/workflows/validate-release-version/action.yml | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/release-binaries.yml b/.github/workflows/release-binaries.yml
index 6fdf5e8c14cb8..d2dbb656d371d 100644
--- a/.github/workflows/release-binaries.yml
+++ b/.github/workflows/release-binaries.yml
@@ -386,6 +386,7 @@ jobs:
           persist-credentials: false
           sparse-checkout: |
             .github/workflows/upload-release-artifact
+            .github/workflows/validate-release-version
             llvm/utils/release/github-upload-release.py
             llvm/utils/git/requirements.txt
           sparse-checkout-cone-mode: false
diff --git a/.github/workflows/validate-release-version/action.yml b/.github/workflows/validate-release-version/action.yml
index 1a10ad67cb549..669369eaf82e6 100644
--- a/.github/workflows/validate-release-version/action.yml
+++ b/.github/workflows/validate-release-version/action.yml
@@ -9,7 +9,7 @@ runs:
   using: "composite"
   steps:
     - env:
-      RELEASE_VERSON: ${{ inputs.release-version }}
-
+        RELEASE_VERSION: ${{ inputs.release-version }}
+      shell: bash
       run: |
         grep -e '^[0-9]\+\.[0-9]\+\.[0-9]\+\(-rc[0-9]\+\)\?$' <<< "$RELEASE_VERSION"

>From 03c1f18aeee0150dc0243cd32b09b5050c9b6224 Mon Sep 17 00:00:00 2001
From: Douglas Yung <douglas.yung at sony.com>
Date: Sat, 18 Jul 2026 02:34:37 +0000
Subject: [PATCH 28/35] Bump version to 23.1.0-rc1

---
 cmake/Modules/LLVMVersion.cmake | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cmake/Modules/LLVMVersion.cmake b/cmake/Modules/LLVMVersion.cmake
index ed3dfebf7548a..e5e1c00cd64c3 100644
--- a/cmake/Modules/LLVMVersion.cmake
+++ b/cmake/Modules/LLVMVersion.cmake
@@ -10,6 +10,6 @@ if(NOT DEFINED LLVM_VERSION_PATCH)
   set(LLVM_VERSION_PATCH 0)
 endif()
 if(NOT DEFINED LLVM_VERSION_SUFFIX)
-  set(LLVM_VERSION_SUFFIX git)
+  set(LLVM_VERSION_SUFFIX ('rc', 1))
 endif()
 

>From acdf320b78fcf075ddcf660b51cf18d5c0af755b Mon Sep 17 00:00:00 2001
From: Douglas Yung <douglas.yung at sony.com>
Date: Sat, 18 Jul 2026 07:35:12 +0000
Subject: [PATCH 29/35] Fix bumping of version to 23.1.0-rc1.

---
 cmake/Modules/LLVMVersion.cmake | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cmake/Modules/LLVMVersion.cmake b/cmake/Modules/LLVMVersion.cmake
index e5e1c00cd64c3..22dbb25383def 100644
--- a/cmake/Modules/LLVMVersion.cmake
+++ b/cmake/Modules/LLVMVersion.cmake
@@ -10,6 +10,6 @@ if(NOT DEFINED LLVM_VERSION_PATCH)
   set(LLVM_VERSION_PATCH 0)
 endif()
 if(NOT DEFINED LLVM_VERSION_SUFFIX)
-  set(LLVM_VERSION_SUFFIX ('rc', 1))
+  set(LLVM_VERSION_SUFFIX -rc1)
 endif()
 

>From 4285c201f92ae76a6db1db99fa9c40f5283b1cfa Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Mon, 20 Jul 2026 08:52:47 -0700
Subject: [PATCH 30/35] workflows/release-documentation: Add missing secrets
 (#210421)

(cherry picked from commit b7810e97d6281f65e255b36af7b39af18d3d2006)
---
 .github/workflows/release-documentation.yml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index 75dfb6fdd3437..12e6a3844660c 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -32,6 +32,12 @@ on:
       WWW_RELEASES_TOKEN:
         description: "Secret used to create a PR with the documentation changes."
         required: false
+      LLVM_TOKEN_GENERATOR_CLIENT_ID:
+        description: "Client ID for our GitHub App we use for generating access tokens."
+        required: true
+      LLVM_TOKEN_GENERATOR_PRIVATE_KEY:
+        description: "Private key for our GitHub App we use for generating access tokens."
+        required: true
 
 jobs:
   # This job checks permissions and validates inputs to prevent potential

>From db494ccad869323687b23af33e4226479a54d8f2 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Mon, 20 Jul 2026 14:12:13 -0700
Subject: [PATCH 31/35] workflows: Add missing checkouts when using
 validate-release-version (#210471)

We need to make sure all composite workflows we use are checked out
manually from th egit repo.

(cherry picked from commit 429c88d37f1f02e68ebc1fc7b0da4511ce6407e3)
---
 .github/workflows/release-binaries-all.yml |  7 +++++++
 .github/workflows/release-binaries.yml     | 10 +++++-----
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/.github/workflows/release-binaries-all.yml b/.github/workflows/release-binaries-all.yml
index 2e2869e4073da..862300a8118e5 100644
--- a/.github/workflows/release-binaries-all.yml
+++ b/.github/workflows/release-binaries-all.yml
@@ -68,6 +68,13 @@ jobs:
       release-version: ${{ steps.vars.outputs.release-version }}
       upload: ${{ steps.vars.outputs.upload }}
     steps:
+      - uses: actions/checkout at de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          persist-credentials: false
+          sparse-checkout: |
+            .github/workflows/validate-release-version
+          sparse-checkout-cone-mode: false
+
       - name: Validate Input
         if: inputs.release-version != ''
         uses: ./.github/workflows/validate-release-version
diff --git a/.github/workflows/release-binaries.yml b/.github/workflows/release-binaries.yml
index d2dbb656d371d..9b00a4945703c 100644
--- a/.github/workflows/release-binaries.yml
+++ b/.github/workflows/release-binaries.yml
@@ -72,17 +72,17 @@ jobs:
       attestation-name: ${{ steps.vars.outputs.attestation-name }}
 
     steps:
+    - name: Checkout LLVM
+      uses: actions/checkout at de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+      with:
+          persist-credentials: false
+
     - name: Validate Release Version
       if: inputs.release-version != ''
       uses: ./.github/workflows/validate-release-version
       with:
         release-version: ${{ inputs.release-version }}
 
-    - name: Checkout LLVM
-      uses: actions/checkout at de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
-      with:
-          persist-credentials: false
-
     - name: Check Permissions
       if: github.event_name != 'pull_request'
       uses: ./.github/workflows/require-team-membership

>From fd8d9d53043e84807bda631d21d9742eb595e30a Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Fri, 17 Jul 2026 13:05:51 -0400
Subject: [PATCH 32/35] [libc++] Target the release runners set from the LLVM
 23 release branch

---
 .github/workflows/libcxx-build-and-test.yaml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/libcxx-build-and-test.yaml b/.github/workflows/libcxx-build-and-test.yaml
index 7244d236877bd..f30f6fa534eb3 100644
--- a/.github/workflows/libcxx-build-and-test.yaml
+++ b/.github/workflows/libcxx-build-and-test.yaml
@@ -36,7 +36,7 @@ concurrency:
 jobs:
   stage1:
     if: github.repository_owner == 'llvm'
-    runs-on: llvm-premerge-libcxx-runners
+    runs-on: llvm-premerge-libcxx-release-runners
     continue-on-error: false
     strategy:
       fail-fast: false
@@ -79,7 +79,7 @@ jobs:
             **/crash_diagnostics/*
   stage2:
     if: github.repository_owner == 'llvm'
-    runs-on: llvm-premerge-libcxx-runners
+    runs-on: llvm-premerge-libcxx-release-runners
     needs: [ stage1 ]
     continue-on-error: false
     strategy:
@@ -130,7 +130,7 @@ jobs:
             **/crash_diagnostics/*
   stage3:
     if: github.repository_owner == 'llvm'
-    runs-on: llvm-premerge-libcxx-runners
+    runs-on: llvm-premerge-libcxx-release-runners
     needs: [ stage2 ]
     continue-on-error: false
     strategy:

>From 83cbf70cb201f58cb174039d7c3792bba6d3f95a Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Tue, 21 Jul 2026 10:03:12 -0700
Subject: [PATCH 33/35] workflows/release-documentation: Fix typo (#210815)

GITHUB_OUT -> GITHUB_OUTPUT

(cherry picked from commit d53ebd23aabd9286075650b663ff0bcbbef9ebd8)
---
 .github/workflows/release-documentation.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index 12e6a3844660c..b187ce4f2e738 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -100,7 +100,7 @@ jobs:
             echo "man-page-ref=llvmorg-$INPUTS_RELEASE_VERSION"
             echo "man-page-upload=$UPLOAD_MAN_PAGES"
             echo "man-page-attestation-name=$RUNNER_OS-$RUNNER_ARCH-release-man-page-attestation"
-          } >> "$GITHUB_OUT"
+          } >> "$GITHUB_OUTPUT"
 
       - name: Checkout LLVM
         uses: actions/checkout at de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -141,7 +141,7 @@ jobs:
         env:
           TARBALL_NAME: ${{ steps.vars.outputs.man-page-tarball-name }}
         run: |
-            echo "man-page-digest=$(cat "$TARBALL_NAME" | sha256sum | cut -d ' ' -f 1)" >> $GITHUB_OUT
+            echo "man-page-digest=$(cat "$TARBALL_NAME" | sha256sum | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT
 
       - id: man-page-artifact-upload
         uses: actions/upload-artifact at 043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1

>From cd2166a355896aa608aae9487285c8b0b48da724 Mon Sep 17 00:00:00 2001
From: Ajay Wakodikar <ajaywakodikarsocial at gmail.com>
Date: Sat, 13 Jun 2026 12:49:23 -0400
Subject: [PATCH 34/35] [Sema] Fix assertion in TreeTransform when rebuilding
 CXXParenListInitExpr

---
 clang/include/clang/AST/ExprCXX.h                   |  4 ++++
 clang/lib/Sema/TreeTransform.h                      |  3 ++-
 .../instantiate-member-initializers.cpp             | 13 +++++++++++++
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 757f2137c90dc..ae69d152c1a23 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -5184,6 +5184,10 @@ class CXXParenListInitExpr final
 
   ArrayRef<Expr *> getInitExprs() const { return getTrailingObjects(NumExprs); }
 
+  MutableArrayRef<Expr *> getUserSpecifiedInitExprs() {
+    return getTrailingObjects(NumUserSpecifiedExprs);
+  }
+
   ArrayRef<Expr *> getUserSpecifiedInitExprs() const {
     return getTrailingObjects(NumUserSpecifiedExprs);
   }
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index cc126f9000717..11cd159c0979e 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -3413,7 +3413,8 @@ class TreeTransform {
 
     if (auto *PLE = dyn_cast<CXXParenListInitExpr>(Sub))
       return getSema().BuildCXXTypeConstructExpr(
-          TInfo, LParenLoc, PLE->getInitExprs(), RParenLoc, ListInitialization);
+          TInfo, LParenLoc, PLE->getUserSpecifiedInitExprs(), RParenLoc,
+          ListInitialization);
 
     return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
                                                MultiExprArg(&Sub, 1), RParenLoc,
diff --git a/clang/test/SemaTemplate/instantiate-member-initializers.cpp b/clang/test/SemaTemplate/instantiate-member-initializers.cpp
index 63862063acdfe..bd84dcdecbe62 100644
--- a/clang/test/SemaTemplate/instantiate-member-initializers.cpp
+++ b/clang/test/SemaTemplate/instantiate-member-initializers.cpp
@@ -41,3 +41,16 @@ template<typename T> struct Array {
   Array() : a() {}
 };
 Array<int> s;
+
+namespace GH194986 {
+  struct S {};
+  template <typename T> struct SS { T t1; T t2; }; // expected-note {{candidate template ignored: could not match 'GH194986::SS<T>' against 'const char *'}} expected-note {{implicit deduction guide declared as 'template <typename T> SS(GH194986::SS<T>) -> GH194986::SS<T>'}} expected-note {{candidate function template not viable: requires 0 arguments, but 1 was provided}} expected-note {{implicit deduction guide declared as 'template <typename T> SS() -> GH194986::SS<T>'}}
+  template <class T, class... Args> T C(Args... args) { return SS("foo"); } // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'SS'}}
+  S s = C<S>();
+
+  template <class T> struct SS2 { T t1, t2; }; // expected-note {{candidate template ignored: could not match 'GH194986::SS2<T>' against 'const char *'}} expected-note {{implicit deduction guide declared as 'template <class T> SS2(GH194986::SS2<T>) -> GH194986::SS2<T>'}} expected-note {{candidate function template not viable: requires 0 arguments, but 1 was provided}} expected-note {{implicit deduction guide declared as 'template <class T> SS2() -> GH194986::SS2<T>'}}
+  template <class> void C2() {
+    SS2("foo"); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'SS2'}}
+  }
+  template void C2<int>();
+};

>From 6a59b7e46eeb0b117c9ee1f37064ecc7fc4545ae Mon Sep 17 00:00:00 2001
From: Ajay Wakodikar <ajaywakodikarsocial at gmail.com>
Date: Wed, 22 Jul 2026 05:46:11 -0400
Subject: [PATCH 35/35] Backport PR #203715 to release/23.x

---
 clang/docs/ReleaseNotes.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 5216f8a97af66..7fffbd30dd1c8 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -835,6 +835,7 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the
 - Fixed a case where function effect analysis (`nonblocking` etc.) did not visit a destructor invoked from a `delete` expression. (#GH184460)
 - Clang now defines the GCC-compatible predefined macros `__WCHAR_MIN__`, `__WINT_MIN__`, and `__SIG_ATOMIC_MIN__`. (#GH199678)
 - Fix a crash in addUnsizedArray due assert not verifying we have a Base before doing checks on it. (#GH44212)
+- Fixed an assertion that could occur when rebuilding parenthesized list initialization expressions during template instantiation or AST transformation.
 
 #### Bug Fixes to Compiler Builtins
 



More information about the cfe-commits mailing list