Bug 186848

Summary: CLANG/LLVM code generation bug with optimisation on i386
Product: Base System Reporter: David Hines <freebsd>
Component: i386Assignee: freebsd-i386 (Nobody) <i386>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 10.0-RELEASE   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.shar none

Description David Hines 2014-02-17 17:50:00 UTC
"cc -O -o clang_bug-O clang_bug.c" generates incorrect code on i386, with the attached sample code. Without the "-O", or on an amd64 install the problem does not occur.

Fix: No fix known. Work-arounds include not using optimiser, or using gcc.

Patch attached with submission follows:
How-To-Repeat: Compile and run the attached programme.

When this is compiled without optimisation the output is correct.
  cc -o clang_bug clang_bug.c; ./clang_bug
  An int has 32 bits

With optimisation it is incorrect.
  cc -O -o clang_bug-O clang_bug.c; ./clang_bug-O
  An int has 33 bits
Comment 1 Bruce Evans freebsd_committer freebsd_triage 2014-02-20 03:06:55 UTC
On Mon, 17 Feb 2014, David Hines wrote:

>> Description:
> "cc -O -o clang_bug-O clang_bug.c" generates incorrect code on i386, with the attached sample code. Without the "-O", or on an amd64 install the problem does not occur.

This is a bug in clang_bug.c.  It's behaviour is undefined.

> Xunion
> X{
> X    int i;
> X} u;
> X
> X
> Xint
> Xmain(int argc, char *argv[])
> X{
> X    int j = 1;
> X
> X    for (u.i = 1;  u.i += u.i;  ++j)
> X	;
> X    printf("An int has %d bits\n", j);
> X
> X    return 0;
> X}

Undefined behaviour occurs when the addition overflows.  clang somehow
notices this (u.i starts as 1, and repeated doublings of it cannot
make it 0 unless overflow occurs).  The addition does in fact overflow.
The result can be anything.

Some people (not me) don't like clang not giving the "normal" behaviour
on overflow.

Bruce
Comment 2 Dimitry Andric freebsd_committer freebsd_triage 2014-03-02 23:25:32 UTC
State Changed
From-To: open->closed

The program relies on integer overflow, which is undefined behavior. 
Either fix the program (recommended), or compile with -fwrapv.