Bug 87546 - [9 Regression] Gcc miscompiles at -O3 on valid code
Summary: [9 Regression] Gcc miscompiles at -O3 on valid code
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 9.0
: P3 normal
Target Milestone: 9.0
Assignee: Jakub Jelinek
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2018-10-08 03:51 UTC by Qirun Zhang
Modified: 2018-11-17 15:58 UTC (History)
3 users (show)

See Also:
Host:
Target: x86_64-*-*
Build:
Known to work: 8.2.1
Known to fail:
Last reconfirmed: 2018-10-08 00:00:00


Attachments
gcc9-pr87546.patch (1.13 KB, patch)
2018-11-16 16:14 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Qirun Zhang 2018-10-08 03:51:41 UTC
It should be a very recent regression.


$ gcc-trunk -v
Using built-in specs.
COLLECT_GCC=gcc-trunk
COLLECT_LTO_WRAPPER=/home/absozero/trunk/root-gcc/libexec/gcc/x86_64-pc-linux-gnu/9.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc/configure --prefix=/home/absozero/trunk/root-gcc --enable-languages=c,c++ --disable-werror --enable-multilib
Thread model: posix
gcc version 9.0.0 20181007 (experimental) [trunk revision 264906] (GCC)


$ gcc-trunk abc.c ; ./a.out
-37
$ gcc-trunk -O3 abc.c ; ./a.out
219


$ cat abc.c
int printf(const char *, ...);
int a;
long b, f;
char c, g;
short d = 219;
int e[7];
int main() {
  for (; c <= 6; c++) {
    g = d < 0 ? d : d >> a;
    f = g + b;
    e[c] = f;
  }
  printf("%d\n", e[1]);
}
Comment 1 Richard Biener 2018-10-08 08:40:58 UTC
Confirmed.  Caused by loop vectorization (some pattern recog stuff appearantly).
Comment 2 Martin Liška 2018-10-08 11:23:22 UTC
Started with r262333.
Comment 3 graham.stott77 2018-10-08 11:33:04 UTC
'b' is never assigned a value, so surely it's undefined

-------- Original message --------
From: helloqirun at gmail dot com <gcc-bugzilla@gcc.gnu.org> 
Date: 08/10/2018  04:51  (GMT+00:00) 
To: gcc-bugs@gcc.gnu.org 
Subject: [Bug tree-optimization/87546] New: Gcc miscompiles at -O3 on valid code 

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87546

            Bug ID: 87546
           Summary: Gcc miscompiles at -O3 on valid code
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: helloqirun at gmail dot com
  Target Milestone: ---

It should be a very recent regression.


$ gcc-trunk -v
Using built-in specs.
COLLECT_GCC=gcc-trunk
COLLECT_LTO_WRAPPER=/home/absozero/trunk/root-gcc/libexec/gcc/x86_64-pc-linux-gnu/9.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc/configure --prefix=/home/absozero/trunk/root-gcc
--enable-languages=c,c++ --disable-werror --enable-multilib
Thread model: posix
gcc version 9.0.0 20181007 (experimental) [trunk revision 264906] (GCC)


$ gcc-trunk abc.c ; ./a.out
-37
$ gcc-trunk -O3 abc.c ; ./a.out
219


$ cat abc.c
int printf(const char *, ...);
int a;
long b, f;
char c, g;
short d = 219;
int e[7];
int main() {
  for (; c <= 6; c++) {
    g = d < 0 ? d : d >> a;
    f = g + b;
    e[c] = f;
  }
  printf("%d\n", e[1]);
}
Comment 4 Jakub Jelinek 2018-10-08 12:09:56 UTC
(In reply to graham.stott77 from comment #3)
> 'b' is never assigned a value, so surely it's undefined

No.  b has static storage duration and therefore it is initialized to zero.
Comment 5 Jakub Jelinek 2018-11-16 15:44:16 UTC
So, I think the bug is in vect_look_through_possible_promotion, which doesn't do what it claims to do is that what it returns can be cast to unprom->type and then promoted to final precision and that it is the same as the original cast sequence.
Here we have:
  _39 = (long int) iftmp.0_19;
in the loop and
  _4 = _2 >> a.4_3;
  iftmp.0_19 = (signed char) _4;
before the loop, with
  int _4;
  signed char iftmp.0_19;
  long int _39;
and we return _4 and unprom is { _4, int, vect_external_def, NULL }
(NULL caster because this is already outside of the loop).
(long int) (int) _4 is not equivalent to (long int) (signed char) (int) _4 though, so we should have returned iftmp.0_19 in this case and unprom { iftmp.0_19, signed char, vect_external_def, caster }.
Comment 6 Jakub Jelinek 2018-11-16 16:14:26 UTC
Created attachment 45026 [details]
gcc9-pr87546.patch

Untested fix.
Comment 7 Jakub Jelinek 2018-11-17 15:11:19 UTC
Author: jakub
Date: Sat Nov 17 15:10:48 2018
New Revision: 266237

URL: https://gcc.gnu.org/viewcvs?rev=266237&root=gcc&view=rev
Log:
	PR tree-optimization/87546
	* tree-vect-patterns.c (vect_look_through_possible_promotion): Add
	min_precision variable, initially set it to orig_precision, only does
	something if op_type's precision is <= min_precision and update
	min_precision whenever calling set_op.

	* gcc.dg/vect/O3-pr87546.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/vect/O3-pr87546.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-vect-patterns.c
Comment 8 Jakub Jelinek 2018-11-17 15:58:22 UTC
Fixed.