Index: clang/lib/AST/Interp/InterpBuiltin.cpp =================================================================== --- clang/lib/AST/Interp/InterpBuiltin.cpp +++ clang/lib/AST/Interp/InterpBuiltin.cpp @@ -299,6 +299,25 @@ return true; } +/// The argument can be a floating, vector or complex type. +/// The return type must be the same. +static bool interp__builtin_arithmetic_fence(InterpState &S, CodePtr OpPC, + const InterpFrame *Frame, + const Function *Func) { + const Expr *E = S.Current->getExpr(OpPC); + const CallExpr *CE = cast(E); + QualType ReturnType = CE->getType(); + + // TODO: Support vector and complex types. + if (!ReturnType->isFloatingType()) + return false; + + // We just ignore this. + const Floating &Val = S.Stk.peek(); + S.Stk.push(Val); + return true; +} + bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F) { InterpFrame *Frame = S.Current; APValue Dummy; @@ -409,6 +428,11 @@ return Ret(S, OpPC, Dummy); break; + case Builtin::BI__arithmetic_fence: + if (interp__builtin_arithmetic_fence(S, OpPC, Frame, F)) + return Ret(S, OpPC, Dummy); + break; + default: return false; } Index: clang/test/AST/Interp/builtin-functions.cpp =================================================================== --- clang/test/AST/Interp/builtin-functions.cpp +++ clang/test/AST/Interp/builtin-functions.cpp @@ -133,3 +133,16 @@ namespace fabs { static_assert(__builtin_fabs(-14.0) == 14.0, ""); } + +namespace ArithmeticFence { + constexpr double d = __arithmetic_fence(13.0); + static_assert(d == 13.0, ""); + constexpr float f = __arithmetic_fence(16.0); + static_assert(f == 16.0f, ""); + + /// TODO: Support complex and vector types in __arithmethic_fence. +#if 0 + _Complex double CD2 = {1.0, 2.0}; + _Complex double CD = __arithmetic_fence(CD); +#endif +}