[PATCH] D41316: [libcxx] Allow random_device to be built optionally

2018-02-09 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added a comment.

ping?


Repository:
  rCXX libc++

https://reviews.llvm.org/D41316



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41316: [libcxx] Allow random_device to be built optionally

2018-02-12 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz updated this revision to Diff 133977.
weimingz added a comment.

Modified the random generator in filesystem_test_helper to use 
high_resolution_clock as seed.


https://reviews.llvm.org/D41316

Files:
  CMakeLists.txt
  include/__config_site.in
  include/random
  src/random.cpp
  test/std/numerics/rand/rand.device/lit.local.cfg
  test/support/filesystem_test_helper.hpp

Index: test/support/filesystem_test_helper.hpp
===
--- test/support/filesystem_test_helper.hpp
+++ test/support/filesystem_test_helper.hpp
@@ -107,7 +107,10 @@
 struct scoped_test_env
 {
 scoped_test_env() : test_root(random_env_path())
-{ fs_helper_run(fs_make_cmd("init_test_directory", test_root)); }
+{ fs_helper_run(fs_make_cmd("init_test_directory", test_root));
+  auto now = std::chrono::high_resolution_clock::now();
+  srand(now.time_since_epoch().count());
+}
 
 ~scoped_test_env()
 { fs_helper_run(fs_make_cmd("destroy_test_directory", test_root)); }
@@ -184,9 +187,7 @@
 }
 
 static char random_hex_char() {
-static std::mt19937 rd { std::random_device{}() };
-static std::uniform_int_distribution mrand{0, 15};
-return to_hex( mrand(rd) );
+return to_hex(rand() & 0xF);
 }
 
 static std::string unique_path_suffix() {
Index: test/std/numerics/rand/rand.device/lit.local.cfg
===
--- /dev/null
+++ test/std/numerics/rand/rand.device/lit.local.cfg
@@ -0,0 +1,3 @@
+# Disable all of the random device tests if the correct feature is not available.
+if 'libcpp-has-no-random-device' in config.available_features:
+  config.unsupported = True
Index: src/random.cpp
===
--- src/random.cpp
+++ src/random.cpp
@@ -8,6 +8,7 @@
 //===--===//
 
 #include <__config>
+#ifndef _LIBCPP_HAS_NO_RANDOM_DEVICE
 
 #if defined(_LIBCPP_USING_WIN32_RANDOM)
 // Must be defined before including stdlib.h to enable rand_s().
@@ -177,3 +178,4 @@
 }
 
 _LIBCPP_END_NAMESPACE_STD
+#endif // _LIBCPP_HAS_NO_RANDOM_DEVICE
Index: include/random
===
--- include/random
+++ include/random
@@ -3476,6 +3476,7 @@
 
 typedef shuffle_order_engine knuth_b;
 
+#ifndef _LIBCPP_HAS_NO_RANDOM_DEVICE
 // random_device
 
 class _LIBCPP_TYPE_VIS random_device
@@ -3511,6 +3512,7 @@
 random_device(const random_device&); // = delete;
 random_device& operator=(const random_device&); // = delete;
 };
+#endif // _LIBCPP_HAS_NO_RANDOM_DEVICE
 
 // seed_seq
 
Index: include/__config_site.in
===
--- include/__config_site.in
+++ include/__config_site.in
@@ -20,6 +20,7 @@
 #cmakedefine _LIBCPP_HAS_NO_THREADS
 #cmakedefine _LIBCPP_HAS_NO_MONOTONIC_CLOCK
 #cmakedefine _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
+#cmakedefine _LIBCPP_HAS_NO_RANDOM_DEVICE
 #cmakedefine _LIBCPP_HAS_MUSL_LIBC
 #cmakedefine _LIBCPP_HAS_THREAD_API_PTHREAD
 #cmakedefine _LIBCPP_HAS_THREAD_API_EXTERNAL
Index: CMakeLists.txt
===
--- CMakeLists.txt
+++ CMakeLists.txt
@@ -71,6 +71,7 @@
 option(LIBCXX_ENABLE_FILESYSTEM "Build filesystem as part of libc++experimental.a"
 ${ENABLE_FILESYSTEM_DEFAULT})
 option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})
+option(LIBCXX_ENABLE_RANDOM_DEVICE "Build random_device class" ON)
 
 # Benchmark options ---
 option(LIBCXX_INCLUDE_BENCHMARKS "Build the libc++ benchmarks and their dependancies" ON)
@@ -629,6 +630,7 @@
 config_define_if_not(LIBCXX_ENABLE_THREADS _LIBCPP_HAS_NO_THREADS)
 config_define_if_not(LIBCXX_ENABLE_MONOTONIC_CLOCK _LIBCPP_HAS_NO_MONOTONIC_CLOCK)
 config_define_if_not(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS)
+config_define_if_not(LIBCXX_ENABLE_RANDOM_DEVICE _LIBCPP_HAS_NO_RANDOM_DEVICE)
 
 config_define_if(LIBCXX_HAS_PTHREAD_API _LIBCPP_HAS_THREAD_API_PTHREAD)
 config_define_if(LIBCXX_HAS_EXTERNAL_THREAD_API _LIBCPP_HAS_THREAD_API_EXTERNAL)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41316: [libcxx] Allow random_device to be built optionally

2018-02-23 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added a comment.

ping?


https://reviews.llvm.org/D41316



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41316: [libcxx] Allow random_device to be built optionally

2017-12-15 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz created this revision.
weimingz added reviewers: EricWF, bcain.
Herald added a subscriber: mgorny.

The default implementation of random_device uses /dev/urandom, which may not be 
available to systems like bare-metals.

This patch adds a CMake option "LIBCXX_ENABLE_RANDOM_DEVICE" to control the 
build. Default is On.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41316

Files:
  CMakeLists.txt
  include/__config_site.in
  include/random
  src/random.cpp


Index: src/random.cpp
===
--- src/random.cpp
+++ src/random.cpp
@@ -8,6 +8,7 @@
 
//===--===//
 
 #include <__config>
+#ifndef _LIBCPP_HAS_NO_RANDOM_DEVICE
 
 #if defined(_LIBCPP_USING_WIN32_RANDOM)
 // Must be defined before including stdlib.h to enable rand_s().
@@ -177,3 +178,4 @@
 }
 
 _LIBCPP_END_NAMESPACE_STD
+#endif // _LIBCPP_HAS_NO_RANDOM_DEVICE
Index: include/random
===
--- include/random
+++ include/random
@@ -3476,6 +3476,7 @@
 
 typedef shuffle_order_engine 
knuth_b;
 
+#ifndef _LIBCPP_HAS_NO_RANDOM_DEVICE
 // random_device
 
 class _LIBCPP_TYPE_VIS random_device
@@ -3511,6 +3512,7 @@
 random_device(const random_device&); // = delete;
 random_device& operator=(const random_device&); // = delete;
 };
+#endif // _LIBCPP_HAS_NO_RANDOM_DEVICE
 
 // seed_seq
 
Index: include/__config_site.in
===
--- include/__config_site.in
+++ include/__config_site.in
@@ -20,6 +20,7 @@
 #cmakedefine _LIBCPP_HAS_NO_THREADS
 #cmakedefine _LIBCPP_HAS_NO_MONOTONIC_CLOCK
 #cmakedefine _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
+#cmakedefine _LIBCPP_HAS_NO_RANDOM_DEVICE
 #cmakedefine _LIBCPP_HAS_MUSL_LIBC
 #cmakedefine _LIBCPP_HAS_THREAD_API_PTHREAD
 #cmakedefine _LIBCPP_HAS_THREAD_API_EXTERNAL
Index: CMakeLists.txt
===
--- CMakeLists.txt
+++ CMakeLists.txt
@@ -71,6 +71,7 @@
 option(LIBCXX_ENABLE_FILESYSTEM "Build filesystem as part of 
libc++experimental.a"
 ${ENABLE_FILESYSTEM_DEFAULT})
 option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})
+option(LIBCXX_ENABLE_RANDOM_DEVICE "Build random_device class" On)
 
 # Benchmark options ---
 option(LIBCXX_INCLUDE_BENCHMARKS "Build the libc++ benchmarks and their 
dependancies" ON)
@@ -610,6 +611,7 @@
 config_define_if_not(LIBCXX_ENABLE_THREADS _LIBCPP_HAS_NO_THREADS)
 config_define_if_not(LIBCXX_ENABLE_MONOTONIC_CLOCK 
_LIBCPP_HAS_NO_MONOTONIC_CLOCK)
 config_define_if_not(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS 
_LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS)
+config_define_if_not(LIBCXX_ENABLE_RANDOM_DEVICE _LIBCPP_HAS_NO_RANDOM_DEVICE)
 
 config_define_if(LIBCXX_HAS_PTHREAD_API _LIBCPP_HAS_THREAD_API_PTHREAD)
 config_define_if(LIBCXX_HAS_EXTERNAL_THREAD_API 
_LIBCPP_HAS_THREAD_API_EXTERNAL)


Index: src/random.cpp
===
--- src/random.cpp
+++ src/random.cpp
@@ -8,6 +8,7 @@
 //===--===//
 
 #include <__config>
+#ifndef _LIBCPP_HAS_NO_RANDOM_DEVICE
 
 #if defined(_LIBCPP_USING_WIN32_RANDOM)
 // Must be defined before including stdlib.h to enable rand_s().
@@ -177,3 +178,4 @@
 }
 
 _LIBCPP_END_NAMESPACE_STD
+#endif // _LIBCPP_HAS_NO_RANDOM_DEVICE
Index: include/random
===
--- include/random
+++ include/random
@@ -3476,6 +3476,7 @@
 
 typedef shuffle_order_engine knuth_b;
 
+#ifndef _LIBCPP_HAS_NO_RANDOM_DEVICE
 // random_device
 
 class _LIBCPP_TYPE_VIS random_device
@@ -3511,6 +3512,7 @@
 random_device(const random_device&); // = delete;
 random_device& operator=(const random_device&); // = delete;
 };
+#endif // _LIBCPP_HAS_NO_RANDOM_DEVICE
 
 // seed_seq
 
Index: include/__config_site.in
===
--- include/__config_site.in
+++ include/__config_site.in
@@ -20,6 +20,7 @@
 #cmakedefine _LIBCPP_HAS_NO_THREADS
 #cmakedefine _LIBCPP_HAS_NO_MONOTONIC_CLOCK
 #cmakedefine _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
+#cmakedefine _LIBCPP_HAS_NO_RANDOM_DEVICE
 #cmakedefine _LIBCPP_HAS_MUSL_LIBC
 #cmakedefine _LIBCPP_HAS_THREAD_API_PTHREAD
 #cmakedefine _LIBCPP_HAS_THREAD_API_EXTERNAL
Index: CMakeLists.txt
===
--- CMakeLists.txt
+++ CMakeLists.txt
@@ -71,6 +71,7 @@
 option(LIBCXX_ENABLE_FILESYSTEM "Build filesystem as part of libc++experimental.a"
 ${ENABLE_FILESYSTEM_DEFAULT})
 option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})
+option(LIBCXX_ENABLE_RANDOM_DEVICE "Build random_device class" On)
 
 # Benchmark options 

[PATCH] D41316: [libcxx] Allow random_device to be built optionally

2017-12-16 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added a comment.

Does it make sense to provide an implementation based on C99 rand?
like 
#ifdef _LIBCPP_USING_C99_RANDOM

  srand(0), rand() 


Repository:
  rCXX libc++

https://reviews.llvm.org/D41316



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41316: [libcxx] Allow random_device to be built optionally

2018-01-02 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added a comment.

Should we go with current patch? or provide a srand/rand based implementation 
as an option?


Repository:
  rCXX libc++

https://reviews.llvm.org/D41316



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41316: [libcxx] Allow random_device to be built optionally

2018-01-05 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added a comment.

We can wrap the random_device as a minstd_rand, a linear congruential enginer 
that a lot of C lib uses for rand().
However based on documentation, we should just provides dummy implementation 
which throws an exception in the constructor of random_device [1,2]
But compared with run-time exception, a link time error is better if we simply 
skip the implementation. Any thoughts?

[1]

> explicit random_device(const string& token = implementation-defined );
>  ...
>  Throws: A value of an implementation-defined type derived from exception if 
> the random_device could not be initialized.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf section 
29.6.6  Class random_device (page 1082)

[2]

> Notice that random devices may not always be available to produce random 
> numbers (and in some systems, they may even never be available). This is 
> signaled by throwing an exception derived from the standard exception or when 
> a number is requested with operator()

http://www.cplusplus.com/reference/random/random_device/


Repository:
  rCXX libc++

https://reviews.llvm.org/D41316



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41316: [libcxx] Allow random_device to be built optionally

2018-01-11 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added a comment.

any suggestions?


Repository:
  rCXX libc++

https://reviews.llvm.org/D41316



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41316: [libcxx] Allow random_device to be built optionally

2018-03-05 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added a comment.

gentle ping?


https://reviews.llvm.org/D41316



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35235: [libc++] Replace __sync_* functions with __libcpp_atomic_* functions

2017-09-19 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz updated this revision to Diff 115891.
weimingz added a comment.

Moved the inclusion from stdexcept.cpp into refstring.h

For exception.cpp and new.cpp, I think it's better to keep the inclusion there. 
Those files include  new_handler_fallback.ipp, exception_fallback.ipp, which 
need the header file. Including it in those .ipp requires relative path as 
"../../include/atomic_support.h" and I tried to avoid that.


https://reviews.llvm.org/D35235

Files:
  src/exception.cpp
  src/include/atomic_support.h
  src/include/refstring.h
  src/locale.cpp
  src/new.cpp
  src/support/runtime/exception_fallback.ipp
  src/support/runtime/new_handler_fallback.ipp

Index: src/support/runtime/new_handler_fallback.ipp
===
--- src/support/runtime/new_handler_fallback.ipp
+++ src/support/runtime/new_handler_fallback.ipp
@@ -15,13 +15,13 @@
 new_handler
 set_new_handler(new_handler handler) _NOEXCEPT
 {
-return __sync_lock_test_and_set(&__new_handler, handler);
+return __libcpp_atomic_exchange(&__new_handler, handler);
 }
 
 new_handler
 get_new_handler() _NOEXCEPT
 {
-return __sync_fetch_and_add(&__new_handler, nullptr);
+return __libcpp_atomic_load(&__new_handler);
 }
 
 } // namespace std
Index: src/support/runtime/exception_fallback.ipp
===
--- src/support/runtime/exception_fallback.ipp
+++ src/support/runtime/exception_fallback.ipp
@@ -20,13 +20,13 @@
 unexpected_handler
 set_unexpected(unexpected_handler func) _NOEXCEPT
 {
-  return __sync_lock_test_and_set(&__unexpected_handler, func);
+  return __libcpp_atomic_exchange(&__unexpected_handler, func);
 }
 
 unexpected_handler
 get_unexpected() _NOEXCEPT
 {
-  return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0);
+  return __libcpp_atomic_load(&__unexpected_handler);
 
 }
 
@@ -41,14 +41,13 @@
 terminate_handler
 set_terminate(terminate_handler func) _NOEXCEPT
 {
-  return __sync_lock_test_and_set(&__terminate_handler, func);
+  return __libcpp_atomic_exchange(&__terminate_handler, func);
 }
 
 terminate_handler
 get_terminate() _NOEXCEPT
 {
-  return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0);
-
+  return __libcpp_atomic_load(&__terminate_handler);
 }
 
 #ifndef __EMSCRIPTEN__ // We provide this in JS
Index: src/new.cpp
===
--- src/new.cpp
+++ src/new.cpp
@@ -12,6 +12,7 @@
 #include 
 
 #include "new"
+#include "include/atomic_support.h"
 
 #if defined(_LIBCPP_ABI_MICROSOFT)
 // nothing todo
Index: src/locale.cpp
===
--- src/locale.cpp
+++ src/locale.cpp
@@ -36,6 +36,7 @@
 #endif
 #include 
 #include 
+#include "include/atomic_support.h"
 #include "__undef_macros"
 
 // On Linux, wint_t and wchar_t have different signed-ness, and this causes
@@ -667,7 +668,7 @@
 void
 locale::id::__init()
 {
-__id_ = __sync_add_and_fetch(&__next_id, 1);
+__id_ = __libcpp_atomic_add(&__next_id, 1);
 }
 
 // template <> class collate_byname
Index: src/include/refstring.h
===
--- src/include/refstring.h
+++ src/include/refstring.h
@@ -18,6 +18,7 @@
 #include 
 #include 
 #endif
+#include "atomic_support.h"
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -83,19 +84,19 @@
 : __imp_(s.__imp_)
 {
 if (__uses_refcount())
-__sync_add_and_fetch(&rep_from_data(__imp_)->count, 1);
+__libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);
 }
 
 inline
 __libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring const& s) _NOEXCEPT {
 bool adjust_old_count = __uses_refcount();
 struct _Rep_base *old_rep = rep_from_data(__imp_);
 __imp_ = s.__imp_;
 if (__uses_refcount())
-__sync_add_and_fetch(&rep_from_data(__imp_)->count, 1);
+__libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);
 if (adjust_old_count)
 {
-if (__sync_add_and_fetch(&old_rep->count, count_t(-1)) < 0)
+if (__libcpp_atomic_add(&old_rep->count, count_t(-1)) < 0)
 {
 ::operator delete(old_rep);
 }
@@ -107,7 +108,7 @@
 __libcpp_refstring::~__libcpp_refstring() {
 if (__uses_refcount()) {
 _Rep_base* rep = rep_from_data(__imp_);
-if (__sync_add_and_fetch(&rep->count, count_t(-1)) < 0) {
+if (__libcpp_atomic_add(&rep->count, count_t(-1)) < 0) {
 ::operator delete(rep);
 }
 }
Index: src/include/atomic_support.h
===
--- src/include/atomic_support.h
+++ src/include/atomic_support.h
@@ -16,6 +16,7 @@
 #if defined(__clang__) && __has_builtin(__atomic_load_n) \
&& __has_builtin(__atomic_store_n)\
&& __has_builtin(__atomic_add_fetch)  \
+   && __

[PATCH] D35235: [libc++] Replace __sync_* functions with __libcpp_atomic_* functions

2017-09-19 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz updated this revision to Diff 115918.
weimingz added a comment.

minor change


https://reviews.llvm.org/D35235

Files:
  src/exception.cpp
  src/include/atomic_support.h
  src/include/refstring.h
  src/locale.cpp
  src/new.cpp
  src/support/runtime/exception_fallback.ipp
  src/support/runtime/new_handler_fallback.ipp

Index: src/support/runtime/new_handler_fallback.ipp
===
--- src/support/runtime/new_handler_fallback.ipp
+++ src/support/runtime/new_handler_fallback.ipp
@@ -15,13 +15,13 @@
 new_handler
 set_new_handler(new_handler handler) _NOEXCEPT
 {
-return __sync_lock_test_and_set(&__new_handler, handler);
+return __libcpp_atomic_exchange(&__new_handler, handler);
 }
 
 new_handler
 get_new_handler() _NOEXCEPT
 {
-return __sync_fetch_and_add(&__new_handler, nullptr);
+return __libcpp_atomic_load(&__new_handler);
 }
 
 } // namespace std
Index: src/support/runtime/exception_fallback.ipp
===
--- src/support/runtime/exception_fallback.ipp
+++ src/support/runtime/exception_fallback.ipp
@@ -20,13 +20,13 @@
 unexpected_handler
 set_unexpected(unexpected_handler func) _NOEXCEPT
 {
-  return __sync_lock_test_and_set(&__unexpected_handler, func);
+  return __libcpp_atomic_exchange(&__unexpected_handler, func);
 }
 
 unexpected_handler
 get_unexpected() _NOEXCEPT
 {
-  return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0);
+  return __libcpp_atomic_load(&__unexpected_handler);
 
 }
 
@@ -41,14 +41,13 @@
 terminate_handler
 set_terminate(terminate_handler func) _NOEXCEPT
 {
-  return __sync_lock_test_and_set(&__terminate_handler, func);
+  return __libcpp_atomic_exchange(&__terminate_handler, func);
 }
 
 terminate_handler
 get_terminate() _NOEXCEPT
 {
-  return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0);
-
+  return __libcpp_atomic_load(&__terminate_handler);
 }
 
 #ifndef __EMSCRIPTEN__ // We provide this in JS
Index: src/new.cpp
===
--- src/new.cpp
+++ src/new.cpp
@@ -12,6 +12,7 @@
 #include 
 
 #include "new"
+#include "include/atomic_support.h"
 
 #if defined(_LIBCPP_ABI_MICROSOFT)
 // nothing todo
Index: src/locale.cpp
===
--- src/locale.cpp
+++ src/locale.cpp
@@ -36,6 +36,7 @@
 #endif
 #include 
 #include 
+#include "include/atomic_support.h"
 #include "__undef_macros"
 
 // On Linux, wint_t and wchar_t have different signed-ness, and this causes
@@ -667,7 +668,7 @@
 void
 locale::id::__init()
 {
-__id_ = __sync_add_and_fetch(&__next_id, 1);
+__id_ = __libcpp_atomic_add(&__next_id, 1);
 }
 
 // template <> class collate_byname
Index: src/include/refstring.h
===
--- src/include/refstring.h
+++ src/include/refstring.h
@@ -18,6 +18,7 @@
 #include 
 #include 
 #endif
+#include "atomic_support.h"
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -83,19 +84,19 @@
 : __imp_(s.__imp_)
 {
 if (__uses_refcount())
-__sync_add_and_fetch(&rep_from_data(__imp_)->count, 1);
+__libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);
 }
 
 inline
 __libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring const& s) _NOEXCEPT {
 bool adjust_old_count = __uses_refcount();
 struct _Rep_base *old_rep = rep_from_data(__imp_);
 __imp_ = s.__imp_;
 if (__uses_refcount())
-__sync_add_and_fetch(&rep_from_data(__imp_)->count, 1);
+__libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);
 if (adjust_old_count)
 {
-if (__sync_add_and_fetch(&old_rep->count, count_t(-1)) < 0)
+if (__libcpp_atomic_add(&old_rep->count, count_t(-1)) < 0)
 {
 ::operator delete(old_rep);
 }
@@ -107,7 +108,7 @@
 __libcpp_refstring::~__libcpp_refstring() {
 if (__uses_refcount()) {
 _Rep_base* rep = rep_from_data(__imp_);
-if (__sync_add_and_fetch(&rep->count, count_t(-1)) < 0) {
+if (__libcpp_atomic_add(&rep->count, count_t(-1)) < 0) {
 ::operator delete(rep);
 }
 }
Index: src/include/atomic_support.h
===
--- src/include/atomic_support.h
+++ src/include/atomic_support.h
@@ -16,6 +16,7 @@
 #if defined(__clang__) && __has_builtin(__atomic_load_n) \
&& __has_builtin(__atomic_store_n)\
&& __has_builtin(__atomic_add_fetch)  \
+   && __has_builtin(__atomic_exchange_n) \
&& __has_builtin(__atomic_compare_exchange_n) \
&& defined(__ATOMIC_RELAXED)  \
&& defined(__ATOMIC_CONSUME)  \
@@ -82,6 +83,14 @@
 return __atomic_add_fetch(__val, __a, __order);
 }
 
+te

[PATCH] D35235: [libc++] Replace __sync_* functions with __libcpp_atomic_* functions

2017-09-19 Thread Weiming Zhao via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL313694: [libc++] Replace __sync_* functions with 
__libcpp_atomic_* functions (authored by weimingz).

Changed prior to commit:
  https://reviews.llvm.org/D35235?vs=115918&id=115922#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D35235

Files:
  libcxx/trunk/src/exception.cpp
  libcxx/trunk/src/include/atomic_support.h
  libcxx/trunk/src/include/refstring.h
  libcxx/trunk/src/locale.cpp
  libcxx/trunk/src/new.cpp
  libcxx/trunk/src/support/runtime/exception_fallback.ipp
  libcxx/trunk/src/support/runtime/new_handler_fallback.ipp

Index: libcxx/trunk/src/support/runtime/new_handler_fallback.ipp
===
--- libcxx/trunk/src/support/runtime/new_handler_fallback.ipp
+++ libcxx/trunk/src/support/runtime/new_handler_fallback.ipp
@@ -15,13 +15,13 @@
 new_handler
 set_new_handler(new_handler handler) _NOEXCEPT
 {
-return __sync_lock_test_and_set(&__new_handler, handler);
+return __libcpp_atomic_exchange(&__new_handler, handler);
 }
 
 new_handler
 get_new_handler() _NOEXCEPT
 {
-return __sync_fetch_and_add(&__new_handler, nullptr);
+return __libcpp_atomic_load(&__new_handler);
 }
 
 } // namespace std
Index: libcxx/trunk/src/support/runtime/exception_fallback.ipp
===
--- libcxx/trunk/src/support/runtime/exception_fallback.ipp
+++ libcxx/trunk/src/support/runtime/exception_fallback.ipp
@@ -20,13 +20,13 @@
 unexpected_handler
 set_unexpected(unexpected_handler func) _NOEXCEPT
 {
-  return __sync_lock_test_and_set(&__unexpected_handler, func);
+  return __libcpp_atomic_exchange(&__unexpected_handler, func);
 }
 
 unexpected_handler
 get_unexpected() _NOEXCEPT
 {
-  return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0);
+  return __libcpp_atomic_load(&__unexpected_handler);
 
 }
 
@@ -41,14 +41,13 @@
 terminate_handler
 set_terminate(terminate_handler func) _NOEXCEPT
 {
-  return __sync_lock_test_and_set(&__terminate_handler, func);
+  return __libcpp_atomic_exchange(&__terminate_handler, func);
 }
 
 terminate_handler
 get_terminate() _NOEXCEPT
 {
-  return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0);
-
+  return __libcpp_atomic_load(&__terminate_handler);
 }
 
 #ifndef __EMSCRIPTEN__ // We provide this in JS
Index: libcxx/trunk/src/include/atomic_support.h
===
--- libcxx/trunk/src/include/atomic_support.h
+++ libcxx/trunk/src/include/atomic_support.h
@@ -16,6 +16,7 @@
 #if defined(__clang__) && __has_builtin(__atomic_load_n) \
&& __has_builtin(__atomic_store_n)\
&& __has_builtin(__atomic_add_fetch)  \
+   && __has_builtin(__atomic_exchange_n) \
&& __has_builtin(__atomic_compare_exchange_n) \
&& defined(__ATOMIC_RELAXED)  \
&& defined(__ATOMIC_CONSUME)  \
@@ -84,6 +85,14 @@
 
 template 
 inline _LIBCPP_INLINE_VISIBILITY
+_ValueType __libcpp_atomic_exchange(_ValueType* __target,
+_ValueType __value, int __order = _AO_Seq)
+{
+return __atomic_exchange_n(__target, __value, __order);
+}
+
+template 
+inline _LIBCPP_INLINE_VISIBILITY
 bool __libcpp_atomic_compare_exchange(_ValueType* __val,
 _ValueType* __expected, _ValueType __after,
 int __success_order = _AO_Seq,
@@ -137,6 +146,16 @@
 
 template 
 inline _LIBCPP_INLINE_VISIBILITY
+_ValueType __libcpp_atomic_exchange(_ValueType* __target,
+_ValueType __value, int __order = _AO_Seq)
+{
+_ValueType old = *__target;
+*__target = __value;
+return old;
+}
+
+template 
+inline _LIBCPP_INLINE_VISIBILITY
 bool __libcpp_atomic_compare_exchange(_ValueType* __val,
 _ValueType* __expected, _ValueType __after,
 int = 0, int = 0)
Index: libcxx/trunk/src/include/refstring.h
===
--- libcxx/trunk/src/include/refstring.h
+++ libcxx/trunk/src/include/refstring.h
@@ -18,6 +18,7 @@
 #include 
 #include 
 #endif
+#include "atomic_support.h"
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -83,19 +84,19 @@
 : __imp_(s.__imp_)
 {
 if (__uses_refcount())
-__sync_add_and_fetch(&rep_from_data(__imp_)->count, 1);
+__libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);
 }
 
 inline
 __libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring const& s) _NOEXCEPT {
 bool adjust_old_count = __uses_refcount();
 struct _Rep_base *old_rep = rep_from_data(__imp_);
 __imp_ = s.__imp_;
 if (__uses_refcount())
-__sync_add_and_fetch(&rep_from_data(__imp_)->count, 1);
+__libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);
 if (adjust_old_count)

[PATCH] D17741: adds __FILE_BASENAME__ builtin macro

2018-04-13 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz updated this revision to Diff 142499.
weimingz edited the summary of this revision.
weimingz added a comment.

split the original into two parts. This one supports 
-ffile-macro-prefix-to-remove function.

I locally verified it.  To add a test case, do we need to use VFS?


https://reviews.llvm.org/D17741

Files:
  include/clang/Driver/Options.td
  include/clang/Lex/PreprocessorOptions.h
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Lex/PPMacroExpansion.cpp

Index: lib/Lex/PPMacroExpansion.cpp
===
--- lib/Lex/PPMacroExpansion.cpp
+++ lib/Lex/PPMacroExpansion.cpp
@@ -26,25 +26,27 @@
 #include "clang/Lex/LexDiagnostic.h"
 #include "clang/Lex/MacroArgs.h"
 #include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/PTHLexer.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/PreprocessorLexer.h"
-#include "clang/Lex/PTHLexer.h"
+#include "clang/Lex/PreprocessorOptions.h"
 #include "clang/Lex/Token.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
 #include 
@@ -1717,7 +1719,16 @@
 // Escape this filename.  Turn '\' -> '\\' '"' -> '\"'
 SmallString<128> FN;
 if (PLoc.isValid()) {
-  FN += PLoc.getFilename();
+  StringRef Filename = PLoc.getFilename();
+  if (II == Ident__FILE__) {
+const std::string &PrefixToRemove =
+getPreprocessorOpts().FileMacroPrefixToRemove;
+if (Filename.startswith(PrefixToRemove))
+  FN += Filename.substr(PrefixToRemove.size());
+else
+  FN += Filename;
+  } else
+FN += Filename;
   Lexer::Stringify(FN);
   OS << '"' << FN << '"';
 }
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -2826,6 +2826,10 @@
   Opts.ObjCXXARCStandardLibrary = (ObjCXXARCStandardLibraryKind)Library;
   }
 
+  if (Arg *A = Args.getLastArg(OPT_ffile_macro_prefix_to_remove)) {
+Opts.FileMacroPrefixToRemove = A->getValue();
+  }
+
   // Always avoid lexing editor placeholders when we're just running the
   // preprocessor as we never want to emit the
   // "editor placeholder in source file" error in PP only mode.
Index: lib/Driver/ToolChains/Clang.cpp
===
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -1264,6 +1264,15 @@
 // For IAMCU add special include arguments.
 getToolChain().AddIAMCUIncludeArgs(Args, CmdArgs);
   }
+
+  // Add FILE macro prefix removing arguments or basename only flags.
+  if (const Arg *A =
+  Args.getLastArg(options::OPT_ffile_macro_prefix_to_remove)) {
+StringRef PrefixToRemove(A->getValue());
+if (!PrefixToRemove.empty())
+  CmdArgs.push_back(Args.MakeArgString("-ffile-macro-prefix-to-remove=" +
+   PrefixToRemove));
+  }
 }
 
 // FIXME: Move to target hook.
Index: include/clang/Lex/PreprocessorOptions.h
===
--- include/clang/Lex/PreprocessorOptions.h
+++ include/clang/Lex/PreprocessorOptions.h
@@ -127,12 +127,16 @@
   /// manipulation of the compiler invocation object, in cases where the 
   /// compiler invocation and its buffers will be reused.
   bool RetainRemappedFileBuffers = false;
-  
+
   /// \brief The Objective-C++ ARC standard library that we should support,
   /// by providing appropriate definitions to retrofit the standard library
   /// with support for lifetime-qualified pointers.
   ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary = ARCXX_nolib;
-
+
+  /// \brief This string will be used in expanding __FILE__ macro. If it
+  /// matches the prefix of __FILE__, the matched part won't be expanded.
+  std::string FileMacroPrefixToRemove;
+
   /// \brief Records the set of modules
   class FailedModulesSet {
 llvm::StringSet<> Failed;
Index: include/clang/Driver/Options.td
===
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -1246,6 +1246,9 @@
   Flag <["-"], "fno-implicit-modules">,
   Group, Flags<[DriverOption, CC1Option]>;
 def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-system-headers">, Group, Fl

[PATCH] D36249: Mark tests that need intel 80-bit floats as x86-only

2017-08-02 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added a comment.

I tried to address it via checking pre-defined macros:
https://reviews.llvm.org/D31573

As long as the macros are defined correctly by clang, we don't need to worry 
about the specific target machine. How do you think about it?


Repository:
  rL LLVM

https://reviews.llvm.org/D36249



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36249: Mark tests that need intel 80-bit floats as x86-only

2017-08-03 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added a comment.

In https://reviews.llvm.org/D36249#830645, @saugustine wrote:

> In https://reviews.llvm.org/D36249#830121, @weimingz wrote:
>
> > I tried to address it via checking pre-defined macros:
> >  https://reviews.llvm.org/D31573
> >
> > As long as the macros are defined correctly by clang, we don't need to 
> > worry about the specific target machine. How do you think about it?
>
>
> I like the idea of a feature check, rather than a specific architecture 
> check--that is clearly the right thing to do.
>
> On the other hand, I would like to mark the test as unsupported and not run 
> in that case, rather than running it, saying it passed, but not actually 
> testing anything. That better reflects the state of the implementation. 
> Unfortunately, I don't think that can be done with macro checks. So my 
> preference would be this patch over https://reviews.llvm.org/D31573, but I 
> would also find https://reviews.llvm.org/D31573 acceptable if it came to that.
>
> Finally, 80-bit doubles are a bit of a historical artifact these days. Only 
> x86 and m68k have them (and not even all m68Ks either). So I don't think it 
> matters that much.


I agree that showing the tests pass on architectures that doesn't actually test 
it is not meaningful. 
This patch LGTM.


Repository:
  rL LLVM

https://reviews.llvm.org/D36249



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36555: Move x86-specific sources to x86-specific source lists.

2017-08-22 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added reviewers: rengolin, compnerd.
weimingz added a comment.

LGTM. Adding Renato and Saleem to approve.


https://reviews.llvm.org/D36555



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36555: Move x86-specific sources to x86-specific source lists.

2017-08-22 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added inline comments.



Comment at: compiler-rt/lib/builtins/CMakeLists.txt:483
+set(powerpc64le_SOURCES ${powerpc64_SOURCES})
+
 set(wasm32_SOURCES ${GENERIC_SOURCES})

why these files were not used before? should the change be in a separate patch? 
or update the patch title/summary as well?


https://reviews.llvm.org/D36555



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41316: [libcxx] Allow random_device to be built optionally

2018-04-05 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added a comment.

Thanks Eli!


Repository:
  rCXX libc++

https://reviews.llvm.org/D41316



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27898: [compiler-rt] [builtins] Implement __floattitf() & __floatuntitf()

2016-12-20 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added a comment.

The code looks OK except for the formatting.  Since the logic is almost the 
same as floattixf / floatuntixf except that some constants are different, I'm 
wondering if it makes sense to reuse the existing code? For example, make 
existing code as floattixf_impl.inc




Comment at: lib/builtins/floattitf.c:32
+COMPILER_RT_ABI fp_t
+__floattitf(ti_int a)
+{

Please put "{" on the same line like __floattitf(ti_int a) {
Same for other occurrences below 



https://reviews.llvm.org/D27898



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27898: [compiler-rt] [builtins] Implement __floattitf() & __floatuntitf()

2016-12-21 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added a comment.

Thanks for the formatting. Regarding the refactoring, Regarding factoring out 
common code, I think it's OK to do it in a follow-up patch. For readability, it 
should be OK. For example, fp_add_impl.inc is used by float, double and long 
double.


https://reviews.llvm.org/D27898



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27898: [compiler-rt] [builtins] Implement __floattitf() & __floatuntitf()

2016-12-21 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added a comment.

The patch looks good to me.


https://reviews.llvm.org/D27898



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28526: [ARM] Add diagnostics when initialization global variables with ropi/rwpi

2017-01-10 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz created this revision.
weimingz added reviewers: olista01, jmolloy.
weimingz added a subscriber: cfe-commits.
Herald added subscribers: rengolin, aemerson.

This patch adds diagnoses when initializing a global variable using the address 
of another global variable that uses ROPI/RWPI relocation model.

For example, 
int a;
extern void foo();
int *x = &a;// we cannot statically initialize x with -frwpi 
void *y = &foo();  // we can't statically initialize y with -fropi

The above code will trigger diagnoses like:

  error: 'x' cannot be initialized using address of 'a' with 'rwpi' relocation


https://reviews.llvm.org/D28526

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/CodeGen/CGDecl.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/CodeGen/CodeGenModule.h
  test/CodeGen/arm-ropi-rwpi.c

Index: test/CodeGen/arm-ropi-rwpi.c
===
--- /dev/null
+++ test/CodeGen/arm-ropi-rwpi.c
@@ -0,0 +1,56 @@
+// REQUIRES: arm-registered-target
+
+// OK with local initialization, rwpi with const gv and ropi with non-const gv.
+// RUN: %clang_cc1 -triple armv7 -mrelocation-model ropi-rwpi %s -S -o /dev/null
+// RUN: %clang_cc1 -triple armv7 -mrelocation-model rwpi -DTEST_RO_1 -DTEST_RO_2 -DTEST_RO_STATIC %s -S -o /dev/null
+// RUN: %clang_cc1 -triple armv7 -mrelocation-model ropi -DTEST_RW_1 -DTEST_RW_STATIC %s -S -o /dev/null
+
+// RUN: not %clang_cc1 -triple armv7 -mrelocation-model ropi -DTEST_RO_1  %s -S -o /dev/null 2>&1 | FileCheck %s -check-prefix=CHECK-RO-1
+// RUN: not %clang_cc1 -triple armv7 -mrelocation-model ropi -DTEST_RO_2  %s -S -o /dev/null 2>&1 | FileCheck %s -check-prefix=CHECK-RO-2
+// RUN: not %clang_cc1 -triple armv7 -mrelocation-model ropi -DTEST_RO_STATIC  %s -S -o /dev/null 2>&1 | FileCheck %s -check-prefix=CHECK-RO-STATIC
+
+// RUN: not %clang_cc1 -triple armv7 -mrelocation-model rwpi -DTEST_RW_1  %s -S -o /dev/null 2>&1 | FileCheck %s -check-prefix=CHECK-RW-1
+
+// RUN: not %clang_cc1 -triple armv7 -mrelocation-model ropi-rwpi -DTEST_RW_STATIC  %s -S -o /dev/null 2>&1 | FileCheck %s -check-prefix=CHECK-RW-STATIC
+
+extern int func(void);
+
+extern int gv;
+
+extern const int c_gv;
+
+#ifdef TEST_RO_1
+void *p1 = &func;
+#endif
+// CHECK-RO-1: error: 'p1' cannot be initilized using address of 'func' with 'ropi' relocation
+
+#ifdef TEST_RO_2
+const void *p2 = &c_gv;
+#endif
+// CHECK-RO-2: error: 'p2' cannot be initilized using address of 'c_gv' with 'ropi' relocation
+
+#ifdef TEST_RO_STATIC
+void bar() {
+  static void *sp = &func;
+}
+#endif
+// CHECK-RO-STATIC: error: 'bar.sp' cannot be initilized using address of 'func' with 'ropi' relocation
+
+#ifdef TEST_RW_1
+void *p3 = &gv;
+#endif
+// CHECK-RW-1: error: 'p3' cannot be initilized using address of 'gv' with 'rwpi' relocation
+
+#ifdef TEST_RW_STATIC
+void bar2() {
+  static void *sp = &gv;
+}
+#endif
+// CHECK-RW-STATIC: error: 'bar2.sp' cannot be initilized using address of 'gv' with 'ropi-rwpi' relocation
+
+unsigned test() {
+  unsigned a = (unsigned)&func;
+  unsigned b = (unsigned)&gv;
+  unsigned c = (unsigned)&c_gv;
+  return a + b + c;
+}
Index: lib/CodeGen/CodeGenModule.h
===
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -500,6 +500,9 @@
   /// MDNodes.
   llvm::DenseMap MetadataIdMap;
 
+  /// The relocaton model for ARM.
+  bool IsROPI, IsRWPI;
+
 public:
   CodeGenModule(ASTContext &C, const HeaderSearchOptions &headersearchopts,
 const PreprocessorOptions &ppopts,
@@ -1189,6 +1192,10 @@
   /// \param QT is the clang QualType of the null pointer.
   llvm::Constant *getNullPointer(llvm::PointerType *T, QualType QT);
 
+  /// Check if a static initialization is valid for ROPI/RWPI.
+  bool isValidInitForPI(const llvm::Constant *Init, StringRef GVName,
+SourceLocation Loc);
+
 private:
   llvm::Constant *
   GetOrCreateLLVMFunction(StringRef MangledName, llvm::Type *Ty, GlobalDecl D,
Index: lib/CodeGen/CodeGenModule.cpp
===
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -159,6 +159,9 @@
   // CoverageMappingModuleGen object.
   if (CodeGenOpts.CoverageMapping)
 CoverageMapping.reset(new CoverageMappingModuleGen(*this, *CoverageInfo));
+
+  IsROPI = StringRef(CodeGenOpts.RelocationModel).startswith("ropi");
+  IsRWPI = StringRef(CodeGenOpts.RelocationModel).endswith("rwpi");
 }
 
 CodeGenModule::~CodeGenModule() {}
@@ -2505,6 +2508,49 @@
   GO.setComdat(TheModule.getOrInsertComdat(GO.getName()));
 }
 
+/// Check if the address of a GV is used in the Init expr and the consntness
+/// matches with IsROPI. If such a GV is used, returns it.
+static const llvm::Constant *UseAddrOfGlobalVar(const llvm::Constant *Init,
+bool IsROPI) {
+  if (!Init)
+return nullptr;
+  if (isa(Init)) {
+   

[PATCH] D28526: [ARM] Add diagnostics when initialization global variables with ropi/rwpi

2017-01-10 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added a comment.

Hi Eli,
Thanks for the comments!
I though of implementation in Sema and  I actually experimented a little bit. 
Then it seemed that the CodeGenOpts is only available in the CGM.  Any ideas?


https://reviews.llvm.org/D28526



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D25157: [compiler-rt] [cmake] Respect COMPILER_RT_BUILD_* for libs, headers and tests

2017-03-29 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added a comment.

Looks good to me but I'm not very familiar with the build of sanitizer and xray.


https://reviews.llvm.org/D25157



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28526: [ARM] Add diagnostics when initialization global variables with ropi/rwpi

2017-01-23 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz updated this revision to Diff 85446.
weimingz edited the summary of this revision.
weimingz added a comment.

As Eli sugguested, it's better to check it in Sema. In order to access 
RelocationModel in Sema, we moved it from CodeGenOpts to LangOpts


https://reviews.llvm.org/D28526

Files:
  include/clang/Basic/LangOptions.def
  include/clang/Basic/LangOptions.h
  include/clang/Frontend/CodeGenOptions.h
  lib/AST/ExprConstant.cpp
  lib/CodeGen/BackendUtil.cpp
  lib/Frontend/CodeGenOptions.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/arm-ropi-rwpi.c
  test/Sema/ropi-rwpi.c

Index: test/Sema/ropi-rwpi.c
===
--- /dev/null
+++ test/Sema/ropi-rwpi.c
@@ -0,0 +1,65 @@
+// OK with local initialization, rwpi with const gv and ropi with non-const gv.
+// RUN: %clang_cc1 -triple armv7 -DDEFAULT -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple armv7 -DROPI -mrelocation-model ropi -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple armv7 -DRWPI -mrelocation-model rwpi -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple armv7 -DROPI -DRWPI -mrelocation-model ropi-rwpi -fsyntax-only -verify %s
+
+extern int func(const int* const []);
+
+extern int gv;
+extern const int c_gv;
+
+void *p1 = &func;
+const void *p2 = &c_gv;
+const int *p_compound_literal_c = &(const int){1};
+
+void ropi_test() {
+  static void *sp1 = &func;
+  static const void *sp2 = &c_gv;
+  static char(*x)[7] = &"abcdef";
+  static const void *x2 = &__func__;
+  static const int *const arr[2] = {&c_gv, &c_gv};
+  static void *addr = &&label1;
+label1:
+  return;
+}
+
+void *p3 = &gv;
+int *p_compound_literal = &(int){1};
+
+void rwpi_test() {
+  static void *sp1 = &gv;
+  static int *const arr[2] = {&gv, &gv};
+}
+
+unsigned test() {
+  unsigned a = (unsigned)&func;
+  unsigned b = (unsigned)&gv;
+  unsigned c = (unsigned)&c_gv;
+  return a + b + c;
+}
+
+#ifdef DEFAULT
+// expected-no-diagnostics
+#endif
+
+#if defined(ROPI)
+// expected-error@12 {{initializer element is not a compile-time constant}}
+// expected-error@13 {{initializer element is not a compile-time constant}}
+// expected-error@14 {{initializer element is not a compile-time constant}}
+
+// expected-error@17 {{initializer element is not a compile-time constant}}
+// expected-error@18 {{initializer element is not a compile-time constant}}
+// expected-error@19 {{initializer element is not a compile-time constant}}
+// expected-error@20 {{initializer element is not a compile-time constant}}
+// expected-error@21 {{initializer element is not a compile-time constant}}
+// expected-error@22 {{initializer element is not a compile-time constant}}
+#endif
+
+#if defined(RWPI)
+// expected-error@27 {{initializer element is not a compile-time constant}}
+// expected-error@28 {{initializer element is not a compile-time constant}}
+
+// expected-error@31 {{initializer element is not a compile-time constant}}
+// expected-error@32 {{initializer element is not a compile-time constant}}
+#endif
Index: test/CodeGen/arm-ropi-rwpi.c
===
--- /dev/null
+++ test/CodeGen/arm-ropi-rwpi.c
@@ -0,0 +1,32 @@
+// REQUIRES: arm-registered-target
+
+// Below tests check if memcpy is not generated with ropi/rwpi for local var initialization.
+// RUN: %clang_cc1 -triple armv7 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=DEFAULT
+// RUN: %clang_cc1 -triple armv7 -S -emit-llvm -mrelocation-model ropi  -o - %s | FileCheck %s --check-prefix=ROPI
+// RUN: %clang_cc1 -triple armv7 -S -emit-llvm -mrelocation-model rwpi  -o - %s | FileCheck %s --check-prefix=RWPI
+// RUN: %clang_cc1 -triple armv7 -S -emit-llvm -mrelocation-model ropi-rwpi  -o - %s | FileCheck %s --check-prefix=ROPI_RWPI
+
+extern int gv;
+extern const int c_gv;
+
+void test_local() {
+// DEFAULT-LABEL: @test_local
+// DEFAULT: call void @{{llvm.memcpy.*@test_local.x}}
+// DEFAULT: call void @{{llvm.memcpy.*@test_local.y}}
+
+// ROPI-LABEL: @test_local
+// ROPI: call void @{{llvm.memcpy.*@test_local.x}}
+// ROPI-NOT: call void@llvm.memcpy
+
+// RWPI-LABEL: @test_local
+// RWPI-NOT: call void@{{llvm.memcpy.*@test_local.x}}
+// RWPI: call void @{{llvm.memcpy.*@test_local.y}}
+
+// ROPI_RWPI-LABEL: @test_local
+// ROPI_RWPI-NOT: call void @llvm.memcpy
+
+  const int *x[] = {&gv, &gv, &gv}; // This is OK, no diagnostic.
+  func(x);
+  const int *y[] = {&c_gv, &c_gv, &c_gv}; // This is OK, no diagnostic.
+  func(y);
+}
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -610,7 +610,6 @@
   Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
   Args.hasArg(OPT_cl_fast_relaxed_math);
   Opts.UnwindTables = Args.hasArg(OPT_munwind_tables);
-  Opts.RelocationModel = Args.getLastArgValue(OPT_mrelocation_model, "pic");
   Opts.ThreadMod

[PATCH] D28526: [ARM] Add diagnostics when initialization global variables with ropi/rwpi

2017-02-02 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz added a comment.

ping ?


https://reviews.llvm.org/D28526



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41316: [libcxx] Allow random_device to be built optionally

2018-01-30 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz updated this revision to Diff 132089.
weimingz added a comment.
Herald added a subscriber: hintonda.

Disable tests that depend on random_device. 
filesystem tests rely on random_device as seed to create random path. Although 
it's possible to avoid the random_device but if the build target has no 
random_device, it's very possible that neither filesystem nor other seeding 
device like clock is available.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41316

Files:
  CMakeLists.txt
  include/__config_site.in
  include/random
  src/random.cpp
  test/libcxx/experimental/filesystem/lit.local.cfg
  test/std/experimental/filesystem/lit.local.cfg
  test/std/numerics/rand/rand.device/lit.local.cfg

Index: test/std/numerics/rand/rand.device/lit.local.cfg
===
--- /dev/null
+++ test/std/numerics/rand/rand.device/lit.local.cfg
@@ -0,0 +1,3 @@
+# Disable all of the random device tests if the correct feature is not available.
+if 'libcpp-has-no-random-device' in config.available_features:
+  config.unsupported = True
Index: test/std/experimental/filesystem/lit.local.cfg
===
--- test/std/experimental/filesystem/lit.local.cfg
+++ test/std/experimental/filesystem/lit.local.cfg
@@ -1,3 +1,7 @@
 # Disable all of the filesystem tests if the correct feature is not available.
 if 'c++filesystem' not in config.available_features:
   config.unsupported = True
+
+# filesystem_test_helper uses random_device to generate random path.
+if 'libcpp-has-no-random-device' in config.available_features:
+  config.unsupported = True
Index: test/libcxx/experimental/filesystem/lit.local.cfg
===
--- test/libcxx/experimental/filesystem/lit.local.cfg
+++ test/libcxx/experimental/filesystem/lit.local.cfg
@@ -1,3 +1,7 @@
 # Disable all of the filesystem tests if the correct feature is not available.
 if 'c++filesystem' not in config.available_features:
   config.unsupported = True
+
+# filesystem_test_helper uses random_device to generate random path.
+if 'libcpp-has-no-random-device' in config.available_features:
+  config.unsupported = True
Index: src/random.cpp
===
--- src/random.cpp
+++ src/random.cpp
@@ -8,6 +8,7 @@
 //===--===//
 
 #include <__config>
+#ifndef _LIBCPP_HAS_NO_RANDOM_DEVICE
 
 #if defined(_LIBCPP_USING_WIN32_RANDOM)
 // Must be defined before including stdlib.h to enable rand_s().
@@ -177,3 +178,4 @@
 }
 
 _LIBCPP_END_NAMESPACE_STD
+#endif // _LIBCPP_HAS_NO_RANDOM_DEVICE
Index: include/random
===
--- include/random
+++ include/random
@@ -3476,6 +3476,7 @@
 
 typedef shuffle_order_engine knuth_b;
 
+#ifndef _LIBCPP_HAS_NO_RANDOM_DEVICE
 // random_device
 
 class _LIBCPP_TYPE_VIS random_device
@@ -3511,6 +3512,7 @@
 random_device(const random_device&); // = delete;
 random_device& operator=(const random_device&); // = delete;
 };
+#endif // _LIBCPP_HAS_NO_RANDOM_DEVICE
 
 // seed_seq
 
Index: include/__config_site.in
===
--- include/__config_site.in
+++ include/__config_site.in
@@ -20,6 +20,7 @@
 #cmakedefine _LIBCPP_HAS_NO_THREADS
 #cmakedefine _LIBCPP_HAS_NO_MONOTONIC_CLOCK
 #cmakedefine _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
+#cmakedefine _LIBCPP_HAS_NO_RANDOM_DEVICE
 #cmakedefine _LIBCPP_HAS_MUSL_LIBC
 #cmakedefine _LIBCPP_HAS_THREAD_API_PTHREAD
 #cmakedefine _LIBCPP_HAS_THREAD_API_EXTERNAL
Index: CMakeLists.txt
===
--- CMakeLists.txt
+++ CMakeLists.txt
@@ -71,6 +71,7 @@
 option(LIBCXX_ENABLE_FILESYSTEM "Build filesystem as part of libc++experimental.a"
 ${ENABLE_FILESYSTEM_DEFAULT})
 option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})
+option(LIBCXX_ENABLE_RANDOM_DEVICE "Build random_device class" On)
 
 # Benchmark options ---
 option(LIBCXX_INCLUDE_BENCHMARKS "Build the libc++ benchmarks and their dependancies" ON)
@@ -629,6 +630,7 @@
 config_define_if_not(LIBCXX_ENABLE_THREADS _LIBCPP_HAS_NO_THREADS)
 config_define_if_not(LIBCXX_ENABLE_MONOTONIC_CLOCK _LIBCPP_HAS_NO_MONOTONIC_CLOCK)
 config_define_if_not(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS)
+config_define_if_not(LIBCXX_ENABLE_RANDOM_DEVICE _LIBCPP_HAS_NO_RANDOM_DEVICE)
 
 config_define_if(LIBCXX_HAS_PTHREAD_API _LIBCPP_HAS_THREAD_API_PTHREAD)
 config_define_if(LIBCXX_HAS_EXTERNAL_THREAD_API _LIBCPP_HAS_THREAD_API_EXTERNAL)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32918: [ARM] Limit the diagnose when an ISR calls a regular function

2017-05-05 Thread Weiming Zhao via Phabricator via cfe-commits
weimingz created this revision.
Herald added subscribers: javed.absar, rengolin, aemerson.

When the function is compiled with soft-float or on CPU with no FPU, we
don't need to diagnose for a call from an ISR to a regular function.


Repository:
  rL LLVM

https://reviews.llvm.org/D32918

Files:
  lib/Basic/Targets.cpp
  lib/Sema/SemaExpr.cpp
  test/Sema/arm-interrupt-attr.c


Index: test/Sema/arm-interrupt-attr.c
===
--- test/Sema/arm-interrupt-attr.c
+++ test/Sema/arm-interrupt-attr.c
@@ -1,7 +1,8 @@
-// RUN: %clang_cc1 %s -triple arm-apple-darwin -verify -fsyntax-only
-// RUN: %clang_cc1 %s -triple thumb-apple-darwin -verify -fsyntax-only
-// RUN: %clang_cc1 %s -triple armeb-none-eabi -verify -fsyntax-only
-// RUN: %clang_cc1 %s -triple thumbeb-none-eabi -verify -fsyntax-only
+// RUN: %clang_cc1 %s -triple arm-apple-darwin  -target-feature +vfp2 -verify 
-fsyntax-only
+// RUN: %clang_cc1 %s -triple thumb-apple-darwin  -target-feature +vfp3 
-verify -fsyntax-only
+// RUN: %clang_cc1 %s -triple armeb-none-eabi  -target-feature +vfp4 -verify 
-fsyntax-only
+// RUN: %clang_cc1 %s -triple thumbeb-none-eabi  -target-feature +neon -verify 
-fsyntax-only
+// RUN: %clang_cc1 %s -triple thumbeb-none-eabi -target-feature +neon 
-target-feature +soft-float -DSOFT -verify -fsyntax-only
 
 __attribute__((interrupt(IRQ))) void foo() {} // expected-error {{'interrupt' 
attribute requires a string}}
 __attribute__((interrupt("irq"))) void foo1() {} // expected-warning 
{{'interrupt' attribute argument not supported: irq}}
@@ -24,6 +25,8 @@
   callee1();
   callee2();
 }
+
+#ifndef SOFT
 __attribute__((interrupt("IRQ"))) void caller2() {
   callee1(); // expected-warning {{call to function without interrupt 
attribute could clobber interruptee's VFP registers}}
   callee2();
@@ -33,3 +36,14 @@
 __attribute__((interrupt("IRQ"))) void caller3() {
   callee3(); // expected-warning {{call to function without interrupt 
attribute could clobber interruptee's VFP registers}}
 }
+#else
+__attribute__((interrupt("IRQ"))) void caller2() {
+  callee1();
+  callee2();
+}
+
+void (*callee3)();
+__attribute__((interrupt("IRQ"))) void caller3() {
+  callee3();
+}
+#endif
Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -5399,9 +5399,11 @@
   // that the callee might not preserve them. This is easy to diagnose here,
   // but can be very challenging to debug.
   if (auto *Caller = getCurFunctionDecl())
-if (Caller->hasAttr())
-  if (!FDecl || !FDecl->hasAttr())
+if (Caller->hasAttr()) {
+  bool VFP = Context.getTargetInfo().hasFeature("vfp");
+  if (VFP && (!FDecl || !FDecl->hasAttr()))
 Diag(Fn->getExprLoc(), diag::warn_arm_interrupt_calling_convention);
+}
 
   // Promote the function operand.
   // We special-case function promotion here because we only allow promoting
Index: lib/Basic/Targets.cpp
===
--- lib/Basic/Targets.cpp
+++ lib/Basic/Targets.cpp
@@ -5443,6 +5443,7 @@
 .Case("softfloat", SoftFloat)
 .Case("thumb", isThumb())
 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
+.Case("vfp", FPU && !SoftFloat)
 .Case("hwdiv", HWDiv & HWDivThumb)
 .Case("hwdiv-arm", HWDiv & HWDivARM)
 .Default(false);


Index: test/Sema/arm-interrupt-attr.c
===
--- test/Sema/arm-interrupt-attr.c
+++ test/Sema/arm-interrupt-attr.c
@@ -1,7 +1,8 @@
-// RUN: %clang_cc1 %s -triple arm-apple-darwin -verify -fsyntax-only
-// RUN: %clang_cc1 %s -triple thumb-apple-darwin -verify -fsyntax-only
-// RUN: %clang_cc1 %s -triple armeb-none-eabi -verify -fsyntax-only
-// RUN: %clang_cc1 %s -triple thumbeb-none-eabi -verify -fsyntax-only
+// RUN: %clang_cc1 %s -triple arm-apple-darwin  -target-feature +vfp2 -verify -fsyntax-only
+// RUN: %clang_cc1 %s -triple thumb-apple-darwin  -target-feature +vfp3 -verify -fsyntax-only
+// RUN: %clang_cc1 %s -triple armeb-none-eabi  -target-feature +vfp4 -verify -fsyntax-only
+// RUN: %clang_cc1 %s -triple thumbeb-none-eabi  -target-feature +neon -verify -fsyntax-only
+// RUN: %clang_cc1 %s -triple thumbeb-none-eabi -target-feature +neon -target-feature +soft-float -DSOFT -verify -fsyntax-only
 
 __attribute__((interrupt(IRQ))) void foo() {} // expected-error {{'interrupt' attribute requires a string}}
 __attribute__((interrupt("irq"))) void foo1() {} // expected-warning {{'interrupt' attribute argument not supported: irq}}
@@ -24,6 +25,8 @@
   callee1();
   callee2();
 }
+
+#ifndef SOFT
 __attribute__((interrupt("IRQ"))) void caller2() {
   callee1(); // expected-warning {{call to function without interrupt attribute could clobber interruptee's VFP registers}}
   callee2();
@@ -33,3 +36,14 @@
 __attribute__((interrupt("IRQ"))) void caller3() {
   callee3(

[PATCH] D32918: [ARM] Limit the diagnose when an ISR calls a regular function

2017-05-05 Thread Weiming Zhao via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL302274: [ARM] Limit the diagnose when an ISR calls a regular 
function (authored by weimingz).

Changed prior to commit:
  https://reviews.llvm.org/D32918?vs=97996&id=98001#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D32918

Files:
  cfe/trunk/lib/Basic/Targets.cpp
  cfe/trunk/lib/Sema/SemaExpr.cpp
  cfe/trunk/test/Sema/arm-interrupt-attr.c


Index: cfe/trunk/lib/Sema/SemaExpr.cpp
===
--- cfe/trunk/lib/Sema/SemaExpr.cpp
+++ cfe/trunk/lib/Sema/SemaExpr.cpp
@@ -5399,9 +5399,11 @@
   // that the callee might not preserve them. This is easy to diagnose here,
   // but can be very challenging to debug.
   if (auto *Caller = getCurFunctionDecl())
-if (Caller->hasAttr())
-  if (!FDecl || !FDecl->hasAttr())
+if (Caller->hasAttr()) {
+  bool VFP = Context.getTargetInfo().hasFeature("vfp");
+  if (VFP && (!FDecl || !FDecl->hasAttr()))
 Diag(Fn->getExprLoc(), diag::warn_arm_interrupt_calling_convention);
+}
 
   // Promote the function operand.
   // We special-case function promotion here because we only allow promoting
Index: cfe/trunk/lib/Basic/Targets.cpp
===
--- cfe/trunk/lib/Basic/Targets.cpp
+++ cfe/trunk/lib/Basic/Targets.cpp
@@ -5443,6 +5443,7 @@
 .Case("softfloat", SoftFloat)
 .Case("thumb", isThumb())
 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
+.Case("vfp", FPU && !SoftFloat)
 .Case("hwdiv", HWDiv & HWDivThumb)
 .Case("hwdiv-arm", HWDiv & HWDivARM)
 .Default(false);
Index: cfe/trunk/test/Sema/arm-interrupt-attr.c
===
--- cfe/trunk/test/Sema/arm-interrupt-attr.c
+++ cfe/trunk/test/Sema/arm-interrupt-attr.c
@@ -1,7 +1,8 @@
-// RUN: %clang_cc1 %s -triple arm-apple-darwin -verify -fsyntax-only
-// RUN: %clang_cc1 %s -triple thumb-apple-darwin -verify -fsyntax-only
-// RUN: %clang_cc1 %s -triple armeb-none-eabi -verify -fsyntax-only
-// RUN: %clang_cc1 %s -triple thumbeb-none-eabi -verify -fsyntax-only
+// RUN: %clang_cc1 %s -triple arm-apple-darwin  -target-feature +vfp2 -verify 
-fsyntax-only
+// RUN: %clang_cc1 %s -triple thumb-apple-darwin  -target-feature +vfp3 
-verify -fsyntax-only
+// RUN: %clang_cc1 %s -triple armeb-none-eabi  -target-feature +vfp4 -verify 
-fsyntax-only
+// RUN: %clang_cc1 %s -triple thumbeb-none-eabi  -target-feature +neon -verify 
-fsyntax-only
+// RUN: %clang_cc1 %s -triple thumbeb-none-eabi -target-feature +neon 
-target-feature +soft-float -DSOFT -verify -fsyntax-only
 
 __attribute__((interrupt(IRQ))) void foo() {} // expected-error {{'interrupt' 
attribute requires a string}}
 __attribute__((interrupt("irq"))) void foo1() {} // expected-warning 
{{'interrupt' attribute argument not supported: irq}}
@@ -24,6 +25,8 @@
   callee1();
   callee2();
 }
+
+#ifndef SOFT
 __attribute__((interrupt("IRQ"))) void caller2() {
   callee1(); // expected-warning {{call to function without interrupt 
attribute could clobber interruptee's VFP registers}}
   callee2();
@@ -33,3 +36,14 @@
 __attribute__((interrupt("IRQ"))) void caller3() {
   callee3(); // expected-warning {{call to function without interrupt 
attribute could clobber interruptee's VFP registers}}
 }
+#else
+__attribute__((interrupt("IRQ"))) void caller2() {
+  callee1();
+  callee2();
+}
+
+void (*callee3)();
+__attribute__((interrupt("IRQ"))) void caller3() {
+  callee3();
+}
+#endif


Index: cfe/trunk/lib/Sema/SemaExpr.cpp
===
--- cfe/trunk/lib/Sema/SemaExpr.cpp
+++ cfe/trunk/lib/Sema/SemaExpr.cpp
@@ -5399,9 +5399,11 @@
   // that the callee might not preserve them. This is easy to diagnose here,
   // but can be very challenging to debug.
   if (auto *Caller = getCurFunctionDecl())
-if (Caller->hasAttr())
-  if (!FDecl || !FDecl->hasAttr())
+if (Caller->hasAttr()) {
+  bool VFP = Context.getTargetInfo().hasFeature("vfp");
+  if (VFP && (!FDecl || !FDecl->hasAttr()))
 Diag(Fn->getExprLoc(), diag::warn_arm_interrupt_calling_convention);
+}
 
   // Promote the function operand.
   // We special-case function promotion here because we only allow promoting
Index: cfe/trunk/lib/Basic/Targets.cpp
===
--- cfe/trunk/lib/Basic/Targets.cpp
+++ cfe/trunk/lib/Basic/Targets.cpp
@@ -5443,6 +5443,7 @@
 .Case("softfloat", SoftFloat)
 .Case("thumb", isThumb())
 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
+.Case("vfp", FPU && !SoftFloat)
 .Case("hwdiv", HWDiv & HWDivThumb)
 .Case("hwdiv-arm", HWDiv & HWDivARM)
 .Default(false);
Index: cfe/trunk/test/Sema/arm-interrupt-attr.c
===
--- cfe/trunk/