Author: Timm Bäder Date: 2022-10-14T14:15:08+02:00 New Revision: ce4d5ae9dcf64deade70f305b8d7ab8d0dc80102
URL: https://github.com/llvm/llvm-project/commit/ce4d5ae9dcf64deade70f305b8d7ab8d0dc80102 DIFF: https://github.com/llvm/llvm-project/commit/ce4d5ae9dcf64deade70f305b8d7ab8d0dc80102.diff LOG: [clang][Interp] Implement bitwise Or operations Analogous to the bitAnd implementation, do the same for bitwise or. Differential Revision: https://reviews.llvm.org/D135361 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 820f2f56adaf..6edf1c450fa3 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -223,6 +223,7 @@ bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) { case BO_And: return Discard(this->emitBitAnd(*T, BO)); case BO_Or: + return Discard(this->emitBitOr(*T, BO)); case BO_LAnd: case BO_LOr: default: diff --git a/clang/lib/AST/Interp/Integral.h b/clang/lib/AST/Interp/Integral.h index 4e7fff63b4b1..9ee9fd6d7fd8 100644 --- a/clang/lib/AST/Interp/Integral.h +++ b/clang/lib/AST/Interp/Integral.h @@ -222,6 +222,11 @@ template <unsigned Bits, bool Signed> class Integral final { return false; } + static bool bitOr(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 073c7db428b0..c9a508448e31 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -170,6 +170,23 @@ bool BitAnd(InterpState &S, CodePtr OpPC) { return false; } +/// 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 BitOr(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::bitOr(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 11d069ccd78d..767ab98f4fc4 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -412,6 +412,7 @@ def Rem : Opcode { let HasGroup = 1; } def BitAnd : IntegerOpcode; +def BitOr : 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 1e1ef49a2f39..f0083e63f35d 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -269,3 +269,12 @@ namespace band { static_assert((1337 & -1) == 1337, ""); static_assert((0 & gimme(12)) == 0, ""); }; + +namespace bitOr { + static_assert((10 | 1) == 11, ""); + static_assert((10 | 10) == 10, ""); + + static_assert((1337 | -1) == -1, ""); + static_assert((0 | gimme(12)) == 12, ""); + static_assert((12 | true) == 13, ""); +}; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits