Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Respect the alignment attribute of functions. #186

Merged
merged 8 commits into from
Jan 15, 2024
18 changes: 18 additions & 0 deletions lib/Target/CBackend/CBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2051,6 +2051,15 @@ static void defineAligns(raw_ostream &Out) {
Out << "#endif\n\n";
}

static void defineFunctionAlign(raw_ostream &Out) {
Out << "#ifdef _MSC_VER\n";
Out << "#define __FUNCTIONALIGN__(X) /* WARNING: THIS FEATURE IS NOT "
"SUPPORTED BY MSVC! */ \n";
Out << "#else\n";
Out << "#define __FUNCTIONALIGN__(X) __attribute__((aligned(X)))\n";
Out << "#endif\n\n";
}

static void defineUnreachable(raw_ostream &Out) {
Out << "#ifdef _MSC_VER\n";
Out << "#define __builtin_unreachable() __assume(0)\n";
Expand Down Expand Up @@ -2355,6 +2364,8 @@ void CWriter::generateCompilerSpecificCode(raw_ostream &Out,
defineUnalignedLoad(Out);
if (headerIncAligns())
defineAligns(Out);
if (headerIncFunctionAlign())
defineFunctionAlign(Out);
if (headerIncNanInf())
defineNanInf(Out);
if (headerIncInt128())
Expand Down Expand Up @@ -2632,6 +2643,7 @@ void CWriter::generateHeader(Module &M) {
headerUseAttributeWeak();
Out << "__MSVC_INLINE__ ";
}

printFunctionProto(Out, &*I, GetValueName(&*I));
printFunctionAttributes(Out, I->getAttributes());
if (I->hasWeakLinkage() || I->hasLinkOnceLinkage()) {
Expand All @@ -2655,6 +2667,12 @@ void CWriter::generateHeader(Module &M) {
Out << " __HIDDEN__";
}

unsigned Alignment = I->getAlignment();
if (Alignment != 0) {
headerUseFunctionAlign();
Out << " __FUNCTIONALIGN__(" << Alignment << ") ";
}

if (I->hasName() && I->getName()[0] == 1)
Out << " __asm__ (\"" << I->getName().substr(1) << "\")";

Expand Down
2 changes: 2 additions & 0 deletions lib/Target/CBackend/CBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class CWriter : public FunctionPass, public InstVisitor<CWriter> {
bool AttributeList : 1;
bool UnalignedLoad : 1;
bool Aligns : 1;
bool FunctionAlign : 1;
bool NanInf : 1;
bool Int128 : 1;
bool ThreadFence : 1;
Expand Down Expand Up @@ -148,6 +149,7 @@ class CWriter : public FunctionPass, public InstVisitor<CWriter> {
USED_HEADERS_FLAG(AttributeList)
USED_HEADERS_FLAG(UnalignedLoad)
USED_HEADERS_FLAG(Aligns)
USED_HEADERS_FLAG(FunctionAlign)
USED_HEADERS_FLAG(NanInf)
USED_HEADERS_FLAG(Int128)
USED_HEADERS_FLAG(ThreadFence)
Expand Down
31 changes: 31 additions & 0 deletions test/cpp_tests/test_virtual_function_calls.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef _MSC_VER
// Suppress "dereferencing type-punned pointer will break strict-aliasing rules"
// gcc_extra_args: -Wno-strict-aliasing
struct A {
int a;
int b;
int f1(int i) { return 1 + i; }
int f2(int i) { return 1 + i; }
typedef int (A::*Function)(int);
int function_wrapper(Function f, int i) __attribute__((noinline)) {
return (this->*f)(i);
}
};

int main() {
A a{};
if (a.function_wrapper(&A::f1, 1) != 2)
return 0;
if (a.function_wrapper(&A::f2, 1) != 2)
return 0;
return 6;
}

#else

/* MSVC doesn't support adding alignment to functions, treat it as an expected
* failure */

int main() { return 25; }

#endif