[VRP] Improve value ranges for unsigned division
As discussed in PR64130, this patch improves the VRP value ranges for unsigned division. Bootstrapped and regression tested on x86_64-linux-gnu and regression tested on arm-none-linux-gnu with no new regression. Is this OK for trunk? Thanks, Kugan gcc/ChangeLog: 2015-06-20 Kugan Vivekanandarajah PR middle-end/64130 * tree-vrp.c (extract_range_from_binary_expr_1): For unsigned division, compute minimum when value ranges for dividend and divisor are available. gcc/testsuite/ChangeLog: 2015-06-20 Kugan Vivekanandarajah PR middle-end/64130 * gcc.dg/tree-ssa/pr64130.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr64130.c b/gcc/testsuite/gcc.dg/tree-ssa/pr64130.c index e69de29..9e96abb 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr64130.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr64130.c @@ -0,0 +1,11 @@ + +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-vrp1" } */ + +int funsigned(unsigned a) +{ + return 0x1L / a == 0; +} + +/* { dg-final { scan-tree-dump ": \\\[2, 8589934591\\\]" "vrp1" } } */ + diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index b517363..2e1c84b 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -3158,7 +3158,16 @@ extract_range_from_binary_expr_1 (value_range_t *vr, type = VR_VARYING; cmp = compare_values (vr0.min, zero); if (cmp == 1) - min = zero; + { + /* For unsigned division when value ranges for dividend +and divisor are available. */ + if (vr1.type == VR_RANGE + && !symbolic_range_p (&vr0) + && !symbolic_range_p (&vr1)) + min = int_const_binop (code, vr0.min, vr1.max); + else + min = zero; + } else if (cmp == 0 || cmp == -1) min = vr0.min; else
Re: [patch] Fix two libstdc++ test failures with -std=gnu++14
On 16/06/2015 22:45, Jonathan Wakely wrote: > On 16/06/15 22:18 +0200, François Dumont wrote: >> On 12/06/2015 01:22, Jonathan Wakely wrote: >>> This fixes two test failures when the default compiler mode is >>> -std=gnu++14 >>> >>> FAIL: 25_algorithms/headers/algorithm/synopsis.cc (test for excess >>> errors) >>> FAIL: ext/profile/mutex_extensions_neg.cc (test for excess errors) >>> >>> I don't really like the change to the synopsis.cc test, but I don't >>> think reproducing the SFINAE constraints in the test is ideal either. >>> >>> The mutex_extensions_neg.cc test works now, but I think we're missing >>> specializations of __is_tuple_like_impl for __gnu_debug::array and >>> __gnu_profile::array. >>> >>> Tested powerpc64le-linux, committed to trunk. >>> >> This patch introduced a regression in >> 20_util/tuple/creation_functions/tuple_cat.cc in debug mode. > > Yes, I noticed this today while testing some changes to , > but hadn't had time to do anything about it, so thanks for taking care > of it. > >> Attached is a proposal to fix it properly. I am using as a >> pivot header between and . This way do not need >> to include anymore. > > I think that's a good improvement. But it doesn't work. needs to be included before tuple to make sure that constexpr involving array will work. So here is a less ambitious patch keeping in . What I don't understand is that when I try to remove from following code stop working: #include #include static_assert(std::is_same>())), std::tuple>::value, "Error"); but if I invert and it does work. Now with in it works fine in any situation. However when I write: #include #include static_assert(std::is_same>())), std::tuple>::value, "Error"); it works too and I don't understand why ! * include/debug/array: Include normal array. Add version namespace when specializing tuple interface to array. Add specialization for __is_tuple_like_impl. * include/profile/array: Likewise. * include/std/array: Include . Add specialization for __is_tuple_like_impl. * include/std/tuple (__is_tuple_like_impl<>, __is_tuple_like_impl): Move... * include/std/utility: ... here. Include . Tested under Linux x86_64 normal and debug modes. Ok to commit ? François diff --git a/libstdc++-v3/include/debug/array b/libstdc++-v3/include/debug/array index 34e6281..a1c7d40 100644 --- a/libstdc++-v3/include/debug/array +++ b/libstdc++-v3/include/debug/array @@ -31,6 +31,8 @@ #pragma GCC system_header +#include + #include #include @@ -292,20 +294,27 @@ namespace __debug } } // namespace __debug +_GLIBCXX_BEGIN_NAMESPACE_VERSION // Tuple interface to class template array. /// tuple_size template -struct tuple_size<__debug::array<_Tp, _Nm>> +struct tuple_size> : public integral_constant { }; /// tuple_element template -struct tuple_element<_Int, __debug::array<_Tp, _Nm>> +struct tuple_element<_Int, std::__debug::array<_Tp, _Nm>> { static_assert(_Int < _Nm, "index is out of bounds"); typedef _Tp type; }; + + template +struct __is_tuple_like_impl> : true_type +{ }; + +_GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // _GLIBCXX_DEBUG_ARRAY diff --git a/libstdc++-v3/include/profile/array b/libstdc++-v3/include/profile/array index 434ca96..687c052 100644 --- a/libstdc++-v3/include/profile/array +++ b/libstdc++-v3/include/profile/array @@ -31,6 +31,8 @@ #pragma GCC system_header +#include + namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile @@ -253,20 +255,27 @@ namespace __profile } } // namespace __profile +_GLIBCXX_BEGIN_NAMESPACE_VERSION // Tuple interface to class template array. /// tuple_size template -struct tuple_size<__profile::array<_Tp, _Nm>> +struct tuple_size> : public integral_constant { }; /// tuple_element template -struct tuple_element<_Int, __profile::array<_Tp, _Nm>> +struct tuple_element<_Int, std::__profile::array<_Tp, _Nm>> { static_assert(_Int < _Nm, "index is out of bounds"); typedef _Tp type; }; + + template +struct __is_tuple_like_impl> : true_type +{ }; + +_GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // _GLIBCXX_PROFILE_ARRAY diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array index 40fbd46..d1b5e6d 100644 --- a/libstdc++-v3/include/std/array +++ b/libstdc++-v3/include/std/array @@ -35,6 +35,7 @@ # include #else +#include #include #include #include @@ -331,6 +332,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef _Tp type; }; + template +struct __is_tuple_like_impl<_GLIBCXX_STD_C::array<_Tp, _Nm>> : true_type +{ }; + _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 953d16b..0504012 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-
Do not take address of empty string front
Hi 2 experimental tests are failing in debug mode because __do_str_codecvt is sometimes taking address of string front() and back() even if empty. It wasn't use so not a big issue but it still seems better to avoid. I propose to rather use string begin() to get buffer address. I kept operator& as it is what was used, do you think we should use addressof ? At the same time I improve string debug mode cause with front() implemented as operator[](0) it is ok even if string is empty while back() implemented as operator[](size()-1) is not which is quite inconsistent. So I added a number of !empty() checks in several methods to detect more easily all those invalid usages. * include/bits/basic_string.h (basic_string<>::front()): Add !empty debug check. (basic_string<>::back()): Likewise. (basic_string<>::pop_back()): Likewise. * include/bits/locale_env.h (__do_std_codecvt): Do not take address of string::front() when string is empty. * include/debug/macros.h (__glibcxx_check_string, __glibcxx_check_string_len): Implement using _GLIBCXX_DEBUG_PEDASSERT. Tested under Linux x86_64 debug mode. Ok to commit ? François diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 093f502..923fb83 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -39,6 +39,7 @@ #include #include #include + #if __cplusplus >= 201103L #include #endif @@ -903,7 +904,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 */ reference front() noexcept - { return operator[](0); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + return operator[](0); + } /** * Returns a read-only (constant) reference to the data at the first @@ -911,7 +915,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 */ const_reference front() const noexcept - { return operator[](0); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + return operator[](0); + } /** * Returns a read/write reference to the data at the last @@ -919,7 +926,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 */ reference back() noexcept - { return operator[](this->size() - 1); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + return operator[](this->size() - 1); + } /** * Returns a read-only (constant) reference to the data at the @@ -927,7 +937,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 */ const_reference back() const noexcept - { return operator[](this->size() - 1); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + return operator[](this->size() - 1); + } #endif // Modifiers: @@ -1506,7 +1519,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 */ void pop_back() noexcept - { _M_erase(size()-1, 1); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + _M_erase(size() - 1, 1); + } #endif // C++11 /** @@ -3308,7 +3324,10 @@ _GLIBCXX_END_NAMESPACE_CXX11 */ reference front() - { return operator[](0); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + return operator[](0); + } /** * Returns a read-only (constant) reference to the data at the first @@ -3316,7 +3335,10 @@ _GLIBCXX_END_NAMESPACE_CXX11 */ const_reference front() const _GLIBCXX_NOEXCEPT - { return operator[](0); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + return operator[](0); + } /** * Returns a read/write reference to the data at the last @@ -3324,7 +3346,10 @@ _GLIBCXX_END_NAMESPACE_CXX11 */ reference back() - { return operator[](this->size() - 1); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + return operator[](this->size() - 1); + } /** * Returns a read-only (constant) reference to the data at the @@ -3332,7 +3357,10 @@ _GLIBCXX_END_NAMESPACE_CXX11 */ const_reference back() const _GLIBCXX_NOEXCEPT - { return operator[](this->size() - 1); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + return operator[](this->size() - 1); + } #endif // Modifiers: @@ -3819,7 +3847,10 @@ _GLIBCXX_END_NAMESPACE_CXX11 */ void pop_back() // FIXME C++11: should be noexcept. - { erase(size()-1, 1); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + erase(size() - 1, 1); + } #endif // C++11 /** diff --git a/libstdc++-v3/include/bits/locale_conv.h b/libstdc++-v3/include/bits/locale_conv.h index 61b535c..8def30d 100644 --- a/libstdc++-v3/include/bits/locale_conv.h +++ b/libstdc++-v3/include/bits/locale_conv.h @@ -66,10 +66,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION do { __outstr.resize(__outstr.size() + (__last - __next) * __maxlen); - auto __outnext = &__outstr.front() + __outchars; - auto const __outlast = &__outstr.back() + 1; + auto __outnext = &(*__outstr.begin()) + __outchars; + auto const __outlast = &(*__o
[PATCH] config/bfin/bfin.c (hwloop_optimize): Set JUMP_LABEL() after emit jump_insn
JUMP_LABLE() must be defined after optimization completed. In this case, it is doing optimization, and is almost finished, so it is no chances to set JUMP_LABLE() next. The related issue is Bug 65803. 2015-06-20 Chen Gang * config/bfin/bfin.c (hwloop_optimize): Set JUMP_LABEL() after emit jump_insn. --- gcc/config/bfin/bfin.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index 3b4b54e..23c2d51 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -3775,7 +3775,10 @@ hwloop_optimize (hwloop_info loop) } else { - emit_jump_insn (gen_jump (label)); + rtx_insn * ret = emit_jump_insn (gen_jump (label)); + + JUMP_LABEL(ret) = label; + LABEL_NUSES (label)++; seq_end = emit_barrier (); } } -- 1.9.3
Re: Do not take address of empty string front
On 20/06/15 12:03 +0200, François Dumont wrote: Hi 2 experimental tests are failing in debug mode because __do_str_codecvt is sometimes taking address of string front() and back() even if empty. It wasn't use so not a big issue but it still seems better to avoid. I propose to rather use string begin() to get buffer address. But derefencing begin() is still undefined for an empty string. Shouldn't that fail for debug mode too? Why change one form of undefined behaviour that we diagnose to another form that we don't diagnose? It would be better if that function didn't do any work when the input range is empty: --- a/libstdc++-v3/include/bits/locale_conv.h +++ b/libstdc++-v3/include/bits/locale_conv.h @@ -58,6 +58,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _OutStr& __outstr, const _Codecvt& __cvt, _State& __state, size_t& __count, _Fn __fn) { + if (__first == __last) + { + __outstr.clear(); + return true; + } + size_t __outchars = 0; auto __next = __first; const auto __maxlen = __cvt.max_length() + 1; I kept operator& as it is what was used, do you think we should use addressof ? I don't expect that function to get used with anything except built-in character types (char, wchar_t, char16_t, char32_t) which don't use ADL so can't find an overloaded operator&. At the same time I improve string debug mode cause with front() implemented as operator[](0) it is ok even if string is empty while back() implemented as operator[](size()-1) is not which is quite inconsistent. So I added a number of !empty() checks in several methods to detect more easily all those invalid usages. Nice. These would all be candidates for the "debug mode lite" that I want. * include/bits/basic_string.h (basic_string<>::front()): Add !empty debug check. (basic_string<>::back()): Likewise. (basic_string<>::pop_back()): Likewise. * include/bits/locale_env.h (__do_std_codecvt): Do not take address of N.B. include/bits/locale_conv.h not locale_env.h
Re: [PATCH, rs6000] Fix PR65914
On Jun 19, 2015, at 5:36 PM, David Edelsohn wrote: > Maybe you should ask Richi or Jakub about the testcase because you are > placing it in a non-target-specific location. It should succeed on > all targets, but it may expose latent bugs on other targets. A latent bug is one that is broken, but appears to work, and then a change in the compiler is made to expose the bug that was always there but didn’t show a failure. It only applies to the compiler proper. In this case, since the change is to add a test case, the test case can only show bugs that aren’t latent (or failures in the test case).