Author: Timm Bäder Date: 2022-10-14T14:00:07+02:00 New Revision: 62a58050ba0afad5c1ca59195f10c6fdc0e0feaa
URL: https://github.com/llvm/llvm-project/commit/62a58050ba0afad5c1ca59195f10c6fdc0e0feaa DIFF: https://github.com/llvm/llvm-project/commit/62a58050ba0afad5c1ca59195f10c6fdc0e0feaa.diff LOG: [clang][Interp] Implement bitwise and operations Differential Revision: https://reviews.llvm.org/D135012 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/Integral.h clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/Opcodes.td clang/test/AST/Interp/literals.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index d504ff36bb99..820f2f56adaf 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -220,6 +220,11 @@ bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) { if (!this->emitStore(*T, BO)) return false; return DiscardResult ? this->emitPopPtr(BO) : true; + case BO_And: + return Discard(this->emitBitAnd(*T, BO)); + case BO_Or: + case BO_LAnd: + case BO_LOr: default: return this->bail(BO); } diff --git a/clang/lib/AST/Interp/Integral.h b/clang/lib/AST/Interp/Integral.h index b50a567d18c7..4e7fff63b4b1 100644 --- a/clang/lib/AST/Interp/Integral.h +++ b/clang/lib/AST/Interp/Integral.h @@ -217,6 +217,11 @@ template <unsigned Bits, bool Signed> class Integral final { return false; } + static bool bitAnd(Integral A, Integral B, unsigned OpBits, Integral *R) { + *R = Integral(A.V & B.V); + return false; + } + static bool neg(Integral A, Integral *R) { *R = -A; return false; diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 6ad3a6aeaa31..073c7db428b0 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -153,6 +153,23 @@ bool Mul(InterpState &S, CodePtr OpPC) { return AddSubMulHelper<T, T::mul, std::multiplies>(S, OpPC, Bits, LHS, RHS); } +/// 1) Pops the RHS from the stack. +/// 2) Pops the LHS from the stack. +/// 3) Pushes 'LHS & RHS' on the stack +template <PrimType Name, class T = typename PrimConv<Name>::T> +bool BitAnd(InterpState &S, CodePtr OpPC) { + const T &RHS = S.Stk.pop<T>(); + const T &LHS = S.Stk.pop<T>(); + + unsigned Bits = RHS.bitWidth(); + T Result; + if (!T::bitAnd(LHS, RHS, Bits, &Result)) { + S.Stk.push<T>(Result); + return true; + } + return false; +} + /// 1) Pops the RHS from the stack. /// 2) Pops the LHS from the stack. /// 3) Pushes 'LHS % RHS' on the stack (the remainder of dividing LHS by RHS). diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td index f47f6492fcd7..11d069ccd78d 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -59,6 +59,11 @@ def NumberTypeClass : TypeClass { Uint32, Sint64, Uint64]; } +def IntegerTypeClass : TypeClass { + let Types = [Sint8, Uint8, Sint16, Uint16, Sint32, + Uint32, Sint64, Uint64]; +} + def AluTypeClass : TypeClass { let Types = !listconcat(NumberTypeClass.Types, [Bool]); } @@ -103,6 +108,11 @@ class AluOpcode : Opcode { let HasGroup = 1; } +class IntegerOpcode : Opcode { + let Types = [IntegerTypeClass]; + let HasGroup = 1; +} + //===----------------------------------------------------------------------===// // Jump opcodes //===----------------------------------------------------------------------===// @@ -401,6 +411,7 @@ def Rem : Opcode { let Types = [NumberTypeClass]; let HasGroup = 1; } +def BitAnd : IntegerOpcode; def Div : Opcode { let Types = [NumberTypeClass]; let HasGroup = 1; diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index f11107c0efb7..1e1ef49a2f39 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -261,3 +261,11 @@ namespace cond { #endif }; + +namespace band { + static_assert((10 & 1) == 0, ""); + static_assert((10 & 10) == 10, ""); + + static_assert((1337 & -1) == 1337, ""); + static_assert((0 & gimme(12)) == 0, ""); +}; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits