diff options
| author | Hal Finkel <hfinkel@anl.gov> | 2014-09-07 22:58:14 +0000 |
|---|---|---|
| committer | Hal Finkel <hfinkel@anl.gov> | 2014-09-07 22:58:14 +0000 |
| commit | bcc06085a894aa52f094e12a8cfdd36ae1f175af (patch) | |
| tree | 5d932a55113890c2447f77376b89f3e48f36c8b0 /clang/lib/Sema | |
| parent | cebf0cc210edeb839894b0e93da1c5787bd5b68b (diff) | |
| download | bcm5719-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.cpp | 46 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 2 |
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; } |

