[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