optimizer problem, possibly involving instcombine

Hi all,

Continuing to enjoy LLVM. I’m seeing something strange with the simple function “f(a,b) = (a+b == b+a)”, which before optimization passes has the following LLVM code:

define i1 @f(i64, i64) {
top:
%a = alloca i64, !dbg !5697
%b = alloca i64, !dbg !5697
store i64 %0, i64* %a, !dbg !5697
store i64 %1, i64* %b, !dbg !5697
%2 = load i64* %a, !dbg !5704
%3 = load i64* %b, !dbg !5704
%4 = add i64 %2, %3, !dbg !5704
%5 = load i64* %b, !dbg !5704
%6 = load i64* %a, !dbg !5704
%7 = add i64 %5, %6, !dbg !5704
%8 = icmp eq i64 %4, %7, !dbg !5704
ret i1 %8, !dbg !5704
}

After our set of optimization passes, I get this strange result:

define i1 @f(i64, i64) {
top:
%2 = icmp eq i64 %1, %0, !dbg !5697
ret i1 %2, !dbg !5697
}

If I switch the order of the arguments in the second addition, so the function is “f(a,b) = (a+b == a+b)”, then the code is optimized to

define i1 @f(i64, i64) {
top:
ret i1 true, !dbg !5832
}

which is correct.

This is LLVM 3.1. You can see the full list of passes I’m running here: https://github.com/JuliaLang/julia/blob/master/src/codegen.cpp#L2564

The linked code currently contains a workaround I found, which was to disable the first two instcombine passes. With that, the original function also reduces to returning a constant true.

Is this a known bug, or am I just mis-ordering the optimization passes somehow?

Many thanks,

-Jeff

Hi Jeff,

Continuing to enjoy LLVM. I'm seeing something strange with the simple function
"f(a,b) = (a+b == b+a)", which before optimization passes has the following LLVM
code:

define i1 @f(i64, i64) {
top:
   %a = alloca i64, !dbg !5697
   %b = alloca i64, !dbg !5697
   store i64 %0, i64* %a, !dbg !5697
   store i64 %1, i64* %b, !dbg !5697
   %2 = load i64* %a, !dbg !5704
   %3 = load i64* %b, !dbg !5704
   %4 = add i64 %2, %3, !dbg !5704
   %5 = load i64* %b, !dbg !5704
   %6 = load i64* %a, !dbg !5704
   %7 = add i64 %5, %6, !dbg !5704
   %8 = icmp eq i64 %4, %7, !dbg !5704
   ret i1 %8, !dbg !5704
}

After our set of optimization passes, I get this strange result:

define i1 @f(i64, i64) {
top:
   %2 = icmp eq i64 %1, %0, !dbg !5697
   ret i1 %2, !dbg !5697
}

as this is wrong, it is a bug: it shouldn't matter in what order you run passes,
the result should always be correct. I suggest you open a bug report including
complete instructions on how to reproduce. The best thing would be if you
attach a complete LLVM IR testcase, and an "opt" command line that reproduces,
along the lines of "opt testcase.ll -S -o - -instcombine -sroa -xyzpass ..."

Best wishes, Duncan.