summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorHal Finkel <hfinkel@anl.gov>2014-09-07 22:58:14 +0000
committerHal Finkel <hfinkel@anl.gov>2014-09-07 22:58:14 +0000
commitbcc06085a894aa52f094e12a8cfdd36ae1f175af (patch)
tree5d932a55113890c2447f77376b89f3e48f36c8b0 /clang/lib/Sema
parentcebf0cc210edeb839894b0e93da1c5787bd5b68b (diff)
downloadbcm5719-llvm-bcc06085a894aa52f094e12a8cfdd36ae1f175af.tar.gz
bcm5719-llvm-bcc06085a894aa52f094e12a8cfdd36ae1f175af.zip
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
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp46
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp2
2 files changed, 46 insertions, 2 deletions
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<FunctionDecl>(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;
}
OpenPOWER on IntegriCloud