[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