1; RUN: llc --mtriple=armv7-eabihf %s -o - | FileCheck %s --enable-var-scope 2 3%struct.S0 = type { [4 x float] } 4%struct.S1 = type { [2 x float] } 5%struct.S2 = type { [4 x float] } 6%struct.D0 = type { [2 x double] } 7%struct.D1 = type { [2 x double] } 8%struct.D2 = type { [4 x double] } 9 10; pass in regs 11declare dso_local float @f0_0(double, double, double, double, double, double, %struct.S0) local_unnamed_addr #0 12define dso_local float @f0_0_call() local_unnamed_addr #0 { 13entry: 14 %call = tail call float @f0_0(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, %struct.S0 { [4 x float] [float 0x3FE3333340000000, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00] }) #0 15 ret float %call 16} 17; CHECK-LABEL: f0_0_call: 18; CHECK: vldr s12, .L[[L:.*]] 19; CHECK: b f0_0 20; CHECK: .L[[L]]: 21; CHECK-NEXT: .long 0x3f19999a 22 23; pass in memory, no split 24declare dso_local float @f0_1(double, double, double, double, double, double, float, %struct.S0) local_unnamed_addr #0 25define dso_local float @f0_1_call() local_unnamed_addr #0 { 26entry: 27 %call = tail call float @f0_1(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, float 0x3FE3333340000000, %struct.S0 { [4 x float] [float 0x3FE6666660000000, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00] }) #0 28 ret float %call 29} 30; CHECK-LABEL: f0_1_call: 31; CHECK: movw r1, #13107 32; CHECK: mov r0, #0 33; CHECK: movt r1, #16179 34; CHECK-DAG: str r1, [sp] 35; CHECK-DAG: str r0, [sp, #4] 36; CHECK-DAG: str r0, [sp, #8] 37; CHECK-DAG: str r0, [sp, #12] 38; CHECK: bl f0_1 39 40; pass memory, alignment 4 41declare dso_local float @f0_2(double, double, double, double, double, double, double, double, float, %struct.S0) local_unnamed_addr #0 42define dso_local float @f0_2_call() local_unnamed_addr #0 { 43entry: 44 %call = tail call float @f0_2(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, double 0x3FE6666666666666, float 0x3FE99999A0000000, %struct.S0 { [4 x float] [float 0x3FECCCCCC0000000, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00] }) #0 45 ret float %call 46} 47; CHECK-LABEL: f0_2_call: 48; CHECK: movw r1, #26214 49; CHECK: movw r2, #52429 50; CHECK: mov r0, #0 51; CHECK: movt r1, #16230 52; CHECK: movt r2, #16204 53; CHECK-DAG: str r2, [sp] 54; CHECK-DAG: str r1, [sp, #4] 55; CHECK-DAG: str r0, [sp, #8] 56; CHECK-DAG: str r0, [sp, #12] 57; CHECK-DAG: str r0, [sp, #16] 58; CHECK: bl f0_2 59 60; pass in regs 61declare dso_local float @f1_0(double, double, double, double, double, double, double, %struct.S1 alignstack(8)) local_unnamed_addr #0 62define dso_local float @f1_0_call() local_unnamed_addr #0 { 63entry: 64 %call = tail call float @f1_0(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, %struct.S1 alignstack(8) { [2 x float] [float 0x3FE6666660000000, float 0.000000e+00] }) #0 65 ret float %call 66} 67; CHECK-LABEL: f1_0_call: 68; CHECK-DAG: vldr s14, .L[[L0:.*]] 69; CHECK-DAG: vldr s15, .L[[L1:.*]] 70; CHECK: b f1_0 71; CHECK: .L[[L0]]: 72; CHECK-NEXT: .long 0x3f333333 73; CHECK: .L[[L1:.*]]: 74; CHECK-NEXT: .long 0x00000000 75 76; pass in memory, no split 77declare dso_local float @f1_1(double, double, double, double, double, double, double, float, %struct.S1 alignstack(8)) local_unnamed_addr #0 78define dso_local float @f1_1_call() local_unnamed_addr #0 { 79entry: 80 %call = tail call float @f1_1(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, float 0x3FE6666660000000, %struct.S1 alignstack(8) { [2 x float] [float 0x3FE99999A0000000, float 0.000000e+00] }) #0 81 ret float %call 82} 83; CHECK-LABEL: f1_1_call: 84; CHECK: movw r1, #52429 85; CHECK: mov r0, #0 86; CHECK: movt r1, #16204 87; CHECK-DAG: str r1, [sp] 88; CHECK-DAG: str r0, [sp, #4] 89; CHECK: bl f1_1 90 91; pass in memory, alignment 8 92declare dso_local float @f1_2(double, double, double, double, double, double, double, double, float, %struct.S1 alignstack(8)) local_unnamed_addr #0 93define dso_local float @f1_2_call() local_unnamed_addr #0 { 94entry: 95 %call = tail call float @f1_2(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, double 0x3FE6666666666666, float 0x3FE99999A0000000, %struct.S1 alignstack(8) { [2 x float] [float 0x3FECCCCCC0000000, float 0.000000e+00] }) #0 96 ret float %call 97} 98; CHECK-LABEL: f1_2_call: 99; CHECK-DAG: mov r0, #0 100; CHECK-DAG: movw r1, #26214 101; CHECK: str r0, [sp, #12] 102; CHECK: movw r0, #52429 103; CHECK: movt r1, #16230 104; CHECK: movt r0, #16204 105; CHECK-DAG: str r1, [sp, #8] 106; CHECK-DAG: str r0, [sp] 107; CHECK: bl f1_2 108 109 110; pass in registers 111declare dso_local float @f2_0(double, double, double, double, double, double, %struct.S2 alignstack(8)) local_unnamed_addr #0 112define dso_local float @f2_0_call() local_unnamed_addr #0 { 113entry: 114 %call = tail call float @f2_0(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, %struct.S2 alignstack(8) { [4 x float] [float 0x3FE3333340000000, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00] }) #0 115 ret float %call 116} 117; CHECK-LABEL: f2_0_call: 118; CHECK-DAG: vldr s12, .L[[L0:.*]] 119; CHECK-DAG: vldr s13, .L[[L1:.*]] 120; CHECK-DAG: vmov.f32 s14, s13 121; CHECK-DAG: vmov.f32 s15, s13 122; CHECK: b f2_0 123; CHECK: .L[[L0]]: 124; CHECK-NEXT: .long 0x3f19999a 125; CHECK: .L[[L1]]: 126; CHECK-NEXT: .long 0x00000000 127 128; pass in memory, no split 129declare dso_local float @f2_1(double, double, double, double, double, double, float, %struct.S2 alignstack(8)) local_unnamed_addr #0 130define dso_local float @f2_1_call() local_unnamed_addr #0 { 131entry: 132 %call = tail call float @f2_1(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, float 0x3FE3333340000000, %struct.S2 alignstack(8) { [4 x float] [float 0x3FE6666660000000, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00] }) #0 133 ret float %call 134} 135; CHECK-LABEL: f2_1_call: 136; CHECK: movw r1, #13107 137; CHECK: mov r0, #0 138; CHECK: movt r1, #16179 139; CHECK: str r1, [sp] 140; CHECK: str r0, [sp, #4] 141; CHECK: vldr s12, .L[[L:.*]] 142; CHECK: str r0, [sp, #8] 143; CHECK: str r0, [sp, #12] 144; CHECK: bl f2_1 145; CHECK: .L[[L]]: 146; CHECK-NEXT: .long 0x3f19999a 147 148; pass in memory, alignment 8 149declare dso_local float @f2_2(double, double, double, double, double, double, double, double, float, %struct.S2 alignstack(8)) local_unnamed_addr #0 150define dso_local float @f2_2_call() local_unnamed_addr #0 { 151entry: 152 %call = tail call float @f2_2(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, double 0x3FE6666666666666, float 0x3FE99999A0000000, %struct.S2 alignstack(8) { [4 x float] [float 0x3FECCCCCC0000000, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00] }) #0 153 ret float %call 154} 155; CHECK-LABEL: f2_2_call: 156; CHECK: mov r0, #0 157; CHECK: movw r1, #26214 158; CHECK: str r0, [sp, #12] 159; CHECK: str r0, [sp, #16] 160; CHECK: movt r1, #16230 161; CHECK: str r0, [sp, #20] 162; CHECK: movw r0, #52429 163; CHECK: movt r0, #16204 164; CHECK: str r1, [sp, #8] 165; CHECK: str r0, [sp] 166; CHECK: bl f2_2 167 168; pass in registers 169declare dso_local double @g0_0(double, double, double, double, double, double, %struct.D0) local_unnamed_addr #0 170define dso_local double @g0_0_call() local_unnamed_addr #0 { 171entry: 172 %call = tail call double @g0_0(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, %struct.D0 { [2 x double] [double 6.000000e-01, double 0.000000e+00] }) #0 173 ret double %call 174} 175; CHECK-LABEL: g0_0_call: 176; CHECK: vldr d6, .L[[L:.*]] 177; CHECK: b g0_0 178; CHECK: .L[[L]] 179; CHECK-NEXT: long 858993459 180; CHECK-NEXT: long 1071854387 181 182; pass in memory, no split 183declare dso_local double @g0_1(double, double, double, double, double, double, double, %struct.D0) local_unnamed_addr #0 184define dso_local double @g0_1_call() local_unnamed_addr #0 { 185entry: 186 %call = tail call double @g0_1(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, %struct.D0 { [2 x double] [double 0x3FE6666666666666, double 0.000000e+00] }) #0 187 ret double %call 188} 189; CHECK-LABEL: g0_1_call: 190; CHECK: movw r0, #26214 191; CHECK: movw r1, #26214 192; CHECK: mov r2, #0 193; CHECK: movt r0, #16358 194; CHECK: movt r1, #26214 195; CHECK: str r1, [sp] 196; CHECK: stmib sp, {r0, r2} 197; CHECK: str r2, [sp, #12] 198; CHECK: bl g0_1 199 200; pass in memory, alignment 8 201declare dso_local double @g0_2(double, double, double, double, double, double, double, double, float, %struct.D0) local_unnamed_addr #0 202define dso_local double @g0_2_call() local_unnamed_addr #0 { 203entry: 204 %call = tail call double @g0_2(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, double 0x3FE6666666666666, float 0x3FE99999A0000000, %struct.D0 { [2 x double] [double 9.000000e-01, double 0.000000e+00] }) #0 205 ret double %call 206} 207; CHECK-LABEL: g0_2_call: 208; CHECK: movw r0, #52428 209; CHECK: movt r0, #16364 210; CHECK: movw r1, #52429 211; CHECK: str r0, [sp, #12] 212; CHECK: movw r0, #52429 213; CHECK: mov r2, #0 214; CHECK: movt r1, #52428 215; CHECK: movt r0, #16204 216; CHECK: str r1, [sp, #8] 217; CHECK: str r2, [sp, #16] 218; CHECK: str r2, [sp, #20] 219; CHECK: str r0, [sp] 220; CHECK: bl g0_2 221 222; pass in registers 223declare dso_local double @g1_0(double, double, double, double, double, double, %struct.D1 alignstack(8)) local_unnamed_addr #0 224define dso_local double @g1_0_call() local_unnamed_addr #0 { 225entry: 226 %call = tail call double @g1_0(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, %struct.D1 alignstack(8) { [2 x double] [double 6.000000e-01, double 0.000000e+00] }) #0 227 ret double %call 228} 229; CHECK-LABEL: g1_0_call: 230; CHECK-DAG: vmov.i32 d7, #0x0 231; CHECK-DAG: vldr d6, .L[[L:.*]] 232; CHECK: b g1_0 233; CHECK: .L[[L]]: 234; CHECK-NEXT: .long 858993459 235; CHECK-NEXT: .long 107185438 236 237; pass in memory, no split 238declare dso_local double @g1_1(double, double, double, double, double, double, double, %struct.D1 alignstack(8)) local_unnamed_addr #0 239define dso_local double @g1_1_call() local_unnamed_addr #0 { 240entry: 241 %call = tail call double @g1_1(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, %struct.D1 alignstack(8) { [2 x double] [double 0x3FE6666666666666, double 0.000000e+00] }) #0 242 ret double %call 243} 244; CHECK-LABEL: g1_1_call: 245; CHECK: movw r0, #26214 246; CHECK: movw r1, #26214 247; CHECK: mov r2, #0 248; CHECK: movt r0, #16358 249; CHECK: movt r1, #26214 250; CHECK: str r1, [sp] 251; CHECK: stmib sp, {r0, r2} 252; CHECK: str r2, [sp, #12] 253; CHECK: bl g1_1 254 255; pass in memory, alignment 8 256declare dso_local double @g1_2(double, double, double, double, double, double, double, double, float, %struct.D1 alignstack(8)) local_unnamed_addr #0 257define dso_local double @g1_2_call() local_unnamed_addr #0 { 258entry: 259 %call = tail call double @g1_2(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, double 0x3FE6666666666666, float 0x3FE99999A0000000, %struct.D1 alignstack(8) { [2 x double] [double 9.000000e-01, double 0.000000e+00] }) #0 260 ret double %call 261} 262; CHECK-LABEL: g1_2_call: 263; CHECK: movw r0, #52428 264; CHECK: movt r0, #16364 265; CHECK: movw r1, #52429 266; CHECK: str r0, [sp, #12] 267; CHECK: movw r0, #52429 268; CHECK: mov r2, #0 269; CHECK: movt r1, #52428 270; CHECK: movt r0, #16204 271; CHECK: str r1, [sp, #8] 272; CHECK: str r2, [sp, #16] 273; CHECK: str r2, [sp, #20] 274; CHECK: str r0, [sp] 275; CHECK: bl g1_2 276 277; pass in registers 278declare dso_local double @g2_0(double, double, double, double, %struct.D2 alignstack(8)) local_unnamed_addr #0 279define dso_local double @g2_0_call() local_unnamed_addr #0 { 280entry: 281 %call = tail call double @g2_0(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, %struct.D2 alignstack(8) { [4 x double] [double 4.000000e-01, double 0.000000e+00, double 0.000000e+00, double 0.000000e+00] }) #0 282 ret double %call 283} 284; CHECK-LABEL: g2_0_call: 285; CHECK-DAG: vldr d4, .L[[L:.*]] 286; CHECK-DAG: vmov.i32 d5, #0x0 287; CHECK-DAG: vmov.i32 d6, #0x0 288; CHECK-DAG: vmov.i32 d7, #0x0 289; CHECK: b g2_0 290; CHECK: .L[[L]]: 291; CHECK-NEXT: .long 2576980378 292; CHECK-NEXT: .long 1071225241 293 294; pass in memory, no split 295; [sp] [sp + 4] = 0x00000000 0x3fe00000 = .5 296; [sp + 8] [sp + 12] = 0 0 = .0 297; ... 298declare dso_local double @g2_1(double, double, double, double, double, %struct.D2 alignstack(8)) local_unnamed_addr #0 299define dso_local double @g2_1_call() local_unnamed_addr #0 { 300entry: 301 %call = tail call double @g2_1(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, %struct.D2 alignstack(8) { [4 x double] [double 5.000000e-01, double 0.000000e+00, double 0.000000e+00, double 0.000000e+00] }) #0 302 ret double %call 303} 304; CHECK-LABEL: g2_1_call: 305; CHECK: movw r0, #0 306; CHECK: mov r1, #0 307; CHECK: movt r0, #16352 308; CHECK: str r1, [sp] 309; CHECK: stmib sp, {r0, r1} 310; CHECK: str r1, [sp, #12] 311; CHECK: str r1, [sp, #16] 312; CHECK: str r1, [sp, #20] 313; CHECK: str r1, [sp, #24] 314; CHECK: str r1, [sp, #28] 315; CHECK: bl g2_1 316 317; pass in memory, alignment 8 318declare dso_local double @g2_2(double, double, double, double, double, double, double, double, float, %struct.D2 alignstack(8)) local_unnamed_addr #0 319define dso_local double @g2_2call() local_unnamed_addr #0 { 320entry: 321 %call = tail call double @g2_2(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, double 0x3FE6666666666666, float 0x3FE99999A0000000, %struct.D2 alignstack(8) { [4 x double] [double 9.000000e-01, double 0.000000e+00, double 0.000000e+00, double 0.000000e+00] }) #0 322 ret double %call 323} 324; CHECK-LABEL: g2_2call: 325; CHECK: movw r0, #52428 326; CHECK: movt r0, #16364 327; CHECK: movw r1, #52429 328; CHECK: str r0, [sp, #12] 329; CHECK: movw r0, #52429 330; CHECK: mov r2, #0 331; CHECK: movt r1, #52428 332; CHECK: movt r0, #16204 333; CHECK: str r1, [sp, #8] 334; CHECK: str r2, [sp, #16] 335; CHECK: str r2, [sp, #20] 336; CHECK: str r2, [sp, #24] 337; CHECK: str r2, [sp, #28] 338; CHECK: str r2, [sp, #32] 339; CHECK: str r2, [sp, #36] 340; CHECK: str r0, [sp] 341; CHECK: bl g2_2 342 343attributes #0 = { nounwind "target-cpu"="generic" "target-features"="+armv7-a,+d32,+dsp,+fp64,+neon,+strict-align,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,-thumb-mode" } 344