--- gcc/cp/cp-gimplify.cc.jj	2024-03-23 11:17:06.958445857 +0100
+++ gcc/cp/cp-gimplify.cc	2024-04-02 11:27:56.069170914 +0200
@@ -3527,6 +3527,78 @@ cp_fold (tree x, fold_flags_t flags)
       x = evaluate_requires_expr (x);
       break;
 
+    case WHILE_STMT:
+      /* For trivially empty iteration statements check if the condition
+	 is constant expression which evaluates to true and in that case
+	 change the condition to the constant, so that the middle-end treats
+	 it as an infinite loop regardless of -ffinite-loops.  */
+      if ((flags & ff_mce_false) && !integer_nonzerop (WHILE_COND (x)))
+	{
+	  tree body = WHILE_BODY (x);
+	  if (expr_first (body) == NULL_TREE)
+	    {
+	      r = maybe_constant_value (WHILE_COND (x), /*decl=*/NULL_TREE,
+					mce_false);
+	      if (integer_nonzerop (r))
+		{
+		  x = copy_node (x);
+		  WHILE_COND (x) = r;
+		  break;
+		}
+	    }
+	}
+      return org_x;
+
+    case DO_STMT:
+      /* For trivially empty iteration statements check if the condition
+	 is constant expression which evaluates to true and in that case
+	 change the condition to the constant, so that the middle-end treats
+	 it as an infinite loop regardless of -ffinite-loops.  */
+      if ((flags & ff_mce_false) && !integer_nonzerop (DO_COND (x)))
+	{
+	  tree body = DO_BODY (x);
+	  if (expr_first (body) == NULL_TREE
+	      || (CONVERT_EXPR_P (body)
+		  && integer_zerop (TREE_OPERAND (body, 0))
+		  && VOID_TYPE_P (TREE_TYPE (body))))
+	    {
+	      r = maybe_constant_value (DO_COND (x), /*decl=*/NULL_TREE,
+					mce_false);
+	      if (integer_nonzerop (r))
+		{
+		  x = copy_node (x);
+		  DO_COND (x) = r;
+		  break;
+		}
+	    }
+	}
+      return org_x;
+
+    case FOR_STMT:
+      /* For trivially empty iteration statements check if the condition
+	 is constant expression which evaluates to true and in that case
+	 change the condition to the constant, so that the middle-end treats
+	 it as an infinite loop regardless of -ffinite-loops.  */
+      if ((flags & ff_mce_false)
+	  && FOR_COND (x)
+	  && FOR_EXPR (x) == NULL_TREE
+	  && !integer_nonzerop (FOR_COND (x)))
+	{
+	  tree body = FOR_BODY (x);
+	  if (expr_first (body) == NULL_TREE)
+	    {
+	      r = maybe_constant_value (FOR_COND (x), /*decl=*/NULL_TREE,
+					mce_false);
+	      if (integer_nonzerop (r))
+		{
+		  x = copy_node (x);
+		  FOR_COND (x) = r;
+		  break;
+		}
+	    }
+	}
+      return org_x;
+
     default:
       return org_x;
     }
--- gcc/testsuite/g++.dg/cpp26/trivial-infinite-loop1.C.jj	2024-04-02 11:50:00.943874185 +0200
+++ gcc/testsuite/g++.dg/cpp26/trivial-infinite-loop1.C	2024-04-02 12:19:52.132211449 +0200
@@ -0,0 +1,150 @@
+// P2809R3 - Trivial infinite loops are not Undefined Behavior
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-fdump-tree-gimple -fno-inline" }
+// { dg-final { scan-tree-dump-not " = foo \\\(\\\)" "gimple" } }
+// { dg-final { scan-tree-dump-not " = S::operator bool \\\(" "gimple" } }
+// { dg-final { scan-tree-dump-not " = baz \\\(\\\)" "gimple" } }
+// { dg-final { scan-tree-dump-not " = std::is_constant_evaluated \\\(\\\)" "gimple" } }
+
+volatile int v;
+
+constexpr bool
+foo ()
+{
+  return true;
+}
+
+struct S
+{
+  constexpr S () : s (true) {}
+  constexpr operator bool () const { return s; }
+  bool s;
+};
+
+#if __cplusplus >= 202002L
+namespace std {
+  constexpr inline bool
+  is_constant_evaluated () noexcept
+  {
+#if __cpp_if_consteval >= 202106L
+    if consteval { return true; } else { return false; }
+#else
+    return __builtin_is_constant_evaluated ();
+#endif
+  }
+}
+
+constexpr bool
+baz ()
+{
+  return !std::is_constant_evaluated ();
+}
+#endif
+
+void
+bar (int x)
+{
+  switch (x)
+    {
+    case 0:
+      while (foo ()) ;
+      break;
+    case 1:
+      while (foo ()) {}
+      break;
+    case 2:
+      do ; while (foo ());
+      break;
+    case 3:
+      do {} while (foo ());
+      break;
+    case 4:
+      for (v = 42; foo (); ) ;
+      break;
+    case 5:
+      for (v = 42; foo (); ) {}
+      break;
+    case 6:
+      for (int w = 42; foo (); ) ;
+      break;
+    case 7:
+      for (int w = 42; foo (); ) {}
+      break;
+    case 10:
+      while (S {}) ;
+      break;
+    case 11:
+      while (S {}) {}
+      break;
+    case 12:
+      do ; while (S {});
+      break;
+    case 13:
+      do {} while (S {});
+      break;
+    case 14:
+      for (v = 42; S {}; ) ;
+      break;
+    case 15:
+      for (v = 42; S {}; ) {}
+      break;
+    case 16:
+      for (int w = 42; S {}; ) ;
+      break;
+    case 17:
+      for (int w = 42; S {}; ) {}
+      break;
+#if __cplusplus >= 202002L
+    case 20:
+      while (baz ()) ;
+      break;
+    case 21:
+      while (baz ()) {}
+      break;
+    case 22:
+      do ; while (baz ());
+      break;
+    case 23:
+      do {} while (baz ());
+      break;
+    case 24:
+      for (v = 42; baz (); ) ;
+      break;
+    case 25:
+      for (v = 42; baz (); ) {}
+      break;
+    case 26:
+      for (int w = 42; baz (); ) ;
+      break;
+    case 27:
+      for (int w = 42; baz (); ) {}
+      break;
+    case 30:
+      while (!std::is_constant_evaluated ()) ;
+      break;
+    case 31:
+      while (!std::is_constant_evaluated ()) {}
+      break;
+    case 32:
+      do ; while (!std::is_constant_evaluated ());
+      break;
+    case 33:
+      do {} while (!std::is_constant_evaluated ());
+      break;
+    case 34:
+      for (v = 42; !std::is_constant_evaluated (); ) ;
+      break;
+    case 35:
+      for (v = 42; !std::is_constant_evaluated (); ) {}
+      break;
+    case 36:
+      for (int w = 42; !std::is_constant_evaluated (); ) ;
+      break;
+    case 37:
+      for (int w = 42; !std::is_constant_evaluated (); ) {}
+      break;
+#endif
+    default:
+      break;
+    }
+}
--- gcc/testsuite/g++.dg/cpp26/trivial-infinite-loop2.C.jj	2024-04-02 12:06:31.494215751 +0200
+++ gcc/testsuite/g++.dg/cpp26/trivial-infinite-loop2.C	2024-04-02 12:20:32.037663398 +0200
@@ -0,0 +1,150 @@
+// P2809R3 - Trivial infinite loops are not Undefined Behavior
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-fdump-tree-gimple -fno-inline" }
+// { dg-final { scan-tree-dump-times " = foo \\\(\\\)" 8 "gimple" } }
+// { dg-final { scan-tree-dump-times " = S::operator bool \\\(" 8 "gimple" } }
+// { dg-final { scan-tree-dump-times " = baz \\\(\\\)" 8 "gimple" { target c++20 } } }
+// { dg-final { scan-tree-dump-times " = std::is_constant_evaluated \\\(\\\)" 9 "gimple" { target c++20 } } }
+
+volatile int v;
+
+constexpr bool
+foo ()
+{
+  return false;
+}
+
+struct S
+{
+  constexpr S () : s (false) {}
+  constexpr operator bool () const { return s; }
+  bool s;
+};
+
+#if __cplusplus >= 202002L
+namespace std {
+  constexpr inline bool
+  is_constant_evaluated () noexcept
+  {
+#if __cpp_if_consteval >= 202106L
+    if consteval { return true; } else { return false; }
+#else
+    return __builtin_is_constant_evaluated ();
+#endif
+  }
+}
+
+constexpr bool
+baz ()
+{
+  return std::is_constant_evaluated ();
+}
+#endif
+
+void
+bar (int x)
+{
+  switch (x)
+    {
+    case 0:
+      while (foo ()) ;
+      break;
+    case 1:
+      while (foo ()) {}
+      break;
+    case 2:
+      do ; while (foo ());
+      break;
+    case 3:
+      do {} while (foo ());
+      break;
+    case 4:
+      for (v = 42; foo (); ) ;
+      break;
+    case 5:
+      for (v = 42; foo (); ) {}
+      break;
+    case 6:
+      for (int w = 42; foo (); ) ;
+      break;
+    case 7:
+      for (int w = 42; foo (); ) {}
+      break;
+    case 10:
+      while (S {}) ;
+      break;
+    case 11:
+      while (S {}) {}
+      break;
+    case 12:
+      do ; while (S {});
+      break;
+    case 13:
+      do {} while (S {});
+      break;
+    case 14:
+      for (v = 42; S {}; ) ;
+      break;
+    case 15:
+      for (v = 42; S {}; ) {}
+      break;
+    case 16:
+      for (int w = 42; S {}; ) ;
+      break;
+    case 17:
+      for (int w = 42; S {}; ) {}
+      break;
+#if __cplusplus >= 202002L
+    case 20:
+      while (baz ()) ;
+      break;
+    case 21:
+      while (baz ()) {}
+      break;
+    case 22:
+      do ; while (baz ());
+      break;
+    case 23:
+      do {} while (baz ());
+      break;
+    case 24:
+      for (v = 42; baz (); ) ;
+      break;
+    case 25:
+      for (v = 42; baz (); ) {}
+      break;
+    case 26:
+      for (int w = 42; baz (); ) ;
+      break;
+    case 27:
+      for (int w = 42; baz (); ) {}
+      break;
+    case 30:
+      while (std::is_constant_evaluated ()) ;
+      break;
+    case 31:
+      while (std::is_constant_evaluated ()) {}
+      break;
+    case 32:
+      do ; while (std::is_constant_evaluated ());
+      break;
+    case 33:
+      do {} while (std::is_constant_evaluated ());
+      break;
+    case 34:
+      for (v = 42; std::is_constant_evaluated (); ) ;
+      break;
+    case 35:
+      for (v = 42; std::is_constant_evaluated (); ) {}
+      break;
+    case 36:
+      for (int w = 42; std::is_constant_evaluated (); ) ;
+      break;
+    case 37:
+      for (int w = 42; std::is_constant_evaluated (); ) {}
+      break;
+#endif
+    default:
+      break;
+    }
+}
--- gcc/testsuite/g++.dg/cpp26/trivial-infinite-loop3.C.jj	2024-04-02 12:14:23.993717999 +0200
+++ gcc/testsuite/g++.dg/cpp26/trivial-infinite-loop3.C	2024-04-02 12:21:10.341137353 +0200
@@ -0,0 +1,151 @@
+// P2809R3 - Trivial infinite loops are not Undefined Behavior
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-fdump-tree-gimple -fno-inline" }
+// { dg-final { scan-tree-dump-times " = foo \\\(\\\)" 8 "gimple" } }
+// { dg-final { scan-tree-dump-times " = S::operator bool \\\(" 8 "gimple" } }
+// { dg-final { scan-tree-dump-times " = baz \\\(\\\)" 8 "gimple" { target c++20 } } }
+// { dg-final { scan-tree-dump-times " = std::is_constant_evaluated \\\(\\\)" 9 "gimple" { target c++20 } } }
+
+volatile int v;
+int y;
+
+constexpr bool
+foo ()
+{
+  return true;
+}
+
+struct S
+{
+  constexpr S () : s (true) {}
+  constexpr operator bool () const { return s; }
+  bool s;
+};
+
+#if __cplusplus >= 202002L
+namespace std {
+  constexpr inline bool
+  is_constant_evaluated () noexcept
+  {
+#if __cpp_if_consteval >= 202106L
+    if consteval { return true; } else { return false; }
+#else
+    return __builtin_is_constant_evaluated ();
+#endif
+  }
+}
+
+constexpr bool
+baz ()
+{
+  return !std::is_constant_evaluated ();
+}
+#endif
+
+void
+bar (int x)
+{
+  switch (x)
+    {
+    case 0:
+      while (foo ()) ++y;
+      break;
+    case 1:
+      while (foo ()) { ++y; }
+      break;
+    case 2:
+      do ++y; while (foo ());
+      break;
+    case 3:
+      do { ++y; } while (foo ());
+      break;
+    case 4:
+      for (v = 42; foo (); ) ++y;
+      break;
+    case 5:
+      for (v = 42; foo (); ) { ++y; }
+      break;
+    case 6:
+      for (int w = 42; foo (); ) ++y;
+      break;
+    case 7:
+      for (int w = 42; foo (); ) { ++y; }
+      break;
+    case 10:
+      while (S {}) ++y;
+      break;
+    case 11:
+      while (S {}) { ++y; }
+      break;
+    case 12:
+      do ++y; while (S {});
+      break;
+    case 13:
+      do { ++y; } while (S {});
+      break;
+    case 14:
+      for (v = 42; S {}; ) ++y;
+      break;
+    case 15:
+      for (v = 42; S {}; ) { ++y; }
+      break;
+    case 16:
+      for (int w = 42; S {}; ) ++y;
+      break;
+    case 17:
+      for (int w = 42; S {}; ) { ++y; }
+      break;
+#if __cplusplus >= 202002L
+    case 20:
+      while (baz ()) ++y;
+      break;
+    case 21:
+      while (baz ()) { ++y; }
+      break;
+    case 22:
+      do ++y; while (baz ());
+      break;
+    case 23:
+      do { ++y; } while (baz ());
+      break;
+    case 24:
+      for (v = 42; baz (); ) ++y;
+      break;
+    case 25:
+      for (v = 42; baz (); ) { ++y; }
+      break;
+    case 26:
+      for (int w = 42; baz (); ) ++y;
+      break;
+    case 27:
+      for (int w = 42; baz (); ) { ++y; }
+      break;
+    case 30:
+      while (!std::is_constant_evaluated ()) ++y;
+      break;
+    case 31:
+      while (!std::is_constant_evaluated ()) { ++y; }
+      break;
+    case 32:
+      do ++y; while (!std::is_constant_evaluated ());
+      break;
+    case 33:
+      do { ++y; } while (!std::is_constant_evaluated ());
+      break;
+    case 34:
+      for (v = 42; !std::is_constant_evaluated (); ) ++y;
+      break;
+    case 35:
+      for (v = 42; !std::is_constant_evaluated (); ) { ++y; }
+      break;
+    case 36:
+      for (int w = 42; !std::is_constant_evaluated (); ) ++y;
+      break;
+    case 37:
+      for (int w = 42; !std::is_constant_evaluated (); ) { ++y; }
+      break;
+#endif
+    default:
+      break;
+    }
+}
