32bit math being promoted to 64 bit

What optimization pass promotes 32 bit math operations to 64 bit
operations so I can disable it? I have code that works fine with
optimizations turned off but fails with it turned on because of this
stage.

Micah Villmow

Systems Engineer

Advanced Technology & Performance

Advanced Micro Devices Inc.

4555 Great America Pkwy,

Santa Clara, CA. 95054

P: 408-572-6219

F: 408-572-6596

Do you have a testcase? An .ll file with no 64-bit operations, and one optimization pass that introduces them?

-Chris

Sounds a lot like the issue I reported in PR 3101.

Can you run your bitcode through opt -instcombine and check for promotions?

Greetings,

Tilmann

I've attached the original ll file and the result of doing

llvm-as < test_fc_27.ll | opt -std-compile-opts > test_fc_27-opt.bc

llvm-dis test_fc_27-opt.bc

This is very problematic as 64 bit integer operations are software
emulated and I would rather not have them generated unless explicitly
requested by the programmer.

test_fc_27.ll (2.39 KB)

test_fc_27-opt.ll (1.65 KB)

instcombine doesn't seem to be doing it. From my testing it seems to
only occur when I use -indvars after a long string of commands.

For example:
llvm-as < test_fc_27.ll | opt -preverify -domtree -verify
-lowersetjmp -raiseallocs -simplifycfg -domtree -domfrontier
-mem2reg -globalopt -globaldce -ipconstprop -deadargelim
-instcombine -simplifycfg -ba
siccg -prune-eh -inline -argpromotion -simplify-libcalls
-instcombine -jump-threading -simplifycfg -domtree -domfrontier
-scalarrepl -instcombine -break-crit-edges -condprop -tailcallelim
-simplifycfg -reassociate -domtree -loops -loopsimplify -domfrontier
-scalar-evolution -lcssa -loop-rotate -licm -lcssa
-scalar-evolution -lcssa -loop-index-split -instcombine
-scalar-evolution -lcssa -simplifycfg -view-cfg

Doesn't cause it, but
llvm-as < test_fc_27.ll | opt -preverify -domtree -verify
-lowersetjmp -raiseallocs -simplifycfg -domtree -domfrontier
-mem2reg -globalopt -globaldce -ipconstprop -deadargelim
-instcombine -simplifycfg -ba
siccg -prune-eh -inline -argpromotion -simplify-libcalls
-instcombine -jump-threading -simplifycfg -domtree -domfrontier
-scalarrepl -instcombine -break-crit-edges -condprop -tailcallelim
-simplifycfg -reassociate -domtree -loops -loopsimplify -domfrontier
-scalar-evolution -lcssa -loop-rotate -licm -lcssa
-scalar-evolution -lcssa -loop-index-split -instcombine
-scalar-evolution -lcssa -indvars -simplifycfg -view-cfg

does.

However, opt -indvars does not cause it, so it seems to be a sequence of
operations that is causing it and not -indvars by itself.

Hope this helps,
Micah

Do you have a testcase? An .ll file with no 64-bit operations, and one
optimization pass that introduces them?

It's pretty common to instcombine to expand 32 bit operations to 64
bit. See, for example, recent issue with CellSPU's 32 =>64 bit muls

Yes, it's indvars. And at least on an architecture with a reasonably
efficient 64-bit multiply, we want to do this. The rewritten version
manages to eliminate the loop completely: it's rewriting the
loop-carried value as a direct computation, and this is generally a
good thing. The code that computes the formula is BinomialCoefficient
in ScalarEvolution.cpp, and the code that puts it into the code is
IndVarSimplify::RewriteLoopExitValues.

That said, this could be really bad on an architecture which can't
perform this kind of multiply natively. Currently, the code has a
hack to disallow generating SCEVs with multiplies larger than 64 bits.
There's a few issues here: one, the code is in the wrong place. And
two, we don't really know the characteristics of the target when we're
running indvars.

For this particular case (a quadratic addrec), though, it's actually
possible to rewrite it without the 64-bit multiply: an equivalent
expression for %tmp.17 is "((%tmp6-1)/2)*((%tmp6-2)|1)". Until we
have a better solution, it might be reasonable to teach the SCEV
expander to recognize this alternate expression for the operation in
question, and make indvars refuse to expand wider addrecs (which tend
to be quite rare).

-Eli

This wouldn't normally be a problem. But it's ironic that this instcombine feature is happening in the middle of libgcc's 64-bit multiplication emulation code.

To get 64-bit multiplication for the Cell SPU, you have to compile __muldi3.c, into which instcombine inserts 64-bit multiplication.

-scooter