Fixture 94
alignment
C · 4 functions · 4 lanes · 16 of 16 function-lanes behave identically
All 4 lanes recompile and return the same results as the original.
C11 alignment: _Alignas raises a member's alignment, which inserts padding that offsetof exposes. sizeof and offsetof are compile-time constants, so the emitted code contains the resolved numbers and nothing else.
#include <stdint.h>
#include <stddef.h>
/* C11 alignment: _Alignas raises a member's alignment, which inserts padding
* that offsetof exposes. sizeof and offsetof are compile-time constants, so the
* emitted code contains the resolved numbers and nothing else. */
struct Padded {
uint8_t tag;
_Alignas(16) int32_t payload;
uint8_t trailer;
};
struct Packed {
uint8_t tag;
int32_t payload;
uint8_t trailer;
};
__attribute__((noinline)) int32_t alignment_of_padded(void) {
return (int32_t)_Alignof(struct Padded);
}
__attribute__((noinline)) int32_t offset_of_payload(int32_t which) {
return which ? (int32_t)offsetof(struct Padded, payload)
: (int32_t)offsetof(struct Packed, payload);
}
__attribute__((noinline)) int32_t size_difference(void) {
return (int32_t)(sizeof(struct Padded) - sizeof(struct Packed));
}
__attribute__((noinline)) int32_t
padded_roundtrip(int32_t tag, int32_t payload) {
struct Padded object;
object.tag = (uint8_t)tag;
object.payload = payload;
object.trailer = (uint8_t)(tag + 1);
return object.payload + (int32_t)object.tag + (int32_t)object.trailer;
} Recovered C
Generated by glaurung decompile --style decbench at b47f6b43.
baseline.json records the result after recompiling the C and calling it beside the
original with seeded inputs.
clang -O0
4/4alignment_of_padded pass 6 lines
// glaurung: alignment_of_padded @ 0x1100
int32_t alignment_of_padded(void) {
// x86-64 prologue: save rbp
// x86-64 epilogue: restore rbp
return 16;
} offset_of_payload pass 6 lines
// glaurung: offset_of_payload @ 0x1110
int32_t offset_of_payload(int32_t arg0) {
// x86-64 prologue: save rbp
// x86-64 epilogue: restore rbp
return (((unsigned long)((unsigned int)(arg0)) != 0) ? 16 : 4);
} padded_roundtrip pass 10 lines
// glaurung: padded_roundtrip @ 0x1140
__attribute__((no_stack_protector)) int32_t padded_roundtrip(int32_t arg0, int32_t arg1) {
unsigned char local_30[32];
// x86-64 prologue: save rbp
*(signed char *)(&local_30[0]) = arg0;
*(int *)((&local_30[0] + 16)) = arg1;
*(signed char *)((&local_30[0] + 20)) = ((unsigned long)((unsigned int)(arg0)) + 1);
// x86-64 epilogue: restore rbp
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)((&local_30[0] + 16)))) + (unsigned int)((unsigned char)(*(char *)(&local_30[0])))))) + (unsigned int)((unsigned char)(*(char *)((&local_30[0] + 20))))));
} size_difference pass 6 lines
// glaurung: size_difference @ 0x1130
int32_t size_difference(void) {
// x86-64 prologue: save rbp
// x86-64 epilogue: restore rbp
return 20;
} clang -O2
4/4alignment_of_padded pass 4 lines
// glaurung: alignment_of_padded @ 0x1100
int32_t alignment_of_padded(void) {
return 16;
} offset_of_payload pass 4 lines
// glaurung: offset_of_payload @ 0x1110
int32_t offset_of_payload(int32_t arg0) {
return (((unsigned long)((unsigned int)(arg0)) == 0) ? 4 : 16);
} padded_roundtrip pass 4 lines
// glaurung: padded_roundtrip @ 0x1130
int32_t padded_roundtrip(int32_t arg0, int32_t arg1) {
return (unsigned int)(((unsigned int)((unsigned char)(((unsigned long)((unsigned int)((arg0 + 1))) & 255))) + (unsigned long)((unsigned int)(((unsigned int)((unsigned char)((arg0 & 255))) + arg1)))));
} size_difference pass 4 lines
// glaurung: size_difference @ 0x1120
int32_t size_difference(void) {
return 20;
} gcc -O0
4/4alignment_of_padded pass 6 lines
// glaurung: alignment_of_padded @ 0x10f9
int32_t alignment_of_padded(void) {
// x86-64 prologue: save rbp
// x86-64 epilogue: restore rbp
return 16;
} offset_of_payload pass 9 lines
// glaurung: offset_of_payload @ 0x1108
int32_t offset_of_payload(int32_t arg0) {
// x86-64 prologue: save rbp
if (((unsigned long)((unsigned int)(arg0)) == 0)) {
return 4;
} else {
return 16;
}
} padded_roundtrip pass 10 lines
// glaurung: padded_roundtrip @ 0x1136
__attribute__((no_stack_protector)) int32_t padded_roundtrip(int32_t arg0, int32_t arg1) {
unsigned char local_20[32];
// x86-64 prologue: save rbp
*(signed char *)(&local_20[0]) = arg0;
*(int *)((&local_20[0] + 16)) = arg1;
*(signed char *)((&local_20[0] + 20)) = ((unsigned long)((unsigned int)(arg0)) + 1);
// x86-64 epilogue: restore rbp
return (unsigned int)(((unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)((&local_20[0] + 20)))) & 255))) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)((&local_20[0] + 16)))) + (unsigned int)((unsigned char)(((unsigned int)((unsigned char)(*(char *)(&local_20[0]))) & 255))))))));
} size_difference pass 6 lines
// glaurung: size_difference @ 0x1127
int32_t size_difference(void) {
// x86-64 prologue: save rbp
// x86-64 epilogue: restore rbp
return 20;
} gcc -O2
4/4alignment_of_padded pass 4 lines
// glaurung: alignment_of_padded @ 0x1100
int32_t alignment_of_padded(void) {
return 16;
} offset_of_payload pass 4 lines
// glaurung: offset_of_payload @ 0x1110
int32_t offset_of_payload(int32_t arg0) {
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned int)((0 - ((unsigned long)((unsigned long)((unsigned int)(arg0))) < (unsigned long)(1)))) & -12))) + 16));
} padded_roundtrip pass 4 lines
// glaurung: padded_roundtrip @ 0x1130
int32_t padded_roundtrip(int32_t arg0, int32_t arg1) {
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned int)((unsigned char)((arg0 & 255))) + arg1))) + (unsigned int)((unsigned char)(((unsigned long)((unsigned int)((arg0 + 1))) & 255)))));
} size_difference pass 4 lines
// glaurung: size_difference @ 0x1120
int32_t size_difference(void) {
return 20;
}