Bug 16456 - PowerPC - redundant subtract involving pointer types
Summary: PowerPC - redundant subtract involving pointer types
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.0.0
: P5 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2004-07-09 17:53 UTC by Pete Steinmetz
Modified: 2016-01-27 19:19 UTC (History)
4 users (show)

See Also:
Host: powerpc64-linux
Target: powerpc64-linux
Build: powerpc64-linux
Known to work: 4.8.5, 6.0
Known to fail:
Last reconfirmed: 2006-10-22 23:13:17


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Pete Steinmetz 2004-07-09 17:53:38 UTC
Description:
A non-optimal code sequence is illustrated.  Two subtract operations are
done where only one is necessary.  Duplicate using gcc 3.5 and command
line:

gcc -O3 -m64 -c test.c

Testcase:
char * ptr1;
char * ptr2;
int x;
long int y;

void foo ()
{
    x = ptr1 - ptr2;
    y = ptr1 - ptr2;
}

Assembly:
      ld 9,.LC0@toc(2)
      ld 11,.LC1@toc(2)
      ld 0,0(9)
      ld 10,0(11)
      ld 8,.LC3@toc(2)
      subf 11,10,0
      ld 9,.LC2@toc(2)
      subf 0,10,0  -- no need to do this subtract, just use the previous
result.
      std 11,0(8)
      stw 0,0(9)
      blr

Comment 1 Andrew Pinski 2004-07-09 19:15:24 UTC
Confirmed, the problem is they are different modes.
(set (reg:SI 124)
        (minus:SI (subreg:SI (reg:DI 119 [ ptr1.1 ]) 4)
            (subreg:SI (reg:DI 120 [ ptr2.4 ]) 4)))

(set (reg:DI 126)
        (minus:DI (reg:DI 119 [ ptr1.1 ])
            (reg:DI 120 [ ptr2.4 ])))
Comment 2 Nathan Sidwell 2004-11-03 11:20:43 UTC
What is happening is that convert_to_integer, which is used to convert the
subtraction result to the type of 'x', reassociates the cast from
  (int)((long)ptr1 - (long)ptr2)
to
  (int)ptr1 - (int)ptr2
As it thinks that's a win.  Unfortunately this stops CSE noticing that
the later subtraction is actually the same.

This is another example of premature tree optimization, and it should be addressed
in the reworking of fold itself.  I don't think this should be attempted at stage 3
Comment 3 Andrew Pinski 2005-11-02 17:16:12 UTC
All P1 enhancements not targeted towards 4.1, moving to P5.
Comment 4 Andrew Pinski 2006-10-22 23:13:17 UTC
(In reply to comment #2)
> This is another example of premature tree optimization, and it should be addressed
> in the reworking of fold itself.  I don't think this should be attempted at stage 3

First off, fold is not doing this but instead convert.c :).  Second I don't think this is premature tree optim but instead just something RTL level should catch.  People can write code like what the tree level gives us so it is not a question of premature tree opt but rather how to catch it on the RTL level.
Comment 5 Ben Elliston 2009-05-14 03:00:32 UTC
Still present in GCC 4.5.0 (20090513).
Comment 6 Martin Sebor 2016-01-27 19:19:56 UTC
This appears to have improved.  Current trunk (as well as 4.8.5) emit what looks like optimal code at both -O2 and -O3.  Resolving as fixed.

.L.foo:
	addis 10,2,.LC0@toc@ha		# gpr load fusion, type long
	ld 10,.LC0@toc@l(10)
	addis 9,2,.LC1@toc@ha		# gpr load fusion, type long
	ld 9,.LC1@toc@l(9)
	addis 8,2,.LC2@toc@ha		# gpr load fusion, type long
	ld 8,.LC2@toc@l(8)
	ld 7,0(10)
	ld 9,0(9)
	addis 10,2,.LC3@toc@ha		# gpr load fusion, type long
	ld 10,.LC3@toc@l(10)
	subf 9,9,7
	stw 9,0(8)
	std 9,0(10)
	blr