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

Eli Bendersky
Fri, 01 Feb 2013 20:11:04 -0000

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?

Thanks in advance,
Eli