Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does clang output alignment specific things

Suppose I have a basic program in c, and I compile it with clang, like the following:

#include "stdio.h"
int x = 0x7FFFFFFF;
int main(void)
{

    printf("%d\n",x);
}

Compiling this with clang -emit-llvm temp.c -fno-rtti -O3 -S produces the following bitcode:

; ModuleID = 'temp.c'
target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
target triple = "i686-pc-linux-gnu"

@x = global i32 2147483647, align 4
@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1

; Function Attrs: nounwind
define i32 @main() #0 {
entry:
  %0 = load i32, i32* @x, align 4, !tbaa !1
  %call = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %0) #1
  ret i32 0
}

; Function Attrs: nounwind
declare i32 @printf(i8* nocapture readonly, ...) #0

attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }

!llvm.ident = !{!0}

!0 = !{!"clang version 3.7.1 "}
!1 = !{!2, !2, i64 0}
!2 = !{!"int", !3, i64 0}
!3 = !{!"omnipotent char", !4, i64 0}
!4 = !{!"Simple C/C++ TBAA"}

Now my real question is about the lines that reference the variable x. If you notice, it seems that x is declared as an aligned variable (it is aligned to 4).

How does clang know that ints should be aligned? My claim is that clang does not have any clue about the alignment of any variables, because this depends on what backend you use. For example I could use a backend for an 8 bit machine, then it would not need to be aligned at all.

So my question is: Why does clang guess at alignment, seeing as it really is not possible?

like image 298
DarthRubik Avatar asked Nov 09 '22 10:11

DarthRubik


1 Answers

Looking at the LLVM MAN

A module may specify a target specific data layout string that specifies how data is to be laid out in memory. The syntax for the data layout is simply:

target datalayout = "layout specification"

The layout specification consists of a list of specifications separated by the minus sign character (‘-‘). Each specification starts with a letter and may include other information after the letter to define some aspect of the data layout. The specifications accepted are as follows:

[...]

n < size1 > : < size2 > : < size3 >...

This specifies a set of native integer widths for the target CPU in bits. For example, it might contain n32 for 32-bit PowerPC, n32:64 for PowerPC 64, or n8:16:32:64 for X86-64. Elements of this set are considered to support most general arithmetic operations efficiently.

emphasis mine

And

When LLVM is determining the alignment for a given type, it uses the following rules:

If the type sought is an exact match for one of the specifications, that specification is used.

  1. If no match is found, and the type sought is an integer type, then the smallest integer type that is larger than the bitwidth of the sought type is used.
  2. If none of the specifications are larger than the bitwidth then the largest integer type is used. For example, given the default specifications above, the i7 type will use the alignment of i8 (next largest) while both i65 and i256 will use the alignment of i64 (largest specified).
  3. If no match is found, and the type sought is a vector type, then the largest vector type that is smaller than the sought vector type will be used as a fall back. This happens because <128 x double> can be implemented in terms of 64 <2 x double>, for example.

And

++Global variables**

[...]

An explicit alignment may be specified for a global, which must be a power of 2. If not present, or if the alignment is set to zero, the alignment of the global is set by the target to whatever it feels convenient. If an explicit alignment is specified, the global is forced to have exactly that alignment.

emphasis mine

like image 135
LPs Avatar answered Nov 14 '22 23:11

LPs