Skip to content

Commit 3afc652

Browse files
authored
Merge pull request #10933 from aschwaighofer/swift-4.0-branch-07-1100-2017-fix_alignment_indirect_byval_args
[4.0] IRGen: Make sure to use the C function type's alignment for indirect byval arguments
2 parents f747e4c + 09cc9b2 commit 3afc652

File tree

4 files changed

+38
-5
lines changed

4 files changed

+38
-5
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -976,8 +976,9 @@ llvm::Type *SignatureExpansion::expandExternalSignatureTypes() {
976976
auto paramTy = getSILFuncConventions().getSILType(param);
977977
auto &paramTI = cast<FixedTypeInfo>(IGM.getTypeInfo(paramTy));
978978
if (AI.getIndirectByVal())
979-
addByvalArgumentAttributes(IGM, Attrs, getCurParamIndex(),
980-
paramTI.getFixedAlignment());
979+
addByvalArgumentAttributes(
980+
IGM, Attrs, getCurParamIndex(),
981+
Alignment(AI.getIndirectAlign().getQuantity()));
981982
addPointerParameter(paramTI.getStorageType());
982983
break;
983984
}
@@ -1851,6 +1852,16 @@ static void externalizeArguments(IRGenFunction &IGF, const Callee &callee,
18511852
auto &ti = cast<LoadableTypeInfo>(IGF.getTypeInfo(paramType));
18521853
Address addr = ti.allocateStack(IGF, paramType, false,
18531854
"indirect-temporary").getAddress();
1855+
// Set at least the alignment the ABI expects.
1856+
if (AI.getIndirectByVal()) {
1857+
auto ABIAlign = AI.getIndirectAlign();
1858+
if (ABIAlign > addr.getAlignment()) {
1859+
auto *AS = cast<llvm::AllocaInst>(addr.getAddress());
1860+
AS->setAlignment(ABIAlign.getQuantity());
1861+
addr = Address(addr.getAddress(), Alignment(ABIAlign.getQuantity()));
1862+
}
1863+
}
1864+
18541865
ti.initialize(IGF, in, addr);
18551866

18561867
out.add(addr.getAddress());

test/IRGen/Inputs/c_functions.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,14 @@ static inline void test_my_log() {
99
__attribute__((internal_linkage)) static const char fmt[] = "foobar";
1010
use(fmt);
1111
}
12+
13+
extern void useInt(unsigned int);
14+
15+
typedef struct {
16+
unsigned int val[8];
17+
} a_thing;
18+
19+
static inline void log_a_thing(const a_thing thing) {
20+
useInt(thing.val[0]);
21+
useInt(thing.val[7]);
22+
}

test/IRGen/abitypes.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class Foo {
107107
}
108108

109109
// Ensure that MyRect is passed as an indirect-byval on x86_64 because we run out of registers for direct arguments
110-
// x86_64-macosx: define hidden float @_T08abitypes3FooC25getXFromRectIndirectByVal{{[_0-9a-zA-Z]*}}FTo(i8*, i8*, float, float, float, float, float, float, float, %TSC6MyRectV* byval align 4) unnamed_addr {{.*}} {
110+
// x86_64-macosx: define hidden float @_T08abitypes3FooC25getXFromRectIndirectByVal{{[_0-9a-zA-Z]*}}FTo(i8*, i8*, float, float, float, float, float, float, float, %TSC6MyRectV* byval align 8) unnamed_addr {{.*}} {
111111
dynamic func getXFromRectIndirectByVal(_: Float, second _: Float,
112112
third _: Float, fourth _: Float,
113113
fifth _: Float, sixth _: Float,
@@ -120,8 +120,8 @@ class Foo {
120120
// x86_64-macosx: define hidden swiftcc float @_T08abitypes3FooC25getXFromRectIndirectSwift{{[_0-9a-zA-Z]*}}F(i64, i64, %T8abitypes3FooC* swiftself) {{.*}} {
121121
func getXFromRectIndirectSwift(_ r: MyRect) -> Float {
122122
let f : Float = 1.0
123-
// x86_64-macosx: [[TEMP:%.*]] = alloca [[TEMPTYPE:%.*]], align 4
124-
// x86_64-macosx: [[RESULT:%.*]] = call float bitcast (void ()* @objc_msgSend to float (i8*, i8*, float, float, float, float, float, float, float, [[TEMPTYPE]]*)*)(i8* %{{.*}}, i8* %{{.*}}, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, [[TEMPTYPE]]* byval align 4 [[TEMP]])
123+
// x86_64-macosx: [[TEMP:%.*]] = alloca [[TEMPTYPE:%.*]], align 8
124+
// x86_64-macosx: [[RESULT:%.*]] = call float bitcast (void ()* @objc_msgSend to float (i8*, i8*, float, float, float, float, float, float, float, [[TEMPTYPE]]*)*)(i8* %{{.*}}, i8* %{{.*}}, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, [[TEMPTYPE]]* byval align 8 [[TEMP]])
125125
// x86_64-macosx: ret float [[RESULT]]
126126
return getXFromRectIndirectByVal(f, second: f, third: f, fourth: f, fifth: f, sixth: f, seventh: f, withRect: r);
127127
}

test/IRGen/c_functions.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,14 @@ func testOverloaded() {
1212
// CHECK: call void @{{.*}}test_my_log
1313
test_my_log()
1414
} // CHECK: {{^}$}}
15+
16+
func test_indirect_by_val_alignment() {
17+
let x = a_thing()
18+
log_a_thing(x)
19+
}
20+
21+
// CHECK-LABEL: define hidden swiftcc void @_T011c_functions30test_indirect_by_val_alignmentyyF()
22+
// CHECK: %indirect-temporary = alloca %TSC7a_thingV, align [[ALIGN:[0-9]+]]
23+
// CHECK: [[CAST:%.*]] = bitcast %TSC7a_thingV* %indirect-temporary to %struct.a_thing*
24+
// CHECK: call void @log_a_thing(%struct.a_thing* byval align [[ALIGN]] [[CAST]])
25+
// CHECK: define internal void @log_a_thing(%struct.a_thing* byval align [[ALIGN]]

0 commit comments

Comments
 (0)