r217349 - Add __builtin_assume and __builtin_assume_aligned using @llvm.assume.
Hal Finkel
hfinkel at anl.gov
Thu Sep 25 09:19:29 PDT 2014
----- Original Message -----
> From: "Richard Smith" <richard at metafoo.co.uk>
> To: "Hal Finkel" <hfinkel at anl.gov>
> Cc: "cfe commits" <cfe-commits at cs.uiuc.edu>
> Sent: Wednesday, September 24, 2014 11:22:47 PM
> Subject: Re: r217349 - Add __builtin_assume and __builtin_assume_aligned using @llvm.assume.
>
>
>
>
>
>
> On Sun, Sep 7, 2014 at 3:58 PM, Hal Finkel < hfinkel at anl.gov > wrote:
>
>
> Author: hfinkel
> Date: Sun Sep 7 17:58:14 2014
> New Revision: 217349
>
> URL: http://llvm.org/viewvc/llvm-project?rev=217349&view=rev
> Log:
> 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.
>
> Added:
> cfe/trunk/test/CodeGen/builtin-assume-aligned.c
> cfe/trunk/test/Sema/builtin-assume-aligned.c
> cfe/trunk/test/SemaCXX/builtin-assume-aligned-tmpl.cpp
> Modified:
> cfe/trunk/docs/LanguageExtensions.rst
> cfe/trunk/include/clang/Basic/Builtins.def
> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> cfe/trunk/include/clang/Sema/Sema.h
> cfe/trunk/lib/AST/ExprConstant.cpp
> cfe/trunk/lib/CodeGen/CGBuiltin.cpp
> cfe/trunk/lib/CodeGen/CGExpr.cpp
> cfe/trunk/lib/CodeGen/CodeGenFunction.h
> cfe/trunk/lib/Sema/SemaChecking.cpp
> cfe/trunk/lib/Sema/SemaDeclAttr.cpp
> cfe/trunk/test/CodeGen/builtin-assume.c
> cfe/trunk/test/Sema/builtin-assume.c
>
> Modified: cfe/trunk/docs/LanguageExtensions.rst
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=217349&r1=217348&r2=217349&view=diff
> ==============================================================================
> --- cfe/trunk/docs/LanguageExtensions.rst (original)
> +++ cfe/trunk/docs/LanguageExtensions.rst Sun Sep 7 17:58:14 2014
> @@ -1228,8 +1228,9 @@ Builtin Functions
> Clang supports a number of builtin library functions with the same
> syntax as
> GCC, including things like ``__builtin_nan``,
> ``__builtin_constant_p``,
> ``__builtin_choose_expr``, ``__builtin_types_compatible_p``,
> -``__sync_fetch_and_add``, etc. In addition to the GCC builtins,
> Clang supports
> -a number of builtins that GCC does not, which are listed here.
> +``__builtin_assume_aligned``, ``__sync_fetch_and_add``, etc. In
> addition to
> +the GCC builtins, Clang supports a number of builtins that GCC does
> not, which
> +are listed here.
>
> Please note that Clang does not and will not support all of the GCC
> builtins
> for vector operations. Instead of using builtins, you should use the
> functions
> @@ -1239,6 +1240,42 @@ implemented directly in terms of :ref:`e
> <langext-vectors>` instead of builtins, in order to reduce the number
> of
> builtins that we need to implement.
>
> +``__builtin_assume``
> +------------------------------
> +
> +``__builtin_assume`` is used to provide the optimizer with a boolean
> +invariant that is defined to be true.
> +
> +**Syntax**:
> +
> +.. code-block:: c++
> +
> + __builtin_assume(bool)
> +
> +**Example of Use**:
> +
> +.. code-block:: c++
> +
> + int foo(int x) {
> + __builtin_assume(x != 0);
> +
> + // The optimizer may short-circuit this check using the invariant.
> + if (x == 0)
> + return do_something();
> +
> + return do_something_else();
> + }
> +
> +**Description**:
> +
> +The boolean argument to this function is defined to be true. The
> optimizer may
> +analyze the form of the expression provided as the argument and
> deduce from
> +that information used to optimize the program. If the condition is
> violated
> +during execution, the behavior is undefined. The argument itself is
> never
> +evaluated, so any side effects of the expression will be discarded.
> +
> +Query for this feature with ``__has_builtin(__builtin_assume)``.
> +
> ``__builtin_readcyclecounter``
> ------------------------------
>
>
> Modified: cfe/trunk/include/clang/Basic/Builtins.def
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=217349&r1=217348&r2=217349&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/Builtins.def (original)
> +++ cfe/trunk/include/clang/Basic/Builtins.def Sun Sep 7 17:58:14
> 2014
> @@ -412,6 +412,7 @@ BUILTIN(__builtin_va_start, "vA.", "nt")
> BUILTIN(__builtin_va_end, "vA", "n")
> BUILTIN(__builtin_va_copy, "vAA", "n")
> BUILTIN(__builtin_stdarg_start, "vA.", "n")
> +BUILTIN(__builtin_assume_aligned, "v*vC*z.", "nc")
> BUILTIN(__builtin_bcmp, "iv*v*z", "n")
> BUILTIN(__builtin_bcopy, "vv*v*z", "n")
> BUILTIN(__builtin_bzero, "vv*z", "nF")
> @@ -1173,6 +1174,9 @@ LIBBUILTIN(_Block_object_dispose, "vvC*i
> // Annotation function
> BUILTIN(__builtin_annotation, "v.", "tn")
>
> +// Invariants
> +BUILTIN(__builtin_assume, "vb", "n")
> +
> // Multiprecision Arithmetic Builtins.
> BUILTIN(__builtin_addcb, "UcUcCUcCUcCUc*", "n")
> BUILTIN(__builtin_addcs, "UsUsCUsCUsCUs*", "n")
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=217349&r1=217348&r2=217349&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Sep 7
> 17:58:14 2014
> @@ -451,7 +451,7 @@ def note_strncat_wrong_size : Note<
> "the terminating null byte">;
>
> def warn_assume_side_effects : Warning<
> - "the argument to __assume has side effects that will be
> discarded">,
> + "the argument to %0 has side effects that will be discarded">,
> InGroup<DiagGroup<"assume">>;
>
> /// main()
> @@ -2078,8 +2078,9 @@ 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_attribute_aligned_not_power_of_two : Error<
> +def err_alignment_not_power_of_two : Error<
> "requested alignment is not a power of 2">;
> +
> def err_attribute_aligned_too_great : Error<
> "requested alignment must be %0 bytes or smaller">;
> def warn_redeclaration_without_attribute_prev_attribute_ignored :
> Warning<
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=217349&r1=217348&r2=217349&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Sun Sep 7 17:58:14 2014
> @@ -8375,6 +8375,7 @@ public:
> private:
> bool SemaBuiltinPrefetch(CallExpr *TheCall);
> bool SemaBuiltinAssume(CallExpr *TheCall);
> + bool SemaBuiltinAssumeAligned(CallExpr *TheCall);
> bool SemaBuiltinLongjmp(CallExpr *TheCall);
> ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult);
> ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult,
>
> Modified: cfe/trunk/lib/AST/ExprConstant.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=217349&r1=217348&r2=217349&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ExprConstant.cpp (original)
> +++ cfe/trunk/lib/AST/ExprConstant.cpp Sun Sep 7 17:58:14 2014
> @@ -6092,6 +6092,7 @@ bool IntExprEvaluator::VisitCallExpr(con
> return Success(Operand, E);
> }
>
> + case Builtin::BI__builtin_assume_aligned:
> case Builtin::BI__builtin_expect:
> return Visit(E->getArg(0));
>
>
>
> We should evaluate (and discard) argument 1 and (if present) argument
> 2 here too, in case they have side-effects or are non-constant.
Actually, I'm having trouble coming up with a test-case for this.
First, argument 1 is restricted to being a constant integer, and I don't think it can have side-effects. Maybe this is not quite right, but currently we get:
error: argument to '__builtin_assume_aligned' must be a constant integer
return __builtin_assume_aligned((int*) 0xfffff000, (++i, 16), i);
^ ~~~~~~~~~
For argument 2, this can have side effects, but even when the pointer argument is constant, I don't see things being folded (and, thus, I don't see side-effects as being dropped). For example:
int foob() {
if (((int*) 0xfffff000) == (int*)0)
return 0;
else
return 1;
}
produces (-O3 -mllvm -disable-llvm-optzns):
define i32 @foob() #0 {
entry:
ret i32 1
}
but this:
int foo5(int i) {
if ((int*)__builtin_assume_aligned((int*) 0xfffff000, 16, i) == (int*)0)
return 0;
else
return 1;
}
does not fold (and changing argument 2 from i to ++i does lead to a dropped side effect). Maybe this related to the fact that Expr::HasSideEffects always returns true for CallExprClass?
Thanks again,
Hal
>
>
> @@ -7967,6 +7968,7 @@ public:
> default:
> return ExprEvaluatorBaseTy::VisitCallExpr(E);
> case Builtin::BI__assume:
> + case Builtin::BI__builtin_assume:
> // The argument is not evaluated!
> return true;
> }
>
> Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=217349&r1=217348&r2=217349&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Sun Sep 7 17:58:14 2014
> @@ -374,6 +374,27 @@ RValue CodeGenFunction::EmitBuiltinExpr(
> "expval");
> return RValue::get(Result);
> }
> + case Builtin::BI__builtin_assume_aligned: {
> + Value *PtrValue = EmitScalarExpr(E->getArg(0));
> + Value *OffsetValue =
> + (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : nullptr;
> +
> + Value *AlignmentValue = EmitScalarExpr(E->getArg(1));
> + ConstantInt *AlignmentCI = cast<ConstantInt>(AlignmentValue);
> + unsigned Alignment = (unsigned) AlignmentCI->getZExtValue();
> +
> + EmitAlignmentAssumption(PtrValue, Alignment, OffsetValue);
> + return RValue::get(PtrValue);
> + }
> + case Builtin::BI__assume:
> + case Builtin::BI__builtin_assume: {
> + if (E->getArg(0)->HasSideEffects(getContext()))
> + return RValue::get(nullptr);
> +
> + Value *ArgValue = EmitScalarExpr(E->getArg(0));
> + Value *FnAssume = CGM.getIntrinsic(Intrinsic::assume);
> + return RValue::get(Builder.CreateCall(FnAssume, ArgValue));
> + }
> case Builtin::BI__builtin_bswap16:
> case Builtin::BI__builtin_bswap32:
> case Builtin::BI__builtin_bswap64: {
> @@ -1510,9 +1531,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(
> case Builtin::BI__noop:
> // __noop always evaluates to an integer literal zero.
> return RValue::get(ConstantInt::get(IntTy, 0));
> - case Builtin::BI__assume:
> - // Until LLVM supports assumptions at the IR level, this becomes
> nothing.
> - return RValue::get(nullptr);
> case Builtin::BI_InterlockedExchange:
> case Builtin::BI_InterlockedExchangePointer:
> return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E);
>
> Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=217349&r1=217348&r2=217349&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sun Sep 7 17:58:14 2014
> @@ -711,6 +711,34 @@ EmitComplexPrePostIncDec(const UnaryOper
> return isPre ? IncVal : InVal;
> }
>
> +void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue,
> + unsigned Alignment,
> + llvm::Value *OffsetValue) {
> + llvm::Value *PtrIntValue =
> + Builder.CreatePtrToInt(PtrValue, IntPtrTy, "ptrint");
> +
> + llvm::Value *Mask = llvm::ConstantInt::get(IntPtrTy,
> + Alignment > 0 ? Alignment - 1 : 0);
> + if (OffsetValue) {
> + bool IsOffsetZero = false;
> + if (llvm::ConstantInt *CI =
> dyn_cast<llvm::ConstantInt>(OffsetValue))
> + IsOffsetZero = CI->isZero();
> +
> + if (!IsOffsetZero) {
> + if (OffsetValue->getType() != IntPtrTy)
> + OffsetValue = Builder.CreateIntCast(OffsetValue, IntPtrTy,
> + /*isSigned*/true, "offsetcast");
> + PtrIntValue = Builder.CreateSub(PtrIntValue, OffsetValue,
> "offsetptr");
> + }
> + }
> +
> + llvm::Value *Zero = llvm::ConstantInt::get(IntPtrTy, 0);
> + llvm::Value *MaskedPtr = Builder.CreateAnd(PtrIntValue, Mask,
> "maskedptr");
> + llvm::Value *InvCond = Builder.CreateICmpEQ(MaskedPtr, Zero,
> "maskcond");
> +
> + llvm::Value *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);
> + Builder.CreateCall(FnAssume, InvCond);
> +}
>
> //===----------------------------------------------------------------------===//
> // LValue Expression Emission
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=217349&r1=217348&r2=217349&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Sun Sep 7 17:58:14 2014
> @@ -1743,6 +1743,10 @@ public:
> bool isInc, bool isPre);
> ComplexPairTy EmitComplexPrePostIncDec(const UnaryOperator *E, LValue
> LV,
> bool isInc, bool isPre);
> +
> + void EmitAlignmentAssumption(llvm::Value *PtrValue, unsigned
> Alignment,
> + llvm::Value *OffsetValue = nullptr);
> +
> //===--------------------------------------------------------------------===//
> // Declaration Emission
> //===--------------------------------------------------------------------===//
>
> Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=217349&r1=217348&r2=217349&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaChecking.cpp Sun Sep 7 17:58:14 2014
> @@ -189,9 +189,14 @@ Sema::CheckBuiltinFunctionCall(unsigned
> 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 *T
>
> 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;
> }
>
> Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=217349&r1=217348&r2=217349&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Sun Sep 7 17:58:14 2014
> @@ -2786,7 +2786,7 @@ void Sema::AddAlignedAttr(SourceRange At
> // 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;
> }
>
> Added: cfe/trunk/test/CodeGen/builtin-assume-aligned.c
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtin-assume-aligned.c?rev=217349&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGen/builtin-assume-aligned.c (added)
> +++ cfe/trunk/test/CodeGen/builtin-assume-aligned.c Sun Sep 7
> 17:58:14 2014
> @@ -0,0 +1,44 @@
> +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s
> | FileCheck %s
> +
> +// CHECK-LABEL: @test1
> +int test1(int *a) {
> +// CHECK: %ptrint = ptrtoint
> +// CHECK: %maskedptr = and i64 %ptrint, 31
> +// CHECK: %maskcond = icmp eq i64 %maskedptr, 0
> +// CHECK: call void @llvm.assume(i1 %maskcond)
> + a = __builtin_assume_aligned(a, 32, 0ull);
> + return a[0];
> +}
> +
> +// CHECK-LABEL: @test2
> +int test2(int *a) {
> +// CHECK: %ptrint = ptrtoint
> +// CHECK: %maskedptr = and i64 %ptrint, 31
> +// CHECK: %maskcond = icmp eq i64 %maskedptr, 0
> +// CHECK: call void @llvm.assume(i1 %maskcond)
> + a = __builtin_assume_aligned(a, 32, 0);
> + return a[0];
> +}
> +
> +// CHECK-LABEL: @test3
> +int test3(int *a) {
> +// CHECK: %ptrint = ptrtoint
> +// CHECK: %maskedptr = and i64 %ptrint, 31
> +// CHECK: %maskcond = icmp eq i64 %maskedptr, 0
> +// CHECK: call void @llvm.assume(i1 %maskcond)
> + a = __builtin_assume_aligned(a, 32);
> + return a[0];
> +}
> +
> +// CHECK-LABEL: @test4
> +int test4(int *a, int b) {
> +// CHECK-DAG: %ptrint = ptrtoint
> +// CHECK-DAG: %conv = sext i32
> +// CHECK: %offsetptr = sub i64 %ptrint, %conv
> +// CHECK: %maskedptr = and i64 %offsetptr, 31
> +// CHECK: %maskcond = icmp eq i64 %maskedptr, 0
> +// CHECK: call void @llvm.assume(i1 %maskcond)
> + a = __builtin_assume_aligned(a, 32, b);
> + return a[0];
> +}
> +
>
> Modified: cfe/trunk/test/CodeGen/builtin-assume.c
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtin-assume.c?rev=217349&r1=217348&r2=217349&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGen/builtin-assume.c (original)
> +++ cfe/trunk/test/CodeGen/builtin-assume.c Sun Sep 7 17:58:14 2014
> @@ -1,8 +1,26 @@
> +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s
> | FileCheck %s
> // RUN: %clang_cc1 -triple i386-mingw32 -fms-extensions -emit-llvm -o
> - %s | FileCheck %s
>
> // CHECK-LABEL: @test1
> -int test1(int *a) {
> - __assume(a != 0);
> +int test1(int *a, int i) {
> +// CHECK: %0 = load i32** %a.addr
> +// CHECK: %cmp = icmp ne i32* %0, null
> +// CHECK: call void @llvm.assume(i1 %cmp)
> +#ifdef _MSC_VER
> + __assume(a != 0)
> +#else
> + __builtin_assume(a != 0);
> +#endif
> +
> +// Nothing is generated for an assume with side effects...
> +// CHECK-NOT: load i32** %i.addr
> +// CHECK-NOT: call void @llvm.assume
> +#ifdef _MSC_VER
> + __assume(++i != 0)
> +#else
> + __builtin_assume(++i != 0);
> +#endif
> +
> return a[0];
> }
>
>
> Added: cfe/trunk/test/Sema/builtin-assume-aligned.c
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/builtin-assume-aligned.c?rev=217349&view=auto
> ==============================================================================
> --- cfe/trunk/test/Sema/builtin-assume-aligned.c (added)
> +++ cfe/trunk/test/Sema/builtin-assume-aligned.c Sun Sep 7 17:58:14
> 2014
> @@ -0,0 +1,43 @@
> +// RUN: %clang_cc1 -fsyntax-only -verify %s
> +
> +int test1(int *a) {
> + a = __builtin_assume_aligned(a, 32, 0ull);
> + return a[0];
> +}
> +
> +int test2(int *a) {
> + a = __builtin_assume_aligned(a, 32, 0);
> + return a[0];
> +}
> +
> +int test3(int *a) {
> + a = __builtin_assume_aligned(a, 32);
> + return a[0];
> +}
> +
> +int test4(int *a) {
> + a = __builtin_assume_aligned(a, -32); // expected-error {{requested
> alignment is not a power of 2}}
> + a = __builtin_assume_aligned(a, 1ULL << 63);
> + return a[0];
> +}
> +
> +int test5(int *a, unsigned *b) {
> + a = __builtin_assume_aligned(a, 32, b); // expected-warning
> {{incompatible pointer to integer conversion passing 'unsigned int
> *' to parameter of type}}
> + return a[0];
> +}
> +
> +int test6(int *a) {
> + a = __builtin_assume_aligned(a, 32, 0, 0); // expected-error {{too
> many arguments to function call, expected at most 3, have 4}}
> + return a[0];
> +}
> +
> +int test7(int *a) {
> + a = __builtin_assume_aligned(a, 31); // expected-error {{requested
> alignment is not a power of 2}}
> + return a[0];
> +}
> +
> +int test8(int *a, int j) {
> + a = __builtin_assume_aligned(a, j); // expected-error {{must be a
> constant integer}}
> + return a[0];
> +}
> +
>
> Modified: cfe/trunk/test/Sema/builtin-assume.c
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/builtin-assume.c?rev=217349&r1=217348&r2=217349&view=diff
> ==============================================================================
> --- cfe/trunk/test/Sema/builtin-assume.c (original)
> +++ cfe/trunk/test/Sema/builtin-assume.c Sun Sep 7 17:58:14 2014
> @@ -1,11 +1,18 @@
> // RUN: %clang_cc1 -triple i386-mingw32 -fms-extensions -fsyntax-only
> -verify %s
> +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only
> -verify %s
>
> int foo(int *a, int i) {
> +#ifdef _MSC_VER
> __assume(i != 4);
> - __assume(++i > 2); //expected-warning {{the argument to __assume
> has side effects that will be discarded}}
> + __assume(++i > 2); //expected-warning {{the argument to '__assume'
> has side effects that will be discarded}}
>
> int test = sizeof(struct{char qq[(__assume(i != 5), 7)];});
> +#else
> + __builtin_assume(i != 4);
> + __builtin_assume(++i > 2); //expected-warning {{the argument to
> '__builtin_assume' has side effects that will be discarded}}
>
> + int test = sizeof(struct{char qq[(__builtin_assume(i != 5), 7)];});
> +#endif
> return a[i];
> }
>
>
> Added: cfe/trunk/test/SemaCXX/builtin-assume-aligned-tmpl.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/builtin-assume-aligned-tmpl.cpp?rev=217349&view=auto
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/builtin-assume-aligned-tmpl.cpp (added)
> +++ cfe/trunk/test/SemaCXX/builtin-assume-aligned-tmpl.cpp Sun Sep 7
> 17:58:14 2014
> @@ -0,0 +1,22 @@
> +// RUN: %clang_cc1 -fsyntax-only -verify %s
> +
> +template<int z>
> +int test9(int *a) {
> + a = (int *) __builtin_assume_aligned(a, z + 1); // expected-error
> {{requested alignment is not a power of 2}}
> + return a[0];
> +}
> +
> +void test9i(int *a) {
> + test9<42>(a); // expected-note {{in instantiation of function
> template specialization 'test9<42>' requested here}}
> +}
> +
> +template<typename T>
> +int test10(int *a, T z) {
> + a = (int *) __builtin_assume_aligned(a, z + 1); // expected-error
> {{must be a constant integer}}
> + return a[0];
> +}
> +
> +int test10i(int *a) {
> + return test10(a, 42); // expected-note {{in instantiation of
> function template specialization 'test10<int>' requested here}}
> +}
> +
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>
--
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory
More information about the cfe-commits
mailing list