instcombine produces strange i32*

I am getting wrong code from one of the passes, namely instcombine. I
see it in my JIT application when calling the pass directly through a
pass manager.
It was not possible for me to reproduce this behaviour with 'opt'
however I could isolate the IR and write a minimal 'opt' myself and
reproduce it.

As you can see the input IR (f.ll) operates most of the time with
floating point numbers and strangly the instcombine pass replaces some
float* with i32*. This is wrong and completely messes up the code and
gives strange restults and segfaults.

I attach the input IR, program and output:

f.ll (input IR)
main.cc (reads f.ll and applies the passes and prints out the
resulting IR)
f_main.ll (output of main)

You can see in f_main.ll strange bitcasts and loads to i32*.

   %31 = getelementptr float, float* %arg3, i64 %13
   %32 = bitcast float* %31 to i32*
   %33 = load i32, i32* %32, align 4

I tried to mimic this with 'opt' with the following command

opt -basicaa -licm -gvn -mem2reg -loop-vectorize -early-cse
-instcombine -S f.ll

This doesn't reproduce the behaviour.

I am seeing this in LLVM 3.8 and 3.9. This is a longer-standing issue
and probably not fixed in trunk right now.

Any idea?

Frank

f.ll (15.8 KB)

f_main.ll (12.7 KB)

main.cc (5.03 KB)

I am getting wrong code from one of the passes, namely instcombine. I
see it in my JIT application when calling the pass directly through a
pass manager.
It was not possible for me to reproduce this behaviour with 'opt'
however I could isolate the IR and write a minimal 'opt' myself and
reproduce it.

As you can see the input IR (f.ll) operates most of the time with
floating point numbers and strangly the instcombine pass replaces some
float* with i32*. This is wrong and completely messes up the code and
gives strange restults and segfaults.

I attach the input IR, program and output:

f.ll (input IR)
main.cc (reads f.ll and applies the passes and prints out the
resulting IR)
f_main.ll (output of main)

You can see in f_main.ll strange bitcasts and loads to i32*.

%31 = getelementptr float, float* %arg3, i64 %13
%32 = bitcast float* %31 to i32*
%33 = load i32, i32* %32, align 4

It is not clear to me what is “wrong” here?
%33 is only stored after, using an i32 instead of a float is OK.

I tried to mimic this with 'opt' with the following command

opt -basicaa -licm -gvn -mem2reg -loop-vectorize -early-cse
-instcombine -S f.ll

First your IR does not have a triple/datalayout.
Second you should add -targetlibinfo -tti at the beginning of the opt arguments list.
And finally, it’ll help in general to get the IR right before instcombine so that you can reproduce with opt -instcombine alone.

For example by modifying your program to comment out the run of InstCombine.