Bug 80341 - [5 Regression] gcc miscompiles division of signed char
Summary: [5 Regression] gcc miscompiles division of signed char
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 7.0.1
: P2 normal
Target Milestone: 6.4
Assignee: Richard Biener
URL:
Keywords: wrong-code
Depends on:
Blocks: yarpgen
  Show dependency treegraph
 
Reported: 2017-04-06 10:48 UTC by Vsevolod Livinskii
Modified: 2021-11-01 23:07 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 6.3.1, 7.0.1
Known to fail: 5.4.0, 6.3.0
Last reconfirmed: 2017-04-06 00:00:00


Attachments
Reproducer. (323 bytes, application/gzip)
2017-04-06 10:48 UTC, Vsevolod Livinskii
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Vsevolod Livinskii 2017-04-06 10:48:39 UTC
Created attachment 41140 [details]
Reproducer.

GCC generates incorrect code. Correct result is 90.

Reproducer:
>$ cat foo.c
extern const signed char var_25;
extern signed char var_465;

void foo() { 
    var_465 = (unsigned short) var_25 / -55; 
} 
>$ cat main.c
#include <stdio.h>

extern void foo ();

const signed char var_25 = -84;
signed char var_465 = 0;

int main () {
    foo ();
    printf("%d\n", (int) var_465);
    return 0;
}

Run:
>$ gcc main.c foo.c ; ./a.out 
1

GCC version:
Rev. 246681
>$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/home/vsevolod/workspace/gcc-dev/bin-trunk/libexec/gcc/x86_64-pc-linux-gnu/7.0.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /home/vsevolod/workspace/gcc-dev/trunk/configure --prefix=/home/vsevolod/workspace/gcc-dev/bin-trunk --disable-bootstrap
Thread model: posix
gcc version 7.0.1 20170404 (experimental) (GCC)
Comment 1 Marek Polacek 2017-04-06 11:07:26 UTC
GCC 4.4 gives 90 but GCC 4.5 gives 1.
Comment 2 Marek Polacek 2017-04-06 12:24:19 UTC
Better testcase:

const signed char c = -84;
signed char s;

void
foo ()
{
  s = (unsigned short) c / -55;
}

int
main ()
{
  foo ();
  if (s != 90)
    __builtin_abort ();
}
Comment 3 Marek Polacek 2017-04-06 12:25:54 UTC
Likely started with

commit 4d307e1ff39d0c2f90123ef789d611e2323be76d
Author: rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Wed Feb 10 11:54:14 2010 +0000

    2010-02-10  Richard Guenther  <rguenther@suse.de>
    
            PR c/43007
            * tree.c (get_unwidened): Handle constants.
            * convert.c (convert_to_integer): Handle TRUNC_DIV_EXPR.
    
            * gcc.c-torture/execute/20100209-1.c: New testcase.
            * gcc.dg/fold-div-3.c: Likewise.
    
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@156653 138bc75d-0d04-0410-961f-82ee72b054a4
Comment 4 Marek Polacek 2017-04-06 12:38:13 UTC
With -O I get
x.c: In function ‘foo’:
x.c:7:7: warning: overflow in implicit constant conversion [-Woverflow]
   s = (unsigned short) c / -55;
       ^
Comment 5 Richard Biener 2017-04-06 12:51:15 UTC
hmm, get_unwidened ((int) (short unsigned int) c) returns c?!  I wonder if that's by design...
Comment 6 Richard Biener 2017-04-06 12:54:25 UTC
Ah, it is as we pass it signed char as 2nd arg...
Comment 7 Richard Biener 2017-04-06 14:01:38 UTC
Testing patch.
Comment 8 Richard Biener 2017-04-07 08:20:56 UTC
Author: rguenth
Date: Fri Apr  7 08:20:24 2017
New Revision: 246756

URL: https://gcc.gnu.org/viewcvs?rev=246756&root=gcc&view=rev
Log:
2017-04-07  Richard Biener  <rguenther@suse.de>

	PR middle-end/80341
	* tree.c (get_unwidened): Also handle ! for_type case for
	INTEGER_CSTs.
	* convert.c (do_narrow): Split out from ...
	(convert_to_integer_1): ... here.  Do not pass final truncation
	type to get_unwidened for TRUNC_DIV_EXPR.

	* gcc.dg/torture/pr80341.c: New testcase.

Added:
    trunk/gcc/testsuite/gcc.dg/torture/pr80341.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/convert.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree.c
Comment 9 Richard Biener 2017-04-07 08:38:30 UTC
Fixed on trunk sofar.
Comment 10 Richard Biener 2017-06-22 07:31:07 UTC
Author: rguenth
Date: Thu Jun 22 07:30:03 2017
New Revision: 249499

URL: https://gcc.gnu.org/viewcvs?rev=249499&root=gcc&view=rev
Log:
2017-06-22  Richard Biener  <rguenther@suse.de>

	Backport from mainline
	2017-04-20  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/80453
	* tree-ssa-sccvn.h (struct vn_phi_s): Add cclhs and ccrhs members.
	* tree-ssa-sccvn.c (cond_stmts_equal_p): Use recorded lhs and rhs
	from the conditions.
	(vn_phi_eq): Pass them down.
	(vn_phi_lookup): Record them.
	(vn_phi_insert): Likewise.

	2017-04-07  Richard Biener  <rguenther@suse.de>

	PR middle-end/80341
	* tree.c (get_unwidened): Also handle ! for_type case for
	INTEGER_CSTs.
	* convert.c (do_narrow): Split out from ...
	(convert_to_integer_1): ... here.  Do not pass final truncation
	type to get_unwidened for TRUNC_DIV_EXPR.

	* gcc.dg/torture/pr80341.c: New testcase.

	2017-04-04  Richard Biener  <rguenther@suse.de>

	PR middle-end/80281
	* match.pd (A + (-B) -> A - B): Make sure to preserve unsigned
	arithmetic done for the negate or the plus.  Simplify.
	(A - (-B) -> A + B): Likewise.
	* fold-const.c (split_tree): Make sure to not negate pointers.

	* gcc.dg/torture/pr80281.c: New testcase.

Modified:
    branches/gcc-6-branch/gcc/ChangeLog
    branches/gcc-6-branch/gcc/convert.c
    branches/gcc-6-branch/gcc/fold-const.c
    branches/gcc-6-branch/gcc/match.pd
    branches/gcc-6-branch/gcc/testsuite/ChangeLog
    branches/gcc-6-branch/gcc/tree-ssa-sccvn.c
    branches/gcc-6-branch/gcc/tree-ssa-sccvn.h
    branches/gcc-6-branch/gcc/tree.c
Comment 11 Richard Biener 2017-09-18 11:10:37 UTC
Author: rguenth
Date: Mon Sep 18 11:10:06 2017
New Revision: 252920

URL: https://gcc.gnu.org/viewcvs?rev=252920&root=gcc&view=rev
Log:
2017-09-18  Richard Biener  <rguenther@suse.de>
 
	Backport from mainline
	2017-04-07  Richard Biener  <rguenther@suse.de>

	PR middle-end/80341
	* gcc.dg/torture/pr80341.c: New testcase.

	2017-04-04  Richard Biener  <rguenther@suse.de>

	PR middle-end/80281
	* gcc.dg/torture/pr80281.c: New testcase.

Added:
    branches/gcc-6-branch/gcc/testsuite/gcc.dg/torture/pr80281.c
    branches/gcc-6-branch/gcc/testsuite/gcc.dg/torture/pr80341.c
Modified:
    branches/gcc-6-branch/gcc/testsuite/ChangeLog
Comment 12 Jakub Jelinek 2017-10-11 09:28:55 UTC
GCC 5 branch has been closed, should be fixed in GCC 6.4 and later.