-
Notifications
You must be signed in to change notification settings - Fork 11.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[clang][AArch64] Correctly align HFA arguments when passed on the stack
When we pass a AArch64 Homogeneous Floating-Point Aggregate (HFA) argument with increased alignment requirements, for example struct S { __attribute__ ((__aligned__(16))) double v[4]; }; Clang uses `[4 x double]` for the parameter, which is passed on the stack at alignment 8, whereas it should be at alignment 16, following Rule C.4 in AAPCS (https://github.com/ARM-software/abi-aa/blob/master/aapcs64/aapcs64.rst#642parameter-passing-rules) Currently we don't have a way to express in LLVM IR the alignment requirements of the function arguments. The align attribute is applicable to pointers only, and only for some special ways of passing arguments (e..g byval). When implementing AAPCS32/AAPCS64, clang resorts to dubious hacks of coercing to types, which naturally have the needed alignment. We don't have enough types to cover all the cases, though. This patch introduces a new use of the stackalign attribute to control stack slot alignment, when and if an argument is passed in memory. The attribute align is left as an optimizer hint - it still applies to pointer types only and pertains to the content of the pointer, whereas the alignment of the pointer itself is determined by the stackalign attribute. For byval arguments, the stackalign attribute assumes the role, previously perfomed by align, falling back to align if stackalign` is absent. On the clang side, when passing arguments using the "direct" style (cf. `ABIArgInfo::Kind`), now we can optionally specify an alignment, which is emitted as the new `stackalign` attribute. Patch by Momchil Velikov and Lucas Prates. Differential Revision: https://reviews.llvm.org/D98794
- Loading branch information
1 parent
4b414b8
commit f9d932e
Showing
21 changed files
with
258 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// RUN: %clang_cc1 -triple aarch64-none-eabi -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-AAPCS | ||
// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DARWIN | ||
// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - -x c %s | FileCheck %s --check-prefixes=CHECK,CHECK-AAPCS | ||
|
||
typedef struct { | ||
float v[2]; | ||
} S0; | ||
|
||
// CHECK: define{{.*}} float @f0([2 x float] %h.coerce) | ||
float f0(S0 h) { | ||
return h.v[0]; | ||
} | ||
|
||
// CHECK: define{{.*}} float @f0_call() | ||
// CHECK: %call = call float @f0([2 x float] %1) | ||
float f0_call() { | ||
S0 h = {1.0f, 2.0f}; | ||
return f0(h); | ||
} | ||
typedef struct { | ||
double v[2]; | ||
} S1; | ||
|
||
// CHECK: define{{.*}} double @f1([2 x double] %h.coerce) | ||
double f1(S1 h) { | ||
return h.v[0]; | ||
} | ||
|
||
// CHECK: define{{.*}} double @f1_call() | ||
// CHECK: %call = call double @f1([2 x double] %1 | ||
double f1_call() { | ||
S1 h = {1.0, 2.0}; | ||
return f1(h); | ||
} | ||
typedef struct { | ||
__attribute__((__aligned__(16))) double v[2]; | ||
} S2; | ||
|
||
// CHECK-AAPCS: define{{.*}} double @f2([2 x double] alignstack(16) %h.coerce) | ||
// CHECK-DARWIN: define{{.*}} double @f2([2 x double] %h.coerce) | ||
double f2(S2 h) { | ||
return h.v[0]; | ||
} | ||
|
||
// CHECK: define{{.*}} double @f2_call() | ||
// CHECK-AAPCS: %call = call double @f2([2 x double] alignstack(16) %1) | ||
// CHECK-DARWIN: %call = call double @f2([2 x double] %1 | ||
double f2_call() { | ||
S2 h = {1.0, 2.0}; | ||
return f2(h); | ||
} | ||
|
||
typedef struct { | ||
__attribute__((__aligned__(32))) double v[4]; | ||
} S3; | ||
|
||
// CHECK-AAPCS: define{{.*}} double @f3([4 x double] alignstack(16) %h.coerce) | ||
// CHECK-DARWIN: define{{.*}} double @f3([4 x double] %h.coerce) | ||
double f3(S3 h) { | ||
return h.v[0]; | ||
} | ||
|
||
// CHECK: define{{.*}} double @f3_call() | ||
// CHECK-AAPCS: %call = call double @f3([4 x double] alignstack(16) %1) | ||
// CHECK-DARWIN: %call = call double @f3([4 x double] %1 | ||
double f3_call() { | ||
S3 h = {1.0, 2.0}; | ||
return f3(h); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.