[LLVMdev] Question about compilation result - taking address of input array member

Eli Bendersky
Fri, 01 Feb 2013 20:14:09 -0000

On Fri, Feb 1, 2013 at 12:11 PM, Eli Bendersky <eliben at google.com>
wrote:
> Hello,
>
> I'm playing around with some LEA-related code generation on x86-64
> (trunk LLVM & Clang), and I run into a case I don't understand:
>
> $ cat takeaddr.c
> int* bar(int table[10]) {
>   return &table[2];
> }
>
> $ clang -cc1 -emit-llvm takeaddr.c
> $ cat takeaddr.ll
> ; ModuleID = 'takeaddr.c'
> target datalayout >
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
> target triple = "x86_64-unknown-linux-gnu"
>
> define i32* @bar(i32* %table) nounwind {
> entry:
>   %table.addr = alloca i32*, align 8
>   store i32* %table, i32** %table.addr, align 8
>   %0 = load i32** %table.addr, align 8
>   %arrayidx = getelementptr inbounds i32* %0, i64 2
>   ret i32* %arrayidx
> }
>
> $ llc -O3 takeaddr.ll -o -
> .file "takeaddr.ll"
> .text
> .globl bar
> .align 16, 0x90
> .type bar, at function
> bar:                                    # @bar
> # BB#0:                                 # %entry
> movq %rdi, -8(%rsp)
> leaq 8(%rdi), %rax
> ret
> .Ltmp0:
> .size bar, .Ltmp0-bar
>
>
> .section ".note.GNU-stack","", at progbits
>
> The first instruction in "bar" is not clear. Why is it needed? It
> seems harmless, but does it serve any purpose? Alignment? ISTM that
> the leaq suffices to pefrorm the actual task of the function. Is this
> a missed optimization of some sort?
>

I should add that if I manually hack takeaddr.ll to avoid the alloca
and store, instead using %table directly in the GEP, the movq goes
away and only leaq remains.

Eli