From bcc06085a894aa52f094e12a8cfdd36ae1f175af Mon Sep 17 00:00:00 2001 From: Hal Finkel Date: Sun, 7 Sep 2014 22:58:14 +0000 Subject: Add __builtin_assume and __builtin_assume_aligned using @llvm.assume. This makes use of the recently-added @llvm.assume intrinsic to implement a __builtin_assume(bool) intrinsic (to provide additional information to the optimizer). This hooks up __assume in MS-compatibility mode to mirror __builtin_assume (the semantics have been intentionally kept compatible), and implements GCC's __builtin_assume_aligned as assume((p - o) & mask == 0). LLVM now contains special logic to deal with assumptions of this form. llvm-svn: 217349 --- clang/lib/Sema/SemaChecking.cpp | 46 ++++++++++++++++++++++++++++++++++++++++- clang/lib/Sema/SemaDeclAttr.cpp | 2 +- 2 files changed, 46 insertions(+), 2 deletions(-) (limited to 'clang/lib/Sema') diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 87042d1c07c..435b951b7c0 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -189,9 +189,14 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return ExprError(); break; case Builtin::BI__assume: + case Builtin::BI__builtin_assume: if (SemaBuiltinAssume(TheCall)) return ExprError(); break; + case Builtin::BI__builtin_assume_aligned: + if (SemaBuiltinAssumeAligned(TheCall)) + return ExprError(); + break; case Builtin::BI__builtin_object_size: if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3)) return ExprError(); @@ -2059,7 +2064,46 @@ bool Sema::SemaBuiltinAssume(CallExpr *TheCall) { if (Arg->HasSideEffects(Context)) return Diag(Arg->getLocStart(), diag::warn_assume_side_effects) - << Arg->getSourceRange(); + << Arg->getSourceRange() + << cast(TheCall->getCalleeDecl())->getIdentifier(); + + return false; +} + +/// Handle __builtin_assume_aligned. This is declared +/// as (const void*, size_t, ...) and can take one optional constant int arg. +bool Sema::SemaBuiltinAssumeAligned(CallExpr *TheCall) { + unsigned NumArgs = TheCall->getNumArgs(); + + if (NumArgs > 3) + return Diag(TheCall->getLocEnd(), + diag::err_typecheck_call_too_many_args_at_most) + << 0 /*function call*/ << 3 << NumArgs + << TheCall->getSourceRange(); + + // The alignment must be a constant integer. + Expr *Arg = TheCall->getArg(1); + + // We can't check the value of a dependent argument. + if (!Arg->isTypeDependent() && !Arg->isValueDependent()) { + llvm::APSInt Result; + if (SemaBuiltinConstantArg(TheCall, 1, Result)) + return true; + + if (!Result.isPowerOf2()) + return Diag(TheCall->getLocStart(), + diag::err_alignment_not_power_of_two) + << Arg->getSourceRange(); + } + + if (NumArgs > 2) { + ExprResult Arg(TheCall->getArg(2)); + InitializedEntity Entity = InitializedEntity::InitializeParameter(Context, + Context.getSizeType(), false); + Arg = PerformCopyInitialization(Entity, SourceLocation(), Arg); + if (Arg.isInvalid()) return true; + TheCall->setArg(2, Arg.get()); + } return false; } diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 91b299fa66a..e3bb2c993e9 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -2786,7 +2786,7 @@ void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, // An alignment specification of zero has no effect. if (!(TmpAttr.isAlignas() && !Alignment) && !llvm::isPowerOf2_64(Alignment.getZExtValue())) { - Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) + Diag(AttrLoc, diag::err_alignment_not_power_of_two) << E->getSourceRange(); return; } -- cgit v1.2.3