summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp77
1 files changed, 40 insertions, 37 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index abcd1d45969..5b8a272d589 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -1647,6 +1647,46 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
"cast");
return RValue::get(Result);
}
+ case Builtin::BI_rotr8:
+ case Builtin::BI_rotr16:
+ case Builtin::BI_rotr:
+ case Builtin::BI_lrotr:
+ case Builtin::BI_rotr64: {
+ Value *Val = EmitScalarExpr(E->getArg(0));
+ Value *Shift = EmitScalarExpr(E->getArg(1));
+
+ llvm::Type *ArgType = Val->getType();
+ Shift = Builder.CreateIntCast(Shift, ArgType, false);
+ unsigned ArgWidth = ArgType->getIntegerBitWidth();
+ Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1);
+
+ Value *RightShiftAmt = Builder.CreateAnd(Shift, Mask);
+ Value *RightShifted = Builder.CreateLShr(Val, RightShiftAmt);
+ Value *LeftShiftAmt = Builder.CreateAnd(Builder.CreateNeg(Shift), Mask);
+ Value *LeftShifted = Builder.CreateShl(Val, LeftShiftAmt);
+ Value *Result = Builder.CreateOr(LeftShifted, RightShifted);
+ return RValue::get(Result);
+ }
+ case Builtin::BI_rotl8:
+ case Builtin::BI_rotl16:
+ case Builtin::BI_rotl:
+ case Builtin::BI_lrotl:
+ case Builtin::BI_rotl64: {
+ Value *Val = EmitScalarExpr(E->getArg(0));
+ Value *Shift = EmitScalarExpr(E->getArg(1));
+
+ llvm::Type *ArgType = Val->getType();
+ Shift = Builder.CreateIntCast(Shift, ArgType, false);
+ unsigned ArgWidth = ArgType->getIntegerBitWidth();
+ Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1);
+
+ Value *LeftShiftAmt = Builder.CreateAnd(Shift, Mask);
+ Value *LeftShifted = Builder.CreateShl(Val, LeftShiftAmt);
+ Value *RightShiftAmt = Builder.CreateAnd(Builder.CreateNeg(Shift), Mask);
+ Value *RightShifted = Builder.CreateLShr(Val, RightShiftAmt);
+ Value *Result = Builder.CreateOr(LeftShifted, RightShifted);
+ return RValue::get(Result);
+ }
case Builtin::BI__builtin_unpredictable: {
// Always return the argument of __builtin_unpredictable. LLVM does not
// handle this builtin. Metadata for this builtin should be added directly
@@ -1701,43 +1741,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
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:
- case Builtin::BI_rotl8: // Microsoft variants of rotate left
- case Builtin::BI_rotl16:
- case Builtin::BI_rotl:
- case Builtin::BI_lrotl:
- case Builtin::BI_rotl64: {
- 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);
- Value *F = CGM.getIntrinsic(Intrinsic::fshl, Ty);
- return RValue::get(Builder.CreateCall(F, { Src, Src, ShiftAmt }));
- }
- case Builtin::BI__builtin_rotateright8:
- case Builtin::BI__builtin_rotateright16:
- case Builtin::BI__builtin_rotateright32:
- case Builtin::BI__builtin_rotateright64:
- case Builtin::BI_rotr8: // Microsoft variants of rotate right
- case Builtin::BI_rotr16:
- case Builtin::BI_rotr:
- case Builtin::BI_lrotr:
- case Builtin::BI_rotr64: {
- 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);
- Value *F = CGM.getIntrinsic(Intrinsic::fshr, Ty);
- return RValue::get(Builder.CreateCall(F, { Src, Src, ShiftAmt }));
- }
-
case Builtin::BI__builtin_object_size: {
unsigned Type =
E->getArg(1)->EvaluateKnownConstInt(getContext()).getZExtValue();
OpenPOWER on IntegriCloud