----- Original Message ----- > From: "Richard Smith" <[email protected]> > To: "Hal Finkel" <[email protected]> > Cc: "cfe commits" <[email protected]> > Sent: Thursday, October 2, 2014 7:13:00 PM > Subject: Re: r217349 - Add __builtin_assume and __builtin_assume_aligned > using @llvm.assume. > > > > > On Thu, Oct 2, 2014 at 2:41 PM, Hal Finkel < [email protected] > wrote: > > > ----- Original Message ----- > > From: "Richard Smith" < [email protected] > > > To: "Hal Finkel" < [email protected] > > > Cc: "cfe commits" < [email protected] > > > > > Sent: Monday, September 29, 2014 2:09:07 PM > > Subject: Re: r217349 - Add __builtin_assume and > > __builtin_assume_aligned using @llvm.assume. > > > > 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. > > But, as it turns out, we do: > > $ cat /tmp/bac.cpp > int n; > constexpr int *p = 0; > constexpr int *k = (int *) __builtin_assume_aligned(p, 16, n = 5); > > $ clang++ -std=c++11 -S -emit-llvm -o - /tmp/bac.cpp > /tmp/bac.cpp:3:29: error: constexpr variable 'k' must be initialized > by a constant expression > constexpr int *k = (int *) __builtin_assume_aligned(p, 16, n = 5); > ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 1 error generated. > > > > > > > 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. > > Agreed, although it seems to be currently not an issue because it > does not work regardless. > > > Oh, I see. It doesn't work because this code was added to the wrong > place: > > > 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)); > > > > This is inside IntExprEvaluator, but a call to > __builtin_assume_aligned does not have integral type. Maybe revert > this hunk?
Makes sense. I've reverted this in r218958. I'll see if I can add it back in a more-useful place (with enhancements as we've discussed). Thanks again, Hal -- Hal Finkel Assistant Computational Scientist Leadership Computing Facility Argonne National Laboratory _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
