Bug 2156088 - GCL miscompiled with -ftree-vrp
Summary: GCL miscompiled with -ftree-vrp
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Fedora
Classification: Fedora
Component: gcc
Version: rawhide
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2022-12-23 20:53 UTC by Jerry James
Modified: 2022-12-24 04:54 UTC (History)
11 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2022-12-23 21:13:00 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Jerry James 2022-12-23 20:53:40 UTC
Description of problem:
GCL misbehaves when built with gcc 12, including strange segfaults.  Upstream produced a test case, which I have reduced to this:

#include <stdio.h>

int
main(int argc,char * argv[]) {
  long x;

  if (argc != 2)
    {
      fprintf(stderr, "Usage: %s integer\n", argv[0]);
      return 3;
    }
  sscanf(argv[1],"%ld",&x);

  long fx = ((unsigned long)&x >= 0x8000000000000000)
    ? (long)((long)&x - 0xA000000000000000) : x;
  if (fx < 0)
    {
      if (((0x2000000000000000 - fx) & 0xC000000000000000) == 0)
	  return 1;
      else
	  return 0;
    }
  else
    {
      return 2;
    }
}

The test is to invoke this program with argument -8874444426961747968.  When built with gcc 11, the test passes (exits with 0) at all optimization levels.  When built with gcc 12 at optimization levels -O0 or -O1, the test passes.  When built with -O2 it fails (exits with 1).  When built with -O2 -fno-tree-vrp, the test passes.

Changing the code in the "then" branch of "if (fx < 0)" to this:

      return (((0x2000000000000000 - fx) & 0xC000000000000000) == 0) ? 1 : 0;

results in a passing test.

Version-Release number of selected component (if applicable):
gcc-12.2.1-4.fc38.x86_64

How reproducible:
Always

Steps to Reproduce:
1. Say the code above is in a file named t.c.  Run "gcc -O2 -o t t.c"
2. Run "./t -8874444426961747968"
3. "echo $?" shows exit code 1
4. Run "gcc -O2 -fno-tree-vrp -o t t.c"
5. Run "./t -8874444426961747968"
6. "echo $?" shows exit code 0

Actual results:
An unexpected branch is taken when -ftree-vrp is in effect.

Expected results:


Additional info:

Comment 1 Jakub Jelinek 2022-12-23 21:13:00 UTC
That testcase invokes undefined behavior.
Compile/link it with -fsanitize=undefined and you'll see it:
/tmp/1.c:18:32: runtime error: signed integer overflow: 2305843009213693952 - -8874444426961747968 cannot be represented in type 'long int'
Signed integer overflow is UB in C/C++.

Comment 2 Jerry James 2022-12-24 04:54:27 UTC
Ah, right you are.  Thank you, Jakub.  I will pass that information upstream.


Note You need to log in before you can comment on or make changes to this bug.