https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/203671

We have several opcodes that can't fail, so add a flag to them indicating that 
they always return `true` anyway.

This simplifies the generated code from e.g.
```c++
PRESERVE_NONE
static bool Interp_Activate(InterpState &S, CodePtr &PC) {
  if (!Activate(S, PC))
    return false;
#if USE_TAILCALLS
  MUSTTAIL return InterpNext(S, PC);
#else
  return true;
#endif
}
```

to

```c++
PRESERVE_NONE
static bool Interp_Activate(InterpState &S, CodePtr &PC) {
  Activate(S, PC);
#if USE_TAILCALLS
  MUSTTAIL return InterpNext(S, PC);
#else
  return true;
#endif
}
```

>From 207c03fc97384c08e0bfb6ffdb56503edb710673 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]>
Date: Fri, 12 Jun 2026 17:11:10 +0200
Subject: [PATCH] AlwaysSucceeds flag

---
 clang/lib/AST/ByteCode/Opcodes.td            | 67 +++++++++++++-------
 clang/utils/TableGen/ClangOpcodesEmitter.cpp | 30 +++++++--
 2 files changed, 69 insertions(+), 28 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Opcodes.td 
b/clang/lib/AST/ByteCode/Opcodes.td
index 09c616aa2ff1d..d45eef067b145 100644
--- a/clang/lib/AST/ByteCode/Opcodes.td
+++ b/clang/lib/AST/ByteCode/Opcodes.td
@@ -145,6 +145,11 @@ class Opcode {
   bit HasCustomLink = 0;
   bit HasCustomEval = 0;
   bit HasGroup = 0;
+  bit CanFail = 1;
+}
+
+class SuccessOpcode : Opcode {
+  let CanFail = 0;
 }
 
 class AluOpcode : Opcode {
@@ -178,15 +183,14 @@ def Jt : JumpOpcode;
 // [Bool] -> [], jumps if false.
 def Jf : JumpOpcode;
 
-def PushIgnoreDiags : Opcode;
-def PopIgnoreDiags : Opcode;
+def PushIgnoreDiags : SuccessOpcode;
+def PopIgnoreDiags : SuccessOpcode;
 
+def StartInit : SuccessOpcode;
+def EndInit : SuccessOpcode;
 
-def StartInit : Opcode;
-def EndInit : Opcode;
-
-def StartSpeculation : Opcode;
-def EndSpeculation : Opcode;
+def StartSpeculation : SuccessOpcode;
+def EndSpeculation : SuccessOpcode;
 def BCP : Opcode {
   let ChangesPC = 1;
   let HasCustomEval = 1;
@@ -204,12 +208,14 @@ def Ret : Opcode {
   let CanReturn = 1;
   let HasGroup = 1;
   let HasCustomEval = 1;
+  let CanFail = 0;
 }
 // [] -> []
 def RetVoid : Opcode {
   let CanReturn = 1;
   let ChangesPC = 1;
   let HasCustomEval = 1;
+  let CanFail = 0;
 }
 // [Value] -> []
 def RetValue : Opcode {
@@ -276,6 +282,7 @@ class ConstOpcode<Type Ty, ArgType ArgTy> : Opcode {
   let Types = [SingletonTypeClass<Ty>];
   let Args = [ArgTy];
   let Name = "Const";
+  let CanFail = 0;
 }
 
 // [] -> [Integer]
@@ -292,20 +299,27 @@ def ConstIntAPS : ConstOpcode<IntAPS, ArgIntAPS>;
 def ConstBool : ConstOpcode<Bool, ArgBool>;
 def ConstFixedPoint : ConstOpcode<FixedPoint, ArgFixedPoint>;
 
-def ConstFloat : Opcode { let Args = [ArgFloat]; }
+def ConstFloat : Opcode {
+  let Args = [ArgFloat];
+  let CanFail = 0;
+}
 
 // [] -> [Integer]
 def Zero : Opcode {
   let Types = [FixedSizeIntegralTypeClass];
   let HasGroup = 1;
+  let CanFail = 0;
+
 }
 
 def ZeroIntAP : Opcode {
   let Args = [ArgUint32];
+  let CanFail = 0;
 }
 
 def ZeroIntAPS : Opcode {
   let Args = [ArgUint32];
+  let CanFail = 0;
 }
 
 // [] -> [Pointer]
@@ -313,6 +327,7 @@ def Null : Opcode {
   let Types = [PtrTypeClass];
   let Args = [ArgUint64, ArgTypePtr];
   let HasGroup = 1;
+  let CanFail = 0;
 }
 
 
//===----------------------------------------------------------------------===//
@@ -355,11 +370,11 @@ def CastMemberPtrDerivedPop : Opcode {
   let Args = [ArgSint32, ArgRecordDecl];
 }
 
-def FinishInitPop : Opcode;
-def FinishInit : Opcode;
-def FinishInitActivate : Opcode;
-def FinishInitActivatePop : Opcode;
-def FinishInitGlobal : Opcode;
+def FinishInitPop : SuccessOpcode;
+def FinishInit : SuccessOpcode;
+def FinishInitActivate : SuccessOpcode;
+def FinishInitActivatePop : SuccessOpcode;
+def FinishInitGlobal : SuccessOpcode;
 
 def GetPtrDerivedPop : Opcode { let Args = [ArgUint32, ArgBool, ArgTypePtr]; }
 
@@ -385,9 +400,9 @@ def This : Opcode;
 def RVOPtr : Opcode;
 
 // [Pointer] -> [Pointer]
-def NarrowPtr : Opcode;
+def NarrowPtr : SuccessOpcode;
 // [Pointer] -> [Pointer]
-def ExpandPtr : Opcode;
+def ExpandPtr : SuccessOpcode;
 // [Pointer, Offset] -> [Pointer]
 def ArrayElemPtr : Opcode {
   let Types = [IntegralTypeClass];
@@ -452,6 +467,7 @@ def CheckEnumValue : Opcode {
   let Args = [ArgEnumDecl];
   let Types = [IntegralTypeClass];
   let HasGroup = 1;
+  let CanFail = 0;
 }
 
 def CheckLiteralType : Opcode {
@@ -541,7 +557,7 @@ def StoreBitFieldPop : StoreBitFieldOpcode {}
 def StoreBitFieldActivate : StoreBitFieldOpcode {}
 def StoreBitFieldActivatePop : StoreBitFieldOpcode {}
 
-def Activate : Opcode {}
+def Activate : SuccessOpcode;
 def ActivateThisField : Opcode { let Args = [ArgUint32]; }
 
 // [Pointer, Value] -> []
@@ -592,6 +608,7 @@ def DecPtr : Opcode;
 
//===----------------------------------------------------------------------===//
 def GetFnPtr : Opcode {
   let Args = [ArgFunction];
+  let CanFail = 0;
 }
 
 def GetIntPtr : Opcode {
@@ -828,17 +845,20 @@ def GE : ComparisonOpcode;
 def Pop : Opcode {
   let Types = [AllTypeClass];
   let HasGroup = 1;
+  let CanFail = 0;
 }
 
 // [Value] -> [Value, Value]
 def Dup : Opcode {
   let Types = [AllTypeClass];
   let HasGroup = 1;
+  let CanFail = 0;
 }
 
 def Flip : Opcode {
   let Types = [AllTypeClass, AllTypeClass];
   let HasGroup = 1;
+  let CanFail = 0;
 }
 
 // [] -> []
@@ -852,7 +872,7 @@ def InvalidCast : Opcode {
 def CheckDynamicCast : Opcode {}
 
 def InvalidStore : Opcode { let Args = [ArgTypePtr]; }
-def CheckPseudoDtor : Opcode {}
+def CheckPseudoDtor : SuccessOpcode;
 
 def InvalidDeclRef : Opcode {
   let Args = [ArgDeclRef, ArgBool];
@@ -878,6 +898,7 @@ def ToMemberPtr : Opcode;
 def CastMemberPtrPtr : Opcode;
 def GetMemberPtr : Opcode {
   let Args = [ArgValueDecl];
+  let CanFail = 0;
 }
 def GetMemberPtrBase : Opcode;
 def GetMemberPtrDecl : Opcode;
@@ -943,8 +964,10 @@ def CheckDestruction : Opcode;
 
 def CtorCheck : Opcode;
 
-def PushCC : Opcode { let Args = [ArgBool]; }
-def PopCC : Opcode;
-
-def PushMSVCCE : Opcode;
-def PopMSVCCE : Opcode;
+def PushCC : Opcode {
+  let Args = [ArgBool];
+  let CanFail = 0;
+}
+def PopCC : SuccessOpcode;
+def PushMSVCCE : SuccessOpcode;
+def PopMSVCCE : SuccessOpcode;
diff --git a/clang/utils/TableGen/ClangOpcodesEmitter.cpp 
b/clang/utils/TableGen/ClangOpcodesEmitter.cpp
index 3192891801ae9..8d0ed4a1ccac5 100644
--- a/clang/utils/TableGen/ClangOpcodesEmitter.cpp
+++ b/clang/utils/TableGen/ClangOpcodesEmitter.cpp
@@ -127,6 +127,7 @@ void 
ClangOpcodesEmitter::EmitInterpFnDispatchers(raw_ostream &OS, StringRef N,
     bool CanReturn = R->getValueAsBit("CanReturn");
     const auto &Args = R->getValueAsListOfDefs("Args");
     bool ChangesPC = R->getValueAsBit("ChangesPC");
+    bool CanFail = R->getValueAsBit("CanFail");
 
     if (Args.empty()) {
       if (CanReturn) {
@@ -137,10 +138,19 @@ void 
ClangOpcodesEmitter::EmitInterpFnDispatchers(raw_ostream &OS, StringRef N,
         return;
       }
 
-      OS << "  if (!" << N;
+      OS << "  ";
+      if (CanFail)
+        OS << "if (!";
+
+      OS << N;
       PrintTypes(OS, TS);
-      OS << "(S, PC))\n";
-      OS << "    return false;\n";
+      OS << "(S, PC)";
+
+      if (CanFail)
+        OS << ") return false\n";
+
+      OS << ";\n";
+
       OS << "#if USE_TAILCALLS\n";
       OS << "  MUSTTAIL return InterpNext(S, PC);\n";
       OS << "#else\n";
@@ -168,7 +178,11 @@ void 
ClangOpcodesEmitter::EmitInterpFnDispatchers(raw_ostream &OS, StringRef N,
       OS << "ReadArg<" << Arg->getValueAsString("Name") << ">(S, PC);\n";
     }
 
-    OS << "    if (!" << N;
+    OS << "    ";
+    if (CanFail)
+      OS << "if (!";
+
+    OS << N;
     PrintTypes(OS, TS);
     OS << "(S";
     if (ChangesPC)
@@ -177,9 +191,13 @@ void 
ClangOpcodesEmitter::EmitInterpFnDispatchers(raw_ostream &OS, StringRef N,
       OS << ", OpPC";
     for (size_t I = 0, N = Args.size(); I < N; ++I)
       OS << ", V" << I;
-    OS << "))\n";
-    OS << "      return false;\n";
 
+    OS << ")";
+
+    if (CanFail)
+      OS << ") return false";
+
+    OS << ";\n";
     OS << "  }\n";
 
     if (!CanReturn) {

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to