[swift-dev] The swift didn't conform the calling convention for ppc64le

Dmitri Gribenko gribozavr at gmail.com
Tue Mar 8 00:28:28 CST 2016


+John

On Mon, 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
>



-- 
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr at gmail.com>*/


More information about the swift-dev mailing list