1; RUN: llc < %s -mtriple=armv6-linux-gnueabi | FileCheck %s -check-prefix=CHECKELF 2; RUN: llc < %s -mtriple=thumbv7-apple-ios5.0 | FileCheck %s -check-prefix=CHECKT2D 3 4%struct.A = type { i8 } 5%struct.B = type { i32 } 6%struct.C = type { %struct.B } 7%struct.D = type { %struct.B } 8%struct.E = type { %struct.B, %struct.B } 9 10declare %struct.A* @A_ctor_base(%struct.A* returned) 11declare %struct.B* @B_ctor_base(%struct.B* returned, i32) 12declare %struct.B* @B_ctor_complete(%struct.B* returned, i32) 13 14declare %struct.A* @A_ctor_base_nothisret(%struct.A*) 15declare %struct.B* @B_ctor_base_nothisret(%struct.B*, i32) 16declare %struct.B* @B_ctor_complete_nothisret(%struct.B*, i32) 17 18define %struct.C* @C_ctor_base(%struct.C* returned %this, i32 %x) { 19entry: 20; CHECKELF-LABEL: C_ctor_base: 21; CHECKELF-NOT: mov {{r[0-9]+}}, r0 22; CHECKELF: bl A_ctor_base 23; CHECKELF-NOT: mov r0, {{r[0-9]+}} 24; CHECKELF: b B_ctor_base 25; CHECKT2D-LABEL: C_ctor_base: 26; CHECKT2D-NOT: mov {{r[0-9]+}}, r0 27; CHECKT2D: bl _A_ctor_base 28; CHECKT2D-NOT: mov r0, {{r[0-9]+}} 29; CHECKT2D: b.w _B_ctor_base 30 %0 = bitcast %struct.C* %this to %struct.A* 31 %call = tail call %struct.A* @A_ctor_base(%struct.A* %0) 32 %1 = getelementptr inbounds %struct.C, %struct.C* %this, i32 0, i32 0 33 %call2 = tail call %struct.B* @B_ctor_base(%struct.B* %1, i32 %x) 34 ret %struct.C* %this 35} 36 37define %struct.C* @C_ctor_base_nothisret(%struct.C* %this, i32 %x) { 38entry: 39; CHECKELF-LABEL: C_ctor_base_nothisret: 40; CHECKELF: mov [[SAVETHIS:r[0-9]+]], r0 41; CHECKELF: bl A_ctor_base_nothisret 42; CHECKELF: mov r0, [[SAVETHIS]] 43; CHECKELF-NOT: b B_ctor_base_nothisret 44; CHECKT2D-LABEL: C_ctor_base_nothisret: 45; CHECKT2D: mov [[SAVETHIS:r[0-9]+]], r0 46; CHECKT2D: bl _A_ctor_base_nothisret 47; CHECKT2D: mov r0, [[SAVETHIS]] 48; CHECKT2D-NOT: b.w _B_ctor_base_nothisret 49 %0 = bitcast %struct.C* %this to %struct.A* 50 %call = tail call %struct.A* @A_ctor_base_nothisret(%struct.A* %0) 51 %1 = getelementptr inbounds %struct.C, %struct.C* %this, i32 0, i32 0 52 %call2 = tail call %struct.B* @B_ctor_base_nothisret(%struct.B* %1, i32 %x) 53 ret %struct.C* %this 54} 55 56define %struct.C* @C_ctor_complete(%struct.C* %this, i32 %x) { 57entry: 58; CHECKELF-LABEL: C_ctor_complete: 59; CHECKELF: b C_ctor_base 60; CHECKT2D-LABEL: C_ctor_complete: 61; CHECKT2D: b.w _C_ctor_base 62 %call = tail call %struct.C* @C_ctor_base(%struct.C* %this, i32 %x) 63 ret %struct.C* %this 64} 65 66define %struct.C* @C_ctor_complete_nothisret(%struct.C* %this, i32 %x) { 67entry: 68; CHECKELF-LABEL: C_ctor_complete_nothisret: 69; CHECKELF-NOT: b C_ctor_base_nothisret 70; CHECKT2D-LABEL: C_ctor_complete_nothisret: 71; CHECKT2D-NOT: b.w _C_ctor_base_nothisret 72 %call = tail call %struct.C* @C_ctor_base_nothisret(%struct.C* %this, i32 %x) 73 ret %struct.C* %this 74} 75 76define %struct.D* @D_ctor_base(%struct.D* %this, i32 %x) { 77entry: 78; CHECKELF-LABEL: D_ctor_base: 79; CHECKELF-NOT: mov {{r[0-9]+}}, r0 80; CHECKELF: bl B_ctor_complete 81; CHECKELF-NOT: mov r0, {{r[0-9]+}} 82; CHECKELF: b B_ctor_complete 83; CHECKT2D-LABEL: D_ctor_base: 84; CHECKT2D-NOT: mov {{r[0-9]+}}, r0 85; CHECKT2D: bl _B_ctor_complete 86; CHECKT2D-NOT: mov r0, {{r[0-9]+}} 87; CHECKT2D: b.w _B_ctor_complete 88 %b = getelementptr inbounds %struct.D, %struct.D* %this, i32 0, i32 0 89 %call = tail call %struct.B* @B_ctor_complete(%struct.B* %b, i32 %x) 90 %call2 = tail call %struct.B* @B_ctor_complete(%struct.B* %b, i32 %x) 91 ret %struct.D* %this 92} 93 94define %struct.E* @E_ctor_base(%struct.E* %this, i32 %x) { 95entry: 96; CHECKELF-LABEL: E_ctor_base: 97; CHECKELF-NOT: b B_ctor_complete 98; CHECKT2D-LABEL: E_ctor_base: 99; CHECKT2D-NOT: b.w _B_ctor_complete 100 %b = getelementptr inbounds %struct.E, %struct.E* %this, i32 0, i32 0 101 %call = tail call %struct.B* @B_ctor_complete(%struct.B* %b, i32 %x) 102 %b2 = getelementptr inbounds %struct.E, %struct.E* %this, i32 0, i32 1 103 %call2 = tail call %struct.B* @B_ctor_complete(%struct.B* %b2, i32 %x) 104 ret %struct.E* %this 105} 106