1; RUN: llc -mtriple armv7-arm-linux-gnueabihf -O2 -mcpu=cortex-a7 < %s | FileCheck %s 2; RUN: llc -mtriple armv7-arm-linux-gnueabihf -O2 -mcpu=cortex-a7 -early-live-intervals < %s | FileCheck %s 3 4%struct.twofloat = type { float, float } 5%struct.twodouble = type { double, double } 6 7; Check support for returning a float in GPR with soft float ABI 8define arm_aapcscc float @zerobits_float_soft() #0 { 9; CHECK-LABEL: zerobits_float_soft 10; CHECK: mov r0, #0 11 %1 = tail call float asm "mov ${0}, #0", "=&r"() 12 ret float %1 13} 14 15; Check support for returning a double in GPR with soft float ABI 16define arm_aapcscc double @zerobits_double_soft() #0 { 17; CHECK-LABEL: zerobits_double_soft 18; CHECK: mov r0, #0 19; CHECK-NEXT: mov r1, #0 20 %1 = tail call double asm "mov ${0:Q}, #0\0Amov ${0:R}, #0", "=&r"() 21 ret double %1 22} 23 24; Check support for returning a float in GPR with matching float input with 25; soft float ABI 26define arm_aapcscc float @flt_gpr_matching_in_op_soft(float %f) #0 { 27; CHECK-LABEL: flt_gpr_matching_in_op_soft 28; CHECK: mov r0, r0 29 %1 = call float asm "mov $0, $1", "=&r,0"(float %f) 30 ret float %1 31} 32 33; Check support for returning a double in GPR with matching double input with 34; soft float ABI 35define arm_aapcscc double @dbl_gpr_matching_in_op_soft(double %d) #0 { 36; CHECK-LABEL: dbl_gpr_matching_in_op_soft 37; CHECK: mov r1, r0 38 %1 = call double asm "mov ${0:R}, ${1:Q}", "=&r,0"(double %d) 39 ret double %1 40} 41 42; Check support for returning a float in specific GPR with matching float input 43; with soft float ABI 44define arm_aapcscc float @flt_gpr_matching_spec_reg_in_op_soft(float %f) #0 { 45; CHECK-LABEL: flt_gpr_matching_spec_reg_in_op_soft 46; CHECK: mov r3, r3 47 %1 = call float asm "mov $0, $1", "=&{r3},0"(float %f) 48 ret float %1 49} 50 51; Check support for returning a double in specific GPR with matching double 52; input with soft float ABI 53define arm_aapcscc double @dbl_gpr_matching_spec_reg_in_op_soft(double %d) #0 { 54; CHECK-LABEL: dbl_gpr_matching_spec_reg_in_op_soft 55; CHECK: mov r3, r2 56 %1 = call double asm "mov ${0:R}, ${1:Q}", "=&{r2},0"(double %d) 57 ret double %1 58} 59 60; Check support for returning several float in GPR 61define arm_aapcscc float @zerobits_float_convoluted_soft() #0 { 62; CHECK-LABEL: zerobits_float_convoluted_soft 63; CHECK: mov r0, #0 64; CHECK-NEXT: mov r1, #0 65 %1 = call { float, float } asm "mov $0, #0; mov $1, #0", "=r,=r"() 66 %asmresult = extractvalue { float, float } %1, 0 67 %asmresult1 = extractvalue { float, float } %1, 1 68 %add = fadd float %asmresult, %asmresult1 69 ret float %add 70} 71 72; Check support for returning several double in GPR 73define double @zerobits_double_convoluted_soft() #0 { 74; CHECK-LABEL: zerobits_double_convoluted_soft 75; CHECK: mov r0, #0 76; CHECK-NEXT: mov r1, #0 77; CHECK-NEXT: mov r2, #0 78; CHECK-NEXT: mov r3, #0 79 %1 = call { double, double } asm "mov ${0:Q}, #0; mov ${0:R}, #0; mov ${1:Q}, #0; mov ${1:R}, #0", "=r,=r"() 80 %asmresult = extractvalue { double, double } %1, 0 81 %asmresult1 = extractvalue { double, double } %1, 1 82 %add = fadd double %asmresult, %asmresult1 83 ret double %add 84} 85 86; Check support for returning several floats in GPRs with matching float inputs 87; with soft float ABI 88define arm_aapcscc float @flt_gprs_matching_in_op_soft(float %f1, float %f2) #0 { 89; CHECK-LABEL: flt_gprs_matching_in_op_soft 90; CHECK: mov r0, r0 91; CHECK-NEXT: mov r1, r1 92 %1 = call { float, float } asm "mov $0, $2; mov $1, $3", "=&r,=&r,0,1"(float %f1, float %f2) 93 %asmresult1 = extractvalue { float, float } %1, 0 94 %asmresult2 = extractvalue { float, float } %1, 1 95 %add = fadd float %asmresult1, %asmresult2 96 ret float %add 97} 98 99; Check support for returning several double in GPRs with matching double input 100; with soft float ABI 101define arm_aapcscc double @dbl_gprs_matching_in_op_soft(double %d1, double %d2) #0 { 102; CHECK-LABEL: dbl_gprs_matching_in_op_soft 103; CHECK: mov r1, r0 104; CHECK-NEXT: mov r3, r2 105 %1 = call { double, double } asm "mov ${0:R}, ${2:Q}; mov ${1:R}, ${3:Q}", "=&r,=&r,0,1"(double %d1, double %d2) 106 %asmresult1 = extractvalue { double, double } %1, 0 107 %asmresult2 = extractvalue { double, double } %1, 1 108 %add = fadd double %asmresult1, %asmresult2 109 ret double %add 110} 111 112; Check support for returning several float in specific GPRs with matching 113; float input with soft float ABI 114define arm_aapcscc float @flt_gprs_matching_spec_reg_in_op_soft(float %f1, float %f2) #0 { 115; CHECK-LABEL: flt_gprs_matching_spec_reg_in_op_soft 116; CHECK: mov r3, r3 117; CHECK-NEXT: mov r4, r4 118 %1 = call { float, float } asm "mov $0, $2; mov $1, $3", "=&{r3},=&{r4},0,1"(float %f1, float %f2) 119 %asmresult1 = extractvalue { float, float } %1, 0 120 %asmresult2 = extractvalue { float, float } %1, 1 121 %add = fadd float %asmresult1, %asmresult2 122 ret float %add 123} 124 125; Check support for returning several double in specific GPRs with matching 126; double input with soft float ABI 127define arm_aapcscc double @dbl_gprs_matching_spec_reg_in_op_soft(double %d1, double %d2) #0 { 128; CHECK-LABEL: dbl_gprs_matching_spec_reg_in_op_soft 129; CHECK: mov r3, r2 130; CHECK-NEXT: mov r5, r4 131 %1 = call { double, double } asm "mov ${0:R}, ${2:Q}; mov ${1:R}, ${3:Q}", "=&{r2},=&{r4},0,1"(double %d1, double %d2) 132 %asmresult1 = extractvalue { double, double } %1, 0 133 %asmresult2 = extractvalue { double, double } %1, 1 134 %add = fadd double %asmresult1, %asmresult2 135 ret double %add 136} 137 138attributes #0 = { nounwind "target-features"="-d32,+vfp2,+vfp3" "use-soft-float"="true" } 139 140 141; Check support for returning a float in GPR with hard float ABI 142define float @zerobits_float_hard() #1 { 143; CHECK-LABEL: zerobits_float_hard 144; CHECK: mov r0, #0 145; CHECK: vmov s0, r0 146 %1 = tail call float asm "mov ${0}, #0", "=&r"() 147 ret float %1 148} 149 150; Check support for returning a double in GPR with hard float ABI 151define double @zerobits_double_hard() #1 { 152; CHECK-LABEL: zerobits_double_hard 153; CHECK: mov r0, #0 154; CHECK-NEXT: mov r1, #0 155; CHECK: vmov d0, r0, r1 156 %1 = tail call double asm "mov ${0:Q}, #0\0Amov ${0:R}, #0", "=&r"() 157 ret double %1 158} 159 160; Check support for returning a float in GPR with matching float input with 161; hard float ABI 162define float @flt_gpr_matching_in_op_hard(float %f) #1 { 163; CHECK-LABEL: flt_gpr_matching_in_op_hard 164; CHECK: vmov r0, s0 165; CHECK: mov r0, r0 166; CHECK: vmov s0, r0 167 %1 = call float asm "mov $0, $1", "=&r,0"(float %f) 168 ret float %1 169} 170 171; Check support for returning a double in GPR with matching double input with 172; hard float ABI 173define double @dbl_gpr_matching_in_op_hard(double %d) #1 { 174; CHECK-LABEL: dbl_gpr_matching_in_op_hard 175; CHECK: vmov r0, r1, d0 176; CHECK: mov r1, r0 177; CHECK: vmov d0, r0, r1 178 %1 = call double asm "mov ${0:R}, ${1:Q}", "=&r,0"(double %d) 179 ret double %1 180} 181 182; Check support for returning a float in specific GPR with matching float 183; input with hard float ABI 184define float @flt_gpr_matching_spec_reg_in_op_hard(float %f) #1 { 185; CHECK-LABEL: flt_gpr_matching_spec_reg_in_op_hard 186; CHECK: vmov r3, s0 187; CHECK: mov r3, r3 188; CHECK: vmov s0, r3 189 %1 = call float asm "mov $0, $1", "=&{r3},0"(float %f) 190 ret float %1 191} 192 193; Check support for returning a double in specific GPR with matching double 194; input with hard float ABI 195define double @dbl_gpr_matching_spec_reg_in_op_hard(double %d) #1 { 196; CHECK-LABEL: dbl_gpr_matching_spec_reg_in_op_hard 197; CHECK: vmov r2, r3, d0 198; CHECK: mov r3, r2 199; CHECK: vmov d0, r2, r3 200 %1 = call double asm "mov ${0:R}, ${1:Q}", "=&{r2},0"(double %d) 201 ret double %1 202} 203 204; Check support for returning several float in GPR 205define %struct.twofloat @zerobits_float_convoluted_hard() #1 { 206; CHECK-LABEL: zerobits_float_convoluted_hard 207; CHECK: mov r0, #0 208; CHECK-NEXT: mov r1, #0 209; CHECK: vmov s0, r0 210; CHECK-NEXT: vmov s1, r1 211 %1 = call { float, float } asm "mov $0, #0; mov $1, #0", "=r,=r"() 212 %asmresult1 = extractvalue { float, float } %1, 0 213 %asmresult2 = extractvalue { float, float } %1, 1 214 %partialres = insertvalue %struct.twofloat undef, float %asmresult1, 0 215 %res = insertvalue %struct.twofloat %partialres, float %asmresult2, 1 216 ret %struct.twofloat %res 217} 218 219; Check support for returning several double in GPR 220define %struct.twodouble @zerobits_double_convoluted_hard() #1 { 221; CHECK-LABEL: zerobits_double_convoluted_hard 222; CHECK: mov r0, #0 223; CHECK-NEXT: mov r1, #0 224; CHECK-NEXT: mov r2, #0 225; CHECK-NEXT: mov r3, #0 226; CHECK: vmov d0, r0, r1 227; CHECK-NEXT: vmov d1, r2, r3 228 %1 = call { double, double } asm "mov ${0:Q}, #0; mov ${0:R}, #0; mov ${1:Q}, #0; mov ${1:R}, #0", "=r,=r"() 229 %asmresult1 = extractvalue { double, double } %1, 0 230 %asmresult2 = extractvalue { double, double } %1, 1 231 %partialres = insertvalue %struct.twodouble undef, double %asmresult1, 0 232 %res = insertvalue %struct.twodouble %partialres, double %asmresult2, 1 233 ret %struct.twodouble %res 234} 235 236; Check support for returning several floats in GPRs with matching float inputs 237; with hard float ABI 238define %struct.twofloat @flt_gprs_matching_in_op_hard(float %f1, float %f2) #1 { 239; CHECK-LABEL: flt_gprs_matching_in_op_hard 240; CHECK: vmov r0, s0 241; CHECK-NEXT: vmov r1, s1 242; CHECK: mov r0, r0 243; CHECK-NEXT: mov r1, r1 244; CHECK: vmov s0, r0 245; CHECK-NEXT: vmov s1, r1 246 %1 = call { float, float } asm "mov $0, $2; mov $1, $3", "=&r,=&r,0,1"(float %f1, float %f2) 247 %asmresult1 = extractvalue { float, float } %1, 0 248 %asmresult2 = extractvalue { float, float } %1, 1 249 %partialres = insertvalue %struct.twofloat undef, float %asmresult1, 0 250 %res = insertvalue %struct.twofloat %partialres, float %asmresult2, 1 251 ret %struct.twofloat %res 252} 253 254; Check support for returning several double in GPRs with matching double input 255; with hard float ABI 256define %struct.twodouble @dbl_gprs_matching_in_op_hard(double %d1, double %d2) #1 { 257; CHECK-LABEL: dbl_gprs_matching_in_op_hard 258; CHECK: vmov r0, r1, d0 259; CHECK-NEXT: vmov r2, r3, d1 260; CHECK: mov r1, r0 261; CHECK-NEXT: mov r3, r2 262; CHECK: vmov d0, r0, r1 263; CHECK-NEXT: vmov d1, r2, r3 264 %1 = call { double, double } asm "mov ${0:R}, ${2:Q}; mov ${1:R}, ${3:Q}", "=&r,=&r,0,1"(double %d1, double %d2) 265 %asmresult1 = extractvalue { double, double } %1, 0 266 %asmresult2 = extractvalue { double, double } %1, 1 267 %partialres = insertvalue %struct.twodouble undef, double %asmresult1, 0 268 %res = insertvalue %struct.twodouble %partialres, double %asmresult2, 1 269 ret %struct.twodouble %res 270} 271 272; Check support for returning several float in specific GPRs with matching 273; float input with hard float ABI 274define %struct.twofloat @flt_gprs_matching_spec_reg_in_op_hard(float %f1, float %f2) #1 { 275; CHECK-LABEL: flt_gprs_matching_spec_reg_in_op_hard 276; CHECK: vmov r3, s0 277; CHECK-NEXT: vmov r4, s1 278; CHECK: mov r3, r3 279; CHECK-NEXT: mov r4, r4 280; CHECK: vmov s0, r3 281; CHECK-NEXT: vmov s1, r4 282 %1 = call { float, float } asm "mov $0, $2; mov $1, $3", "=&{r3},=&{r4},0,1"(float %f1, float %f2) 283 %asmresult1 = extractvalue { float, float } %1, 0 284 %asmresult2 = extractvalue { float, float } %1, 1 285 %partialres = insertvalue %struct.twofloat undef, float %asmresult1, 0 286 %res = insertvalue %struct.twofloat %partialres, float %asmresult2, 1 287 ret %struct.twofloat %res 288} 289 290; Check support for returning several double in specific GPRs with matching 291; double input with hard float ABI 292define %struct.twodouble @dbl_gprs_matching_spec_reg_in_op_hard(double %d1, double %d2) #1 { 293; CHECK-LABEL: dbl_gprs_matching_spec_reg_in_op_hard 294; CHECK: vmov r2, r3, d0 295; CHECK-NEXT: vmov r4, r5, d1 296; CHECK: mov r3, r2 297; CHECK-NEXT: mov r5, r4 298; CHECK: vmov d0, r2, r3 299; CHECK-NEXT: vmov d1, r4, r5 300 %1 = call { double, double } asm "mov ${0:R}, ${2:Q}; mov ${1:R}, ${3:Q}", "=&{r2},=&{r4},0,1"(double %d1, double %d2) 301 %asmresult1 = extractvalue { double, double } %1, 0 302 %asmresult2 = extractvalue { double, double } %1, 1 303 %partialres = insertvalue %struct.twodouble undef, double %asmresult1, 0 304 %res = insertvalue %struct.twodouble %partialres, double %asmresult2, 1 305 ret %struct.twodouble %res 306} 307 308attributes #1 = { nounwind "target-features"="-d32,+vfp2,+vfp3" "use-soft-float"="false" } 309