[PATCH, i386]: Handle variable shifts in STV pass (PR 70799)

2017-04-23 Thread Uros Bizjak
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

2017-04-23 Thread Paul Richard Thomas
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

2017-04-23 Thread Janus Weil
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

2017-04-23 Thread Bernd Edlinger
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

2017-04-23 Thread Pedro Alves
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

2017-04-23 Thread Pedro Alves
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

2017-04-23 Thread Volker Reichelt
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

2017-04-23 Thread Marc Glisse

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

2017-04-23 Thread Marc Glisse

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

2017-04-23 Thread Jakub Jelinek
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