This revision was automatically updated to reflect the committed changes.
Closed by commit rL340141: [CodeGen] add rotate builtins that map to LLVM
funnel shift (authored by spatel, committed by ).
Changed prior to commit:
https://reviews.llvm.org/D50924?vs=161398&id=161402#toc
Repository:
rL LLVM
https://reviews.llvm.org/D50924
Files:
cfe/trunk/docs/LanguageExtensions.rst
cfe/trunk/include/clang/Basic/Builtins.def
cfe/trunk/lib/CodeGen/CGBuiltin.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
Index: cfe/trunk/docs/LanguageExtensions.rst
===================================================================
--- cfe/trunk/docs/LanguageExtensions.rst
+++ cfe/trunk/docs/LanguageExtensions.rst
@@ -1739,6 +1739,70 @@
the bitpattern of an integer value; for example ``0b10110110`` becomes
``0b01101101``.
+``__builtin_rotateleft``
+------------------------
+
+* ``__builtin_rotateleft8``
+* ``__builtin_rotateleft16``
+* ``__builtin_rotateleft32``
+* ``__builtin_rotateleft64``
+
+**Syntax**:
+
+.. code-block:: c++
+
+ __builtin_rotateleft32(x, y)
+
+**Examples**:
+
+.. code-block:: c++
+
+ uint8_t rot_x = __builtin_rotateleft8(x, y);
+ uint16_t rot_x = __builtin_rotateleft16(x, y);
+ uint32_t rot_x = __builtin_rotateleft32(x, y);
+ uint64_t rot_x = __builtin_rotateleft64(x, y);
+
+**Description**:
+
+The '``__builtin_rotateleft``' family of builtins is used to rotate
+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.
+
+``__builtin_rotateright``
+_------------------------
+
+* ``__builtin_rotateright8``
+* ``__builtin_rotateright16``
+* ``__builtin_rotateright32``
+* ``__builtin_rotateright64``
+
+**Syntax**:
+
+.. code-block:: c++
+
+ __builtin_rotateright32(x, y)
+
+**Examples**:
+
+.. code-block:: c++
+
+ uint8_t rot_x = __builtin_rotateright8(x, y);
+ uint16_t rot_x = __builtin_rotateright16(x, y);
+ uint32_t rot_x = __builtin_rotateright32(x, y);
+ uint64_t rot_x = __builtin_rotateright64(x, y);
+
+**Description**:
+
+The '``__builtin_rotateright``' family of builtins is used to rotate
+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.
+
``__builtin_unreachable``
-------------------------
Index: cfe/trunk/include/clang/Basic/Builtins.def
===================================================================
--- cfe/trunk/include/clang/Basic/Builtins.def
+++ cfe/trunk/include/clang/Basic/Builtins.def
@@ -428,6 +428,15 @@
BUILTIN(__builtin_bitreverse32, "UiUi", "nc")
BUILTIN(__builtin_bitreverse64, "ULLiULLi", "nc")
+BUILTIN(__builtin_rotateleft8, "UcUcUc", "nc")
+BUILTIN(__builtin_rotateleft16, "UsUsUs", "nc")
+BUILTIN(__builtin_rotateleft32, "UiUiUi", "nc")
+BUILTIN(__builtin_rotateleft64, "ULLiULLiULLi", "nc")
+BUILTIN(__builtin_rotateright8, "UcUcUc", "nc")
+BUILTIN(__builtin_rotateright16, "UsUsUs", "nc")
+BUILTIN(__builtin_rotateright32, "UiUiUi", "nc")
+BUILTIN(__builtin_rotateright64, "ULLiULLiULLi", "nc")
+
// Random GCC builtins
BUILTIN(__builtin_constant_p, "i.", "nctu")
BUILTIN(__builtin_classify_type, "i.", "nctu")
Index: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp
@@ -1252,6 +1252,21 @@
return Res;
}
+RValue CodeGenFunction::emitRotate(const CallExpr *E, bool IsRotateRight) {
+ llvm::Value *Src = EmitScalarExpr(E->getArg(0));
+ llvm::Value *ShiftAmt = EmitScalarExpr(E->getArg(1));
+
+ // The builtin's shift arg may have a different type than the source arg and
+ // result, but the LLVM intrinsic uses the same type for all values.
+ llvm::Type *Ty = Src->getType();
+ ShiftAmt = Builder.CreateIntCast(ShiftAmt, Ty, false);
+
+ // Rotate is a special case of LLVM funnel shift - 1st 2 args are the same.
+ unsigned IID = IsRotateRight ? Intrinsic::fshr : Intrinsic::fshl;
+ Value *F = CGM.getIntrinsic(IID, Ty);
+ return RValue::get(Builder.CreateCall(F, { Src, Src, ShiftAmt }));
+}
+
RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
unsigned BuiltinID, const CallExpr *E,
ReturnValueSlot ReturnValue) {
@@ -1741,6 +1756,18 @@
case Builtin::BI__builtin_bitreverse64: {
return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::bitreverse));
}
+ case Builtin::BI__builtin_rotateleft8:
+ case Builtin::BI__builtin_rotateleft16:
+ case Builtin::BI__builtin_rotateleft32:
+ case Builtin::BI__builtin_rotateleft64:
+ return emitRotate(E, false);
+
+ case Builtin::BI__builtin_rotateright8:
+ case Builtin::BI__builtin_rotateright16:
+ case Builtin::BI__builtin_rotateright32:
+ case Builtin::BI__builtin_rotateright64:
+ return emitRotate(E, true);
+
case Builtin::BI__builtin_object_size: {
unsigned Type =
E->getArg(1)->EvaluateKnownConstInt(getContext()).getZExtValue();
Index: cfe/trunk/lib/CodeGen/CodeGenFunction.h
===================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h
@@ -3681,6 +3681,8 @@
unsigned BuiltinID, const CallExpr *E,
ReturnValueSlot ReturnValue);
+ RValue emitRotate(const CallExpr *E, bool IsRotateRight);
+
/// Emit IR for __builtin_os_log_format.
RValue emitBuiltinOSLogFormat(const CallExpr &E);
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits