================
@@ -908,6 +908,73 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
     incrementProfileCounter(&S);
 }
 
+bool CodeGenFunction::checkIfLoopMustProgress(const Expr 
*ControllingExpression,
+                                              bool IsTrivialCXXLoop) {
+  if (CGM.getCodeGenOpts().getFiniteLoops() ==
+      CodeGenOptions::FiniteLoopsKind::Always)
+    return true;
+  if (CGM.getCodeGenOpts().getFiniteLoops() ==
+      CodeGenOptions::FiniteLoopsKind::Never)
+    return false;
+
+  // Now apply rules for plain C (see  6.8.5.6 in C11).
+  // Loops with constant conditions do not have to make progress in any C
+  // version.
+  // As an extension, we consisider loops whose constant expression
+  // can be constant-folded.
+  Expr::EvalResult Result;
+  bool CondIsConstInt =
+      !ControllingExpression ||
+      (ControllingExpression->EvaluateAsInt(Result, getContext()) &&
+       Result.Val.isInt());
+  bool IsTrue = CondIsConstInt &&
+                (!ControllingExpression || Result.Val.getInt().getBoolValue());
+
+  if (getLangOpts().C99 && CondIsConstInt)
+    return false;
+
+  // Loops with non-constant conditions must make progress in C11 and later.
+  if (getLangOpts().C11)
+    return true;
+
+  // [C++26][intro.progress] (DR)
+  // The implementation may assume that any thread will eventually do one of 
the
+  // following:
+  // [...]
+  // - continue execution of a trivial infinite loop ([stmt.iter.general]).
+  if (getLangOpts().CPlusPlus11) {
+    if (IsTrivialCXXLoop && IsTrue) {
+      CurFn->removeFnAttr(llvm::Attribute::MustProgress);
----------------
efriedma-quic wrote:

I... have to apologize here.  I was pretty sure I remembered how mustprogress 
worked, but then I went back to read the patches, and it's actually slightly 
different than what I remembered. mustprogress applies to control flow and 
calls within a function, but it doesn't propagate: an infinite loop in a 
non-mustprogress counts as an "effect".  I'll propose a patch to clarify 
LangRef.

So your original patch was essentially right.  If we drop the mustprogress 
attribute from functions that contain an infinite loop, we end up with 
essentially the right behavior: if a function doesn't contain a 
trivially-infinite loop, we can mark it mustprogress.  And we mark individual 
loops with metadata either way.

https://github.com/llvm/llvm-project/pull/90066
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to