diff --git a/RELEASES.md b/RELEASES.md
index ecc5f5adab06d..81310c20c5ef9 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,13 @@
+Version 1.97.1 (2026-07-16)
+==========================
+
+
+
+- [rustc: Fix miscompilation in LLVM optimization](https://github.com/rust-lang/rust/issues/159035)
+ This backports an LLVM submodule bump to include the LLVM-side fix and a
+ revert of the rustc change that is one known trigger for the bug. The rustc
+ side revert should not be strictly necessary but is done out of abundance of caution.
+
Version 1.97.0 (2026-07-09)
==========================
@@ -35,14 +45,14 @@ Stabilized APIs
- [`Send for std::fs::File` on UEFI](https://github.com/rust-lang/rust/pull/154003)
- [`<{integer}>::isolate_highest_one`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.isolate_highest_one)
- [`<{integer}>::isolate_lowest_one`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.isolate_lowest_one)
+- [`<{integer}>::highest_one`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.highest_one)
+- [`<{integer}>::lowest_one`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.lowest_one)
+- [`<{integer}>::bit_width`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.bit_width)
- [`NonZero<{integer}>::isolate_highest_one`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.isolate_highest_one)
- [`NonZero<{integer}>::isolate_lowest_one`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.isolate_lowest_one)
-- [`<{integer}>::bit_width`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.bit_width)
-- [`<{integer}>::lowest_one`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.lowest_one)
-- [`<{integer}>::highest_one`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.highest_one)
-- [`NonZero<{integer}>::bit_width`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.bit_width)
- [`NonZero<{integer}>::highest_one`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.highest_one)
- [`NonZero<{integer}>::lowest_one`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.lowest_one)
+- [`NonZero<{integer}>::bit_width`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.bit_width)
These previously stable APIs are now stable in const contexts:
@@ -66,6 +76,8 @@ Rustdoc
-----
- [Stabilize `--emit` flag](https://github.com/rust-lang/rust/pull/146220)
- [Stabilize `--remap-path-prefix`](https://github.com/rust-lang/rust/pull/155307)
+
+
Compatibility Notes
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 5e1a95d620f2a..47ab63a899d08 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -2063,8 +2063,7 @@ impl Niche {
let distance_end_zero = max_value - v.end;
// FIXME: this ought to work for `bool` too, but that seems to be hitting a miscompilation
//
- let is_bool = size.bytes() == 1 && v == WrappingRange { start: 0, end: 1 };
- if count == 1 && !is_bool {
+ if count == 1 && v != (WrappingRange { start: 0, end: 1 }) {
// We only need one, so just pick the one closest to zero.
// Not only does that obviously use zero if it's possible, but it also
// simplifies testing things like `Option`, since looking for `-1`
diff --git a/src/llvm-project b/src/llvm-project
index 08c84e69a84d9..dcc3606807c98 160000
--- a/src/llvm-project
+++ b/src/llvm-project
@@ -1 +1 @@
-Subproject commit 08c84e69a84d95936296dfcab0e38b34100725d5
+Subproject commit dcc3606807c989700e0ac1cac18c31741bcd40d9
diff --git a/src/version b/src/version
index acbb747ac540f..4d00f49dadcc8 100644
--- a/src/version
+++ b/src/version
@@ -1 +1 @@
-1.97.0
+1.97.1
diff --git a/tests/codegen-llvm/function-arguments.rs b/tests/codegen-llvm/function-arguments.rs
index 6eab9a58b47ad..667e4f79df8c5 100644
--- a/tests/codegen-llvm/function-arguments.rs
+++ b/tests/codegen-llvm/function-arguments.rs
@@ -282,7 +282,7 @@ pub fn return_slice(x: &[u16]) -> &[u16] {
x
}
-// CHECK: { i16, i16 } @enum_id_1(i16 noundef{{( range\(i16 -1, 2\))?}} %x.0, i16 %x.1)
+// CHECK: { i16, i16 } @enum_id_1(i16 noundef{{( range\(i16 0, 3\))?}} %x.0, i16 %x.1)
#[no_mangle]
pub fn enum_id_1(x: Option>) -> Option> {
x
diff --git a/tests/ui/codegen/dont-miscompile-enums.rs b/tests/ui/codegen/dont-miscompile-enums.rs
new file mode 100644
index 0000000000000..f31a70bf754d6
--- /dev/null
+++ b/tests/ui/codegen/dont-miscompile-enums.rs
@@ -0,0 +1,43 @@
+//@ run-pass
+
+// Bad regression test for https://github.com/rust-lang/rust/issues/159035
+// This should probably be replaced with a codegen test, though that might need to be in LLVM,
+// as it seems that the miscompilation may occur on correct IR misoptimized by SimplifyCFG.
+
+#![allow(dead_code)]
+
+enum Inner {
+ A(u32),
+ B(u32),
+}
+struct Big {
+ _pad: u64,
+ inner: Inner,
+}
+struct Small {
+ a: u16,
+ b: u16,
+ _f: fn(),
+}
+enum Checksum {
+ X(Big),
+ Y(Small),
+}
+impl Checksum {
+ fn finalize(self) -> u32 {
+ match self {
+ Checksum::X(h) => match h.inner {
+ Inner::A(s) => s,
+ Inner::B(s) => s,
+ },
+ Checksum::Y(s) => (u32::from(s.b) << 16) | u32::from(s.a),
+ }
+ }
+}
+#[inline(never)]
+fn run(c: Option) -> Option {
+ c.map(|c| c.finalize())
+}
+fn main() {
+ println!("{:?}", run(std::hint::black_box(None)));
+}