Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-12 Thread Jeff Law

On 08/06/14 13:45, DJ Delorie wrote:

That's one of the things that would be largely made irrelevant by
DJ's proposed changes.  Instead of using PSImode,


What’s PSImode?


PSImode is a mode with more precision than HImode, but less than SImode.


we'd be able to define modes of precisely the number of bits one
of these targets needs.


Not quite, Jeff.  We still use PSImode but now it has a known defined
precision, not just fits in SImode, and may correspond to one of the
__intN types.
Ah, cool, I didn't know all that was in.  Glad to know that we can 
precisely define the precision of the partial modes.



There's still lots of places in gcc that use SIZE where they should
use PRECISION.

Yea, I suspect this is rather pervasive.

Jeff


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-12 Thread DJ Delorie

 Ah, cool, I didn't know all that was in.

Well, the precision part is in, but the __intN part isn't yet.  Each
time I do a final check for regressions, something new has been
added to gcc which breaks it all again... :-P


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-07 Thread Richard Biener
On Wed, 6 Aug 2014, Mike Stump wrote:

 On Aug 6, 2014, at 12:56 AM, Richard Biener rguent...@suse.de wrote:
  My concern is the code we're removing discusses the need to simplify when
  these expressions are in static initializers.  What's going to ensure that
  we're still simplifying instances which appear in static initializers?  I
  don't see anything which tests that.   And does it still work for targets
  which utilize PSImode?
  
  You mean stuff like
  
  int i[4];
  const int p = i - (i + 2);
 
 No.
 
   long p = i - (i + 2);
 
 in C++.  It is valid and so it has to work.  Further, there is a well known 
 problem that if you get all the constants correct, you get to statically 
 initialize this and have no constructors.  Though the above is trivial, in 
 large C++ source bases, there is an important set of things that one must do 
 to hit expected quality.  Fold, fold, fold is the name of the game, and if 
 you do it well, you get app startup time that is short, and if you don’t do 
 it well, you get app startup time that sucks.  Some folks care about startup 
 time.  So for example, there are well known pdf viewers that use gcc to 
 compile and whose startup time would be a order of magnitude or more worse if 
 gcc didn’t optimize it as well as it does.  There are large OS vendors that 
 had:

It always works - you eventually get a runtime constructor though.

   -Wglobal-constructors
   Warn about namespace scope data that requires construction or 
 destruction, or functions that use the constructor
   attribute or the destructor attribute.  Additionally warn if the 
 Objective-C GNU runtime is used to initialize
   various metadata.
 
 and used it to ensure (-Werror) that no constructors would sneak in anyplace, 
 as the corporate guide was no, you don’t get to do that.  Exceptions are made 
 and really, the main thing that hurt the most were libraries that users might 
 use, but you get the idea.
 
 The right way to think of the cost was page faults proportional to the size 
 of the app, or, 0.  Pages faults turn out to be rather expensive as the core 
 speed of the processor is rather fast.  I know sounds overly expensive, but 
 that is my experience with Ado.., oops, I mean, with one critical customer.
 
 Now, what do you have to do to get it right, evaluate all constant things 
 including constructors and destructors and be able to do this for a class 
 hierarchy.  We didn’t do if and while, but it would have been nice to do 
 those.  Things like:
 
 class B {
   int k;
   B(int i) {
 k = i;
 }
 
 class A :public B {
   int i;
   int j;
   A () :i (1) b(5) {
 j = 5;
   }
 } a;
 
 not that demanding…  Note, I tried the code at the top, and gcc generate 
 runtime code for it.  :-(  Ouch.  clang does this:
 
 _p:
   .quad   -2  ## 0xfffe
 
 Ah.  I’d like to think that used to work at one point.

Probably not ;)

But seriously it's a matter of a) keeping constructors for each
variable separate and optimize them in GIMPLE, b) recognize
resulting code that can be expressed with a initializer

a) can be done with delaying inlining to IPA time and hoping
that early opts do enough to perform the necessary simplification,
b) needs a new pass (but I guess it shouldn't be _that_ hard...)

I think we already have constructor functions marked specially,
hopefully with a link to the initialized variable.

Richard.

Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-07 Thread Jan Hubicka
 
 err yeah, I guess we'd need to rework things so front end just creates
 functions for each variable and then middle end pass creates function
 that call all of them if necessary.

There is already code for that in cdtor optimization pass (ipa.c), but I think
C++ does its own wrapper to solve orderin issues - but I am not sure abou thtat.
Never really cared why those in-frontend wrappers are produced.

Honza
 
  Should not be hard to add though. Need to read back why inlining would
  be undesriable here - not inliing ctors in general would indeed be 
  problematic
  (preventing SRA and more stuff)
 
 yeah, doesn't seem that hard.
 
 Trev
 
  
  Honza
   
   Trev
   

Richard.


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-07 Thread Richard Biener
On Thu, 7 Aug 2014, Jan Hubicka wrote:

   
   Probably not ;)
   
   But seriously it's a matter of a) keeping constructors for each
   variable separate and optimize them in GIMPLE, b) recognize
   resulting code that can be expressed with a initializer
   
   a) can be done with delaying inlining to IPA time and hoping
   that early opts do enough to perform the necessary simplification,
   b) needs a new pass (but I guess it shouldn't be _that_ hard...)
  
  I'm not sure totally skipping inlining in C++ is that great an idea
  since most C++ ctors will end up calling things.  Isn't it enough to not
  inline the initializer for a variable into the file level function that
  calls all the initializers, which you could do by internally apply
  attribute noinline I guess.
  
   I think we already have constructor functions marked specially,
   hopefully with a link to the initialized variable.
  
  I'd expect that's what DECL_STATIC_CONSTRUCTOR does, but I'm not sure
  there's a link or where we could put one if there isn't.
 
 If you mean language level static constructors, then it doesn't. C++ FE
 produce them and then wrap thems in static_construction functions that
 are the only having DECL_STATIC_CONSTRUCTOR calling the actual ctors.
 
 Should not be hard to add though. Need to read back why inlining would
 be undesriable here - not inliing ctors in general would indeed be problematic
 (preventing SRA and more stuff)

It's only important to not inline the static constructor into the
one function calling all of them.  And only not doing that during
early inlining (but still inline into those constructors).  That's
because we eventually want to eliminate the body of the static
constructor in favor of a DECL_INITIAL in that new pass.

So we need to be able to identify

struct X { int i; X() { i = 1; } } a;

_constructor_of_a ()
{
  a.i = 1;
}

and place 'a' into .data with the appropriate initialization.
And then remove a.i = 1

Of course similar thing would be possible from the function
with all those constructors inlined but I guess it's much
harder if you may end up seeing calls inside (stuff may get
overwritten...).

OTOH, I wonder if

struct X { int i; X() { i = 1; } } a;
struct X { int i; X() { i = 1; a.i = 2; } } b;

is well-defined (with proper constructor priority attribute
to init a last or without).  That is, may we write to 'a'
from the constructor of b before it has been constructed?

Richard.


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-07 Thread Trevor Saunders
On Thu, Aug 07, 2014 at 01:44:02PM +0200, Jan Hubicka wrote:
  It's only important to not inline the static constructor into the
  one function calling all of them.  And only not doing that during
  early inlining (but still inline into those constructors).  That's
  because we eventually want to eliminate the body of the static
  constructor in favor of a DECL_INITIAL in that new pass.
 
 I see, that indeed makes sense (and I was thinking of that).
 Disabling early inlining of static ctors seems OK, but we may
 not even need to do that given that we process topologically - so
 we will identify simple ctor before we inline it.
 (assuming we do not want to do this at LTO that would also make
 sense)
  
  So we need to be able to identify
  
  struct X { int i; X() { i = 1; } } a;
  
  _constructor_of_a ()
  {
a.i = 1;
  }
  
  and place 'a' into .data with the appropriate initialization.
  And then remove a.i = 1
 
 Yeah, I think annotating cgraph nodes with info this is static
 ctor of this variable would be easy and we don't neven need to
 mess with the rest of C++ FE finalization code (i.e. one unifying
 it to static construction functions).
 Early inliner can skip inlining these if desirable and the new
 pass can easily identify them.

I'm not sure how you find the variable given a cgraph node, but if you
do great.

 Being able to turn stores into ctor is something that may be
 shareable with Martin's ipa-prop analysis.

that's handy, have a link?

 He is basically doing that IMO.
  
  Of course similar thing would be possible from the function
  with all those constructors inlined but I guess it's much
  harder if you may end up seeing calls inside (stuff may get
  overwritten...).
  
  OTOH, I wonder if
  
  struct X { int i; X() { i = 1; } } a;
  struct X { int i; X() { i = 1; a.i = 2; } } b;
  
  is well-defined (with proper constructor priority attribute
  to init a last or without).  That is, may we write to 'a'
  from the constructor of b before it has been constructed?
 
 Hehe, not a question for me :) 

I feel like the anser should be if you write to a global before its
I feel like it should only be valid to write to a global variable after
its initialized, but I really don't know what C++ says.

Trev


 
 Honza
  
  Richard.


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-06 Thread Richard Biener
On Tue, 5 Aug 2014, Jeff Law wrote:

 On 08/05/14 08:36, Marek Polacek wrote:
  On Mon, Aug 04, 2014 at 02:04:36PM +0200, Richard Biener wrote:
Looks like .fre can optimize q - (q - 1) into 1:
bb 2:
q.0_3 = (long int) MEM[(void *)i + 4B];
_5 = (long int) i;
-  _6 = q.0_3 - _5;
-  t.1_7 = _6 /[ex] 4;
-  t ={v} t.1_7;
+  t ={v} 1;
i ={v} {CLOBBER};
return;

But associate_plusminus doesn't optimize it:
   else if (code == MINUS_EXPR
 CONVERT_EXPR_CODE_P (def_code)
 TREE_CODE (gimple_assign_rhs1 (def_stmt)) ==
SSA_NAME
 TREE_CODE (rhs2) == SSA_NAME)
 {
   /* (T)(P + A) - (T)P - (T)A.  */
becase gimple_assign_rhs1 (def_stmt) is not an SSA_NAME, but ADDR_EXPR
(it's
MEM[(void *)i + 4B]).  Then there's transformation A - (A +- B) - -+
B
below, but that doesn't handle casts.

So - should I try to handle it in associate_plusminus?
   
   Yes please, with a (few) testcase(s).
  
  Ok, so the following adds the (T)P - (T)(P + A) - (T)-A
  transformation.  It is based on code hunk that does the
  (T)(P + A) - (T)P - (T)A transformation.  The difference it makes is
  in the .optimized dump something like:
  
int fn2(int, int) (int p, int i)
{
  -  unsigned int p.2_2;
  +  unsigned int _3;
  int _4;
  -  unsigned int _5;
  unsigned int _6;
  -  int _7;
  
  bb 2:
  -  p.2_2 = (unsigned int) p_1(D);
  -  _4 = p_1(D) + i_3(D);
  -  _5 = (unsigned int) _4;
  -  _6 = p.2_2 - _5;
  -  _7 = (int) _6;
  -  return _7;
  +  _6 = (unsigned int) i_2(D);
  +  _3 = -_6;
  +  _4 = (int) _3;
  +  return _4;
  
  i.e., the PLUS_EXPR and MINUS_EXPR are gone, and NEGATE_EXPR is used
  instead.
  During bootstrap with --enable-languages=c,c++ this optimization triggered
  238 times.
  
  Bootstrapped/regtested on x86_64-linux, ok for trunk?
  
  2014-08-05  Marek Polacek  pola...@redhat.com
  
  PR c/61240
  * tree-ssa-forwprop.c (associate_plusminus): Add (T)P - (T)(P + A)
  - (T)-A transformation.
  c/
  * c-typeck.c (pointer_diff): Remove P - (P + CST) optimization.
  testsuite/
  * gcc.dg/pr61240.c: New test.
  * gcc.dg/tree-ssa/forwprop-29.c: New test.
 So I'm all for delaying folding when possible, so I'm comfortable with the
 general direction this is going.
 
 My concern is the code we're removing discusses the need to simplify when
 these expressions are in static initializers.  What's going to ensure that
 we're still simplifying instances which appear in static initializers?  I
 don't see anything which tests that.   And does it still work for targets
 which utilize PSImode?

You mean stuff like

int i[4];
const int p = i - (i + 2);

?  I don't think that i - (i + 2) fulfills the requirements of an
integral constant expression, so we are free to reject it.

OTOH, ISTR that we tried hard in the past to support initializers
that implement offsetof in various ways.

Btw, before the idea of moving foldings to GIMPLE the consensus was
that moving foldings from frontends and convert to fold-const.c was
the appropriate thing to do.

As this is offsetof-like moving it to fold-const.c would work for
me as well (also given that forwprop is hardly a generic folding
framework).

Bah, I should accelerate that match-and-simplify stuff ...

Richard.


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-06 Thread Marek Polacek
On Tue, Aug 05, 2014 at 02:14:21PM -0600, Jeff Law wrote:
 My concern is the code we're removing discusses the need to simplify when
 these expressions are in static initializers.  What's going to ensure that
 we're still simplifying instances which appear in static initializers?  I
 don't see anything which tests that.   And does it still work for targets
 which utilize PSImode?

Aw nuts.  So with the patch we'd start erroring out on
static __PTRDIFF_TYPE__ d1 = p - (p + 1);
static __PTRDIFF_TYPE__ d2 = p - (p - 1);
(it's nowhere in the testsuite/code base - and I hadn't noticed that
until today :()
while we'd still accept
static __PTRDIFF_TYPE__ d5 = (p - 1) - p;
static __PTRDIFF_TYPE__ d6 = (p + 1) - p;
(Those are not constant expression according to ISO C.)

The reason is that fold_build can fold
(long int) (p + 4) - (long int) p to 4, but not
(long int) p - (long int) (p + 4).

That means we have to have a way how to fold the latter, but only in
static initializers.  So I guess I need to implement this in
fold-const.c...   Oh well.

Nevertheless, I'd guess the fwprop bits could go in separately (it's
beneficial for C++).

As for PSImode, I dunno - seems only m32c and AVR use that?  I have no
way how to perform testing on such targets.

Marek


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-06 Thread Jakub Jelinek
On Wed, Aug 06, 2014 at 10:22:19AM +0200, Marek Polacek wrote:
 On Tue, Aug 05, 2014 at 02:14:21PM -0600, Jeff Law wrote:
  My concern is the code we're removing discusses the need to simplify when
  these expressions are in static initializers.  What's going to ensure that
  we're still simplifying instances which appear in static initializers?  I
  don't see anything which tests that.   And does it still work for targets
  which utilize PSImode?
 
 Aw nuts.  So with the patch we'd start erroring out on
 static __PTRDIFF_TYPE__ d1 = p - (p + 1);
 static __PTRDIFF_TYPE__ d2 = p - (p - 1);
 (it's nowhere in the testsuite/code base - and I hadn't noticed that
 until today :()
 while we'd still accept
 static __PTRDIFF_TYPE__ d5 = (p - 1) - p;
 static __PTRDIFF_TYPE__ d6 = (p + 1) - p;
 (Those are not constant expression according to ISO C.)
 
 The reason is that fold_build can fold
 (long int) (p + 4) - (long int) p to 4, but not
 (long int) p - (long int) (p + 4).
 
 That means we have to have a way how to fold the latter, but only in
 static initializers.  So I guess I need to implement this in
 fold-const.c...   Oh well.
 
 Nevertheless, I'd guess the fwprop bits could go in separately (it's
 beneficial for C++).

Well, if you are going to implement it in fwprop AND fold-const, then the
natural place to fix that would be in *.pd on the match-and-simplify branch.

Jakub


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-06 Thread Marek Polacek
On Wed, Aug 06, 2014 at 10:26:29AM +0200, Jakub Jelinek wrote:
 Well, if you are going to implement it in fwprop AND fold-const, then the
 natural place to fix that would be in *.pd on the match-and-simplify branch.

True.  So I guess I'll have to put this one on hold for a while...

Marek


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-06 Thread Richard Biener
On Wed, 6 Aug 2014, Marek Polacek wrote:

 On Tue, Aug 05, 2014 at 02:14:21PM -0600, Jeff Law wrote:
  My concern is the code we're removing discusses the need to simplify when
  these expressions are in static initializers.  What's going to ensure that
  we're still simplifying instances which appear in static initializers?  I
  don't see anything which tests that.   And does it still work for targets
  which utilize PSImode?
 
 Aw nuts.  So with the patch we'd start erroring out on
 static __PTRDIFF_TYPE__ d1 = p - (p + 1);
 static __PTRDIFF_TYPE__ d2 = p - (p - 1);
 (it's nowhere in the testsuite/code base - and I hadn't noticed that
 until today :()
 while we'd still accept
 static __PTRDIFF_TYPE__ d5 = (p - 1) - p;
 static __PTRDIFF_TYPE__ d6 = (p + 1) - p;
 (Those are not constant expression according to ISO C.)
 
 The reason is that fold_build can fold
 (long int) (p + 4) - (long int) p to 4, but not
 (long int) p - (long int) (p + 4).
 
 That means we have to have a way how to fold the latter, but only in
 static initializers.  So I guess I need to implement this in
 fold-const.c...   Oh well.
 
 Nevertheless, I'd guess the fwprop bits could go in separately (it's
 beneficial for C++).
 
 As for PSImode, I dunno - seems only m32c and AVR use that?  I have no
 way how to perform testing on such targets.

The issue for those targets is mainly how they define their 'sizetype'
vs. their pointer types.  For m32c IIRC sizetype is 16bits while
pointer types are 24bit (PSImode).  That means that pointer-to-int
conversion is usually widening and that pointer-offsetting cannot
access large objects fully.  See also

/* Allow conversions from pointer type to integral type only if
   there is no sign or zero extension involved.
   For targets were the precision of ptrofftype doesn't match that
   of pointers we need to allow arbitrary conversions to 
ptrofftype.  */
if ((POINTER_TYPE_P (lhs_type)
  INTEGRAL_TYPE_P (rhs1_type))
|| (POINTER_TYPE_P (rhs1_type)
 INTEGRAL_TYPE_P (lhs_type)
 (TYPE_PRECISION (rhs1_type) = TYPE_PRECISION 
(lhs_type)
|| ptrofftype_p (sizetype
  return false;

which we may restrict better with checking whether the pointer
uses a partial integer mode.  Not sure how PSImode - SImode
extends on RTL?

Richard.


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-06 Thread Richard Biener
On Wed, 6 Aug 2014, Marek Polacek wrote:

 On Wed, Aug 06, 2014 at 10:26:29AM +0200, Jakub Jelinek wrote:
  Well, if you are going to implement it in fwprop AND fold-const, then the
  natural place to fix that would be in *.pd on the match-and-simplify branch.
 
 True.  So I guess I'll have to put this one on hold for a while...

You can restrict it to fold-const.c for now.  I really hope to get
match-and-simplify into mergeable state this month.

Richard.


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-06 Thread Marek Polacek
On Wed, Aug 06, 2014 at 10:28:13AM +0200, Richard Biener wrote:
 On Wed, 6 Aug 2014, Marek Polacek wrote:
 
  On Wed, Aug 06, 2014 at 10:26:29AM +0200, Jakub Jelinek wrote:
   Well, if you are going to implement it in fwprop AND fold-const, then the
   natural place to fix that would be in *.pd on the match-and-simplify 
   branch.
  
  True.  So I guess I'll have to put this one on hold for a while...
 
 You can restrict it to fold-const.c for now.  I really hope to get
 match-and-simplify into mergeable state this month.

Okay, I'll look into it.  Thanks.

Marek


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-06 Thread Jeff Law

On 08/06/14 02:27, Richard Biener wrote:



which we may restrict better with checking whether the pointer
uses a partial integer mode.  Not sure how PSImode - SImode
extends on RTL?
Well, at least on the mn102, I defined both a zero and sign extension 
for PSI - SI.  So whichever one the generic parts of the compiler 
needed, the backend provided.


As to what bits are modified, that's target dependent as the precise 
size of the partial modes is target dependent.  That's one of the things 
that would be largely made irrelevant by DJ's proposed changes.  Instead 
of using PSImode, we'd be able to define modes of precisely the number 
of bits one of these targets needs.


Jeff


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-06 Thread DJ Delorie

 As for PSImode, I dunno - seems only m32c and AVR use that?  I have no
 way how to perform testing on such targets.

and msp430.  m32c and msp430 have simulators in gdb.


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-06 Thread Mike Stump
On Aug 6, 2014, at 9:04 AM, Jeff Law l...@redhat.com wrote:
 which we may restrict better with checking whether the pointer
 uses a partial integer mode.  Not sure how PSImode - SImode
 extends on RTL?
 Well, at least on the mn102, I defined both a zero and sign extension for PSI 
 - SI.  So whichever one the generic parts of the compiler needed, the 
 backend provided.

I have a port that defines exactly the bit width of all partials.  The 
extending of it is machine independent and obvious.  Though, there are places 
in the backend that just call the conversion operation they are interested in 
and pretend they can’t understand what’s going on.  I tend to prefer the 
backend know and I prefer to explain to it the width of all the partials.

Wait, did I submit that?

config/msp430/msp430-modes.def:
  /* 20-bit address */
  PARTIAL_INT_MODE (SI, 20, PSI);

ah, yes, I think I did.  You scared me for a second.

 As to what bits are modified, that's target dependent as the precise size of 
 the partial modes is target dependent.

GET_MODE_PRECISION (mode) is the precision of all modes.

 That's one of the things that would be largely made irrelevant by DJ's 
 proposed changes.  Instead of using PSImode,

What’s PSImode?

 we'd be able to define modes of precisely the number of bits one of these 
 targets needs.

Gosh, we already do that.  GET_MODE_PRECISION (mode) is exactly the width:

 PARTIAL_INT_MODE (MODE, PRECISION, NAME); |
declares a mode of class PARTIAL_INT with the same size as |
MODE (which must be an INT mode) and precision PREC.   |
Optionally, NAME is the new name of the mode.  NAME is the |
name of the mode.  |

?

Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-06 Thread DJ Delorie

Responding wrt DJ's proposed changes:

  As to what bits are modified, that's target dependent as the
  precise size of the partial modes is target dependent.
 
 GET_MODE_PRECISION (mode) is the precision of all modes.

True, but not all the compiler uses that info when it should.  There
are even testsuite cases that get it wrong.

  That's one of the things that would be largely made irrelevant by
  DJ's proposed changes.  Instead of using PSImode,
 
 What’s PSImode?

PSImode is a mode with more precision than HImode, but less than SImode.

  we'd be able to define modes of precisely the number of bits one
  of these targets needs.

Not quite, Jeff.  We still use PSImode but now it has a known defined
precision, not just fits in SImode, and may correspond to one of the
__intN types.

 Gosh, we already do that.  GET_MODE_PRECISION (mode) is exactly the width:

There's still lots of places in gcc that use SIZE where they should
use PRECISION.  I also added a step that looks for target-defined
conversions between, for example, HImode and PSImode (rather than go
HI-SI-PSI).

Plus, as there was no real C type for partial int modes, a lot of
gcc made assumptions about type sizes.  The addition of arbitrary
__intN types means there are more places in the code that are able to
properly handle partial integer modes.


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-06 Thread Mike Stump
On Aug 6, 2014, at 12:56 AM, Richard Biener rguent...@suse.de wrote:
 My concern is the code we're removing discusses the need to simplify when
 these expressions are in static initializers.  What's going to ensure that
 we're still simplifying instances which appear in static initializers?  I
 don't see anything which tests that.   And does it still work for targets
 which utilize PSImode?
 
 You mean stuff like
 
 int i[4];
 const int p = i - (i + 2);

No.

  long p = i - (i + 2);

in C++.  It is valid and so it has to work.  Further, there is a well known 
problem that if you get all the constants correct, you get to statically 
initialize this and have no constructors.  Though the above is trivial, in 
large C++ source bases, there is an important set of things that one must do to 
hit expected quality.  Fold, fold, fold is the name of the game, and if you do 
it well, you get app startup time that is short, and if you don’t do it well, 
you get app startup time that sucks.  Some folks care about startup time.  So 
for example, there are well known pdf viewers that use gcc to compile and whose 
startup time would be a order of magnitude or more worse if gcc didn’t optimize 
it as well as it does.  There are large OS vendors that had:

  -Wglobal-constructors
  Warn about namespace scope data that requires construction or 
destruction, or functions that use the constructor
  attribute or the destructor attribute.  Additionally warn if the 
Objective-C GNU runtime is used to initialize
  various metadata.

and used it to ensure (-Werror) that no constructors would sneak in anyplace, 
as the corporate guide was no, you don’t get to do that.  Exceptions are made 
and really, the main thing that hurt the most were libraries that users might 
use, but you get the idea.

The right way to think of the cost was page faults proportional to the size of 
the app, or, 0.  Pages faults turn out to be rather expensive as the core speed 
of the processor is rather fast.  I know sounds overly expensive, but that is 
my experience with Ado.., oops, I mean, with one critical customer.

Now, what do you have to do to get it right, evaluate all constant things 
including constructors and destructors and be able to do this for a class 
hierarchy.  We didn’t do if and while, but it would have been nice to do those. 
 Things like:

class B {
  int k;
  B(int i) {
k = i;
}

class A :public B {
  int i;
  int j;
  A () :i (1) b(5) {
j = 5;
  }
} a;

not that demanding…  Note, I tried the code at the top, and gcc generate 
runtime code for it.  :-(  Ouch.  clang does this:

_p:
.quad   -2  ## 0xfffe

Ah.  I’d like to think that used to work at one point.

Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-06 Thread DJ Delorie

  There's still lots of places in gcc that use SIZE where they should
  use PRECISION.
 
 Yes, and in time, they’ll all get cleaned up.

Hopefully not much time, if I can get my patches commit-worthy.  I'm
actually debugging a pointer-signed-math regression now.

  I also added a step that looks for target-defined
  conversions between, for example, HImode and PSImode (rather than go
  HI-SI-PSI).
 
 I hope they always fall back to the usual conversions.  On my port,
 I can move them into gprs and do all the usual gpr instructions on
 them.  The register allocator allocates the mode specific registers
 and moves them around as appropriate.

Yeah, it's a check before the usual conversions that just says if the
target has a MODE1 to MODE2 converter of the right type, just use it.

Without this check, the only mode conversions are (for example) HI-SI
and PSI-SI.  The check allows for HI-PSI or QI-PTI or whatever the
target has opcodes for.


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-05 Thread Marek Polacek
On Mon, Aug 04, 2014 at 02:04:36PM +0200, Richard Biener wrote:
  Looks like .fre can optimize q - (q - 1) into 1:
 bb 2:
 q.0_3 = (long int) MEM[(void *)i + 4B];
 _5 = (long int) i;
  -  _6 = q.0_3 - _5;
  -  t.1_7 = _6 /[ex] 4;
  -  t ={v} t.1_7;
  +  t ={v} 1;
 i ={v} {CLOBBER};
 return;
   
  But associate_plusminus doesn't optimize it:
else if (code == MINUS_EXPR
  CONVERT_EXPR_CODE_P (def_code)
  TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
  TREE_CODE (rhs2) == SSA_NAME)
  {
/* (T)(P + A) - (T)P - (T)A.  */
  becase gimple_assign_rhs1 (def_stmt) is not an SSA_NAME, but ADDR_EXPR (it's
  MEM[(void *)i + 4B]).  Then there's transformation A - (A +- B) - -+ B
  below, but that doesn't handle casts.
  
  So - should I try to handle it in associate_plusminus?
 
 Yes please, with a (few) testcase(s).

Ok, so the following adds the (T)P - (T)(P + A) - (T)-A
transformation.  It is based on code hunk that does the 
(T)(P + A) - (T)P - (T)A transformation.  The difference it makes is
in the .optimized dump something like:

 int fn2(int, int) (int p, int i)
 {
-  unsigned int p.2_2;
+  unsigned int _3;
   int _4;
-  unsigned int _5;
   unsigned int _6;
-  int _7;
 
   bb 2:
-  p.2_2 = (unsigned int) p_1(D);
-  _4 = p_1(D) + i_3(D);
-  _5 = (unsigned int) _4;
-  _6 = p.2_2 - _5;
-  _7 = (int) _6;
-  return _7;
+  _6 = (unsigned int) i_2(D);
+  _3 = -_6;
+  _4 = (int) _3;
+  return _4;

i.e., the PLUS_EXPR and MINUS_EXPR are gone, and NEGATE_EXPR is used instead.
During bootstrap with --enable-languages=c,c++ this optimization triggered 238 
times.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2014-08-05  Marek Polacek  pola...@redhat.com

PR c/61240
* tree-ssa-forwprop.c (associate_plusminus): Add (T)P - (T)(P + A)
- (T)-A transformation.
c/
* c-typeck.c (pointer_diff): Remove P - (P + CST) optimization.
testsuite/
* gcc.dg/pr61240.c: New test.
* gcc.dg/tree-ssa/forwprop-29.c: New test.

diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c
index fe9440c..5f46944 100644
--- gcc/c/c-typeck.c
+++ gcc/c/c-typeck.c
@@ -3460,7 +3460,6 @@ pointer_diff (location_t loc, tree op0, tree op1)
   addr_space_t as0 = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op0)));
   addr_space_t as1 = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op1)));
   tree target_type = TREE_TYPE (TREE_TYPE (op0));
-  tree con0, con1, lit0, lit1;
   tree orig_op1 = op1;
 
   /* If the operands point into different address spaces, we need to
@@ -3490,7 +3489,6 @@ pointer_diff (location_t loc, tree op0, tree op1)
   else
 inttype = restype;
 
-
   if (TREE_CODE (target_type) == VOID_TYPE)
 pedwarn (loc, OPT_Wpointer_arith,
 pointer of type %void *% used in subtraction);
@@ -3498,50 +3496,6 @@ pointer_diff (location_t loc, tree op0, tree op1)
 pedwarn (loc, OPT_Wpointer_arith,
 pointer to a function used in subtraction);
 
-  /* If the conversion to ptrdiff_type does anything like widening or
- converting a partial to an integral mode, we get a convert_expression
- that is in the way to do any simplifications.
- (fold-const.c doesn't know that the extra bits won't be needed.
- split_tree uses STRIP_SIGN_NOPS, which leaves conversions to a
- different mode in place.)
- So first try to find a common term here 'by hand'; we want to cover
- at least the cases that occur in legal static initializers.  */
-  if (CONVERT_EXPR_P (op0)
-   (TYPE_PRECISION (TREE_TYPE (op0))
- == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)
-con0 = TREE_OPERAND (op0, 0);
-  else
-con0 = op0;
-  if (CONVERT_EXPR_P (op1)
-   (TYPE_PRECISION (TREE_TYPE (op1))
- == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0)
-con1 = TREE_OPERAND (op1, 0);
-  else
-con1 = op1;
-
-  if (TREE_CODE (con0) == POINTER_PLUS_EXPR)
-{
-  lit0 = TREE_OPERAND (con0, 1);
-  con0 = TREE_OPERAND (con0, 0);
-}
-  else
-lit0 = integer_zero_node;
-
-  if (TREE_CODE (con1) == POINTER_PLUS_EXPR)
-{
-  lit1 = TREE_OPERAND (con1, 1);
-  con1 = TREE_OPERAND (con1, 0);
-}
-  else
-lit1 = integer_zero_node;
-
-  if (operand_equal_p (con0, con1, 0))
-{
-  op0 = lit0;
-  op1 = lit1;
-}
-
-
   /* First do the subtraction as integers;
  then drop through to build the divide operator.
  Do not do default conversions on the minus operator
diff --git gcc/testsuite/gcc.dg/pr61240.c gcc/testsuite/gcc.dg/pr61240.c
index e69de29..115e415 100644
--- gcc/testsuite/gcc.dg/pr61240.c
+++ gcc/testsuite/gcc.dg/pr61240.c
@@ -0,0 +1,13 @@
+/* PR c/61240 */
+/* { dg-do compile } */
+
+void
+foo (void)
+{
+  volatile __PTRDIFF_TYPE__ t;
+  int i;
+  int *p = i;
+  int *q = i + 1;
+  t = q - (q - 1);
+  t = p - (p - 1);
+}
diff --git gcc/testsuite/gcc.dg/tree-ssa/forwprop-29.c 

Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-05 Thread Jeff Law

On 08/05/14 08:36, Marek Polacek wrote:

On Mon, Aug 04, 2014 at 02:04:36PM +0200, Richard Biener wrote:

Looks like .fre can optimize q - (q - 1) into 1:
bb 2:
q.0_3 = (long int) MEM[(void *)i + 4B];
_5 = (long int) i;
-  _6 = q.0_3 - _5;
-  t.1_7 = _6 /[ex] 4;
-  t ={v} t.1_7;
+  t ={v} 1;
i ={v} {CLOBBER};
return;

But associate_plusminus doesn't optimize it:
   else if (code == MINUS_EXPR
 CONVERT_EXPR_CODE_P (def_code)
 TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
 TREE_CODE (rhs2) == SSA_NAME)
 {
   /* (T)(P + A) - (T)P - (T)A.  */
becase gimple_assign_rhs1 (def_stmt) is not an SSA_NAME, but ADDR_EXPR (it's
MEM[(void *)i + 4B]).  Then there's transformation A - (A +- B) - -+ B
below, but that doesn't handle casts.

So - should I try to handle it in associate_plusminus?


Yes please, with a (few) testcase(s).


Ok, so the following adds the (T)P - (T)(P + A) - (T)-A
transformation.  It is based on code hunk that does the
(T)(P + A) - (T)P - (T)A transformation.  The difference it makes is
in the .optimized dump something like:

  int fn2(int, int) (int p, int i)
  {
-  unsigned int p.2_2;
+  unsigned int _3;
int _4;
-  unsigned int _5;
unsigned int _6;
-  int _7;

bb 2:
-  p.2_2 = (unsigned int) p_1(D);
-  _4 = p_1(D) + i_3(D);
-  _5 = (unsigned int) _4;
-  _6 = p.2_2 - _5;
-  _7 = (int) _6;
-  return _7;
+  _6 = (unsigned int) i_2(D);
+  _3 = -_6;
+  _4 = (int) _3;
+  return _4;

i.e., the PLUS_EXPR and MINUS_EXPR are gone, and NEGATE_EXPR is used instead.
During bootstrap with --enable-languages=c,c++ this optimization triggered 238 
times.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2014-08-05  Marek Polacek  pola...@redhat.com

PR c/61240
* tree-ssa-forwprop.c (associate_plusminus): Add (T)P - (T)(P + A)
- (T)-A transformation.
c/
* c-typeck.c (pointer_diff): Remove P - (P + CST) optimization.
testsuite/
* gcc.dg/pr61240.c: New test.
* gcc.dg/tree-ssa/forwprop-29.c: New test.
So I'm all for delaying folding when possible, so I'm comfortable with 
the general direction this is going.


My concern is the code we're removing discusses the need to simplify 
when these expressions are in static initializers.  What's going to 
ensure that we're still simplifying instances which appear in static 
initializers?  I don't see anything which tests that.   And does it 
still work for targets which utilize PSImode?


Jeff




[C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-04 Thread Marek Polacek
This PR is about bogus overflow warning that we issue for e.g.
  int *q = i + 1;
  q - (q - 1);
because pointer_diff receives p - (p + -1U) which gets simplified to
1U - with overflow.  We could drop the overflow flag to suppress the
warning, but I think we should just remove the optimization
altogether.  First, FE shouldn't perform such transformations at
all.  Second, C++ FE has its own pointer_diff function that doesn't
do such optimization.  With this patch, the C FE will generate the
same expression as the C++ FE.  It's true that we should try to
optimize this, but not in the front end.  It ought to be easy to
write a pattern for match-and-simplify that would handle this.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2014-08-04  Marek Polacek  pola...@redhat.com

PR c/61240
* c-typeck.c (pointer_diff): Remove P - (P + CST) optimization.

* gcc.dg/pr61240.c: New test.

diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c
index fe9440c..5f46944 100644
--- gcc/c/c-typeck.c
+++ gcc/c/c-typeck.c
@@ -3460,7 +3460,6 @@ pointer_diff (location_t loc, tree op0, tree op1)
   addr_space_t as0 = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op0)));
   addr_space_t as1 = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op1)));
   tree target_type = TREE_TYPE (TREE_TYPE (op0));
-  tree con0, con1, lit0, lit1;
   tree orig_op1 = op1;
 
   /* If the operands point into different address spaces, we need to
@@ -3490,7 +3489,6 @@ pointer_diff (location_t loc, tree op0, tree op1)
   else
 inttype = restype;
 
-
   if (TREE_CODE (target_type) == VOID_TYPE)
 pedwarn (loc, OPT_Wpointer_arith,
 pointer of type %void *% used in subtraction);
@@ -3498,50 +3496,6 @@ pointer_diff (location_t loc, tree op0, tree op1)
 pedwarn (loc, OPT_Wpointer_arith,
 pointer to a function used in subtraction);
 
-  /* If the conversion to ptrdiff_type does anything like widening or
- converting a partial to an integral mode, we get a convert_expression
- that is in the way to do any simplifications.
- (fold-const.c doesn't know that the extra bits won't be needed.
- split_tree uses STRIP_SIGN_NOPS, which leaves conversions to a
- different mode in place.)
- So first try to find a common term here 'by hand'; we want to cover
- at least the cases that occur in legal static initializers.  */
-  if (CONVERT_EXPR_P (op0)
-   (TYPE_PRECISION (TREE_TYPE (op0))
- == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)
-con0 = TREE_OPERAND (op0, 0);
-  else
-con0 = op0;
-  if (CONVERT_EXPR_P (op1)
-   (TYPE_PRECISION (TREE_TYPE (op1))
- == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0)
-con1 = TREE_OPERAND (op1, 0);
-  else
-con1 = op1;
-
-  if (TREE_CODE (con0) == POINTER_PLUS_EXPR)
-{
-  lit0 = TREE_OPERAND (con0, 1);
-  con0 = TREE_OPERAND (con0, 0);
-}
-  else
-lit0 = integer_zero_node;
-
-  if (TREE_CODE (con1) == POINTER_PLUS_EXPR)
-{
-  lit1 = TREE_OPERAND (con1, 1);
-  con1 = TREE_OPERAND (con1, 0);
-}
-  else
-lit1 = integer_zero_node;
-
-  if (operand_equal_p (con0, con1, 0))
-{
-  op0 = lit0;
-  op1 = lit1;
-}
-
-
   /* First do the subtraction as integers;
  then drop through to build the divide operator.
  Do not do default conversions on the minus operator
diff --git gcc/testsuite/gcc.dg/pr61240.c gcc/testsuite/gcc.dg/pr61240.c
index e69de29..e90c070 100644
--- gcc/testsuite/gcc.dg/pr61240.c
+++ gcc/testsuite/gcc.dg/pr61240.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+void
+foo (void)
+{
+  volatile __PTRDIFF_TYPE__ t;
+  int i;
+  int *p = i;
+  int *q = i + 1;
+  t = q - (q - 1);
+  t = (q - 1) - q; /* { dg-warning integer overflow in expression } */
+  t = p - (p - 1);
+  t = (p - 1) - p ; /* { dg-warning integer overflow in expression } */
+}

Marek


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-04 Thread Richard Biener
On Mon, 4 Aug 2014, Marek Polacek wrote:

 This PR is about bogus overflow warning that we issue for e.g.
   int *q = i + 1;
   q - (q - 1);
 because pointer_diff receives p - (p + -1U) which gets simplified to
 1U - with overflow.  We could drop the overflow flag to suppress the
 warning, but I think we should just remove the optimization
 altogether.  First, FE shouldn't perform such transformations at
 all.  Second, C++ FE has its own pointer_diff function that doesn't
 do such optimization.  With this patch, the C FE will generate the
 same expression as the C++ FE.  It's true that we should try to
 optimize this, but not in the front end.  It ought to be easy to
 write a pattern for match-and-simplify that would handle this.

I think that tree-ssa-forwprop.c already simplifies this in
associate_plusminus with (T)(P + A) - (T)P - (T)A.  Well,
maybe not - but then the code should be massages to handle it.

Can you double-check and do that?

Otherwise I agree with removing this (and other) premature
optimizations scattered throughout the frontends (and convert.c).

Thanks,
Richard.

 Bootstrapped/regtested on x86_64-linux, ok for trunk?
 
 2014-08-04  Marek Polacek  pola...@redhat.com
 
   PR c/61240
   * c-typeck.c (pointer_diff): Remove P - (P + CST) optimization.
 
   * gcc.dg/pr61240.c: New test.
 
 diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c
 index fe9440c..5f46944 100644
 --- gcc/c/c-typeck.c
 +++ gcc/c/c-typeck.c
 @@ -3460,7 +3460,6 @@ pointer_diff (location_t loc, tree op0, tree op1)
addr_space_t as0 = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op0)));
addr_space_t as1 = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op1)));
tree target_type = TREE_TYPE (TREE_TYPE (op0));
 -  tree con0, con1, lit0, lit1;
tree orig_op1 = op1;
  
/* If the operands point into different address spaces, we need to
 @@ -3490,7 +3489,6 @@ pointer_diff (location_t loc, tree op0, tree op1)
else
  inttype = restype;
  
 -
if (TREE_CODE (target_type) == VOID_TYPE)
  pedwarn (loc, OPT_Wpointer_arith,
pointer of type %void *% used in subtraction);
 @@ -3498,50 +3496,6 @@ pointer_diff (location_t loc, tree op0, tree op1)
  pedwarn (loc, OPT_Wpointer_arith,
pointer to a function used in subtraction);
  
 -  /* If the conversion to ptrdiff_type does anything like widening or
 - converting a partial to an integral mode, we get a convert_expression
 - that is in the way to do any simplifications.
 - (fold-const.c doesn't know that the extra bits won't be needed.
 - split_tree uses STRIP_SIGN_NOPS, which leaves conversions to a
 - different mode in place.)
 - So first try to find a common term here 'by hand'; we want to cover
 - at least the cases that occur in legal static initializers.  */
 -  if (CONVERT_EXPR_P (op0)
 -   (TYPE_PRECISION (TREE_TYPE (op0))
 -   == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)
 -con0 = TREE_OPERAND (op0, 0);
 -  else
 -con0 = op0;
 -  if (CONVERT_EXPR_P (op1)
 -   (TYPE_PRECISION (TREE_TYPE (op1))
 -   == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0)
 -con1 = TREE_OPERAND (op1, 0);
 -  else
 -con1 = op1;
 -
 -  if (TREE_CODE (con0) == POINTER_PLUS_EXPR)
 -{
 -  lit0 = TREE_OPERAND (con0, 1);
 -  con0 = TREE_OPERAND (con0, 0);
 -}
 -  else
 -lit0 = integer_zero_node;
 -
 -  if (TREE_CODE (con1) == POINTER_PLUS_EXPR)
 -{
 -  lit1 = TREE_OPERAND (con1, 1);
 -  con1 = TREE_OPERAND (con1, 0);
 -}
 -  else
 -lit1 = integer_zero_node;
 -
 -  if (operand_equal_p (con0, con1, 0))
 -{
 -  op0 = lit0;
 -  op1 = lit1;
 -}
 -
 -
/* First do the subtraction as integers;
   then drop through to build the divide operator.
   Do not do default conversions on the minus operator
 diff --git gcc/testsuite/gcc.dg/pr61240.c gcc/testsuite/gcc.dg/pr61240.c
 index e69de29..e90c070 100644
 --- gcc/testsuite/gcc.dg/pr61240.c
 +++ gcc/testsuite/gcc.dg/pr61240.c
 @@ -0,0 +1,14 @@
 +/* { dg-do compile } */
 +
 +void
 +foo (void)
 +{
 +  volatile __PTRDIFF_TYPE__ t;
 +  int i;
 +  int *p = i;
 +  int *q = i + 1;
 +  t = q - (q - 1);
 +  t = (q - 1) - q; /* { dg-warning integer overflow in expression } */
 +  t = p - (p - 1);
 +  t = (p - 1) - p ; /* { dg-warning integer overflow in expression } */
 +}
 
   Marek
 
 

-- 
Richard Biener rguent...@suse.de
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imendorffer


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-04 Thread Marc Glisse

On Mon, 4 Aug 2014, Marek Polacek wrote:


+/* { dg-do compile } */
+
+void
+foo (void)
+{
+  volatile __PTRDIFF_TYPE__ t;
+  int i;
+  int *p = i;
+  int *q = i + 1;
+  t = q - (q - 1);
+  t = (q - 1) - q; /* { dg-warning integer overflow in expression } */
+  t = p - (p - 1);
+  t = (p - 1) - p ; /* { dg-warning integer overflow in expression } */
+}


Why do you want a warning for (q - 1) - q ? It looks like a perfectly 
correct way to say -1 to me (ptrdiff_t is a signed type for a reason).


--
Marc Glisse


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-04 Thread Richard Biener
On Mon, 4 Aug 2014, Marc Glisse wrote:

 On Mon, 4 Aug 2014, Marek Polacek wrote:
 
  +/* { dg-do compile } */
  +
  +void
  +foo (void)
  +{
  +  volatile __PTRDIFF_TYPE__ t;
  +  int i;
  +  int *p = i;
  +  int *q = i + 1;
  +  t = q - (q - 1);
  +  t = (q - 1) - q; /* { dg-warning integer overflow in expression } */
  +  t = p - (p - 1);
  +  t = (p - 1) - p ; /* { dg-warning integer overflow in expression } */
  +}
 
 Why do you want a warning for (q - 1) - q ? It looks like a perfectly correct
 way to say -1 to me (ptrdiff_t is a signed type for a reason).

But computing object - 1 does not result in a valid pointer,
so p - 1 is what we want to warn about?  OTOH (q - 1) - q is fine.

Indeed that POINTER_PLUS_EXPR has an unsigned offset is an implementation
detail.

Richard.


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-04 Thread Jakub Jelinek
On Mon, Aug 04, 2014 at 12:26:01PM +0200, Richard Biener wrote:
 I think that tree-ssa-forwprop.c already simplifies this in
 associate_plusminus with (T)(P + A) - (T)P - (T)A.  Well,
 maybe not - but then the code should be massages to handle it.
 
 Can you double-check and do that?
 
 Otherwise I agree with removing this (and other) premature
 optimizations scattered throughout the frontends (and convert.c).

IMHO a precondition of such changes is exactly verifying the middle-end
can perform those optimizations later on and if not, teaching the middle-end
to optimize that.

Jakub


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-04 Thread Richard Biener
On Mon, 4 Aug 2014, Jakub Jelinek wrote:

 On Mon, Aug 04, 2014 at 12:26:01PM +0200, Richard Biener wrote:
  I think that tree-ssa-forwprop.c already simplifies this in
  associate_plusminus with (T)(P + A) - (T)P - (T)A.  Well,
  maybe not - but then the code should be massages to handle it.
  
  Can you double-check and do that?
  
  Otherwise I agree with removing this (and other) premature
  optimizations scattered throughout the frontends (and convert.c).
 
 IMHO a precondition of such changes is exactly verifying the middle-end
 can perform those optimizations later on and if not, teaching the middle-end
 to optimize that.

Yep.  Which is why I said double-check and do that, do that in
extend what tree-ssa-forwrpop.c does.

Richard.


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-04 Thread Marek Polacek
On Mon, Aug 04, 2014 at 12:26:01PM +0200, Richard Biener wrote:
 On Mon, 4 Aug 2014, Marek Polacek wrote:
 
  This PR is about bogus overflow warning that we issue for e.g.
int *q = i + 1;
q - (q - 1);
  because pointer_diff receives p - (p + -1U) which gets simplified to
  1U - with overflow.  We could drop the overflow flag to suppress the
  warning, but I think we should just remove the optimization
  altogether.  First, FE shouldn't perform such transformations at
  all.  Second, C++ FE has its own pointer_diff function that doesn't
  do such optimization.  With this patch, the C FE will generate the
  same expression as the C++ FE.  It's true that we should try to
  optimize this, but not in the front end.  It ought to be easy to
  write a pattern for match-and-simplify that would handle this.
 
 I think that tree-ssa-forwprop.c already simplifies this in
 associate_plusminus with (T)(P + A) - (T)P - (T)A.  Well,
 maybe not - but then the code should be massages to handle it.
 
 Can you double-check and do that?

Looks like .fre can optimize q - (q - 1) into 1:
   bb 2:
   q.0_3 = (long int) MEM[(void *)i + 4B];
   _5 = (long int) i;
-  _6 = q.0_3 - _5;
-  t.1_7 = _6 /[ex] 4;
-  t ={v} t.1_7;
+  t ={v} 1;
   i ={v} {CLOBBER};
   return;
 
But associate_plusminus doesn't optimize it:
  else if (code == MINUS_EXPR
CONVERT_EXPR_CODE_P (def_code)
TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
TREE_CODE (rhs2) == SSA_NAME)
{
  /* (T)(P + A) - (T)P - (T)A.  */
becase gimple_assign_rhs1 (def_stmt) is not an SSA_NAME, but ADDR_EXPR (it's
MEM[(void *)i + 4B]).  Then there's transformation A - (A +- B) - -+ B
below, but that doesn't handle casts.

So - should I try to handle it in associate_plusminus?

Marek


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-04 Thread Marek Polacek
On Mon, Aug 04, 2014 at 12:51:06PM +0200, Richard Biener wrote:
 On Mon, 4 Aug 2014, Marc Glisse wrote:
 
  On Mon, 4 Aug 2014, Marek Polacek wrote:
  
   +/* { dg-do compile } */
   +
   +void
   +foo (void)
   +{
   +  volatile __PTRDIFF_TYPE__ t;
   +  int i;
   +  int *p = i;
   +  int *q = i + 1;
   +  t = q - (q - 1);
   +  t = (q - 1) - q; /* { dg-warning integer overflow in expression } */
   +  t = p - (p - 1);
   +  t = (p - 1) - p ; /* { dg-warning integer overflow in expression } */
   +}
  
  Why do you want a warning for (q - 1) - q ? It looks like a perfectly 
  correct
  way to say -1 to me (ptrdiff_t is a signed type for a reason).
 
It's not that I want the warning there.  I can probably drop the two
lines from the test.

 But computing object - 1 does not result in a valid pointer,
 so p - 1 is what we want to warn about?  OTOH (q - 1) - q is fine.
 
 Indeed that POINTER_PLUS_EXPR has an unsigned offset is an implementation
 detail.

I'm inclined to think that we shouldn't issue the warning at all, note
how it talks about integer overflow, but this is pointer arithmetic.
We can't really decide at that point whether the pointer is valid I'm
afraid.

Marek


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-04 Thread Richard Biener
On Mon, 4 Aug 2014, Marek Polacek wrote:

 On Mon, Aug 04, 2014 at 12:26:01PM +0200, Richard Biener wrote:
  On Mon, 4 Aug 2014, Marek Polacek wrote:
  
   This PR is about bogus overflow warning that we issue for e.g.
 int *q = i + 1;
 q - (q - 1);
   because pointer_diff receives p - (p + -1U) which gets simplified to
   1U - with overflow.  We could drop the overflow flag to suppress the
   warning, but I think we should just remove the optimization
   altogether.  First, FE shouldn't perform such transformations at
   all.  Second, C++ FE has its own pointer_diff function that doesn't
   do such optimization.  With this patch, the C FE will generate the
   same expression as the C++ FE.  It's true that we should try to
   optimize this, but not in the front end.  It ought to be easy to
   write a pattern for match-and-simplify that would handle this.
  
  I think that tree-ssa-forwprop.c already simplifies this in
  associate_plusminus with (T)(P + A) - (T)P - (T)A.  Well,
  maybe not - but then the code should be massages to handle it.
  
  Can you double-check and do that?
 
 Looks like .fre can optimize q - (q - 1) into 1:
bb 2:
q.0_3 = (long int) MEM[(void *)i + 4B];
_5 = (long int) i;
 -  _6 = q.0_3 - _5;
 -  t.1_7 = _6 /[ex] 4;
 -  t ={v} t.1_7;
 +  t ={v} 1;
i ={v} {CLOBBER};
return;
  
 But associate_plusminus doesn't optimize it:
   else if (code == MINUS_EXPR
 CONVERT_EXPR_CODE_P (def_code)
 TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
 TREE_CODE (rhs2) == SSA_NAME)
 {
   /* (T)(P + A) - (T)P - (T)A.  */
 becase gimple_assign_rhs1 (def_stmt) is not an SSA_NAME, but ADDR_EXPR (it's
 MEM[(void *)i + 4B]).  Then there's transformation A - (A +- B) - -+ B
 below, but that doesn't handle casts.
 
 So - should I try to handle it in associate_plusminus?

Yes please, with a (few) testcase(s).

Thanks,
Richard.


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-04 Thread Marc Glisse

On Mon, 4 Aug 2014, Marek Polacek wrote:


On Mon, Aug 04, 2014 at 12:51:06PM +0200, Richard Biener wrote:

On Mon, 4 Aug 2014, Marc Glisse wrote:


On Mon, 4 Aug 2014, Marek Polacek wrote:


+/* { dg-do compile } */
+
+void
+foo (void)
+{
+  volatile __PTRDIFF_TYPE__ t;
+  int i;
+  int *p = i;
+  int *q = i + 1;
+  t = q - (q - 1);
+  t = (q - 1) - q; /* { dg-warning integer overflow in expression } */
+  t = p - (p - 1);
+  t = (p - 1) - p ; /* { dg-warning integer overflow in expression } */
+}


Why do you want a warning for (q - 1) - q ? It looks like a perfectly correct
way to say -1 to me (ptrdiff_t is a signed type for a reason).


It's not that I want the warning there.  I can probably drop the two
lines from the test.


Well, no, I think we want those two lines, but to test that there is *no* 
warning. The bug is only halfway fixed if we still warn for (q-1)-q. But 
maybe you are trying to split the fix in 2 patches, in which case I don't 
really mind what the intermediate status is.



But computing object - 1 does not result in a valid pointer,
so p - 1 is what we want to warn about?  OTOH (q - 1) - q is fine.

Indeed that POINTER_PLUS_EXPR has an unsigned offset is an implementation
detail.


I'm inclined to think that we shouldn't issue the warning at all, note
how it talks about integer overflow, but this is pointer arithmetic.
We can't really decide at that point whether the pointer is valid I'm
afraid.


Richard is talking about a new, unrelated warning, that would warn for 
obj-1. That seems doable. Though warning for p-1 when p is defined as 
obj sounds much harder in the front-end.


--
Marc Glisse


Re: [C PATCH] Discard P - (P + CST) optimization in pointer_diff (PR c/61240)

2014-08-04 Thread Marek Polacek
On Mon, Aug 04, 2014 at 02:36:12PM +0200, Marc Glisse wrote:
 On Mon, 4 Aug 2014, Marek Polacek wrote:
 
 On Mon, Aug 04, 2014 at 12:51:06PM +0200, Richard Biener wrote:
 On Mon, 4 Aug 2014, Marc Glisse wrote:
 
 On Mon, 4 Aug 2014, Marek Polacek wrote:
 
 +/* { dg-do compile } */
 +
 +void
 +foo (void)
 +{
 +  volatile __PTRDIFF_TYPE__ t;
 +  int i;
 +  int *p = i;
 +  int *q = i + 1;
 +  t = q - (q - 1);
 +  t = (q - 1) - q; /* { dg-warning integer overflow in expression } */
 +  t = p - (p - 1);
 +  t = (p - 1) - p ; /* { dg-warning integer overflow in expression } */
 +}
 
 Why do you want a warning for (q - 1) - q ? It looks like a perfectly 
 correct
 way to say -1 to me (ptrdiff_t is a signed type for a reason).
 
 It's not that I want the warning there.  I can probably drop the two
 lines from the test.
 
 Well, no, I think we want those two lines, but to test that there is *no*
 warning. The bug is only halfway fixed if we still warn for (q-1)-q. But
 maybe you are trying to split the fix in 2 patches, in which case I don't
 really mind what the intermediate status is.
 
Yeah - I'd like to deal with reimplementing the optimization in fwprop
first.  The (p - 1) - p warning will need a different fix.

Marek