LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 26256 - wrong code at -O2 and -O3 on x86_64-linux-gnu
Summary: wrong code at -O2 and -O3 on x86_64-linux-gnu
Status: RESOLVED FIXED
Alias: None
Product: clang
Classification: Unclassified
Component: -New Bugs (show other bugs)
Version: trunk
Hardware: PC All
: P normal
Assignee: Matthias Braun
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-01-22 10:52 PST by Zhendong Su
Modified: 2016-01-25 16:10 PST (History)
6 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Zhendong Su 2016-01-22 10:52:03 PST
The following code is miscompiled by the current clang trunk (and 3.7.x) on x86_64-linux-gnu at -O2 and -O3 in both 32-bit and 64-bit modes.

This is a regression from 3.6.x.


$ clang-trunk -v
clang version 3.9.0 (trunk 258416)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/tools/bin
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/4.9
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/4.9.3
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/5.2.1
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.4
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.4.7
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.6
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.6.4
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.7
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.7.3
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8.4
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9.3
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.2.1
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Candidate multilib: x32;@mx32
Selected multilib: .;@m64
$
$ clang-trunk -Os small.c; ./a.out
$ clang-3.6 -O2 small.c; ./a.out
$
$ clang-trunk -O2 small.c
$ ./a.out
0
$ clang-3.7 -O2 small.c
$ ./a.out
0
$


------------------------------------


int printf (const char *, ...);

int a = 8, b, d, e, f;
short c;

void
fn1 ()
{ 
  char g = c, h = c = c | 195;
  if (d)
    ;
  if ((!a && c > d) || c < d)
    for (g = 0; g < 20; g++)
      e ^= f;
  a = 2 & g;
  if (h >= c || g)
    printf ("%d\n", b);
  if (a)
    { 
      fn1 ();
      for (;;)
        ;
    }
}

int
main ()
{ 
  fn1 ();
  return 0;
}
Comment 1 David Majnemer 2016-01-24 22:55:42 PST
Bisection points to r231507:
Author: Matthias Braun <matze@braunis.de>
Date:   Fri Mar 6 19:49:10 2015 +0000

    DAGCombiner: Canonicalize select(and/or,x,y) depending on target.
    
    This is based on the following equivalences:
    select(C0 & C1, X, Y) <=> select(C0, select(C1, X, Y), Y)
    select(C0 | C1, X, Y) <=> select(C0, X, select(C1, X, Y))
    
    Many target cannot perform and/or on the CPU flags and therefore the
    right side should be choosen to avoid materializign the i1 flags in an
    integer register. If the target can perform this operation efficiently
    we normalize to the left form.

Matthias, can you please take a look?
Comment 2 Matthias Braun 2016-01-25 16:10:07 PST
The problem turned out to be unrelated to my commit. Fixed in r258729. +Ahmed who may be interested in a post-commit review (maybe there's a more elegant way to fix it).