OpenCL v2.0 s6.5.5 restricts conversion of pointers to different address spaces:
- the named address spaces (__global, __local, and __private) => __generic - implicitly converted;
- __generic => named - with an explicit cast;
- named <=> named - disallowed;
- __constant <=> any other - disallowed.
llvm-svn: 222834
This is a new form of expression of the form:
(expr op ... op expr)
where one of the exprs is a parameter pack. It expands into
(expr1 op (expr2onwards op ... op expr))
(and likewise if the pack is on the right). The non-pack operand can be
omitted; in that case, an empty pack gives a fallback value or an error,
depending on the operator.
llvm-svn: 221573
complete object to a pointer to the start of another complete object does
not evaluate to the constant 'false'. All other comparisons between the
addresses of subobjects of distinct complete objects still do.
llvm-svn: 220343
and !=) to support mixed complex and real operand types.
This requires removing an assert from SemaChecking, and adding support
both to the constant evaluator and the code generator to synthesize the
imaginary part when needed. This seemed somewhat cleaner than having
just the comparison operators force real-to-complex conversions.
I've added test cases for these operations. I'm really terrified that
there were *no* tests in-tree which exercised this.
This turned up when trying to build R after my change to the complex
type lowering.
llvm-svn: 219570
operators where one type is a C complex type, and to emit both the
efficient and correct implementation for complex arithmetic according to
C11 Annex G using this extra information.
For both multiply and divide the old code was writing a long-hand
reduced version of the math without any of the special handling of inf
and NaN recommended by the standard here. Instead of putting more
complexity here, this change does what GCC does which is to emit
a libcall for the fully general case.
However, the old code also failed to do the proper minimization of the
set of operations when there was a mixed complex and real operation. In
those cases, C provides a spec for much more minimal operations that are
valid. Clang now emits the exact suggested operations. This change isn't
*just* about performance though, without minimizing these operations, we
again lose the correct handling of infinities and NaNs. It is critical
that this happen in the frontend based on assymetric type operands to
complex math operations.
The performance implications of this change aren't trivial either. I've
run a set of benchmarks in Eigen, an open source mathematics library
that makes heavy use of complex. While a few have slowed down due to the
libcall being introduce, most sped up and some by a huge amount: up to
100% and 140%.
In order to make all of this work, also match the algorithm in the
constant evaluator to the one in the runtime library. Currently it is
a broken port of the simplifications from C's Annex G to the long-hand
formulation of the algorithm.
Splitting this patch up is very hard because none of this works without
the AST change to preserve non-complex operands. Sorry for the enormous
change.
Follow-up changes will include support for sinking the libcalls onto
cold paths in common cases and fastmath improvements to allow more
aggressive backend folding.
Differential Revision: http://reviews.llvm.org/D5698
llvm-svn: 219557
Assertion failed: "Computed __func__ length differs from type!"
Reworked PredefinedExpr representation with internal StringLiteral field for function declaration.
Differential Revision: http://reviews.llvm.org/D5365
llvm-svn: 219393
Richard noted in the review of r217349 that extra handling of
__builtin_assume_aligned inside of the expression evaluator was needed. He was
right, and this should address the concerns raised, namely:
1. The offset argument to __builtin_assume_aligned can have side effects, and
we need to make sure that all arguments are properly evaluated.
2. If the alignment assumption does not hold, that introduces undefined
behavior, and undefined behavior cannot appear inside a constexpr.
and hopefully the diagnostics produced are detailed enough to explain what is
going on.
llvm-svn: 218992
Adding handling of __builtin_assume_aligned to IntExprEvaluator does not make
sense because __builtin_assume_aligned returns a pointer (not an integer).
Thanks to Richard for figuring out why this was not doing anything.
I'll add this back in a better place (PointerExprEvaluator perhaps).
llvm-svn: 218958
constexpr function. Part of this fix is a tentative fix for an as-yet-unfiled
core issue (we're missing a prohibition against reading mutable members from
unions via a trivial constructor/assignment, since that doesn't perform an
lvalue-to-rvalue conversion on the members).
llvm-svn: 217852
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
Changes diagnostic options, language standard options, diagnostic identifiers, diagnostic wording to use c++14 instead of c++1y. It also modifies related test cases to use the updated diagnostic wording.
llvm-svn: 215982
or a class derived from T. We already supported this when initializing
_Atomic(T) from T for most (and maybe all) other reasonable values of T.
llvm-svn: 214390
The class seems to have an invariant that Entries is non-empty if
Invalid is false. It appears this method was previously private, and
all internal uses checked Invalid. Now there is an external caller, so
check Invalid to avoid array OOB underflow.
Fixes PR20420.
llvm-svn: 213816
This is a follow-up to an IRC conversation with Richard last night; __assume
does not evaluate its argument, and so the argument should not contribute to
whether (__assume(e), constant) can be used where a constant is required.
llvm-svn: 213267
This is a follow-up to David's r211677. For the following code,
we would end up referring to 'foo' in the initializer for 'arr',
and then fail to link, because 'foo' is dllimport and needs to be
accessed through the __imp_?foo.
__declspec(dllimport) extern const char foo[];
const char* f() {
static const char* const arr[] = { foo };
return arr[0];
}
Differential Revision: http://reviews.llvm.org/D4299
llvm-svn: 211736
The C++ language requires that the address of a function be the same
across all translation units. To make __declspec(dllimport) useful,
this means that a dllimported function must also obey this rule. MSVC
implements this by dynamically querying the import address table located
in the linked executable. This means that the address of such a
function in C++ is not constant (which violates other rules).
However, the C language has no notion of ODR nor does it permit dynamic
initialization whatsoever. This requires implementations to _not_
dynamically query the import address table and instead utilize a wrapper
function that will be synthesized by the linker which will eventually
query the import address table. The effect this has is, to say the
least, perplexing.
Consider the following C program:
__declspec(dllimport) void f(void);
typedef void (*fp)(void);
static const fp var = &f;
const fp fun() { return &f; }
int main() { return fun() == var; }
MSVC will statically initialize "var" with the address of the wrapper
function and "fun" returns the address of the actual imported function.
This means that "main" will return false!
Note that LLVM's optimizers are strong enough to figure out that "main"
should return true. However, this result is dependent on having
optimizations enabled!
N.B. This change also permits the usage of dllimport declarators inside
of template arguments; they are sufficiently constant for such a
purpose. Add tests to make sure we don't regress here.
llvm-svn: 211677
The address of dllimport functions can be accessed one of two ways:
- Through the IAT which is symbolically referred to with a symbol
starting with __imp_.
- Via the wrapper-function which ends up calling through the __imp_
symbol.
The problem with using the wrapper-function is that it's address will
not compare as equal in all translation units. Specifically, it will
compare unequally with the translation unit which defines the function.
This fixes PR19955.
llvm-svn: 211570
The address of dllimport variables isn't something that can be
meaningfully used in a constexpr context and isn't suitable for
evaluation at load-time. They require loads from memory to properly
evaluate.
This fixes PR19955.
Differential Revision: http://reviews.llvm.org/D4250
llvm-svn: 211568
expression of array-of-unknown-bound type, don't try to complete the array
bound, and return the alignment of the element type rather than 1.
llvm-svn: 210608
Summary:
Gracefully fail to evaluate a constant expression if its type is
unknown, rather than failing an assertion trying to access the type.
Reviewers: klimek
Reviewed By: klimek
CC: chandlerc, cfe-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D3075
llvm-svn: 203950
initialized from a constant expression in C++98, it can be used in
constant expressions, even if it was brace-initialized. Patch by
Rahul Jain!
llvm-svn: 200098
A return type is the declared or deduced part of the function type specified in
the declaration.
A result type is the (potentially adjusted) type of the value of an expression
that calls the function.
Rule of thumb:
* Declarations have return types and parameters.
* Expressions have result types and arguments.
llvm-svn: 200082
Remove UnaryTypeTraitExpr and switch all remaining type trait related handling
over to TypeTraitExpr.
The UTT/BTT/TT enum prefix and evaluation code is retained pending further
cleanup.
This is part of the ongoing work to unify type traits following the removal of
BinaryTypeTraitExpr in r197273.
llvm-svn: 198271
There's nothing special about type traits accepting two arguments.
This commit eliminates BinaryTypeTraitExpr and switches all related handling
over to TypeTraitExpr.
Also fixes a CodeGen failure with variadic type traits appearing in a
non-constant expression.
The BTT/TT prefix and evaluation code is retained as-is for now but will soon
be further cleaned up.
This is part of the ongoing work to unify type traits.
llvm-svn: 197273
With the introduction of explicit address space casts into LLVM, there's
a need to provide a new cast kind the front-end can create for C/OpenCL/CUDA
and code to produce address space casts from those kinds when appropriate.
Patch by Michele Scandale!
llvm-svn: 197036
where we didn't. Extend our constant evaluation for __builtin_strlen to handle
any constant array of chars, not just string literals, to match.
llvm-svn: 194762
bit more robust against future changes. This includes a slight diagnostic
improvement: if we know we're only trying to form a constant expression, take
the first diagnostic which shows the expression is not a constant expression,
rather than preferring the first one which makes the expression unfoldable.
llvm-svn: 194098
LLVM supports applying conversion instructions to vectors of the same number of
elements (fptrunc, fptosi, etc.) but there had been no way for a Clang user to
cause such instructions to be generated when using builtin vector types.
C-style casting on vectors is already defined in terms of bitcasts, and so
cannot be used for these conversions as well (without leading to a very
confusing set of semantics). As a result, this adds a __builtin_convertvector
intrinsic (patterned after the OpenCL __builtin_astype intrinsic). This is
intended to aid the creation of vector intrinsic headers that create generic IR
instead of target-dependent intrinsics (in other words, this is a generic
_mm_cvtepi32_ps). As noted in the documentation, the action of
__builtin_convertvector is defined in terms of the action of a C-style cast on
each vector element.
llvm-svn: 190915
Like any other type, an init list for a vector can have the same type as
the vector itself; handle that case.
<rdar://problem/14990460>
llvm-svn: 190844
I changed the diagnostic printing code because it's probably better
to cut off a digit from DBL_MAX than to print something like
1.300000001 when the user wrote 1.3.
llvm-svn: 189625
This is the same way GenericSelectionExpr works, and it's generally a
more consistent approach.
A large part of this patch is devoted to caching the value of the condition
of a ChooseExpr; it's needed to avoid threading an ASTContext into
IgnoreParens().
Fixes <rdar://problem/14438917>.
llvm-svn: 186738
& operator (ignoring any overloaded operator& for the type). The purpose of
this builtin is for use in std::addressof, to allow it to be made constexpr;
the existing implementation technique (reinterpret_cast to some reference type,
take address, reinterpert_cast back) does not permit this because
reinterpret_cast between reference types is not permitted in a constant
expression in C++11 onwards.
llvm-svn: 186053
Introduce CXXStdInitializerListExpr node, representing the implicit
construction of a std::initializer_list<T> object from its underlying array.
The AST representation of such an expression goes from an InitListExpr with a
flag set, to a CXXStdInitializerListExpr containing a MaterializeTemporaryExpr
containing an InitListExpr (possibly wrapped in a CXXBindTemporaryExpr).
This more detailed representation has several advantages, the most important of
which is that the new MaterializeTemporaryExpr allows us to directly model
lifetime extension of the underlying temporary array. Using that, this patch
*drastically* simplifies the IR generation of this construct, provides IR
generation support for nested global initializer_list objects, fixes several
bugs where the destructors for the underlying array would accidentally not get
invoked, and provides constant expression evaluation support for
std::initializer_list objects.
llvm-svn: 183872
must be initialized by a constant expression (not just a core constant
expression), because we're going to emit it as a global. Core issue for this is
pending.
llvm-svn: 183388
handle temporaries which have been lifetime-extended to static storage duration
within constant expressions. This correctly handles nested lifetime extension
(through reference members of aggregates in aggregate initializers) but
non-constant-expression emission hasn't yet been updated to do the same.
llvm-svn: 183283
materialized temporary with the corresponding MaterializeTemporaryExpr. This is
groundwork for providing C++11's guaranteed static initialization for global
references bound to lifetime-extended temporaries (if the initialization is a
constant expression).
In passing, fix a couple of bugs where some evaluation failures didn't trigger
diagnostics, and a rejects-valid where potential constant expression testing
would assume that it knew the dynamic type of *this and would reject programs
which relied on it being some derived type.
llvm-svn: 183093
* Treat _Atomic(T) as a literal type if T is a literal type.
* Evaluate expressions of this type properly.
* Fix a lurking bug where we built completely bogus ASTs for converting to
_Atomic types in C++ in some cases, caught by the tests for this change.
llvm-svn: 182541
The most common (non-buggy) case are where such objects are used as
return expressions in bool-returning functions or as boolean function
arguments. In those cases I've used (& added if necessary) a named
function to provide the equivalent (or sometimes negative, depending on
convenient wording) test.
DiagnosticBuilder kept its implicit conversion operator owing to the
prevalent use of it in return statements.
One bug was found in ExprConstant.cpp involving a comparison of two
PointerUnions (PointerUnion did not previously have an operator==, so
instead both operands were converted to bool & then compared). A test
is included in test/SemaCXX/constant-expression-cxx1y.cpp for the fix
(adding operator== to PointerUnion in LLVM).
llvm-svn: 181869
inefficient; we perform a linear scan of switch labels to find the one matching
the condition, and then walk the body looking for that label. Both parts should
be straightforward to optimize.
llvm-svn: 181671
object x, x's subobjects can be constructed by constexpr constructor even if
they are of non-literal type, and can be read and written even though they're
not members of a constexpr object or temporary.
llvm-svn: 181506
temporary to an lvalue before taking its address. This removes a weird special
case from the AST representation, and allows the constant expression evaluator
to deal with it without (broken) hacks.
llvm-svn: 180866
statement in constexpr functions. Everything which doesn't require variable
mutation is also allowed as an extension in C++11. 'void' becomes a literal
type to support constexpr functions which return 'void'.
llvm-svn: 180022