[PATCH, i386]: Handle variable shifts in STV pass (PR 70799)
Hello! Attached patch adds handling of variable shifts in STV pass. The patch detects when we are processing QImode count register of a scalar shift instruction, and zero-extends it from QImode to DImode, either from scalar register or vector register. The extension is necessary, since scalar shifts operate with QImode value, where vector shifts truncate shifts using DImode value from count register. When the compiler is bootstrapped with --with-arch=corei7-avx --with-cpu=corei7-avx, there are quite some vector shifts generated in 32bit libraries. 2017-04-23 Uros Bizjak PR target/70799 * config/i386/i386.c (dimode_scalar_to_vector_candidate_p) : Also consider variable shifts. Check "XEXP (src, 1)" operand here. : Check "XEXP (src, 1)" operand here. (dimode_scalar_chain::make_vector_copies): Detect count register of a shift instruction. Zero extend count register from QImode to DImode to satisfy vector shift pattern count operand predicate. Substitute vector shift count operand with a DImode copy. (dimode_scalar_chain::convert_reg): Ditto, zero-extend from vector register. testsuite/ChangeLog: 2017-04-23 Uros Bizjak PR target/70799 * gcc.target/i386/pr70799-4.c: New test. Patch was bootstrapped and regression tested on x86_64-linux-gnu {,-m32}, configured with --with-arch=corei7-avx --with-cpu=corei7-avx. Index: config/i386/i386.c === --- config/i386/i386.c (revision 247077) +++ config/i386/i386.c (working copy) @@ -2811,10 +2811,17 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *ins { case ASHIFT: case LSHIFTRT: - /* FIXME: consider also variable shifts. */ - if (!CONST_INT_P (XEXP (src, 1)) - || !IN_RANGE (INTVAL (XEXP (src, 1)), 0, 63)) + if (!REG_P (XEXP (src, 1)) + && (!SUBREG_P (XEXP (src, 1)) + || SUBREG_BYTE (XEXP (src, 1)) != 0 + || !REG_P (SUBREG_REG (XEXP (src, 1 + && (!CONST_INT_P (XEXP (src, 1)) + || !IN_RANGE (INTVAL (XEXP (src, 1)), 0, 63))) return false; + + if (GET_MODE (XEXP (src, 1)) != QImode + && !CONST_INT_P (XEXP (src, 1))) + return false; break; case PLUS: @@ -2826,6 +2833,10 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *ins && !MEM_P (XEXP (src, 1)) && !CONST_INT_P (XEXP (src, 1))) return false; + + if (GET_MODE (XEXP (src, 1)) != DImode + && !CONST_INT_P (XEXP (src, 1))) + return false; break; case NEG: @@ -2852,12 +2863,8 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *ins || !REG_P (XEXP (XEXP (src, 0), 0 return false; - if ((GET_MODE (XEXP (src, 0)) != DImode - && !CONST_INT_P (XEXP (src, 0))) - || (GET_CODE (src) != NEG - && GET_CODE (src) != NOT - && GET_MODE (XEXP (src, 1)) != DImode - && !CONST_INT_P (XEXP (src, 1 + if (GET_MODE (XEXP (src, 0)) != DImode + && !CONST_INT_P (XEXP (src, 0))) return false; return true; @@ -3407,12 +3414,17 @@ dimode_scalar_chain::compute_convert_gain () else if (GET_CODE (src) == ASHIFT || GET_CODE (src) == LSHIFTRT) { - gain += ix86_cost->shift_const; if (CONST_INT_P (XEXP (src, 0))) gain -= vector_const_cost (XEXP (src, 0)); - if (CONST_INT_P (XEXP (src, 1)) - && INTVAL (XEXP (src, 1)) >= 32) - gain -= COSTS_N_INSNS (1); + if (CONST_INT_P (XEXP (src, 1))) + { + gain += ix86_cost->shift_const; + if (INTVAL (XEXP (src, 1)) >= 32) + gain -= COSTS_N_INSNS (1); + } + else + /* Additional gain for omitting two CMOVs. */ + gain += ix86_cost->shift_var + COSTS_N_INSNS (2); } else if (GET_CODE (src) == PLUS || GET_CODE (src) == MINUS @@ -3528,16 +3540,60 @@ dimode_scalar_chain::make_vector_copies (unsigned { rtx reg = regno_reg_rtx[regno]; rtx vreg = gen_reg_rtx (DImode); + bool count_reg = false; df_ref ref; for (ref = DF_REG_DEF_CHAIN (regno); ref; ref = DF_REF_NEXT_REG (ref)) if (!bitmap_bit_p (insns, DF_REF_INSN_UID (ref))) { - rtx_insn *insn = DF_REF_INSN (ref); + df_ref use; + /* Detect the count register of a shift instruction. */ + for (use = DF_REG_USE_CHAIN (regno); use; use = DF_REF_NEXT_REG (use)) + if (bitmap_bit_p (insns, DF_REF_INSN_UID (use))) + { + rtx_insn *insn = DF_REF_INSN (use); + rtx def_set = single_set (insn); + + gcc_assert (def_set); + + rtx src = SET_SRC (def_set); + + if ((GET_CODE (src) == ASHIFT + || GET_CODE (src) == LSHIFTRT) + && !CONST_INT_P (XEXP (src, 1)) + && reg_or_subregno (XEXP (src, 1)) == regno) +
Re: [patch, libgfortran] PR80484 Three syntax errors involving derived-type I/O
Hi Jerry, OK for trunk and 7-branch, when it reopens. Thanks for keeping Walt happy :-) Cheers Paul On 23 April 2017 at 03:28, Jerry DeLisle wrote: > Hi all, > > The attached patch fixes these issues. > > Regression tested on x86_64-pc-linux-gnu. New test attached. > > OK for Trunk (8)? I think we should backport to 7 when it re-opens. The > failing repeat count on DT format is very not good. > > Regards, > > Jerry > > 2017-04-22 Jerry DeLisle > > PR fortran/80484 > * io.c (format_lex): Check for '/' and set token to FMT_SLASH. > (check_format): Move FMT_DT checking code to data_desc section. > * module.c (gfc_match_use): Include the case of INTERFACE_DTIO. -- "If you can't explain it simply, you don't understand it well enough" - Albert Einstein
Re: [Patch, Fortran] PR 80121: Memory leak with derived-type intent(out) argument
Hi Thomas, >> the patch in the attachment fixes a memory leak by auto-deallocating >> the allocatable components of an allocatable intent(out) argument. >> >> Regtests cleanly on x86_64-linux-gnu. Ok for trunk? > > OK for trunk. thanks for the review! Committed as r247083. > Also (because this is a quite serious bug) > OK for gcc 7 after the release of 7.1. I tend to be a bit hesitant with backporting non-regression-fixes, but in this case I agree that it might make sense. (Will commit to 7-branch once it's open again, if no one objects.) At least the patch fixes the leak in the least invasive way I could find, although I was thinking out loudly about ways to refactor the intent(out) handling: > My feeling is that it would be a good idea to handle allocatable derived > types inside > of the callee as well. I can see at least two advantages: > * It would avoid code duplication if the procedure is called several times. > * It would take some complexity out of gfc_conv_procedure_call, which is > quite a > monster. > > From the technical side a treatment in the callee should be possible AFAICS. > I wonder > why it is being done in the caller at all? Any feedback is welcome here (possibly I'm missing some reason why this needs to be done by the caller?) ... Cheers, Janus
Re: [PATCH][ PR rtl-optimization/79286] Drop may_trap_p exception to testing dominance in update_equiv_regs
Hi Jeff, this patch tries to fix the handling of pic_offset_rtx + const(unspec(symbol_ref)+ const_int) in may_trap_p, and restores the original state of affairs in update_equiv_regs. What do you think is it OK to extract the symbol_ref out of the unspec in this way, or is does it need a target hook? Patch works at least for x86_64 and arm. Is it OK for trunk? Bernd. 2017-04-23 Bernd Edlinger rtl-optimizatoin/79286 * ira.c (update_equiv_regs): Revert to using may_tap_p again. * rtlanal.c (rtx_addr_can_trap_p_1): SYMBOL_REF_FUNCTION_P can never trap. Extract constant offset from pic_offset_table_rtx + const(unspec(symbol_ref)+int_val) and pic_offset_table_rtx + const(unspec(symbol_ref)), otherwise RTL may trap. Index: gcc/ira.c === --- gcc/ira.c (revision 247077) +++ gcc/ira.c (working copy) @@ -3551,7 +3551,8 @@ update_equiv_regs (void) if (DF_REG_DEF_COUNT (regno) == 1 && note && !rtx_varies_p (XEXP (note, 0), 0) - && def_dominates_uses (regno)) + && (!may_trap_or_fault_p (XEXP (note, 0)) + || def_dominates_uses (regno))) { rtx note_value = XEXP (note, 0); remove_note (insn, note); Index: gcc/rtlanal.c === --- gcc/rtlanal.c (revision 247077) +++ gcc/rtlanal.c (working copy) @@ -485,7 +485,7 @@ rtx_addr_can_trap_p_1 (const_rtx x, HOST_WIDE_INT case SYMBOL_REF: if (SYMBOL_REF_WEAK (x)) return 1; - if (!CONSTANT_POOL_ADDRESS_P (x)) + if (!CONSTANT_POOL_ADDRESS_P (x) && !SYMBOL_REF_FUNCTION_P (x)) { tree decl; HOST_WIDE_INT decl_size; @@ -645,8 +645,23 @@ rtx_addr_can_trap_p_1 (const_rtx x, HOST_WIDE_INT case PLUS: /* An address is assumed not to trap if: - it is the pic register plus a constant. */ - if (XEXP (x, 0) == pic_offset_table_rtx && CONSTANT_P (XEXP (x, 1))) - return 0; + if (XEXP (x, 0) == pic_offset_table_rtx + && GET_CODE (XEXP (x, 1)) == CONST) + { + x = XEXP (XEXP (x, 1), 0); + if (GET_CODE (x) == UNSPEC + && GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF) + return rtx_addr_can_trap_p_1(XVECEXP (x, 0, 0), + offset, size, mode, unaligned_mems); + if (GET_CODE (x) == PLUS + && GET_CODE (XEXP (x, 0)) == UNSPEC + && GET_CODE (XVECEXP (XEXP (x, 0), 0, 0)) == SYMBOL_REF + && CONST_INT_P (XEXP (x, 1))) + return rtx_addr_can_trap_p_1(XVECEXP (XEXP (x, 0), 0, 0), + offset + INTVAL (XEXP (x, 1)), + size, mode, unaligned_mems); + return 1; + } /* - or it is an address that can't trap plus a constant integer. */ if (CONST_INT_P (XEXP (x, 1))
[PATCH] Finish implementing P0426R1 "Constexpr for std::char_traits" for C++17
Hi! As I had suggested in PR c++/80265, here's a patch that uses __builtin_constant_p to tell whether we can defer to a constexpr algorithm, which avoids having to wait for compiler support. Unfortunately I ran out of cycles today to run a full bootstrap/regtest cycle, but constexpr_functions_c++17.cc passes cleanly on x86_64 GNU/Linux at least. If this looks like a reasonable approach, I can maybe try running full tests on the gcc compile farm next week. WDYT? Thanks, Pedro Alves >From 91606ca1f51309121e292559bcb6b2cfc126737b Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Sun, 23 Apr 2017 14:16:09 +0100 Subject: [PATCH] Finish implementing P0426R1 "Constexpr for std::char_traits" for C++17 As discussed in PR c++/80265 (__builtin_{memcmp,memchr,strlen} are not usable in constexpr functions), use __builtin_constant_p to tell whether we can defer to a constexpr algorithm. I used __always_inline__ just to be thorough. It isn't really really necessary as far as I could determine. Changes like these: if (__n == 0) return 0; - return wmemcmp(__s1, __s2, __n); + else +return wmemcmp(__s1, __s2, __n); are necessary otherwise G++ complains that we're calling a non-constexpr function, which looks like a a manifestation of PR67026 to me. libstdc++-v3: 2017-04-23 Pedro Alves * doc/xml/manual/status_cxx2017.xml: Update C++17 constexpr char_traits status. * doc/html/*: Regenerate. * include/bits/char_traits.h (_GLIBCXX_ALWAYS_INLINE): Define if not already defined. (__cpp_lib_constexpr_char_traits): Uncomment. (__constant_string_p, __constant_char_array_p): New. (std::char_traits, std::char_traits): Add _GLIBCXX17_CONSTEXPR on compare, length, find and assign and use __constant_string_p, __constant_char_array_p and __builtin_constant_p to defer to __gnu_cxx::char_traits at compile time. * testsuite/21_strings/char_traits/requirements/ constexpr_functions_c++17.cc: Uncomment __cpp_lib_constexpr_char_traits tests. Uncomment test_compare, test_length, test_find, test_compare, test_length and test_find static_assert tests. --- libstdc++-v3/doc/xml/manual/status_cxx2017.xml | 4 +- libstdc++-v3/include/bits/char_traits.h| 120 ++--- .../requirements/constexpr_functions_c++17.cc | 16 +-- 3 files changed, 116 insertions(+), 24 deletions(-) diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml index 0e35f75..fed91f9 100644 --- a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml +++ b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml @@ -489,8 +489,8 @@ Feature-testing recommendations for C++. P0426R1 - 7 (partial) - ??? + 7 + __cpp_lib_constexpr_char_traits >= 201611 diff --git a/libstdc++-v3/include/bits/char_traits.h b/libstdc++-v3/include/bits/char_traits.h index 75db5b8..cc636a9 100644 --- a/libstdc++-v3/include/bits/char_traits.h +++ b/libstdc++-v3/include/bits/char_traits.h @@ -40,6 +40,10 @@ #include // For streampos #include// For WEOF, wmemmove, wmemset, etc. +#ifndef _GLIBCXX_ALWAYS_INLINE +#define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__)) +#endif + namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -139,7 +143,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } }; -// #define __cpp_lib_constexpr_char_traits 201611 +#define __cpp_lib_constexpr_char_traits 201611 template _GLIBCXX14_CONSTEXPR int @@ -212,6 +216,42 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +#if __cplusplus > 201402 + /** + * @brief Determine whether the characters of a NULL-terminated + * string are known at compile time. + * @param __s The string. + * + * Assumes that _CharT is a built-in character type. + */ + template +static _GLIBCXX_ALWAYS_INLINE constexpr bool +__constant_string_p(const _CharT* __s) +{ + while (__builtin_constant_p(*__s) && *__s) + __s++; + return __builtin_constant_p(*__s); +} + + /** + * @brief Determine whether the characters of a character array are + * known at compile time. + * @param __a The character array. + * @param __n Number of characters. + * + * Assumes that _CharT is a built-in character type. + */ + template +static _GLIBCXX_ALWAYS_INLINE constexpr bool +__constant_char_array_p(const _CharT* __a, size_t __n) +{ + size_t __i = 0; + while (__builtin_constant_p(__a[__i]) && __i < __n) + __i++; + return __i == __n; +} +#endif + // 21.1 /** * @brief Basis for explicit traits specializations. @@ -256,21 +296,39 @@ _GLIBCXX_BEGI
Re: [PATCH] Finish implementing P0426R1 "Constexpr for std::char_traits" for C++17
On 04/23/2017 06:54 PM, Pedro Alves wrote: > Hi! > > As I had suggested in PR c++/80265, here's a patch that uses > __builtin_constant_p to tell whether we can defer to a constexpr > algorithm, which avoids having to wait for compiler support. > > Unfortunately I ran out of cycles today to run a full bootstrap/regtest > cycle, but constexpr_functions_c++17.cc passes cleanly on > x86_64 GNU/Linux at least. > > If this looks like a reasonable approach, I can maybe try running > full tests on the gcc compile farm next week. > > WDYT? Reading the patch via the list made me spot something that was incorrect. > > - static char_type* > + static _GLIBCXX17_CONSTEXPR char_type* >assign(char_type* __s, size_t __n, char_type __a) >{ > +#if __cplusplus > 201402 > + if (__constant_string_p(__s) This should probably have been __constant_char_array_p, but now that I look again at the paper, I see I got myself confused -- this assign overload is not meant to be constexpr in the first place. So here's an updated patch that drops that bit. (Same testing as before.) >From 71cf9b9a3ea79bd790d792c9a02e5a577f1af156 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Sun, 23 Apr 2017 14:16:09 +0100 Subject: [PATCH] Finish implementing P0426R1 "Constexpr for std::char_traits" for C++17 As discussed in PR c++/80265 (__builtin_{memcmp,memchr,strlen} are not usable in constexpr functions), use __builtin_constant_p to tell whether we can defer to a constexpr algorithm. I used __always_inline__ just to be thorough. It isn't really really necessary as far as I could determine. Changes like these: if (__n == 0) return 0; - return wmemcmp(__s1, __s2, __n); + else +return wmemcmp(__s1, __s2, __n); are necessary otherwise G++ complains that we're calling a non-constexpr function, which looks like a a manifestation of PR67026 to me. libstdc++-v3: 2017-04-23 Pedro Alves * doc/xml/manual/status_cxx2017.xml: Update C++17 constexpr char_traits status. * doc/html/*: Regenerate. * include/bits/char_traits.h (_GLIBCXX_ALWAYS_INLINE): Define if not already defined. (__cpp_lib_constexpr_char_traits): Uncomment. (__constant_string_p, __constant_char_array_p): New. (std::char_traits, std::char_traits): Add _GLIBCXX17_CONSTEXPR on compare, length and find and use __constant_string_p, __constant_char_array_p and __builtin_constant_p to defer to __gnu_cxx::char_traits at compile time. * testsuite/21_strings/char_traits/requirements/ constexpr_functions_c++17.cc: Uncomment __cpp_lib_constexpr_char_traits tests. Uncomment test_compare, test_length, test_find, test_compare, test_length and test_find static_assert tests. --- libstdc++-v3/doc/xml/manual/status_cxx2017.xml | 4 +- libstdc++-v3/include/bits/char_traits.h| 101 ++--- .../requirements/constexpr_functions_c++17.cc | 16 ++-- 3 files changed, 100 insertions(+), 21 deletions(-) diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml index 0e35f75..fed91f9 100644 --- a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml +++ b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml @@ -489,8 +489,8 @@ Feature-testing recommendations for C++. P0426R1 - 7 (partial) - ??? + 7 + __cpp_lib_constexpr_char_traits >= 201611 diff --git a/libstdc++-v3/include/bits/char_traits.h b/libstdc++-v3/include/bits/char_traits.h index 75db5b8..3ecc30e 100644 --- a/libstdc++-v3/include/bits/char_traits.h +++ b/libstdc++-v3/include/bits/char_traits.h @@ -40,6 +40,10 @@ #include // For streampos #include// For WEOF, wmemmove, wmemset, etc. +#ifndef _GLIBCXX_ALWAYS_INLINE +#define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__)) +#endif + namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -139,7 +143,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } }; -// #define __cpp_lib_constexpr_char_traits 201611 +#define __cpp_lib_constexpr_char_traits 201611 template _GLIBCXX14_CONSTEXPR int @@ -212,6 +216,42 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +#if __cplusplus > 201402 + /** + * @brief Determine whether the characters of a NULL-terminated + * string are known at compile time. + * @param __s The string. + * + * Assumes that _CharT is a built-in character type. + */ + template +static _GLIBCXX_ALWAYS_INLINE constexpr bool +__constant_string_p(const _CharT* __s) +{ + while (__builtin_constant_p(*__s) && *__s) + __s++; + return __builtin_constant_p(*__s); +} + + /** + * @brief Determine whet
[PATCH] Simplify quoting in diagnostics of C++ frontend
Hi, the following patch simplifies quoting in diagnostics by using %qD instead of %<%D%> etc. Bootstrapped and regtested on x86_64-pc-linux-gnu. Btw, line 14563 in pt.c error ("enumerator value %E is outside the range of underlying " contains an unquoted %E. Shouldn't that be replaced with %qE? OK for trunk? Regards, Volker 2017-04-23 Volker Reichelt * decl.c (grokdeclarator): Use %qT instead of %<%T%> in diagnostics. (start_enum): Likewise. (build_enumerator): Likewise. * parser.c (cp_parser_mem_initializer_list): Use %qD instead of %<%D%> in diagnostics. (cp_parser_elaborated_type_specifier): Likewise. * pt.c (make_pack_expansion): Use %qT and %qE instead of %<%T%> and %<%E%> in diagnostics. (tsubst_pack_expansion): Likewise. Index: gcc/cp/decl.c === --- gcc/cp/decl.c (revision 247067) +++ gcc/cp/decl.c (working copy) @@ -11433,9 +11433,9 @@ { error (funcdef_flag || initialized ? G_("cannot define member function %<%T::%s%> " - "within %<%T%>") + "within %qT") : G_("cannot declare member function %<%T::%s%> " - "within %<%T%>"), + "within %qT"), ctype, name, current_class_type); return error_mark_node; } @@ -14150,7 +14150,7 @@ else if (dependent_type_p (underlying_type)) ENUM_UNDERLYING_TYPE (enumtype) = underlying_type; else -error ("underlying type %<%T%> of %<%T%> must be an integral type", +error ("underlying type %qT of %qT must be an integral type", underlying_type, enumtype); } @@ -14561,7 +14561,7 @@ { if (!int_fits_type_p (value, ENUM_UNDERLYING_TYPE (enumtype))) error ("enumerator value %E is outside the range of underlying " - "type %<%T%>", value, ENUM_UNDERLYING_TYPE (enumtype)); + "type %qT", value, ENUM_UNDERLYING_TYPE (enumtype)); /* Convert the value to the appropriate type. */ value = fold_convert (ENUM_UNDERLYING_TYPE (enumtype), value); Index: gcc/cp/parser.c === --- gcc/cp/parser.c (revision 247067) +++ gcc/cp/parser.c (working copy) @@ -14073,7 +14073,7 @@ && !TYPE_P (TREE_PURPOSE (mem_initializer))) { error_at (token->location, - "cannot expand initializer for member %<%D%>", + "cannot expand initializer for member %qD", TREE_PURPOSE (mem_initializer)); mem_initializer = error_mark_node; } @@ -17263,7 +17263,7 @@ || cp_lexer_next_token_is_keyword (parser->lexer, RID_STRUCT)) { pedwarn (input_location, 0, "elaborated-type-specifier " - "for a scoped enum must not use the %<%D%> keyword", + "for a scoped enum must not use the %qD keyword", cp_lexer_peek_token (parser->lexer)->u.value); /* Consume the `struct' or `class' and parse it anyway. */ cp_lexer_consume_token (parser->lexer); Index: gcc/cp/pt.c === --- gcc/cp/pt.c (revision 247067) +++ gcc/cp/pt.c (working copy) @@ -3701,7 +3701,7 @@ if (parameter_packs == NULL_TREE) { - error ("base initializer expansion %<%T%> contains no parameter packs", arg); + error ("base initializer expansion %qT contains no parameter packs", arg); delete ppd.visited; return error_mark_node; } @@ -3765,9 +3765,9 @@ if (parameter_packs == NULL_TREE) { if (TYPE_P (arg)) -error ("expansion pattern %<%T%> contains no argument packs", arg); +error ("expansion pattern %qT contains no argument packs", arg); else -error ("expansion pattern %<%E%> contains no argument packs", arg); +error ("expansion pattern %qE contains no argument packs", arg); return error_mark_node; } PACK_EXPANSION_PARAMETER_PACKS (result) = parameter_packs; @@ -11409,12 +11409,10 @@ if (!(complain & tf_error)) /* Fail quietly. */; else if (TREE_CODE (t) == TYPE_PACK_EXPANSION) -error ("mismatched argument pack lengths while expanding " - "%<%T%>", +error ("mismatched argument pack lengths while expanding %qT", pattern); else -error ("mismatched argument pack lengths while expanding " - "%<%E%>", +error ("mismatched argument pack lengths while expanding %qE",
Let tree_single_nonzero_warnv_p use VRP
Hello, this patches teaches tree_expr_nonzero_warnv_p to handle SSA_NAME using range information and known (non-)zero bits, by delegating to expr_not_equal_to which already knows how to handle all that. This makes one strict overflow warning disappear. It isn't particularly surprising, since the new code makes tree_expr_nonzero_warnv_p return true without warning (we do not remember if the range information was obtained using strict overflow). In my opinion, improving code generation is more important than this specific warning. Bootstrap+regtest on powerpc64le-unknown-linux-gnu. 2017-04-24 Marc Glisse gcc/ * fold-const.c (tree_single_nonzero_warnv_p): Handle SSA_NAME. gcc/testsuite/ * gcc.dg/tree-ssa/cmpmul-1.c: New file. * gcc.dg/Wstrict-overflow-18.c: Xfail. -- Marc GlisseIndex: gcc/fold-const.c === --- gcc/fold-const.c (revision 247083) +++ gcc/fold-const.c (working copy) @@ -13405,20 +13405,23 @@ tree_single_nonzero_warnv_p (tree t, boo &sub_strict_overflow_p) && tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 2), &sub_strict_overflow_p)) { if (sub_strict_overflow_p) *strict_overflow_p = true; return true; } break; +case SSA_NAME: + return expr_not_equal_to (t, wi::zero (TYPE_PRECISION (TREE_TYPE (t; + default: break; } return false; } #define integer_valued_real_p(X) \ _Pragma ("GCC error \"Use RECURSE for recursive calls\"") 0 #define RECURSE(X) \ Index: gcc/testsuite/gcc.dg/Wstrict-overflow-18.c === --- gcc/testsuite/gcc.dg/Wstrict-overflow-18.c (revision 247083) +++ gcc/testsuite/gcc.dg/Wstrict-overflow-18.c (working copy) @@ -7,16 +7,16 @@ struct c { unsigned int a; unsigned int b; }; extern void bar (struct c *); int foo (struct c *p) { int i; int sum = 0; for (i = 0; i < p->a - p->b; ++i) { - if (i > 0) /* { dg-warning "signed overflow" "" } */ + if (i > 0) /* { dg-warning "signed overflow" "" { xfail *-*-* } } */ sum += 2; bar (p); } return sum; } Index: gcc/testsuite/gcc.dg/tree-ssa/cmpmul-1.c === --- gcc/testsuite/gcc.dg/tree-ssa/cmpmul-1.c (nonexistent) +++ gcc/testsuite/gcc.dg/tree-ssa/cmpmul-1.c (working copy) @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized-raw" } */ + +int f(int a, int b, int c){ + c |= 1; // c cannot be 0 + a *= c; + b *= c; + return a == b; +} + +/* { dg-final { scan-tree-dump-not "bit_ior_expr" "optimized" } } */
X /[ex] 4 < Y /[ex] 4
Hello, we were missing this simplification on comparisons. Note that the testcase still does not simplify as much as one might like, we don't turn x+z gcc/ * match.pd (X/[ex]C CMP Y/[ex]C): New transformation. gcc/testsuite/ * gcc.dg/tree-ssa/cmpexactdiv-2.c: New file. -- Marc GlisseIndex: gcc/match.pd === --- gcc/match.pd (revision 247083) +++ gcc/match.pd (working copy) @@ -1028,20 +1028,27 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (simplify (cmp (mult:c @0 @1) (mult:c @2 @1)) (if (INTEGRAL_TYPE_P (TREE_TYPE (@1)) && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))) (if (tree_expr_nonnegative_p (@1) && tree_expr_nonzero_p (@1)) (cmp @0 @2) (if (TREE_CODE (@1) == INTEGER_CST && wi::neg_p (@1, TYPE_SIGN (TREE_TYPE (@1 (cmp @2 @0)) +/* X / 4 < Y / 4 iif X < Y when the division is known to be exact. */ +(for cmp (simple_comparison) + (simplify + (cmp (exact_div @0 INTEGER_CST@2) (exact_div @1 @2)) + (if (wi::gt_p(@2, 0, TYPE_SIGN (TREE_TYPE (@2 + (cmp @0 @1 + /* ((X inner_op C0) outer_op C1) With X being a tree where value_range has reasoned certain bits to always be zero throughout its computed value range, inner_op = {|,^}, outer_op = {|,^} and inner_op != outer_op where zero_mask has 1's for all bits that are sure to be 0 in and 0's otherwise. if (inner_op == '^') C0 &= ~C1; if ((C0 & ~zero_mask) == 0) then emit (X outer_op (C0 outer_op C1) if ((C1 & ~zero_mask) == 0) then emit (X inner_op (C0 outer_op C1) */ Index: gcc/testsuite/gcc.dg/tree-ssa/cmpexactdiv-2.c === --- gcc/testsuite/gcc.dg/tree-ssa/cmpexactdiv-2.c (nonexistent) +++ gcc/testsuite/gcc.dg/tree-ssa/cmpexactdiv-2.c (working copy) @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized-raw" } */ + +int f (long *a, long *b, long *c) { +__PTRDIFF_TYPE__ l1 = b - a; +__PTRDIFF_TYPE__ l2 = c - a; +return l1 < l2; +} + +/* Eventually we also want to remove all minus_expr. */ +/* { dg-final { scan-tree-dump-not "exact_div_expr" "optimized" } } */
Re: X /[ex] 4 < Y /[ex] 4
On Mon, Apr 24, 2017 at 08:24:48AM +0200, Marc Glisse wrote: > --- gcc/match.pd (revision 247083) > +++ gcc/match.pd (working copy) > @@ -1028,20 +1028,27 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (simplify >(cmp (mult:c @0 @1) (mult:c @2 @1)) >(if (INTEGRAL_TYPE_P (TREE_TYPE (@1)) > && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))) > (if (tree_expr_nonnegative_p (@1) && tree_expr_nonzero_p (@1)) > (cmp @0 @2) > (if (TREE_CODE (@1) == INTEGER_CST > && wi::neg_p (@1, TYPE_SIGN (TREE_TYPE (@1 > (cmp @2 @0)) > > +/* X / 4 < Y / 4 iif X < Y when the division is known to be exact. */ s/iif/iff/ ? Jakub