Skip to content

Commit

Permalink
Enable constexpr on ROTATELEFT/ROTATERIGHT builtin intrinsics (PR47249)
Browse files Browse the repository at this point in the history
This enables us to use the __builtin_rotateleft / __builtin_rotateright 8/16/32/64 intrinsics inside constexpr code.

Differential Revision: https://reviews.llvm.org/D86342
  • Loading branch information
RKSimon committed Aug 22, 2020
1 parent ec06b38 commit 2ceac91
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 3 deletions.
6 changes: 4 additions & 2 deletions clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2016,7 +2016,8 @@ the bits in the first argument by the amount in the second argument.
For example, ``0b10000110`` rotated left by 11 becomes ``0b00110100``.
The shift value is treated as an unsigned amount modulo the size of
the arguments. Both arguments and the result have the bitwidth specified
by the name of the builtin.
by the name of the builtin. These builtins can be used within constant
expressions.
``__builtin_rotateright``
-------------------------
Expand Down Expand Up @@ -2048,7 +2049,8 @@ the bits in the first argument by the amount in the second argument.
For example, ``0b10000110`` rotated right by 3 becomes ``0b11010000``.
The shift value is treated as an unsigned amount modulo the size of
the arguments. Both arguments and the result have the bitwidth specified
by the name of the builtin.
by the name of the builtin. These builtins can be used within constant
expressions.
``__builtin_unreachable``
-------------------------
Expand Down
8 changes: 7 additions & 1 deletion clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,13 @@ Improvements to Clang's diagnostics
Non-comprehensive list of changes in this release
-------------------------------------------------

- ...
- The builtin intrinsics ``__builtin_rotateleft8``, ``__builtin_rotateleft16``,
``__builtin_rotateleft32`` and ``__builtin_rotateleft64`` may now be used
within constant expressions.

- The builtin intrinsics ``__builtin_rotateright8``, ``__builtin_rotateright16``,
``__builtin_rotateright32`` and ``__builtin_rotateright64`` may now be used
within constant expressions.

New Compiler Flags
------------------
Expand Down
24 changes: 24 additions & 0 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11347,6 +11347,30 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
return Success(Val.countPopulation(), E);
}

case Builtin::BI__builtin_rotateleft8:
case Builtin::BI__builtin_rotateleft16:
case Builtin::BI__builtin_rotateleft32:
case Builtin::BI__builtin_rotateleft64: {
APSInt Val, Amt;
if (!EvaluateInteger(E->getArg(0), Val, Info) ||
!EvaluateInteger(E->getArg(1), Amt, Info))
return false;

return Success(Val.rotl(Amt.urem(Val.getBitWidth())), E);
}

case Builtin::BI__builtin_rotateright8:
case Builtin::BI__builtin_rotateright16:
case Builtin::BI__builtin_rotateright32:
case Builtin::BI__builtin_rotateright64: {
APSInt Val, Amt;
if (!EvaluateInteger(E->getArg(0), Val, Info) ||
!EvaluateInteger(E->getArg(1), Amt, Info))
return false;

return Success(Val.rotr(Amt.urem(Val.getBitWidth())), E);
}

case Builtin::BIstrlen:
case Builtin::BIwcslen:
// A call to strlen is not a constant expression.
Expand Down
10 changes: 10 additions & 0 deletions clang/test/Sema/constant-builtins-2.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,16 @@ char parity8[__builtin_parity(~0) == 0 ? 1 : -1];
char parity9[__builtin_parityl(1L << (BITSIZE(long) - 1)) == 1 ? 1 : -1];
char parity10[__builtin_parityll(1LL << (BITSIZE(long long) - 1)) == 1 ? 1 : -1];

char rotateleft1[__builtin_rotateleft8(0x01, 5) == 0x20 ? 1 : -1];
char rotateleft2[__builtin_rotateleft16(0x3210, 11) == 0x8190 ? 1 : -1];
char rotateleft2[__builtin_rotateleft32(0x76543210, 22) == 0x841D950C ? 1 : -1];

This comment has been minimized.

Copy link
@chfast

chfast Jul 18, 2023

Member

Looks like a typo, should have been rotateleft3.

char rotateleft2[__builtin_rotateleft64(0xFEDCBA9876543210ULL, 55) == 0x87F6E5D4C3B2A19ULL ? 1 : -1];

char rotateright1[__builtin_rotateright8(0x01, 5) == 0x08 ? 1 : -1];
char rotateright2[__builtin_rotateright16(0x3210, 11) == 0x4206 ? 1 : -1];
char rotateright2[__builtin_rotateright32(0x76543210, 22) == 0x50C841D9 ? 1 : -1];
char rotateright2[__builtin_rotateright64(0xFEDCBA9876543210ULL, 55) == 0xB97530ECA86421FDULL ? 1 : -1];

char ffs1[__builtin_ffs(0) == 0 ? 1 : -1];
char ffs2[__builtin_ffs(1) == 1 ? 1 : -1];
char ffs3[__builtin_ffs(0xfbe71) == 1 ? 1 : -1];
Expand Down

0 comments on commit 2ceac91

Please sign in to comment.