[LLVMdev] llvm-gcc: code generated for pre- and post-increment

Eli Friedman eli.friedman at gmail.com
Fri Oct 8 15:58:51 PDT 2010


On Fri, Oct 8, 2010 at 7:51 AM, Steve Montgomery
<stephen.montgomery3 at btinternet.com> wrote:
> I'm relatively new to LLVM so apologies in advance if this is a dumb
> question. I've been experimenting with re-targeting LLVM onto a 16-bit
> micro which has pre and post increment and decrement addressing modes.
> I've been using llvm-gcc to generate llvm bitcode and llvm 2.7 to go
> from here to my target assembly code.
>
> I've got the Combine pass to deal with post-increment/decrement modes
> without any difficulty but I can't seem to get pre-increment/decrement
> modes to work. If I examine the bitcode for:
>
> char c, *p;
>
> void func(void)
> {
>   c = *++p;
> }
>
> then I get (with llvm-gcc 4.2.1):
>
> %0 = load i8** @p, align 4
> %1 = getelementptr inbounds i8* %0, i32 1
> store i8* %1, i8** @p, align 4
> %2 = load i8*, %1, align 1
> store i* %2m i8* @c, align 1
>
> I think the position of the first store is preventing
> DAGCombiner::CombineToPreIndexedLoadStore from folding the base
> pointer (test #3 out of the 4 tests it makes). If I move that store
> into p to the end of the code then it's happy to fold it.
>
> Why does llvm-gcc emit llvm code that seems to preclude the combiner
> from ever being able to combine a pre-increment/decrement? Given that
> the order of side-effects between sequence points is unspecified and
> the behaviour undefined if any object is modified more than once
> between sequence points it seems to me to be perfectly legal to move
> that first load to the end.

Note that pre-increment is only precluded in cases where you're
incrementing something which both can't be eliminated by mem2reg and
can't be LICM'ed out of a loop.  Yes, it's not ideal, but your
testcase isn't representative of many places where pre-increments are
used.

> In passing, I note that the clang front-end seems to emit code that
> will never be a candidate for folding into either pre or post
> increment/decrement operations.

I don't really know llvm-gcc that well, but the clang code generator
is completely naive here: it generates the complete increment, then
loads from the address.  If you're interested, though, it wouldn't be
too hard to change clang to detect constructs like this and shuffle
around the generated code.

-Eli




More information about the llvm-dev mailing list