Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc < %s -march=arm64 | FileCheck %s
      2 
      3 %struct.A = type { i8 }
      4 %struct.B = type { i32 }
      5 %struct.C = type { %struct.B }
      6 %struct.D = type { %struct.B }
      7 %struct.E = type { %struct.B, %struct.B }
      8 
      9 declare %struct.A* @A_ctor_base(%struct.A* returned)
     10 declare %struct.B* @B_ctor_base(%struct.B* returned, i32)
     11 declare %struct.B* @B_ctor_complete(%struct.B* returned, i32)
     12 
     13 declare %struct.A* @A_ctor_base_nothisret(%struct.A*)
     14 declare %struct.B* @B_ctor_base_nothisret(%struct.B*, i32)
     15 declare %struct.B* @B_ctor_complete_nothisret(%struct.B*, i32)
     16 
     17 define %struct.C* @C_ctor_base(%struct.C* returned %this, i32 %x) {
     18 entry:
     19 ; CHECK-LABEL: C_ctor_base:
     20 ; CHECK-NOT: mov {{x[0-9]+}}, x0
     21 ; CHECK: bl {{_?A_ctor_base}}
     22 ; CHECK-NOT: mov x0, {{x[0-9]+}}
     23 ; CHECK: b {{_?B_ctor_base}}
     24   %0 = bitcast %struct.C* %this to %struct.A*
     25   %call = tail call %struct.A* @A_ctor_base(%struct.A* %0)
     26   %1 = getelementptr inbounds %struct.C, %struct.C* %this, i32 0, i32 0
     27   %call2 = tail call %struct.B* @B_ctor_base(%struct.B* %1, i32 %x)
     28   ret %struct.C* %this
     29 }
     30 
     31 define %struct.C* @C_ctor_base_nothisret(%struct.C* %this, i32 %x) {
     32 entry:
     33 ; CHECK-LABEL: C_ctor_base_nothisret:
     34 ; CHECK: mov [[SAVETHIS:x[0-9]+]], x0
     35 ; CHECK: bl {{_?A_ctor_base_nothisret}}
     36 ; CHECK: mov x0, [[SAVETHIS]]
     37 ; CHECK-NOT: b {{_?B_ctor_base_nothisret}}
     38   %0 = bitcast %struct.C* %this to %struct.A*
     39   %call = tail call %struct.A* @A_ctor_base_nothisret(%struct.A* %0)
     40   %1 = getelementptr inbounds %struct.C, %struct.C* %this, i32 0, i32 0
     41   %call2 = tail call %struct.B* @B_ctor_base_nothisret(%struct.B* %1, i32 %x)
     42   ret %struct.C* %this
     43 }
     44 
     45 define %struct.C* @C_ctor_complete(%struct.C* %this, i32 %x) {
     46 entry:
     47 ; CHECK-LABEL: C_ctor_complete:
     48 ; CHECK: b {{_?C_ctor_base}}
     49   %call = tail call %struct.C* @C_ctor_base(%struct.C* %this, i32 %x)
     50   ret %struct.C* %this
     51 }
     52 
     53 define %struct.C* @C_ctor_complete_nothisret(%struct.C* %this, i32 %x) {
     54 entry:
     55 ; CHECK-LABEL: C_ctor_complete_nothisret:
     56 ; CHECK-NOT: b {{_?C_ctor_base_nothisret}}
     57   %call = tail call %struct.C* @C_ctor_base_nothisret(%struct.C* %this, i32 %x)
     58   ret %struct.C* %this
     59 }
     60 
     61 define %struct.D* @D_ctor_base(%struct.D* %this, i32 %x) {
     62 entry:
     63 ; CHECK-LABEL: D_ctor_base:
     64 ; CHECK-NOT: mov {{x[0-9]+}}, x0
     65 ; CHECK: bl {{_?B_ctor_complete}}
     66 ; CHECK-NOT: mov x0, {{x[0-9]+}}
     67 ; CHECK: b {{_?B_ctor_complete}}
     68   %b = getelementptr inbounds %struct.D, %struct.D* %this, i32 0, i32 0
     69   %call = tail call %struct.B* @B_ctor_complete(%struct.B* %b, i32 %x)
     70   %call2 = tail call %struct.B* @B_ctor_complete(%struct.B* %b, i32 %x)
     71   ret %struct.D* %this
     72 }
     73 
     74 define %struct.E* @E_ctor_base(%struct.E* %this, i32 %x) {
     75 entry:
     76 ; CHECK-LABEL: E_ctor_base:
     77 ; CHECK-NOT: b {{_?B_ctor_complete}}
     78   %b = getelementptr inbounds %struct.E, %struct.E* %this, i32 0, i32 0
     79   %call = tail call %struct.B* @B_ctor_complete(%struct.B* %b, i32 %x)
     80   %b2 = getelementptr inbounds %struct.E, %struct.E* %this, i32 0, i32 1
     81   %call2 = tail call %struct.B* @B_ctor_complete(%struct.B* %b2, i32 %x)
     82   ret %struct.E* %this
     83 }
     84