[llvm] r265482 - Swift Calling Convention: swiftcc for ARM.

Manman Ren via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 5 15:44:47 PDT 2016


Author: mren
Date: Tue Apr  5 17:44:44 2016
New Revision: 265482

URL: http://llvm.org/viewvc/llvm-project?rev=265482&view=rev
Log:
Swift Calling Convention: swiftcc for ARM.

Differential Revision: http://reviews.llvm.org/D18769

Added:
    llvm/trunk/test/CodeGen/ARM/swift-ios.ll
    llvm/trunk/test/CodeGen/ARM/swift-return.ll
Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/lib/Target/ARM/ARMFastISel.cpp
    llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=265482&r1=265481&r2=265482&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Tue Apr  5 17:44:44 2016
@@ -430,6 +430,7 @@ added in the future:
 "``swiftcc``" - This calling convention is used for Swift language.
     - On X86-64 RCX and R8 are available for additional integer returns, and
       XMM2 and XMM3 are available for additional FP/vector returns.
+    - On iOS platforms, we use AAPCS-VFP calling convention.
 "``cc <n>``" - Numbered convention
     Any calling convention may be specified by number, allowing
     target-specific calling conventions to be used. Target specific

Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=265482&r1=265481&r2=265482&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Tue Apr  5 17:44:44 2016
@@ -1859,6 +1859,7 @@ CCAssignFn *ARMFastISel::CCAssignFnForCa
       return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
     }
   case CallingConv::ARM_AAPCS_VFP:
+  case CallingConv::Swift:
     if (!isVarArg)
       return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP);
     // Fall through to soft float variant, variadic functions don't
@@ -3007,6 +3008,7 @@ bool ARMFastISel::fastLowerArguments() {
   case CallingConv::ARM_AAPCS_VFP:
   case CallingConv::ARM_AAPCS:
   case CallingConv::ARM_APCS:
+  case CallingConv::Swift:
     break;
   }
 

Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=265482&r1=265481&r2=265482&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Tue Apr  5 17:44:44 2016
@@ -1388,6 +1388,7 @@ ARMTargetLowering::getEffectiveCallingCo
   case CallingConv::PreserveMost:
     return CallingConv::PreserveMost;
   case CallingConv::ARM_AAPCS_VFP:
+  case CallingConv::Swift:
     return isVarArg ? CallingConv::ARM_AAPCS : CallingConv::ARM_AAPCS_VFP;
   case CallingConv::C:
     if (!Subtarget->isAAPCS_ABI())

Added: llvm/trunk/test/CodeGen/ARM/swift-ios.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/swift-ios.ll?rev=265482&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/swift-ios.ll (added)
+++ llvm/trunk/test/CodeGen/ARM/swift-ios.ll Tue Apr  5 17:44:44 2016
@@ -0,0 +1,68 @@
+; RUN: llc -mtriple=armv7-apple-ios < %s | FileCheck %s
+
+define swiftcc float @t1(float %a, float %b) {
+entry:
+; CHECK: t1
+; CHECK-NOT: vmov
+; CHECK: vadd.f32
+  %add = fadd float %a, %b
+  ret float %add
+}
+
+define swiftcc double @t2(double %a, double %b) {
+entry:
+; CHECK: t2
+; CHECK-NOT: vmov
+; CHECK: vadd.f64
+  %add = fadd double %a, %b
+  ret double %add
+}
+
+define swiftcc double @t9(double %d0, double %d1, double %d2, double %d3,
+    double %d4, double %d5, double %d6, double %d7, float %a, float %b) {
+entry:
+; CHECK-LABEL: t9:
+; CHECK-NOT: vmov
+; CHECK: vldr
+  %add = fadd float %a, %b
+  %conv = fpext float %add to double
+  ret double %conv
+}
+
+define swiftcc double @t10(double %d0, double %d1, double %d2, double %d3,
+    double %d4, double %d5, double %a, float %b, double %c) {
+entry:
+; CHECK-LABEL: t10:
+; CHECK-NOT: vmov
+; CHECK: vldr
+  %add = fadd double %a, %c
+  ret double %add
+}
+
+define swiftcc float @t11(double %d0, double %d1, double %d2, double %d3,
+    double %d4, double %d5, double %d6, float %a, double %b, float %c) {
+entry:
+; CHECK-LABEL: t11:
+; CHECK: vldr
+  %add = fadd float %a, %c
+  ret float %add
+}
+
+define swiftcc double @t12(double %a, double %b) {
+entry:
+; CHECK-LABEL: t12:
+; CHECK: vstr
+  %add = fadd double %a, %b
+  %sub = fsub double %a, %b
+  %call = tail call swiftcc double @x(double 0.000000e+00, double 0.000000e+00,
+                 double 0.000000e+00, double 0.000000e+00, double 0.000000e+00,
+                 double 0.000000e+00, double %add, float 0.000000e+00,
+                 double %sub)
+  ret double %call
+}
+
+declare swiftcc double @x(double, double, double, double, double, double,
+                          double, float, double)
+
+attributes #0 = { readnone }
+attributes #1 = { readonly }

Added: llvm/trunk/test/CodeGen/ARM/swift-return.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/swift-return.ll?rev=265482&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/swift-return.ll (added)
+++ llvm/trunk/test/CodeGen/ARM/swift-return.ll Tue Apr  5 17:44:44 2016
@@ -0,0 +1,133 @@
+; RUN: llc -mtriple=armv7k-apple-ios8.0 -mcpu=cortex-a7 -verify-machineinstrs < %s | FileCheck %s
+; RUN: llc -mtriple=armv7k-apple-ios8.0 -mcpu=cortex-a7 -verify-machineinstrs < %s -O0 | FileCheck --check-prefix=CHECK-O0 %s
+
+; RUN: llc -mtriple=armv7-apple-ios -verify-machineinstrs < %s | FileCheck %s
+; RUN: llc -mtriple=armv7-apple-ios -verify-machineinstrs < %s -O0 | FileCheck --check-prefix=CHECK-O0 %s
+
+; Test how llvm handles return type of {i16, i8}. The return value will be
+; passed in %r0 and %r1.
+; CHECK-LABEL: test:
+; CHECK: bl {{.*}}gen
+; CHECK: sxth {{.*}}, r0
+; CHECK: sxtab r0, {{.*}}, r1
+; CHECK-O0-LABEL: test:
+; CHECK-O0: bl {{.*}}gen
+; CHECK-O0: sxth r0, r0
+; CHECK-O0: sxtb r1, r1
+; CHECK-O0: add r0, r0, r1
+define i16 @test(i32 %key) {
+entry:
+  %key.addr = alloca i32, align 4
+  store i32 %key, i32* %key.addr, align 4
+  %0 = load i32, i32* %key.addr, align 4
+  %call = call swiftcc { i16, i8 } @gen(i32 %0)
+  %v3 = extractvalue { i16, i8 } %call, 0
+  %v1 = sext i16 %v3 to i32
+  %v5 = extractvalue { i16, i8 } %call, 1
+  %v2 = sext i8 %v5 to i32
+  %add = add nsw i32 %v1, %v2
+  %conv = trunc i32 %add to i16
+  ret i16 %conv
+}
+
+declare swiftcc { i16, i8 } @gen(i32)
+
+; We can't pass every return value in register, instead, pass everything in
+; memroy.
+; The caller provides space for the return value and passes the address in %r0.
+; The first input argument will be in %r1.
+; CHECK-LABEL: test2:
+; CHECK: mov r1, r0
+; CHECK: mov r0, sp
+; CHECK: bl {{.*}}gen2
+; CHECK-DAG: add
+; CHECK-DAG: ldr {{.*}}, [sp, #16]
+; CHECK-DAG: add
+; CHECK-DAG: add
+; CHECK-DAG: add
+; CHECK-O0-LABEL: test2:
+; CHECK-O0: str r0
+; CHECK-O0: mov r0, sp
+; CHECK-O0: bl {{.*}}gen2
+; CHECK-O0-DAG: ldr {{.*}}, [sp]
+; CHECK-O0-DAG: ldr {{.*}}, [sp, #4]
+; CHECK-O0-DAG: ldr {{.*}}, [sp, #8]
+; CHECK-O0-DAG: ldr {{.*}}, [sp, #12]
+; CHECK-O0-DAG: ldr {{.*}}, [sp, #16]
+; CHECK-O0-DAG: add
+; CHECK-O0-DAG: add
+; CHECK-O0-DAG: add
+; CHECK-O0-DAG: add
+define i32 @test2(i32 %key) #0 {
+entry:
+  %key.addr = alloca i32, align 4
+  store i32 %key, i32* %key.addr, align 4
+  %0 = load i32, i32* %key.addr, align 4
+  %call = call swiftcc { i32, i32, i32, i32, i32 } @gen2(i32 %0)
+
+  %v3 = extractvalue { i32, i32, i32, i32, i32 } %call, 0
+  %v5 = extractvalue { i32, i32, i32, i32, i32 } %call, 1
+  %v6 = extractvalue { i32, i32, i32, i32, i32 } %call, 2
+  %v7 = extractvalue { i32, i32, i32, i32, i32 } %call, 3
+  %v8 = extractvalue { i32, i32, i32, i32, i32 } %call, 4
+
+  %add = add nsw i32 %v3, %v5
+  %add1 = add nsw i32 %add, %v6
+  %add2 = add nsw i32 %add1, %v7
+  %add3 = add nsw i32 %add2, %v8
+  ret i32 %add3
+}
+
+; The address of the return value is passed in %r0.
+; CHECK-LABEL: gen2:
+; CHECK-DAG: str r1, [r0]
+; CHECK-DAG: str r1, [r0, #4]
+; CHECK-DAG: str r1, [r0, #8]
+; CHECK-DAG: str r1, [r0, #12]
+; CHECK-DAG: str r1, [r0, #16]
+; CHECK-O0-LABEL: gen2:
+; CHECK-O0-DAG: str r1, [r0]
+; CHECK-O0-DAG: str r1, [r0, #4]
+; CHECK-O0-DAG: str r1, [r0, #8]
+; CHECK-O0-DAG: str r1, [r0, #12]
+; CHECK-O0-DAG: str r1, [r0, #16]
+define swiftcc { i32, i32, i32, i32, i32 } @gen2(i32 %key) {
+  %Y = insertvalue { i32, i32, i32, i32, i32 } undef, i32 %key, 0
+  %Z = insertvalue { i32, i32, i32, i32, i32 } %Y, i32 %key, 1
+  %Z2 = insertvalue { i32, i32, i32, i32, i32 } %Z, i32 %key, 2
+  %Z3 = insertvalue { i32, i32, i32, i32, i32 } %Z2, i32 %key, 3
+  %Z4 = insertvalue { i32, i32, i32, i32, i32 } %Z3, i32 %key, 4
+  ret { i32, i32, i32, i32, i32 } %Z4
+}
+
+; The return value {i32, i32, i32, i32} will be returned via registers %r0, %r1,
+; %r2, %r3.
+; CHECK-LABEL: test3:
+; CHECK: bl {{.*}}gen3
+; CHECK: add r0, r0, r1
+; CHECK: add r0, r0, r2
+; CHECK: add r0, r0, r3
+; CHECK-O0-LABEL: test3:
+; CHECK-O0: bl {{.*}}gen3
+; CHECK-O0: add r0, r0, r1
+; CHECK-O0: add r0, r0, r2
+; CHECK-O0: add r0, r0, r3
+define i32 @test3(i32 %key) #0 {
+entry:
+  %key.addr = alloca i32, align 4
+  store i32 %key, i32* %key.addr, align 4
+  %0 = load i32, i32* %key.addr, align 4
+  %call = call swiftcc { i32, i32, i32, i32 } @gen3(i32 %0)
+
+  %v3 = extractvalue { i32, i32, i32, i32 } %call, 0
+  %v5 = extractvalue { i32, i32, i32, i32 } %call, 1
+  %v6 = extractvalue { i32, i32, i32, i32 } %call, 2
+  %v7 = extractvalue { i32, i32, i32, i32 } %call, 3
+
+  %add = add nsw i32 %v3, %v5
+  %add1 = add nsw i32 %add, %v6
+  %add2 = add nsw i32 %add1, %v7
+  ret i32 %add2
+}
+
+declare swiftcc { i32, i32, i32, i32 } @gen3(i32 %key)




More information about the llvm-commits mailing list