r285544 - Add support for __builtin_alloca_with_align
David Majnemer via cfe-commits
cfe-commits at lists.llvm.org
Sun Oct 30 22:37:49 PDT 2016
Author: majnemer
Date: Mon Oct 31 00:37:48 2016
New Revision: 285544
URL: http://llvm.org/viewvc/llvm-project?rev=285544&view=rev
Log:
Add support for __builtin_alloca_with_align
__builtin_alloca always uses __BIGGEST_ALIGNMENT__ for the alignment of
the allocation. __builtin_alloca_with_align allows the programmer to
specify the alignment of the allocation.
This fixes PR30658.
Added:
cfe/trunk/test/Sema/builtin-alloca-with-align.c
Modified:
cfe/trunk/include/clang/Basic/Builtins.def
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/CodeGen/CGBuiltin.cpp
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
cfe/trunk/test/CodeGen/builtins-ms.c
Modified: cfe/trunk/include/clang/Basic/Builtins.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=285544&r1=285543&r2=285544&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Builtins.def (original)
+++ cfe/trunk/include/clang/Basic/Builtins.def Mon Oct 31 00:37:48 2016
@@ -512,6 +512,7 @@ BUILTIN(__builtin_unreachable, "v", "nr"
BUILTIN(__builtin_shufflevector, "v." , "nc")
BUILTIN(__builtin_convertvector, "v." , "nct")
BUILTIN(__builtin_alloca, "v*z" , "Fn")
+BUILTIN(__builtin_alloca_with_align, "v*zIz", "Fn")
BUILTIN(__builtin_call_with_static_chain, "v.", "nt")
// "Overloaded" Atomic operator builtins. These are overloaded to support data
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=285544&r1=285543&r2=285544&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Oct 31 00:37:48 2016
@@ -2440,6 +2440,10 @@ def err_no_accessor_for_property : Error
def error_cannot_find_suitable_accessor : Error<
"cannot find suitable %select{getter|setter}0 for property %1">;
+def err_alignment_too_small : Error<
+ "requested alignment must be %0 or greater">;
+def err_alignment_too_big : Error<
+ "requested alignment must be %0 or smaller">;
def err_alignment_not_power_of_two : Error<
"requested alignment is not a power of 2">;
def err_alignment_dependent_typedef_name : Error<
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=285544&r1=285543&r2=285544&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Oct 31 00:37:48 2016
@@ -9719,6 +9719,7 @@ public:
private:
bool SemaBuiltinPrefetch(CallExpr *TheCall);
+ bool SemaBuiltinAllocaWithAlign(CallExpr *TheCall);
bool SemaBuiltinAssume(CallExpr *TheCall);
bool SemaBuiltinAssumeAligned(CallExpr *TheCall);
bool SemaBuiltinLongjmp(CallExpr *TheCall);
Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=285544&r1=285543&r2=285544&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Mon Oct 31 00:37:48 2016
@@ -1147,6 +1147,19 @@ RValue CodeGenFunction::EmitBuiltinExpr(
AI->setAlignment(SuitableAlignmentInBytes);
return RValue::get(AI);
}
+
+ case Builtin::BI__builtin_alloca_with_align: {
+ Value *Size = EmitScalarExpr(E->getArg(0));
+ Value *AlignmentValue = EmitScalarExpr(E->getArg(1));
+ auto *AlignmentCI = cast<ConstantInt>(AlignmentValue);
+ unsigned Alignment = AlignmentCI->getZExtValue();
+ const TargetInfo &TI = getContext().getTargetInfo();
+ unsigned AlignmentInBytes = Alignment / TI.getCharWidth();
+ AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size);
+ AI->setAlignment(AlignmentInBytes);
+ return RValue::get(AI);
+ }
+
case Builtin::BIbzero:
case Builtin::BI__builtin_bzero: {
Address Dest = EmitPointerWithAlignment(E->getArg(0));
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=285544&r1=285543&r2=285544&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Mon Oct 31 00:37:48 2016
@@ -791,6 +791,10 @@ Sema::CheckBuiltinFunctionCall(FunctionD
if (SemaBuiltinPrefetch(TheCall))
return ExprError();
break;
+ case Builtin::BI__builtin_alloca_with_align:
+ if (SemaBuiltinAllocaWithAlign(TheCall))
+ return ExprError();
+ break;
case Builtin::BI__assume:
case Builtin::BI__builtin_assume:
if (SemaBuiltinAssume(TheCall))
@@ -3902,6 +3906,36 @@ bool Sema::SemaBuiltinAssume(CallExpr *T
return false;
}
+
+/// Handle __builtin_assume_aligned. This is declared
+/// as (size_t, size_t) where the second size_t must be a power of 2 greater
+/// than 8.
+bool Sema::SemaBuiltinAllocaWithAlign(CallExpr *TheCall) {
+ // 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 = Arg->EvaluateKnownConstInt(Context);
+
+ if (!Result.isPowerOf2())
+ return Diag(TheCall->getLocStart(),
+ diag::err_alignment_not_power_of_two)
+ << Arg->getSourceRange();
+
+ if (Result < Context.getCharWidth())
+ return Diag(TheCall->getLocStart(), diag::err_alignment_too_small)
+ << (unsigned)Context.getCharWidth()
+ << Arg->getSourceRange();
+
+ if (Result > INT32_MAX)
+ return Diag(TheCall->getLocStart(), diag::err_alignment_too_big)
+ << INT32_MAX
+ << Arg->getSourceRange();
+ }
+
+ return false;
+}
/// Handle __builtin_assume_aligned. This is declared
/// as (const void*, size_t, ...) and can take one optional constant int arg.
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp?rev=285544&r1=285543&r2=285544&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp Mon Oct 31 00:37:48 2016
@@ -55,6 +55,7 @@ bool BuiltinFunctionChecker::evalCall(co
return true;
}
+ case Builtin::BI__builtin_alloca_with_align:
case Builtin::BI__builtin_alloca: {
// FIXME: Refactor into StoreManager itself?
MemRegionManager& RM = C.getStoreManager().getRegionManager();
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp?rev=285544&r1=285543&r2=285544&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp Mon Oct 31 00:37:48 2016
@@ -43,6 +43,7 @@ public:
void CheckReallocZero(CheckerContext &C, const CallExpr *CE) const;
void CheckReallocfZero(CheckerContext &C, const CallExpr *CE) const;
void CheckAllocaZero(CheckerContext &C, const CallExpr *CE) const;
+ void CheckAllocaWithAlignZero(CheckerContext &C, const CallExpr *CE) const;
void CheckVallocZero(CheckerContext &C, const CallExpr *CE) const;
typedef void (UnixAPIChecker::*SubChecker)(CheckerContext &,
@@ -337,6 +338,11 @@ void UnixAPIChecker::CheckAllocaZero(Che
BasicAllocationCheck(C, CE, 1, 0, "alloca");
}
+void UnixAPIChecker::CheckAllocaWithAlignZero(CheckerContext &C,
+ const CallExpr *CE) const {
+ BasicAllocationCheck(C, CE, 2, 0, "__builtin_alloca_with_align");
+}
+
void UnixAPIChecker::CheckVallocZero(CheckerContext &C,
const CallExpr *CE) const {
BasicAllocationCheck(C, CE, 1, 0, "valloc");
@@ -366,6 +372,8 @@ void UnixAPIChecker::checkPreStmt(const
.Case("realloc", &UnixAPIChecker::CheckReallocZero)
.Case("reallocf", &UnixAPIChecker::CheckReallocfZero)
.Cases("alloca", "__builtin_alloca", &UnixAPIChecker::CheckAllocaZero)
+ .Case("__builtin_alloca_with_align",
+ &UnixAPIChecker::CheckAllocaWithAlignZero)
.Case("valloc", &UnixAPIChecker::CheckVallocZero)
.Default(nullptr);
Modified: cfe/trunk/test/CodeGen/builtins-ms.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtins-ms.c?rev=285544&r1=285543&r2=285544&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/builtins-ms.c (original)
+++ cfe/trunk/test/CodeGen/builtins-ms.c Mon Oct 31 00:37:48 2016
@@ -1,9 +1,16 @@
// RUN: %clang_cc1 %s -emit-llvm -o - -fms-extensions -triple i686-pc-win32 | FileCheck %s
-// CHECK-LABEL: define void @test_alloca
+// CHECK-LABEL: define void @test_alloca(
void capture(void *);
void test_alloca(int n) {
capture(_alloca(n));
// CHECK: %[[arg:.*]] = alloca i8, i32 %{{.*}}, align 16
// CHECK: call void @capture(i8* %[[arg]])
}
+
+// CHECK-LABEL: define void @test_alloca_with_align(
+void test_alloca_with_align(int n) {
+ capture(__builtin_alloca_with_align(n, 64));
+ // CHECK: %[[arg:.*]] = alloca i8, i32 %{{.*}}, align 8
+ // CHECK: call void @capture(i8* %[[arg]])
+}
Added: cfe/trunk/test/Sema/builtin-alloca-with-align.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/builtin-alloca-with-align.c?rev=285544&view=auto
==============================================================================
--- cfe/trunk/test/Sema/builtin-alloca-with-align.c (added)
+++ cfe/trunk/test/Sema/builtin-alloca-with-align.c Mon Oct 31 00:37:48 2016
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void test1(int a) {
+ __builtin_alloca_with_align(a, 32);
+}
+
+void test2(int a) {
+ __builtin_alloca_with_align(a, -32); // expected-error {{requested alignment is not a power of 2}}
+}
+
+void test3(unsigned *b) {
+ __builtin_alloca_with_align(b, 32); // expected-warning {{incompatible pointer to integer conversion passing 'unsigned int *' to parameter of type}}
+}
+
+void test4(int a) {
+ __builtin_alloca_with_align(a, 32, 0); // expected-error {{too many arguments to function call, expected 2, have 3}}
+}
+
+void test5(int a) {
+ __builtin_alloca_with_align(a, 31); // expected-error {{requested alignment is not a power of 2}}
+}
+
+void test6(int a, int j) {
+ __builtin_alloca_with_align(a, j); // expected-error {{must be a constant integer}}
+}
+
+void test7(int a) {
+ __builtin_alloca_with_align(a, 2); // expected-error {{requested alignment must be 8 or greater}}
+}
More information about the cfe-commits
mailing list