[clang] 760136f - [clang][Interp] Implement __builtin_assume

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 26 23:03:53 PST 2023


Author: Timm Bäder
Date: 2023-01-27T07:54:37+01:00
New Revision: 760136ff13ba172787c3367664fe9f3f7b3b64ef

URL: https://github.com/llvm/llvm-project/commit/760136ff13ba172787c3367664fe9f3f7b3b64ef
DIFF: https://github.com/llvm/llvm-project/commit/760136ff13ba172787c3367664fe9f3f7b3b64ef.diff

LOG: [clang][Interp] Implement __builtin_assume

Just ignore it.

As part of this, move the Ret and RetVoid implementation to Interp.h, so
they can be shared with InterpBuiltin.cpp.

Differential Revision: https://reviews.llvm.org/D141193

Added: 
    

Modified: 
    clang/lib/AST/Interp/Interp.cpp
    clang/lib/AST/Interp/Interp.h
    clang/lib/AST/Interp/InterpBuiltin.cpp
    clang/test/AST/Interp/builtins.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index 77b85d81c5f8..319aba0ffa94 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -26,51 +26,6 @@
 using namespace clang;
 using namespace clang::interp;
 
-//===----------------------------------------------------------------------===//
-// Ret
-//===----------------------------------------------------------------------===//
-
-template <PrimType Name, class T = typename PrimConv<Name>::T>
-static bool Ret(InterpState &S, CodePtr &PC, APValue &Result) {
-  S.CallStackDepth--;
-  const T &Ret = S.Stk.pop<T>();
-
-  assert(S.Current->getFrameOffset() == S.Stk.size() && "Invalid frame");
-  if (!S.checkingPotentialConstantExpression())
-    S.Current->popArgs();
-
-  if (InterpFrame *Caller = S.Current->Caller) {
-    PC = S.Current->getRetPC();
-    delete S.Current;
-    S.Current = Caller;
-    S.Stk.push<T>(Ret);
-  } else {
-    delete S.Current;
-    S.Current = nullptr;
-    if (!ReturnValue<T>(Ret, Result))
-      return false;
-  }
-  return true;
-}
-
-static bool RetVoid(InterpState &S, CodePtr &PC, APValue &Result) {
-  S.CallStackDepth--;
-
-  assert(S.Current->getFrameOffset() == S.Stk.size() && "Invalid frame");
-  if (!S.checkingPotentialConstantExpression())
-    S.Current->popArgs();
-
-  if (InterpFrame *Caller = S.Current->Caller) {
-    PC = S.Current->getRetPC();
-    delete S.Current;
-    S.Current = Caller;
-  } else {
-    delete S.Current;
-    S.Current = nullptr;
-  }
-  return true;
-}
-
 static bool RetValue(InterpState &S, CodePtr &Pt, APValue &Result) {
   llvm::report_fatal_error("Interpreter cannot return values");
 }

diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index b36b513c067f..14d132533d24 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -145,10 +145,58 @@ bool CheckFloatResult(InterpState &S, CodePtr OpPC, APFloat::opStatus Status);
 /// Interpreter entry point.
 bool Interpret(InterpState &S, APValue &Result);
 
-bool InterpretBuiltin(InterpState &S, CodePtr PC, unsigned BuiltinID);
+/// Interpret a builtin function.
+bool InterpretBuiltin(InterpState &S, CodePtr &PC, unsigned BuiltinID);
 
 enum class ArithOp { Add, Sub };
 
+//===----------------------------------------------------------------------===//
+// Returning values
+//===----------------------------------------------------------------------===//
+
+template <PrimType Name, bool Builtin = false,
+          class T = typename PrimConv<Name>::T>
+bool Ret(InterpState &S, CodePtr &PC, APValue &Result) {
+  S.CallStackDepth--;
+  const T &Ret = S.Stk.pop<T>();
+
+  assert(S.Current->getFrameOffset() == S.Stk.size() && "Invalid frame");
+  if (Builtin || !S.checkingPotentialConstantExpression())
+    S.Current->popArgs();
+
+  if (InterpFrame *Caller = S.Current->Caller) {
+    PC = S.Current->getRetPC();
+    delete S.Current;
+    S.Current = Caller;
+    S.Stk.push<T>(Ret);
+  } else {
+    delete S.Current;
+    S.Current = nullptr;
+    if (!ReturnValue<T>(Ret, Result))
+      return false;
+  }
+  return true;
+}
+
+template <bool Builtin = false>
+inline bool RetVoid(InterpState &S, CodePtr &PC, APValue &Result) {
+  S.CallStackDepth--;
+
+  assert(S.Current->getFrameOffset() == S.Stk.size() && "Invalid frame");
+  if (Builtin || !S.checkingPotentialConstantExpression())
+    S.Current->popArgs();
+
+  if (InterpFrame *Caller = S.Current->Caller) {
+    PC = S.Current->getRetPC();
+    delete S.Current;
+    S.Current = Caller;
+  } else {
+    delete S.Current;
+    S.Current = nullptr;
+  }
+  return true;
+}
+
 //===----------------------------------------------------------------------===//
 // Add, Sub, Mul
 //===----------------------------------------------------------------------===//

diff  --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp
index 8e6b83fe50ae..c929ad687d82 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -13,35 +13,17 @@
 namespace clang {
 namespace interp {
 
-/// This is a slightly simplified version of the Ret() we have in Interp.cpp
-/// If they end up diverging in the future, we should get rid of the code
-/// duplication.
-template <PrimType Name, class T = typename PrimConv<Name>::T>
-static bool Ret(InterpState &S, CodePtr &PC) {
-  S.CallStackDepth--;
-  const T &Ret = S.Stk.pop<T>();
+bool InterpretBuiltin(InterpState &S, CodePtr &PC, unsigned BuiltinID) {
+  APValue Dummy;
 
-  assert(S.Current->getFrameOffset() == S.Stk.size() && "Invalid frame");
-  if (!S.checkingPotentialConstantExpression())
-    S.Current->popArgs();
-
-  InterpFrame *Caller = S.Current->Caller;
-  assert(Caller);
-
-  PC = S.Current->getRetPC();
-  delete S.Current;
-  S.Current = Caller;
-  S.Stk.push<T>(Ret);
-
-  return true;
-}
-
-bool InterpretBuiltin(InterpState &S, CodePtr PC, unsigned BuiltinID) {
   switch (BuiltinID) {
   case Builtin::BI__builtin_is_constant_evaluated:
     S.Stk.push<Boolean>(Boolean::from(S.inConstantContext()));
-    Ret<PT_Bool>(S, PC);
-    return true;
+    return Ret<PT_Bool, true>(S, PC, Dummy);
+  case Builtin::BI__builtin_assume:
+    return RetVoid<true>(S, PC, Dummy);
+  default:
+    return false;
   }
 
   return false;

diff  --git a/clang/test/AST/Interp/builtins.cpp b/clang/test/AST/Interp/builtins.cpp
index 535686f9c482..5e2ffe50f374 100644
--- a/clang/test/AST/Interp/builtins.cpp
+++ b/clang/test/AST/Interp/builtins.cpp
@@ -22,3 +22,10 @@ static_assert(std::is_constant_evaluated() , "");
 bool is_this_constant() {
   return __builtin_is_constant_evaluated(); // CHECK: ret i1 false
 }
+
+constexpr bool assume() {
+  __builtin_assume(true);
+  __builtin_assume(false);
+  return true;
+}
+static_assert(assume(), "");


        


More information about the cfe-commits mailing list