Bug 56837 - -ftree-loop-distribute-patterns generates incorrect code
Summary: -ftree-loop-distribute-patterns generates incorrect code
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: Richard Biener
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2013-04-04 07:39 UTC by Philip Blakely
Modified: 2013-04-04 11:01 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-04-04 00:00:00


Attachments
Compilation output from adding -v -save-temps (1.03 KB, application/octet-stream)
2013-04-04 07:39 UTC, Philip Blakely
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Philip Blakely 2013-04-04 07:39:02 UTC
Created attachment 29801 [details]
Compilation output from adding -v -save-temps

With gcc-4.8.0 release, and up to and including gcc-4.8-20130328, -ftree-loop-distribute-patterns can give incorrect results:

Minimal test-case (named OptBug-4.8.C):

extern int __builtin_printf (__const char *__restrict __format, ...);

int main(void)
{
  bool* b = new bool[5];
  for(unsigned int i=0 ; i < 5 ; i++)
  {
    b[i] = true;
  }
  
  for(unsigned int i=0 ; i < 5 ; i++)
  {
    __builtin_printf("%d\n", b[i]);
  }
  
  return 0;
}

Compilation command: g++-4.8-20130328 OptBug-4.8.C -o OptBug-4.8 -O1 -ftree-loop-distribute-patterns

Expected output:
1
1
1
1
1

Actual output:
255
255
255
255
255

The expected output is produced if the -ftree-loop-distribute-patterns flag is removed.
The incorrect behaviour is not exhibited by gcc-4.7.2.
Comment 1 Marek Polacek 2013-04-04 07:57:14 UTC
That's because .ldist substitutes the first loop with __builtin_memset (b_7, -1, 5);
Comment 2 Richard Biener 2013-04-04 07:58:19 UTC
Eh.  Mine.
Comment 3 Richard Biener 2013-04-04 08:32:35 UTC
Testcase

extern "C" void abort (void);
extern "C" int memcmp (const void *, const void *, __SIZE_TYPE__);

bool b1[8];
bool b2[8] = { true, true, true, true, true, true, true, true };

int main()
{
  unsigned int i;
  for(i=0 ; i < 8; i++)
    b1[i] = true;

  if (memcmp (b1, b2, 8) != 0)
    abort ();

  return 0;
}

I have a patch.
Comment 4 Richard Biener 2013-04-04 11:01:51 UTC
Author: rguenth
Date: Thu Apr  4 10:55:25 2013
New Revision: 197476

URL: http://gcc.gnu.org/viewcvs?rev=197476&root=gcc&view=rev
Log:
2013-04-04  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/56837
	* tree-loop-distribution.c (classify_partition): For non-zero
	values require that the value has the same precision as its
	mode to be useful as memset value.

	* g++.dg/torture/pr56837.C: New testcase.

Added:
    trunk/gcc/testsuite/g++.dg/torture/pr56837.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-loop-distribution.c

Author: rguenth
Date: Thu Apr  4 11:00:45 2013
New Revision: 197477

URL: http://gcc.gnu.org/viewcvs?rev=197477&root=gcc&view=rev
Log:
2013-04-04  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/56837
	* tree-loop-distribution.c (classify_partition): For non-zero
	values require that the value has the same precision as its
	mode to be useful as memset value.

	* g++.dg/torture/pr56837.C: New testcase.

Added:
    branches/gcc-4_8-branch/gcc/testsuite/g++.dg/torture/pr56837.C
Modified:
    branches/gcc-4_8-branch/gcc/ChangeLog
    branches/gcc-4_8-branch/gcc/testsuite/ChangeLog
    branches/gcc-4_8-branch/gcc/tree-loop-distribution.c