]> granicus.if.org Git - clang/commitdiff
[CodeGen] Implicitly set stackrealign on the main function, if custom stack alignment...
authorMartin Storsjo <martin@martin.st>
Tue, 21 Aug 2018 20:41:17 +0000 (20:41 +0000)
committerMartin Storsjo <martin@martin.st>
Tue, 21 Aug 2018 20:41:17 +0000 (20:41 +0000)
If using a custom stack alignment, one is expected to make sure
that all callers provide such alignment, or realign the stack in
all entry points (and callbacks).

Despite this, the compiler can assume that the main function will
need realignment in these cases, since the startup routines calling
the main function most probably won't provide the custom alignment.

This matches what GCC does in similar cases; if compiling with
-mincoming-stack-boundary=X -mpreferred-stack-boundary=X, GCC normally
assumes such alignment on entry to a function, but specifically for
the main function still does realignment.

Differential Revision: https://reviews.llvm.org/D51026

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@340334 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenFunction.cpp
test/CodeGen/stackrealign-main.c [new file with mode: 0644]

index 030101d2f4edd9a1ce2eb90089ada44650a0ab48..d3b1bd77dc43149a3ce497df0d8cb35b82b07185 100644 (file)
@@ -979,6 +979,13 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
       if (FD->isMain())
         Fn->addFnAttr(llvm::Attribute::NoRecurse);
 
+  // If a custom alignment is used, force realigning to this alignment on
+  // any main function which certainly will need it.
+  if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
+    if ((FD->isMain() || FD->isMSVCRTEntryPoint()) &&
+        CGM.getCodeGenOpts().StackAlignment)
+      Fn->addFnAttr("stackrealign");
+
   llvm::BasicBlock *EntryBB = createBasicBlock("entry", CurFn);
 
   // Create a marker to make it easy to insert allocas into the entryblock
diff --git a/test/CodeGen/stackrealign-main.c b/test/CodeGen/stackrealign-main.c
new file mode 100644 (file)
index 0000000..10b21bf
--- /dev/null
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - -mstack-alignment=64 %s | FileCheck %s
+
+// CHECK-LABEL: define void @other()
+// CHECK: [[OTHER:#[0-9]+]]
+// CHECK: {
+void other(void) {}
+
+// CHECK-LABEL: define i32 @main(
+// CHECK: [[MAIN:#[0-9]+]]
+// CHECK: {
+int main(int argc, char **argv) {
+  other();
+  return 0;
+}
+
+// CHECK: attributes [[OTHER]] = { noinline nounwind optnone
+// CHECK-NOT: "stackrealign"
+// CHECK: }
+// CHECK: attributes [[MAIN]] = { noinline nounwind optnone {{.*}}"stackrealign"{{.*}} }