summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
Commit message (Collapse)AuthorAgeFilesLines
* Fix __builtin_assume_aligned with too large values.Erich Keane2019-10-101-0/+10
| | | | | | | | | | | | | | Code to handle __builtin_assume_aligned was allowing larger values, but would convert this to unsigned along the way. This patch removes the EmitAssumeAligned overloads that take unsigned to do away with this problem. Additionally, it adds a warning that values greater than 1 <<29 are ignored by LLVM. Differential Revision: https://reviews.llvm.org/D68824 llvm-svn: 374450
* [OPENMP50]Support for 'master taskloop' directive.Alexey Bataev2019-10-102-1/+62
| | | | | | Added full support for master taskloop directive. llvm-svn: 374437
* [sema] Revise `getCurrentMangleNumberContext` interface. NFC.Michael Liao2019-10-103-26/+31
| | | | | | | - Prefer returning mulitple values using a tuple instead of additional pointers/references. llvm-svn: 374274
* Re-land [mangle] Fix mangling where an extra mangle context is required.Reid Kleckner2019-10-101-10/+2
| | | | | | | | | | | This reverts r374268 (git commit c34385d07c7d59447bf836b740f032235391d121) I think I reverted this by mistake, so I'm relanding it. While my bisect found this revision, I think the crashes I'm seeing locally must be environmental. Maybe the version of clang I'm using miscompiles tot clang. llvm-svn: 374269
* Revert [mangle] Fix mangling where an extra mangle context is required.Reid Kleckner2019-10-101-2/+10
| | | | | | | | This reverts r374200 (git commit fd18e94697c987d5f24e25aa4e27adaffff3cce4) Causes crashes just compiling `int main() {}` on my machine. llvm-svn: 374268
* [CUDA][HIP] Fix host/device check with -fopenmpYaxun Liu2019-10-093-127/+155
| | | | | | | | | | | | | | | | CUDA/HIP program may be compiled with -fopenmp. In this case, -fopenmp is only passed to host compilation to take advantages of multi-threads computation. CUDA/HIP and OpenMP both use Sema::DeviceCallGraph to store functions to be analyzed and remove them once they decide the function is sure to be emitted. CUDA/HIP and OpenMP have different functions to determine if a function is sure to be emitted. To check host/device correctly for CUDA/HIP when -fopenmp is enabled, there needs a unified logic to determine whether a function is to be emitted. The logic needs to be aware of both CUDA and OpenMP logic. Differential Revision: https://reviews.llvm.org/D67837 llvm-svn: 374263
* [mangle] Fix mangling where an extra mangle context is required.Michael Liao2019-10-091-10/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: - [Itanium C++ ABI][1], for certain contexts like default parameter and etc., mangling numbering will be local to the particular argument in which it appears. - However, for these cases, the mangle numbering context is allocated per expression evaluation stack entry. That causes, for example, two lambdas defined/used understand the same default parameter are numbered as the same value and, in turn, one of them is not generated at all. - In this patch, an extra mangle numbering context map is maintained in the AST context to map taht extra declaration context to its numbering context. So that, 2 different lambdas defined/used in the same default parameter are numbered differently. [1]: https://itanium-cxx-abi.github.io/cxx-abi/abi.html Reviewers: rsmith, eli.friedman Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D68715 llvm-svn: 374200
* [Sema] Emit diagnostics for uncorrected delayed typos at the end of TUIlya Biryukov2019-10-091-2/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Instead of asserting all typos are corrected in the sema destructor. The sema destructor is not run in the common case of running the compiler with the -disable-free cc1 flag (which is the default in the driver). Having this assertion led to crashes in libclang and clangd, which are not reproducible when running the compiler. Asserting at the end of the TU could be an option, but finding all missing typo correction cases is hard and having worse diagnostics instead of a failing assertion is a better trade-off. For more discussion on this, see: https://lists.llvm.org/pipermail/cfe-dev/2019-July/062872.html Reviewers: sammccall, rsmith Reviewed By: rsmith Subscribers: usaxena95, dgoldman, jkorous, vsapsai, rnk, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D64799 llvm-svn: 374152
* [c++20] P1152R4: warn on any simple-assignment to a volatile lvalueRichard Smith2019-10-092-15/+76
| | | | | | | | | | | | whose value is not ignored. We don't warn on all the cases that are deprecated: specifically, we choose to not warn for now if there are parentheses around the assignment but its value is not actually used. This seems like a more defensible rule, particularly for cases like sizeof(v = a), where the parens are part of the operand rather than the sizeof syntax. llvm-svn: 374135
* [c++20] Implement most of P1152R4.Richard Smith2019-10-093-0/+50
| | | | | | | | | | | | | | Diagnose some now-deprecated uses of volatile types: * as function parameter types and return types * as the type of a structured binding declaration * as the type of the lvalue operand of an increment / decrement / compound assignment operator This does not implement a check for the deprecation of simple assignments whose results are used; that check requires somewhat more complexity and will be addressed separately. llvm-svn: 374133
* [OPENMP50]Multiple vendors in vendor context must be treated as logicalAlexey Bataev2019-10-082-5/+7
| | | | | | | | | | | | | and of vendors, not or. If several vendors are provided in the same vendor context trait, the context shall match only if all vendors are matching, not one of them. This is per OpenMP 5.0, 2.3.3 Matching and Scoring Context Selectors, all selectors in the construct, device, and implementation sets of the context selector appear in the corresponding trait set of the OpenMP context. llvm-svn: 374107
* [BPF] do compile-once run-everywhere relocation for bitfieldsYonghong Song2019-10-081-0/+39
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A bpf specific clang intrinsic is introduced: u32 __builtin_preserve_field_info(member_access, info_kind) Depending on info_kind, different information will be returned to the program. A relocation is also recorded for this builtin so that bpf loader can patch the instruction on the target host. This clang intrinsic is used to get certain information to facilitate struct/union member relocations. The offset relocation is extended by 4 bytes to include relocation kind. Currently supported relocation kinds are enum { FIELD_BYTE_OFFSET = 0, FIELD_BYTE_SIZE, FIELD_EXISTENCE, FIELD_SIGNEDNESS, FIELD_LSHIFT_U64, FIELD_RSHIFT_U64, }; for __builtin_preserve_field_info. The old access offset relocation is covered by FIELD_BYTE_OFFSET = 0. An example: struct s { int a; int b1:9; int b2:4; }; enum { FIELD_BYTE_OFFSET = 0, FIELD_BYTE_SIZE, FIELD_EXISTENCE, FIELD_SIGNEDNESS, FIELD_LSHIFT_U64, FIELD_RSHIFT_U64, }; void bpf_probe_read(void *, unsigned, const void *); int field_read(struct s *arg) { unsigned long long ull = 0; unsigned offset = __builtin_preserve_field_info(arg->b2, FIELD_BYTE_OFFSET); unsigned size = __builtin_preserve_field_info(arg->b2, FIELD_BYTE_SIZE); #ifdef USE_PROBE_READ bpf_probe_read(&ull, size, (const void *)arg + offset); unsigned lshift = __builtin_preserve_field_info(arg->b2, FIELD_LSHIFT_U64); #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ lshift = lshift + (size << 3) - 64; #endif #else switch(size) { case 1: ull = *(unsigned char *)((void *)arg + offset); break; case 2: ull = *(unsigned short *)((void *)arg + offset); break; case 4: ull = *(unsigned int *)((void *)arg + offset); break; case 8: ull = *(unsigned long long *)((void *)arg + offset); break; } unsigned lshift = __builtin_preserve_field_info(arg->b2, FIELD_LSHIFT_U64); #endif ull <<= lshift; if (__builtin_preserve_field_info(arg->b2, FIELD_SIGNEDNESS)) return (long long)ull >> __builtin_preserve_field_info(arg->b2, FIELD_RSHIFT_U64); return ull >> __builtin_preserve_field_info(arg->b2, FIELD_RSHIFT_U64); } There is a minor overhead for bpf_probe_read() on big endian. The code and relocation generated for field_read where bpf_probe_read() is used to access argument data on little endian mode: r3 = r1 r1 = 0 r1 = 4 <=== relocation (FIELD_BYTE_OFFSET) r3 += r1 r1 = r10 r1 += -8 r2 = 4 <=== relocation (FIELD_BYTE_SIZE) call bpf_probe_read r2 = 51 <=== relocation (FIELD_LSHIFT_U64) r1 = *(u64 *)(r10 - 8) r1 <<= r2 r2 = 60 <=== relocation (FIELD_RSHIFT_U64) r0 = r1 r0 >>= r2 r3 = 1 <=== relocation (FIELD_SIGNEDNESS) if r3 == 0 goto LBB0_2 r1 s>>= r2 r0 = r1 LBB0_2: exit Compare to the above code between relocations FIELD_LSHIFT_U64 and FIELD_LSHIFT_U64, the code with big endian mode has four more instructions. r1 = 41 <=== relocation (FIELD_LSHIFT_U64) r6 += r1 r6 += -64 r6 <<= 32 r6 >>= 32 r1 = *(u64 *)(r10 - 8) r1 <<= r6 r2 = 60 <=== relocation (FIELD_RSHIFT_U64) The code and relocation generated when using direct load. r2 = 0 r3 = 4 r4 = 4 if r4 s> 3 goto LBB0_3 if r4 == 1 goto LBB0_5 if r4 == 2 goto LBB0_6 goto LBB0_9 LBB0_6: # %sw.bb1 r1 += r3 r2 = *(u16 *)(r1 + 0) goto LBB0_9 LBB0_3: # %entry if r4 == 4 goto LBB0_7 if r4 == 8 goto LBB0_8 goto LBB0_9 LBB0_8: # %sw.bb9 r1 += r3 r2 = *(u64 *)(r1 + 0) goto LBB0_9 LBB0_5: # %sw.bb r1 += r3 r2 = *(u8 *)(r1 + 0) goto LBB0_9 LBB0_7: # %sw.bb5 r1 += r3 r2 = *(u32 *)(r1 + 0) LBB0_9: # %sw.epilog r1 = 51 r2 <<= r1 r1 = 60 r0 = r2 r0 >>= r1 r3 = 1 if r3 == 0 goto LBB0_11 r2 s>>= r1 r0 = r2 LBB0_11: # %sw.epilog exit Considering verifier is able to do limited constant propogation following branches. The following is the code actually traversed. r2 = 0 r3 = 4 <=== relocation r4 = 4 <=== relocation if r4 s> 3 goto LBB0_3 LBB0_3: # %entry if r4 == 4 goto LBB0_7 LBB0_7: # %sw.bb5 r1 += r3 r2 = *(u32 *)(r1 + 0) LBB0_9: # %sw.epilog r1 = 51 <=== relocation r2 <<= r1 r1 = 60 <=== relocation r0 = r2 r0 >>= r1 r3 = 1 if r3 == 0 goto LBB0_11 r2 s>>= r1 r0 = r2 LBB0_11: # %sw.epilog exit For native load case, the load size is calculated to be the same as the size of load width LLVM otherwise used to load the value which is then used to extract the bitfield value. Differential Revision: https://reviews.llvm.org/D67980 llvm-svn: 374099
* [OPENMP50]Allow functions in declare variant directive to have differentAlexey Bataev2019-10-082-4/+6
| | | | | | | | | | C linkage. After some discussion with OpenMP developers, it was decided that the functions with the different C linkage can be used in declare variant directive. llvm-svn: 374057
* [Diagnostics] Silence -Wsizeof-array-div for character buffersJames Clarke2019-10-081-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Character buffers are sometimes used to represent a pool of memory that contains non-character objects, due to them being synonymous with a stream of bytes on almost all modern architectures. Often, when interacting with hardware devices, byte buffers are therefore used as an intermediary and so we can end Character buffers are sometimes used to represent a pool of memory that contains non-character objects, due to them being synonymous with a stream of bytes on almost all modern architectures. Often, when interacting with hardware devices, byte buffers are therefore used as an intermediary and so we can end up generating lots of false-positives. Moreover, due to the ability of character pointers to alias non-character pointers, the strict aliasing violations that would generally be implied by the calculations caught by the warning (if the calculation itself is in fact correct) do not apply here, and so although the length calculation may be wrong, that is the only possible issue. Reviewers: rsmith, xbolva00, thakis Reviewed By: xbolva00, thakis Subscribers: thakis, lebedev.ri, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D68526 llvm-svn: 374035
* [Diagnostics] Emit better -Wbool-operation's warning message if we known ↵David Bolvansky2019-10-072-4/+7
| | | | | | that the result is always true llvm-svn: 373973
* [OPENMP50]Treat range-based for as canonical loop.Alexey Bataev2019-10-072-11/+43
| | | | | | | According to OpenMP 5.0, range-based for is also considered as a canonical form of loops. llvm-svn: 373939
* Sema - silence static analyzer getAs<> null dereference warnings. NFCI.Simon Pilgrim2019-10-074-11/+11
| | | | | | The static analyzer is warning about potential null dereferences, but in these cases we should be able to use castAs<> directly and if not assert will fire for us. llvm-svn: 373911
* Fix behavior of __builtin_bit_cast when the From and To types are theRichard Smith2019-10-071-5/+0
| | | | | | | | | | same. We were missing the lvalue-to-rvalue conversion entirely in this case, and in fact still need the full CK_LValueToRValueBitCast conversion to perform a load with no TBAA. llvm-svn: 373874
* Implements CWG 1601 in [over.ics.rank/4.2]Richard Smith2019-10-061-0/+42
| | | | | | | | | | | | | | | | | | | Summary: The overload resolution for enums with a fixed underlying type has changed in the C++14 standard. This patch implements the new rule. Patch by Mark de Wever! Reviewers: rsmith Reviewed By: rsmith Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D65695 llvm-svn: 373866
* [Sema] Avoids an assertion failure when an invalid conversion declaration is ↵Richard Smith2019-10-061-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | used Summary: When using a user-defined conversion function template with a deduced return type the compiler gives a set of warnings: ``` bug.cc:252:44: error: cannot specify any part of a return type in the declaration of a conversion function; use an alias template to declare a conversion to 'auto (Ts &&...) const' template <typename... Ts> operator auto()(Ts &&... xs) const; ^~~~~~~~~~~~~~~~~~~ bug.cc:252:29: error: conversion function cannot convert to a function type template <typename... Ts> operator auto()(Ts &&... xs) const; ^ error: pointer to function type cannot have 'const' qualifier ``` after which it triggers an assertion failure. It seems the last error is incorrect and doesn't have any location information. This patch stops the compilation after the second warning. Fixes bug 31422. Patch by Mark de Wever! Reviewers: rsmith Reviewed By: rsmith Subscribers: bbannier, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D64820 llvm-svn: 373862
* [Diagnostics] Highlight expr's source range for -Wbool-operationDavid Bolvansky2019-10-051-0/+1
| | | | | | Warning message looks better; and GCC adds it too. llvm-svn: 373828
* SemaTemplate - silence static analyzer getAs<> null dereference warnings. NFCI.Simon Pilgrim2019-10-051-4/+4
| | | | | | The static analyzer is warning about potential null dereferences, but we should be able to use castAs<> directly and if not assert will fire for us. llvm-svn: 373827
* TreeTransform - silence static analyzer getAs<> null dereference warnings. NFCI.Simon Pilgrim2019-10-051-4/+4
| | | | | | The static analyzer is warning about potential null dereferences, but we should be able to use castAs<> directly and if not assert will fire for us. llvm-svn: 373826
* Remove redundant !HasDependentValue check. NFCI.Simon Pilgrim2019-10-051-1/+1
| | | | | | Fixes cppcheck warning. llvm-svn: 373825
* SemaStmt - silence static analyzer getAs<> null dereference warnings. NFCI.Simon Pilgrim2019-10-051-5/+5
| | | | | | The static analyzer is warning about potential null dereferences, but we should be able to use castAs<> directly and if not assert will fire for us. llvm-svn: 373824
* [Diagnostics] Use Expr::isKnownToHaveBooleanValue() to check bitwise ↵David Bolvansky2019-10-051-1/+1
| | | | | | | | negation of bool in languages without a bool type Thanks for this advice, Richard Trieu! llvm-svn: 373817
* [clang] fix a typo from r372531Yuanfang Chen2019-10-041-1/+1
| | | | | | | | | | | | Reviewers: xbolva00 Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D68482 llvm-svn: 373792
* [Sema] Split out -Wformat-type-confusion from -Wformat-pedanticErik Pilkington2019-10-041-15/+33
| | | | | | | | | The warnings now in -Wformat-type-confusion don't align with how we interpret 'pedantic' in clang, and don't belong in -pedantic. Differential revision: https://reviews.llvm.org/D67775 llvm-svn: 373774
* SemaDeclAttr - silence static analyzer getAs<> null dereference warnings. NFCI.Simon Pilgrim2019-10-041-4/+4
| | | | | | The static analyzer is warning about potential null dereferences, but in these cases we should be able to use castAs<> directly and if not assert will fire for us. llvm-svn: 373753
* [CodeComplete] Ensure object is the same in compareOverloads()Ilya Biryukov2019-10-041-0/+3
| | | | | | | | | | | | | | | | | | Summary: This fixes a regression that led to size() not being available in clangd when completing 'deque().^' and using libc++. Reviewers: sammccall Reviewed By: sammccall Subscribers: jkorous, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D68335 llvm-svn: 373710
* Properly handle instantiation-dependent array bounds.Richard Smith2019-10-049-33/+46
| | | | | | | | | We previously failed to treat an array with an instantiation-dependent but not value-dependent bound as being an instantiation-dependent type. We now track the array bound expression as part of a constant array type if it's an instantiation-dependent expression. llvm-svn: 373685
* Check for qualified function types after substituting into the operandRichard Smith2019-10-032-1/+16
| | | | | | | | | | of 'typeid'. This is a rare place where it's valid for a function type to be substituted but not valid for a qualified function type to be substituted, so needs a special check. llvm-svn: 373648
* PR43547: substitute into the type of a non-type template parameter ifRichard Smith2019-10-031-3/+1
| | | | | | | | it's instantiation-dependent, even if it's not dependent. There might be a SFINAE check in the parameter type. llvm-svn: 373643
* [Diagnostics] Bitwise negation of a boolean expr always evaluates to true; ↵David Bolvansky2019-10-031-1/+3
| | | | | | | | | warn with -Wbool-operation Requested here: http://lists.llvm.org/pipermail/cfe-dev/2019-October/063452.html llvm-svn: 373614
* Silence static analyzer getAs<RecordType> null dereference warnings. NFCI.Simon Pilgrim2019-10-039-16/+17
| | | | | | The static analyzer is warning about potential null dereferences, but in these cases we should be able to use castAs<RecordType> directly and if not assert will fire for us. llvm-svn: 373584
* [OPENMP50]Add parsing/sema analysis for declare variant score.Alexey Bataev2019-10-022-3/+23
| | | | | | | | Context selectors may include optional score clause in format `score(<expr>):`, where `<expr>` must be a constant integer expression. Added parsing/sema analysis only. llvm-svn: 373502
* Silence static analyzer getAs<VectorType> null dereference warnings. NFCI.Simon Pilgrim2019-10-021-5/+5
| | | | | | The static analyzer is warning about potential null dereferences, but in these cases we should be able to use castAs<VectorType> directly and if not assert will fire for us. llvm-svn: 373478
* SemaOverload - silence static analyzer getAs<> null dereference warnings. NFCI.Simon Pilgrim2019-10-021-25/+25
| | | | | | The static analyzer is warning about potential null dereferences, but in these cases we should be able to use castAs<> directly and if not assert will fire for us. llvm-svn: 373475
* SemaInit - silence static analyzer getAs<> null dereference warnings. NFCI.Simon Pilgrim2019-10-021-16/+16
| | | | | | The static analyzer is warning about potential null dereferences, but in these cases we should be able to use castAs<> directly and if not assert will fire for us. llvm-svn: 373474
* Rename TypeNodes.def to TypeNodes.inc for consistency across allJohn McCall2019-10-024-5/+5
| | | | | | | | our autogenerated files. NFC. As requested by Nico Weber. llvm-svn: 373425
* Revert r368237 - Update fix-it hints for std::move warnings.Richard Trieu2019-10-021-27/+24
| | | | | | | | r368237 attempted to improve fix-its for move warnings, but introduced some regressions to -Wpessimizing-move. Revert that change and add the missing test cases to the pessimizing move test to prevent future regressions. llvm-svn: 373421
* [OPENMP]Fix PR43516: Compiler crash with collapse(2) on non-rectangularAlexey Bataev2019-10-011-5/+13
| | | | | | | | | loop. Missed check if the condition is also dependent when building final expressions for the collapsed loop directives. llvm-svn: 373348
* [clang] Make handling of unnamed template params similar to function paramsKadir Cetinkaya2019-10-011-9/+4
| | | | | | | | | | | | | | | | | | | | | Summary: Clang uses the location identifier should be inserted for declarator decls when a decl is unnamed. But for type template and template template paramaters it uses the location of "typename/class" keyword, which makes it hard for tooling to insert/change parameter names. This change tries to unify these two cases by making template parameter parsing and sourcerange operations similar to function params/declarator decls. Reviewers: ilya-biryukov Subscribers: arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D68143 llvm-svn: 373340
* [Diagnostics] Warn if enumeration type mismatch in conditional expressionDavid Bolvansky2019-09-301-0/+28
| | | | | | | | | | | | | | | | | | Summary: - Useful warning - GCC compatibility (GCC warns in C++ mode) Reviewers: rsmith, aaron.ballman Reviewed By: aaron.ballman Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D67919 llvm-svn: 373252
* [OPENMP50]Do not emit warning for the function with the currentlyAlexey Bataev2019-09-301-2/+3
| | | | | | | | | defined body. If the function is currently defined, we should not emit a warning that it might be emitted already because it was not really emitted. llvm-svn: 373243
* [OPENMP] Fix comment, NFC.Alexey Bataev2019-09-301-1/+1
| | | | llvm-svn: 373210
* Don't crash if a variable with a constexpr destructor has aRichard Smith2019-09-291-1/+2
| | | | | | value-dependent initializer. llvm-svn: 373173
* For P0784R7: compute whether a variable has constant destruction if itRichard Smith2019-09-291-0/+13
| | | | | | | | | | has a constexpr destructor. For constexpr variables, reject if the variable does not have constant destruction. In all cases, do not emit runtime calls to the destructor for variables with constant destruction. llvm-svn: 373159
* SemaExpr - silence static analyzer getAs<> null dereference warnings. NFCI.Simon Pilgrim2019-09-281-30/+30
| | | | | | The static analyzer is warning about potential null dereferences, but in these cases we should be able to use castAs<> directly and if not assert will fire for us. llvm-svn: 373150
* [clang] [AST] Treat "inline gnu_inline" the same way as "extern inline ↵Martin Storsjo2019-09-271-0/+3
| | | | | | | | | | | | | | | | | gnu_inline" in C++ mode This matches how GCC handles it, see e.g. https://gcc.godbolt.org/z/HPplnl. GCC documents the gnu_inline attribute with "In C++, this attribute does not depend on extern in any way, but it still requires the inline keyword to enable its special behavior." The previous behaviour of gnu_inline in C++, without the extern keyword, can be traced back to the original commit that added support for gnu_inline, SVN r69045. Differential Revision: https://reviews.llvm.org/D67414 llvm-svn: 373078
OpenPOWER on IntegriCloud