[swift-dev] The swift didn't conform the calling convention for ppc64le
Joe Groff
jgroff at apple.com
Tue Mar 8 11:57:38 CST 2016
Swift does not use the C calling convention.
-Joe
> On Mar 7, 2016, at 10:16 PM, bluedream via swift-dev <swift-dev at swift.org> wrote:
>
> 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?
>
> _______________________________________________
> swift-dev mailing list
> swift-dev at swift.org
> https://lists.swift.org/mailman/listinfo/swift-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20160308/1558e039/attachment.html>
More information about the swift-dev
mailing list