why do undefined globals end up in .data instead of .bss?

Here is a module:

@vals = internal unnamed_addr global [20000000 x i32] undef, align 4

When I compile it into an .o file:

$ clang -c test.ll

$ objdump -t test.o

test.o: file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l df ABS 0000000000000000 test.ll
0000000000000000 l O .data 0000000004c4b400 vals

LLVM puts the global in the .data section, and results in a 77MB .o file of mostly zeroes. Why does this variable not go in the .bss section?

I think it's just an oversight; it doesn't matter for clang because it never emits globals like that. See TargetLoweringObjectFile::getKindForGlobal for the relevant logic.

-Eli

I see, thanks. Would a patch be welcome which changed this behavior? Or I
suppose I could emit zeroinitializer instead of undef. But it seems like
undef is the more correct value.

Sure, patch welcome.

-Eli

Are you producing these undef values yourself (in a pass/fronted)? Can you elaborate a little on why you think “undef” is the correct value? Inside LLVM, undef essentially means “any value we choose”. The language reference has a section on this. It would be entirely correct if we emitted all 1s instead of all 0s for undef. If you really want it to be .bss, zeroinitializer seems to be the better choice.

Tobias

It sounded like he didn't care what the actual data was, just that it
didn't consume space in the object file.

Tim.

I see, thanks. Would a patch be welcome which changed this behavior? Or I
suppose I could emit zeroinitializer instead of undef. But it seems like
undef is the more correct value.

Are you producing these undef values yourself (in a pass/fronted)?

Yes, frontend

Can you elaborate a little on why you think "undef" is the correct value?
Inside LLVM, undef essentially means "any value we choose". The language
reference has a section on this. It would be entirely correct if we emitted
all 1s instead of all 0s for undef. If you really want it to be .bss,
zeroinitializer seems to be the better choice.

Yes, any value would be semantically correct. What I am communicating to
LLVM is "any value will be fine here" which means that LLVM can do whatever
it wants here to achieve better performance, compile time speed, smaller
object size, or another goal that I have not thought of. And in this email
thread I am suggesting that LLVM should probably choose the smaller object
size goal in this situation, choose 0 for the value, and put it in .bss.

Ah ok, in that case it makes sense. As Eli said, feel free to submit a patch.

Thanks,
Tobias