[swift-dev] The swift didn't conform the calling convention for ppc64le
bluedream
48825004 at qq.com
Tue Mar 8 00:16:23 CST 2016
Hi, all,
I am trying the swift compiler these days in ppc64le, and found that, if the function return type is aggr, the code swift generated didn't conform the ppc64le ABI.
> cat test.swift
func test() -> (Bool, Double, Int){
return (true,3.0,3);
}
test();
> swiftc test.swift -emit-ir
; ModuleID = '-'
target datalayout = "e-m:e-i64:64-n32:64"
target triple = "powerpc64le-unknown-linux-gnu"
...
define protected signext i32 @main(i32 signext, i8**) #0 {
entry:
%2 = bitcast i8** %1 to i8*
store i32 %0, i32* getelementptr inbounds (%Vs5Int32, %Vs5Int32* @_TZvOs7Process5_argcVs5Int32, i32 0, i32 0), align 4
call void @swift_once(i64* @globalinit_33_1BDF70FFC18749BAB495A73B459ED2F0_token3, i8* bitcast (void ()* @globalinit_33_1BDF70FFC18749BAB495A73B459ED2F0_func3 to i8*))
store i8* %2, i8** getelementptr inbounds (%Sp, %Sp* @_TZvOs7Process11_unsafeArgvGSpGSpVs4Int8__, i32 0, i32 0), align 8
%3 = call { i1, double, i64 } @_TF4test4testFT_TSbSdSi_()
%4 = extractvalue { i1, double, i64 } %3, 0
%5 = extractvalue { i1, double, i64 } %3, 1
%6 = extractvalue { i1, double, i64 } %3, 2
ret i32 0
}
We can see that, swift emit the { i1, double, i64 } as its return type and llvm will pass the return value of _TF4test4testFT_TSbSdSi_ by register.
> objdump -dr test.o
...
4c: R_PPC64_TOC16_HA .toc+0x18
50: 00 00 63 e8 ld r3,0(r3)
50: R_PPC64_TOC16_LO_DS .toc+0x18
54: 60 00 9f e8 ld r4,96(r31)
58: 00 00 83 f8 std r4,0(r3)
5c: 01 00 00 48 bl 5c <main+0x5c>
5c: R_PPC64_REL24 _TF4test4testFT_TSbSdSi_
60: 00 00 00 60 nop
However, for ppc64le ABI, this should be passed by address. See what clang emit the ir for return aggr of this type.
> cat test2.cpp
struct A {
bool b;
double d;
long long m;
};
A test();
int main() {
test();
return 0;
}
> clang test2.cpp -S -emit-llvm
> cat test2.ll
; ModuleID = 'test2.cpp'
target datalayout = "e-m:e-i64:64-n32:64"
target triple = "powerpc64le-unknown-linux-gnu"
%struct.A = type { i8, double, i64 }
; Function Attrs: norecurse
define signext i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca %struct.A, align 8
store i32 0, i32* %1, align 4
call void @_Z4testv(%struct.A* sret %2)
ret i32 0
}
declare void @_Z4testv(%struct.A* sret) #1
Clang frontend will place it as the first parameter of the function. That would cause serious issues if we are linking with code write from other language(i.e. c/c++). Any comments?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20160308/c81db283/attachment.html>
More information about the swift-dev
mailing list