Why -fno-pic and -fPIC gives the same results?

Hi,

I got this. Why -fno-pic and -fPIC are the same?

$ cat f.c
void f() { }
$ clang -fno-pic f.c -c -o nopic.o
$ clang -fPIC f.c -c -o pic.o
$ cmp nopic.o pic.o
$ echo "$?"
0

Hello,

On many targets the instructions needed for an empty function won't
need to refer to an address at all, so will always be position
independent, hence no difference in code-generation. If you make the
example a bit more complex, such as using a global variable then
you'll see some code-generation differences between -fPIC and
-fno-pic.

Hope this helps.

Peter

On many targets the instructions needed for an empty function won't
need to refer to an address at all, so will always be position
independent, hence no difference in code-generation. If you make the
example a bit more complex, such as using a global variable then
you'll see some code-generation differences between -fPIC and
-fno-pic.

Could you help make a minimal example? I used some global variables.
But the results are still the same. Thanks.

A caveat, this is on X86_64. Your clang may have a target where all
code is PIC. Let me know if I've misunderstood your question?

int global;

int f() { return global; }

I've edited the assembler output to remove directives.
clang f.c -fno-pic -S -o -
f:
pushq %rbp
movq %rsp, %rbp
movl global, %eax
popq %rbp
retq

clang f.c -fPIC -S -o -
f:
pushq %rbp
movq %rsp, %rbp
movq global@GOTPCREL(%rip), %rax
movl (%rax), %eax
popq %rbp
retq

Here is what I have. So Mac OS X does not support -fno-pic? I think
that clang should show some messages when -fno-pic is not supported.

$ uname
Darwin
$ cat main.sh
#!/usr/bin/env bash
# vim: set noexpandtab tabstop=2:

set -v
function cmd {
diff <($CC -S -fno-pic f.c -c -o -) <($CC -S -fPIC f.c -c -o -)
}

CC=clang cmd
CC=gcc cmd
$ ./main.sh
function cmd {
diff <($CC -S -fno-pic f.c -c -o -) <($CC -S -fPIC f.c -c -o -)
}

CC=clang cmd
CC=gcc cmd
$ cat f.c
/* vim: set noexpandtab tabstop=2: */
#include <stdio.h>

int global;
int f() { return global; }

$ uname
Linux
$ ./main.sh
function cmd {
diff <("$CC" -S -fno-pic f.c -c -o -) <("$CC" -S -fPIC f.c -c -o -)
}

CC=clang cmd
"$CC" -S -fPIC f.c -c -o -
"$CC" -S -fno-pic f.c -c -o -
14c14,15
< movl global, %eax

64-bit mac binaries (both x86 and arm) always force PIC on and it can’t be disabled there. (cf http://llvm-cs.pcc.me.uk/tools/clang/lib/Driver/ToolChains/Darwin.cpp#2222)