On Thu, Sep 25, 2014 at 9:19 AM, Hal Finkel <[email protected]> wrote: > ----- Original Message ----- > > From: "Richard Smith" <[email protected]> > > To: "Hal Finkel" <[email protected]> > > Cc: "cfe commits" <[email protected]> > > 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 < [email protected] > 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?
Try this (in C++11 onwards): int n; constexpr int *p = 0; constexpr int k = __builtin_assume_aligned(p, 16, n = 5); We should reject; I suspect we won't. Hmm, also... should __builtin_assume* be non-constant when the assumption does not hold? In C++11 we have a general rule that undefined behavior is non-constant, and assumption failure seems like it should be UB.
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
