1; RUN: llc -mtriple=arm64ec-pc-windows-msvc < %s | FileCheck %s 2 3define void @no_op() nounwind { 4; CHECK-LABEL .def $ientry_thunk$cdecl$v$v; 5; CHECK: .section .wowthk$aa,"xr",discard,$ientry_thunk$cdecl$v$v 6; CHECK: // %bb.0: 7; CHECK-NEXT: stp q6, q7, [sp, #-176]! // 32-byte Folded Spill 8; CHECK-NEXT: .seh_save_any_reg_px q6, 176 9; CHECK-NEXT: stp q8, q9, [sp, #32] // 32-byte Folded Spill 10; CHECK-NEXT: .seh_save_any_reg_p q8, 32 11; CHECK-NEXT: stp q10, q11, [sp, #64] // 32-byte Folded Spill 12; CHECK-NEXT: .seh_save_any_reg_p q10, 64 13; CHECK-NEXT: stp q12, q13, [sp, #96] // 32-byte Folded Spill 14; CHECK-NEXT: .seh_save_any_reg_p q12, 96 15; CHECK-NEXT: stp q14, q15, [sp, #128] // 32-byte Folded Spill 16; CHECK-NEXT: .seh_save_any_reg_p q14, 128 17; CHECK-NEXT: stp x29, x30, [sp, #160] // 16-byte Folded Spill 18; CHECK-NEXT: .seh_save_fplr 160 19; CHECK-NEXT: add x29, sp, #160 20; CHECK-NEXT: .seh_add_fp 160 21; CHECK-NEXT: .seh_endprologue 22; CHECK-NEXT: blr x9 23; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_ret 24; CHECK-NEXT: ldr x0, [x8, :lo12:__os_arm64x_dispatch_ret] 25; CHECK-NEXT: .seh_startepilogue 26; CHECK-NEXT: ldp x29, x30, [sp, #160] // 16-byte Folded Reload 27; CHECK-NEXT: .seh_save_fplr 160 28; CHECK-NEXT: ldp q14, q15, [sp, #128] // 32-byte Folded Reload 29; CHECK-NEXT: .seh_save_any_reg_p q14, 128 30; CHECK-NEXT: ldp q12, q13, [sp, #96] // 32-byte Folded Reload 31; CHECK-NEXT: .seh_save_any_reg_p q12, 96 32; CHECK-NEXT: ldp q10, q11, [sp, #64] // 32-byte Folded Reload 33; CHECK-NEXT: .seh_save_any_reg_p q10, 64 34; CHECK-NEXT: ldp q8, q9, [sp, #32] // 32-byte Folded Reload 35; CHECK-NEXT: .seh_save_any_reg_p q8, 32 36; CHECK-NEXT: ldp q6, q7, [sp], #176 // 32-byte Folded Reload 37; CHECK-NEXT: .seh_save_any_reg_px q6, 176 38; CHECK-NEXT: .seh_endepilogue 39; CHECK-NEXT: br x0 40; CHECK-NEXT: .seh_endfunclet 41; CHECK-NEXT: .seh_endproc 42 ret void 43} 44 45define i64 @simple_integers(i8, i16, i32, i64) nounwind { 46; CHECK-LABEL: .def $ientry_thunk$cdecl$i8$i8i8i8i8; 47; CHECK: .section .wowthk$aa,"xr",discard,$ientry_thunk$cdecl$i8$i8i8i8i8 48; CHECK: // %bb.0: 49; CHECK-NEXT: stp q6, q7, [sp, #-176]! // 32-byte Folded Spill 50; CHECK-NEXT: .seh_save_any_reg_px q6, 176 51; CHECK-NEXT: stp q8, q9, [sp, #32] // 32-byte Folded Spill 52; CHECK-NEXT: .seh_save_any_reg_p q8, 32 53; CHECK-NEXT: stp q10, q11, [sp, #64] // 32-byte Folded Spill 54; CHECK-NEXT: .seh_save_any_reg_p q10, 64 55; CHECK-NEXT: stp q12, q13, [sp, #96] // 32-byte Folded Spill 56; CHECK-NEXT: .seh_save_any_reg_p q12, 96 57; CHECK-NEXT: stp q14, q15, [sp, #128] // 32-byte Folded Spill 58; CHECK-NEXT: .seh_save_any_reg_p q14, 128 59; CHECK-NEXT: stp x29, x30, [sp, #160] // 16-byte Folded Spill 60; CHECK-NEXT: .seh_save_fplr 160 61; CHECK-NEXT: add x29, sp, #160 62; CHECK-NEXT: .seh_add_fp 160 63; CHECK-NEXT: .seh_endprologue 64; CHECK-NEXT: blr x9 65; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_ret 66; CHECK-NEXT: ldr x1, [x8, :lo12:__os_arm64x_dispatch_ret] 67; CHECK-NEXT: mov x8, x0 68; CHECK-NEXT: .seh_startepilogue 69; CHECK-NEXT: ldp x29, x30, [sp, #160] // 16-byte Folded Reload 70; CHECK-NEXT: .seh_save_fplr 160 71; CHECK-NEXT: ldp q14, q15, [sp, #128] // 32-byte Folded Reload 72; CHECK-NEXT: .seh_save_any_reg_p q14, 128 73; CHECK-NEXT: ldp q12, q13, [sp, #96] // 32-byte Folded Reload 74; CHECK-NEXT: .seh_save_any_reg_p q12, 96 75; CHECK-NEXT: ldp q10, q11, [sp, #64] // 32-byte Folded Reload 76; CHECK-NEXT: .seh_save_any_reg_p q10, 64 77; CHECK-NEXT: ldp q8, q9, [sp, #32] // 32-byte Folded Reload 78; CHECK-NEXT: .seh_save_any_reg_p q8, 32 79; CHECK-NEXT: ldp q6, q7, [sp], #176 // 32-byte Folded Reload 80; CHECK-NEXT: .seh_save_any_reg_px q6, 176 81; CHECK-NEXT: .seh_endepilogue 82; CHECK-NEXT: br x1 83; CHECK-NEXT: .seh_endfunclet 84; CHECK-NEXT: .seh_endproc 85 ret i64 0 86} 87 88; NOTE: Only float and double are supported. 89define double @simple_floats(float, double) nounwind { 90; CHECK-LABEL: .def $ientry_thunk$cdecl$d$fd; 91; CHECK: .section .wowthk$aa,"xr",discard,$ientry_thunk$cdecl$d$fd 92; CHECK: // %bb.0: 93; CHECK-NEXT: stp q6, q7, [sp, #-176]! // 32-byte Folded Spill 94; CHECK-NEXT: .seh_save_any_reg_px q6, 176 95; CHECK-NEXT: stp q8, q9, [sp, #32] // 32-byte Folded Spill 96; CHECK-NEXT: .seh_save_any_reg_p q8, 32 97; CHECK-NEXT: stp q10, q11, [sp, #64] // 32-byte Folded Spill 98; CHECK-NEXT: .seh_save_any_reg_p q10, 64 99; CHECK-NEXT: stp q12, q13, [sp, #96] // 32-byte Folded Spill 100; CHECK-NEXT: .seh_save_any_reg_p q12, 96 101; CHECK-NEXT: stp q14, q15, [sp, #128] // 32-byte Folded Spill 102; CHECK-NEXT: .seh_save_any_reg_p q14, 128 103; CHECK-NEXT: stp x29, x30, [sp, #160] // 16-byte Folded Spill 104; CHECK-NEXT: .seh_save_fplr 160 105; CHECK-NEXT: add x29, sp, #160 106; CHECK-NEXT: .seh_add_fp 160 107; CHECK-NEXT: .seh_endprologue 108; CHECK-NEXT: blr x9 109; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_ret 110; CHECK-NEXT: ldr x0, [x8, :lo12:__os_arm64x_dispatch_ret] 111; CHECK-NEXT: .seh_startepilogue 112; CHECK-NEXT: ldp x29, x30, [sp, #160] // 16-byte Folded Reload 113; CHECK-NEXT: .seh_save_fplr 160 114; CHECK-NEXT: ldp q14, q15, [sp, #128] // 32-byte Folded Reload 115; CHECK-NEXT: .seh_save_any_reg_p q14, 128 116; CHECK-NEXT: ldp q12, q13, [sp, #96] // 32-byte Folded Reload 117; CHECK-NEXT: .seh_save_any_reg_p q12, 96 118; CHECK-NEXT: ldp q10, q11, [sp, #64] // 32-byte Folded Reload 119; CHECK-NEXT: .seh_save_any_reg_p q10, 64 120; CHECK-NEXT: ldp q8, q9, [sp, #32] // 32-byte Folded Reload 121; CHECK-NEXT: .seh_save_any_reg_p q8, 32 122; CHECK-NEXT: ldp q6, q7, [sp], #176 // 32-byte Folded Reload 123; CHECK-NEXT: .seh_save_any_reg_px q6, 176 124; CHECK-NEXT: .seh_endepilogue 125; CHECK-NEXT: br x0 126; CHECK-NEXT: .seh_endfunclet 127; CHECK-NEXT: .seh_endproc 128 ret double 0.0 129} 130 131define void @has_varargs(...) nounwind { 132; CHECK-LABEL: .def $ientry_thunk$cdecl$v$varargs; 133; CHECK: .section .wowthk$aa,"xr",discard,$ientry_thunk$cdecl$v$varargs 134; CHECK: // %bb.0: 135; CHECK-NEXT: stp q6, q7, [sp, #-176]! // 32-byte Folded Spill 136; CHECK-NEXT: .seh_save_any_reg_px q6, 176 137; CHECK-NEXT: stp q8, q9, [sp, #32] // 32-byte Folded Spill 138; CHECK-NEXT: .seh_save_any_reg_p q8, 32 139; CHECK-NEXT: stp q10, q11, [sp, #64] // 32-byte Folded Spill 140; CHECK-NEXT: .seh_save_any_reg_p q10, 64 141; CHECK-NEXT: stp q12, q13, [sp, #96] // 32-byte Folded Spill 142; CHECK-NEXT: .seh_save_any_reg_p q12, 96 143; CHECK-NEXT: stp q14, q15, [sp, #128] // 32-byte Folded Spill 144; CHECK-NEXT: .seh_save_any_reg_p q14, 128 145; CHECK-NEXT: stp x29, x30, [sp, #160] // 16-byte Folded Spill 146; CHECK-NEXT: .seh_save_fplr 160 147; CHECK-NEXT: add x29, sp, #160 148; CHECK-NEXT: .seh_add_fp 160 149; CHECK-NEXT: .seh_endprologue 150; CHECK-NEXT: add x4, x4, #32 151; CHECK-NEXT: mov x5, xzr 152; CHECK-NEXT: blr x9 153; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_ret 154; CHECK-NEXT: ldr x0, [x8, :lo12:__os_arm64x_dispatch_ret] 155; CHECK-NEXT: .seh_startepilogue 156; CHECK-NEXT: ldp x29, x30, [sp, #160] // 16-byte Folded Reload 157; CHECK-NEXT: .seh_save_fplr 160 158; CHECK-NEXT: ldp q14, q15, [sp, #128] // 32-byte Folded Reload 159; CHECK-NEXT: .seh_save_any_reg_p q14, 128 160; CHECK-NEXT: ldp q12, q13, [sp, #96] // 32-byte Folded Reload 161; CHECK-NEXT: .seh_save_any_reg_p q12, 96 162; CHECK-NEXT: ldp q10, q11, [sp, #64] // 32-byte Folded Reload 163; CHECK-NEXT: .seh_save_any_reg_p q10, 64 164; CHECK-NEXT: ldp q8, q9, [sp, #32] // 32-byte Folded Reload 165; CHECK-NEXT: .seh_save_any_reg_p q8, 32 166; CHECK-NEXT: ldp q6, q7, [sp], #176 // 32-byte Folded Reload 167; CHECK-NEXT: .seh_save_any_reg_px q6, 176 168; CHECK-NEXT: .seh_endepilogue 169; CHECK-NEXT: br x0 170; CHECK-NEXT: .seh_endfunclet 171; CHECK-NEXT: .seh_endproc 172 ret void 173} 174 175define void @has_sret(ptr sret([100 x i8])) nounwind { 176; CHECK-LABEL: .def $ientry_thunk$cdecl$i8$v; 177; CHECK: .section .wowthk$aa,"xr",discard,$ientry_thunk$cdecl$i8$v 178; CHECK: // %bb.0: 179; CHECK-NEXT: stp q6, q7, [sp, #-176]! // 32-byte Folded Spill 180; CHECK-NEXT: .seh_save_any_reg_px q6, 176 181; CHECK-NEXT: stp q8, q9, [sp, #32] // 32-byte Folded Spill 182; CHECK-NEXT: .seh_save_any_reg_p q8, 32 183; CHECK-NEXT: stp q10, q11, [sp, #64] // 32-byte Folded Spill 184; CHECK-NEXT: .seh_save_any_reg_p q10, 64 185; CHECK-NEXT: stp q12, q13, [sp, #96] // 32-byte Folded Spill 186; CHECK-NEXT: .seh_save_any_reg_p q12, 96 187; CHECK-NEXT: stp q14, q15, [sp, #128] // 32-byte Folded Spill 188; CHECK-NEXT: .seh_save_any_reg_p q14, 128 189; CHECK-NEXT: stp x29, x30, [sp, #160] // 16-byte Folded Spill 190; CHECK-NEXT: .seh_save_fplr 160 191; CHECK-NEXT: add x29, sp, #160 192; CHECK-NEXT: .seh_add_fp 160 193; CHECK-NEXT: .seh_endprologue 194; CHECK-NEXT: blr x9 195; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_ret 196; CHECK-NEXT: ldr x1, [x8, :lo12:__os_arm64x_dispatch_ret] 197; CHECK-NEXT: mov x8, x0 198; CHECK-NEXT: .seh_startepilogue 199; CHECK-NEXT: ldp x29, x30, [sp, #160] // 16-byte Folded Reload 200; CHECK-NEXT: .seh_save_fplr 160 201; CHECK-NEXT: ldp q14, q15, [sp, #128] // 32-byte Folded Reload 202; CHECK-NEXT: .seh_save_any_reg_p q14, 128 203; CHECK-NEXT: ldp q12, q13, [sp, #96] // 32-byte Folded Reload 204; CHECK-NEXT: .seh_save_any_reg_p q12, 96 205; CHECK-NEXT: ldp q10, q11, [sp, #64] // 32-byte Folded Reload 206; CHECK-NEXT: .seh_save_any_reg_p q10, 64 207; CHECK-NEXT: ldp q8, q9, [sp, #32] // 32-byte Folded Reload 208; CHECK-NEXT: .seh_save_any_reg_p q8, 32 209; CHECK-NEXT: ldp q6, q7, [sp], #176 // 32-byte Folded Reload 210; CHECK-NEXT: .seh_save_any_reg_px q6, 176 211; CHECK-NEXT: .seh_endepilogue 212; CHECK-NEXT: br x1 213; CHECK-NEXT: .seh_endfunclet 214; CHECK-NEXT: .seh_endproc 215 ret void 216} 217 218define i8 @matches_has_sret() nounwind { 219; Verify that $ientry_thunk$cdecl$i8$v is re-used by a function with matching signature. 220; CHECK-NOT: .def $ientry_thunk$cdecl$i8$v; 221 ret i8 0 222} 223 224%TSRet = type { i64, i64 } 225define void @has_aligned_sret(ptr align 32 sret(%TSRet), i32) nounwind { 226; CHECK-LABEL: .def $ientry_thunk$cdecl$m16$i8; 227; CHECK: .section .wowthk$aa,"xr",discard,$ientry_thunk$cdecl$m16$i8 228; CHECK: // %bb.0: 229; CHECK-NEXT: stp q6, q7, [sp, #-192]! // 32-byte Folded Spill 230; CHECK-NEXT: .seh_save_any_reg_px q6, 192 231; CHECK-NEXT: stp q8, q9, [sp, #32] // 32-byte Folded Spill 232; CHECK-NEXT: .seh_save_any_reg_p q8, 32 233; CHECK-NEXT: stp q10, q11, [sp, #64] // 32-byte Folded Spill 234; CHECK-NEXT: .seh_save_any_reg_p q10, 64 235; CHECK-NEXT: stp q12, q13, [sp, #96] // 32-byte Folded Spill 236; CHECK-NEXT: .seh_save_any_reg_p q12, 96 237; CHECK-NEXT: stp q14, q15, [sp, #128] // 32-byte Folded Spill 238; CHECK-NEXT: .seh_save_any_reg_p q14, 128 239; CHECK-NEXT: str x19, [sp, #160] // 8-byte Folded Spill 240; CHECK-NEXT: .seh_save_reg x19, 160 241; CHECK-NEXT: stp x29, x30, [sp, #168] // 16-byte Folded Spill 242; CHECK-NEXT: .seh_save_fplr 168 243; CHECK-NEXT: add x29, sp, #168 244; CHECK-NEXT: .seh_add_fp 168 245; CHECK-NEXT: .seh_endprologue 246; CHECK-NEXT: mov x19, x0 247; CHECK-NEXT: mov x8, x0 248; CHECK-NEXT: mov x0, x1 249; CHECK-NEXT: blr x9 250; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_ret 251; CHECK-NEXT: ldr x0, [x8, :lo12:__os_arm64x_dispatch_ret] 252; CHECK-NEXT: mov x8, x19 253; CHECK-NEXT: .seh_startepilogue 254; CHECK-NEXT: ldp x29, x30, [sp, #168] // 16-byte Folded Reload 255; CHECK-NEXT: .seh_save_fplr 168 256; CHECK-NEXT: ldr x19, [sp, #160] // 8-byte Folded Reload 257; CHECK-NEXT: .seh_save_reg x19, 160 258; CHECK-NEXT: ldp q14, q15, [sp, #128] // 32-byte Folded Reload 259; CHECK-NEXT: .seh_save_any_reg_p q14, 128 260; CHECK-NEXT: ldp q12, q13, [sp, #96] // 32-byte Folded Reload 261; CHECK-NEXT: .seh_save_any_reg_p q12, 96 262; CHECK-NEXT: ldp q10, q11, [sp, #64] // 32-byte Folded Reload 263; CHECK-NEXT: .seh_save_any_reg_p q10, 64 264; CHECK-NEXT: ldp q8, q9, [sp, #32] // 32-byte Folded Reload 265; CHECK-NEXT: .seh_save_any_reg_p q8, 32 266; CHECK-NEXT: ldp q6, q7, [sp], #192 // 32-byte Folded Reload 267; CHECK-NEXT: .seh_save_any_reg_px q6, 192 268; CHECK-NEXT: .seh_endepilogue 269; CHECK-NEXT: br x0 270; CHECK-NEXT: .seh_endfunclet 271; CHECK-NEXT: .seh_endproc 272 ret void 273} 274 275define [2 x i8] @small_array([2 x i8] %0, [2 x float]) nounwind { 276; CHECK-LABEL: .def $ientry_thunk$cdecl$m2$m2F8; 277; CHECK: .section .wowthk$aa,"xr",discard,$ientry_thunk$cdecl$m2$m2F8 278; CHECK: // %bb.0: 279; CHECK-NEXT: sub sp, sp, #192 280; CHECK-NEXT: .seh_stackalloc 192 281; CHECK-NEXT: stp q6, q7, [sp, #16] // 32-byte Folded Spill 282; CHECK-NEXT: .seh_save_any_reg_p q6, 16 283; CHECK-NEXT: stp q8, q9, [sp, #48] // 32-byte Folded Spill 284; CHECK-NEXT: .seh_save_any_reg_p q8, 48 285; CHECK-NEXT: stp q10, q11, [sp, #80] // 32-byte Folded Spill 286; CHECK-NEXT: .seh_save_any_reg_p q10, 80 287; CHECK-NEXT: stp q12, q13, [sp, #112] // 32-byte Folded Spill 288; CHECK-NEXT: .seh_save_any_reg_p q12, 112 289; CHECK-NEXT: stp q14, q15, [sp, #144] // 32-byte Folded Spill 290; CHECK-NEXT: .seh_save_any_reg_p q14, 144 291; CHECK-NEXT: stp x29, x30, [sp, #176] // 16-byte Folded Spill 292; CHECK-NEXT: .seh_save_fplr 176 293; CHECK-NEXT: add x29, sp, #176 294; CHECK-NEXT: .seh_add_fp 176 295; CHECK-NEXT: .seh_endprologue 296; CHECK-NEXT: stur x1, [sp, #4] 297; CHECK-NEXT: ubfx w1, w0, #8, #8 298; CHECK-NEXT: ldp s0, s1, [sp, #4] 299; CHECK-NEXT: strh w0, [sp, #14] 300; CHECK-NEXT: blr x9 301; CHECK-NEXT: adrp x9, __os_arm64x_dispatch_ret 302; CHECK-NEXT: strb w0, [sp, #2] 303; CHECK-NEXT: strb w1, [sp, #3] 304; CHECK-NEXT: ldrh w8, [sp, #2] 305; CHECK-NEXT: ldr x0, [x9, :lo12:__os_arm64x_dispatch_ret] 306; CHECK-NEXT: .seh_startepilogue 307; CHECK-NEXT: ldp x29, x30, [sp, #176] // 16-byte Folded Reload 308; CHECK-NEXT: .seh_save_fplr 176 309; CHECK-NEXT: ldp q14, q15, [sp, #144] // 32-byte Folded Reload 310; CHECK-NEXT: .seh_save_any_reg_p q14, 144 311; CHECK-NEXT: ldp q12, q13, [sp, #112] // 32-byte Folded Reload 312; CHECK-NEXT: .seh_save_any_reg_p q12, 112 313; CHECK-NEXT: ldp q10, q11, [sp, #80] // 32-byte Folded Reload 314; CHECK-NEXT: .seh_save_any_reg_p q10, 80 315; CHECK-NEXT: ldp q8, q9, [sp, #48] // 32-byte Folded Reload 316; CHECK-NEXT: .seh_save_any_reg_p q8, 48 317; CHECK-NEXT: ldp q6, q7, [sp, #16] // 32-byte Folded Reload 318; CHECK-NEXT: .seh_save_any_reg_p q6, 16 319; CHECK-NEXT: add sp, sp, #192 320; CHECK-NEXT: .seh_stackalloc 192 321; CHECK-NEXT: .seh_endepilogue 322; CHECK-NEXT: br x0 323; CHECK-NEXT: .seh_endfunclet 324; CHECK-NEXT: .seh_endproc 325 ret [2 x i8] %0 326} 327 328define [3 x i64] @large_array([3 x i64] %0, [2 x double], [2 x [2 x i64]]) nounwind { 329; CHECK-LABEL: .def $ientry_thunk$cdecl$m24$m24D16m32; 330; CHECK: .section .wowthk$aa,"xr",discard,$ientry_thunk$cdecl$m24$m24D16m32 331; CHECK: // %bb.0: 332; CHECK-NEXT: stp q6, q7, [sp, #-192]! // 32-byte Folded Spill 333; CHECK-NEXT: .seh_save_any_reg_px q6, 192 334; CHECK-NEXT: stp q8, q9, [sp, #32] // 32-byte Folded Spill 335; CHECK-NEXT: .seh_save_any_reg_p q8, 32 336; CHECK-NEXT: stp q10, q11, [sp, #64] // 32-byte Folded Spill 337; CHECK-NEXT: .seh_save_any_reg_p q10, 64 338; CHECK-NEXT: stp q12, q13, [sp, #96] // 32-byte Folded Spill 339; CHECK-NEXT: .seh_save_any_reg_p q12, 96 340; CHECK-NEXT: stp q14, q15, [sp, #128] // 32-byte Folded Spill 341; CHECK-NEXT: .seh_save_any_reg_p q14, 128 342; CHECK-NEXT: str x19, [sp, #160] // 8-byte Folded Spill 343; CHECK-NEXT: .seh_save_reg x19, 160 344; CHECK-NEXT: stp x29, x30, [sp, #168] // 16-byte Folded Spill 345; CHECK-NEXT: .seh_save_fplr 168 346; CHECK-NEXT: add x29, sp, #168 347; CHECK-NEXT: .seh_add_fp 168 348; CHECK-NEXT: .seh_endprologue 349; CHECK-NEXT: ldp x10, x8, [x1, #8] 350; CHECK-NEXT: mov x19, x0 351; CHECK-NEXT: ldp d0, d1, [x2] 352; CHECK-NEXT: ldr x0, [x1] 353; CHECK-NEXT: ldp x5, x6, [x3, #16] 354; CHECK-NEXT: ldp x3, x4, [x3] 355; CHECK-NEXT: mov x1, x10 356; CHECK-NEXT: mov x2, x8 357; CHECK-NEXT: blr x9 358; CHECK-NEXT: stp x0, x1, [x19] 359; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_ret 360; CHECK-NEXT: str x2, [x19, #16] 361; CHECK-NEXT: ldr x0, [x8, :lo12:__os_arm64x_dispatch_ret] 362; CHECK-NEXT: .seh_startepilogue 363; CHECK-NEXT: ldp x29, x30, [sp, #168] // 16-byte Folded Reload 364; CHECK-NEXT: .seh_save_fplr 168 365; CHECK-NEXT: ldr x19, [sp, #160] // 8-byte Folded Reload 366; CHECK-NEXT: .seh_save_reg x19, 160 367; CHECK-NEXT: ldp q14, q15, [sp, #128] // 32-byte Folded Reload 368; CHECK-NEXT: .seh_save_any_reg_p q14, 128 369; CHECK-NEXT: ldp q12, q13, [sp, #96] // 32-byte Folded Reload 370; CHECK-NEXT: .seh_save_any_reg_p q12, 96 371; CHECK-NEXT: ldp q10, q11, [sp, #64] // 32-byte Folded Reload 372; CHECK-NEXT: .seh_save_any_reg_p q10, 64 373; CHECK-NEXT: ldp q8, q9, [sp, #32] // 32-byte Folded Reload 374; CHECK-NEXT: .seh_save_any_reg_p q8, 32 375; CHECK-NEXT: ldp q6, q7, [sp], #192 // 32-byte Folded Reload 376; CHECK-NEXT: .seh_save_any_reg_px q6, 192 377; CHECK-NEXT: .seh_endepilogue 378; CHECK-NEXT: br x0 379; CHECK-NEXT: .seh_endfunclet 380; CHECK-NEXT: .seh_endproc 381 ret [3 x i64] %0 382} 383 384%T1 = type { i16 } 385%T2 = type { i32, float } 386%T3 = type { i64, double } 387%T4 = type { i64, double, i8 } 388define %T2 @simple_struct(%T1 %0, %T2 %1, %T3, %T4) nounwind { 389; CHECK-LABEL: .def $ientry_thunk$cdecl$m8$i8m8m16m24; 390; CHECK: .section .wowthk$aa,"xr",discard,$ientry_thunk$cdecl$m8$i8m8m16m24 391; CHECK: // %bb.0: 392; CHECK-NEXT: sub sp, sp, #192 393; CHECK-NEXT: .seh_stackalloc 192 394; CHECK-NEXT: stp q6, q7, [sp, #16] // 32-byte Folded Spill 395; CHECK-NEXT: .seh_save_any_reg_p q6, 16 396; CHECK-NEXT: stp q8, q9, [sp, #48] // 32-byte Folded Spill 397; CHECK-NEXT: .seh_save_any_reg_p q8, 48 398; CHECK-NEXT: stp q10, q11, [sp, #80] // 32-byte Folded Spill 399; CHECK-NEXT: .seh_save_any_reg_p q10, 80 400; CHECK-NEXT: stp q12, q13, [sp, #112] // 32-byte Folded Spill 401; CHECK-NEXT: .seh_save_any_reg_p q12, 112 402; CHECK-NEXT: stp q14, q15, [sp, #144] // 32-byte Folded Spill 403; CHECK-NEXT: .seh_save_any_reg_p q14, 144 404; CHECK-NEXT: stp x29, x30, [sp, #176] // 16-byte Folded Spill 405; CHECK-NEXT: .seh_save_fplr 176 406; CHECK-NEXT: add x29, sp, #176 407; CHECK-NEXT: .seh_add_fp 176 408; CHECK-NEXT: .seh_endprologue 409; CHECK-NEXT: str x1, [sp, #8] 410; CHECK-NEXT: ldr x8, [x2] 411; CHECK-NEXT: ldr x10, [x3] 412; CHECK-NEXT: ldr d1, [x2, #8] 413; CHECK-NEXT: // kill: def $w1 killed $w1 killed $x1 414; CHECK-NEXT: ldr s0, [sp, #12] 415; CHECK-NEXT: ldr d2, [x3, #8] 416; CHECK-NEXT: mov x2, x8 417; CHECK-NEXT: ldrb w4, [x3, #16] 418; CHECK-NEXT: mov x3, x10 419; CHECK-NEXT: blr x9 420; CHECK-NEXT: adrp x9, __os_arm64x_dispatch_ret 421; CHECK-NEXT: str w0, [sp] 422; CHECK-NEXT: str s0, [sp, #4] 423; CHECK-NEXT: ldr x8, [sp] 424; CHECK-NEXT: ldr x0, [x9, :lo12:__os_arm64x_dispatch_ret] 425; CHECK-NEXT: .seh_startepilogue 426; CHECK-NEXT: ldp x29, x30, [sp, #176] // 16-byte Folded Reload 427; CHECK-NEXT: .seh_save_fplr 176 428; CHECK-NEXT: ldp q14, q15, [sp, #144] // 32-byte Folded Reload 429; CHECK-NEXT: .seh_save_any_reg_p q14, 144 430; CHECK-NEXT: ldp q12, q13, [sp, #112] // 32-byte Folded Reload 431; CHECK-NEXT: .seh_save_any_reg_p q12, 112 432; CHECK-NEXT: ldp q10, q11, [sp, #80] // 32-byte Folded Reload 433; CHECK-NEXT: .seh_save_any_reg_p q10, 80 434; CHECK-NEXT: ldp q8, q9, [sp, #48] // 32-byte Folded Reload 435; CHECK-NEXT: .seh_save_any_reg_p q8, 48 436; CHECK-NEXT: ldp q6, q7, [sp, #16] // 32-byte Folded Reload 437; CHECK-NEXT: .seh_save_any_reg_p q6, 16 438; CHECK-NEXT: add sp, sp, #192 439; CHECK-NEXT: .seh_stackalloc 192 440; CHECK-NEXT: .seh_endepilogue 441; CHECK-NEXT: br x0 442; CHECK-NEXT: .seh_endfunclet 443; CHECK-NEXT: .seh_endproc 444 ret %T2 %1 445} 446 447define void @cxx_method(ptr noundef nonnull align 8 dereferenceable(8) %0, ptr dead_on_unwind inreg noalias writable sret(i64) align 8 %1) { 448; CHECK-LABEL: .def $ientry_thunk$cdecl$i8$i8i8; 449; CHECK: .section .wowthk$aa,"xr",discard,$ientry_thunk$cdecl$i8$i8i8 450; CHECK: // %bb.0: 451; CHECK-NEXT: stp q6, q7, [sp, #-176]! // 32-byte Folded Spill 452; CHECK-NEXT: .seh_save_any_reg_px q6, 176 453; CHECK-NEXT: stp q8, q9, [sp, #32] // 32-byte Folded Spill 454; CHECK-NEXT: .seh_save_any_reg_p q8, 32 455; CHECK-NEXT: stp q10, q11, [sp, #64] // 32-byte Folded Spill 456; CHECK-NEXT: .seh_save_any_reg_p q10, 64 457; CHECK-NEXT: stp q12, q13, [sp, #96] // 32-byte Folded Spill 458; CHECK-NEXT: .seh_save_any_reg_p q12, 96 459; CHECK-NEXT: stp q14, q15, [sp, #128] // 32-byte Folded Spill 460; CHECK-NEXT: .seh_save_any_reg_p q14, 128 461; CHECK-NEXT: stp x29, x30, [sp, #160] // 16-byte Folded Spill 462; CHECK-NEXT: .seh_save_fplr 160 463; CHECK-NEXT: add x29, sp, #160 464; CHECK-NEXT: .seh_add_fp 160 465; CHECK-NEXT: .seh_endprologue 466; CHECK-NEXT: blr x9 467; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_ret 468; CHECK-NEXT: ldr x1, [x8, :lo12:__os_arm64x_dispatch_ret] 469; CHECK-NEXT: mov x8, x0 470; CHECK-NEXT: .seh_startepilogue 471; CHECK-NEXT: ldp x29, x30, [sp, #160] // 16-byte Folded Reload 472; CHECK-NEXT: .seh_save_fplr 160 473; CHECK-NEXT: ldp q14, q15, [sp, #128] // 32-byte Folded Reload 474; CHECK-NEXT: .seh_save_any_reg_p q14, 128 475; CHECK-NEXT: ldp q12, q13, [sp, #96] // 32-byte Folded Reload 476; CHECK-NEXT: .seh_save_any_reg_p q12, 96 477; CHECK-NEXT: ldp q10, q11, [sp, #64] // 32-byte Folded Reload 478; CHECK-NEXT: .seh_save_any_reg_p q10, 64 479; CHECK-NEXT: ldp q8, q9, [sp, #32] // 32-byte Folded Reload 480; CHECK-NEXT: .seh_save_any_reg_p q8, 32 481; CHECK-NEXT: ldp q6, q7, [sp], #176 // 32-byte Folded Reload 482; CHECK-NEXT: .seh_save_any_reg_px q6, 176 483; CHECK-NEXT: .seh_endepilogue 484; CHECK-NEXT: br x1 485; CHECK-NEXT: .seh_endfunclet 486; CHECK-NEXT: .seh_endproc 487 ret void 488} 489 490define <4 x i8> @small_vector(<4 x i8> %0) { 491; CHECK-LABEL: .def $ientry_thunk$cdecl$m$m; 492; CHECK: .section .wowthk$aa,"xr",discard,$ientry_thunk$cdecl$m$m 493; CHECK: // %bb.0: 494; CHECK-NEXT: sub sp, sp, #192 495; CHECK-NEXT: .seh_stackalloc 192 496; CHECK-NEXT: stp q6, q7, [sp, #16] // 32-byte Folded Spill 497; CHECK-NEXT: .seh_save_any_reg_p q6, 16 498; CHECK-NEXT: stp q8, q9, [sp, #48] // 32-byte Folded Spill 499; CHECK-NEXT: .seh_save_any_reg_p q8, 48 500; CHECK-NEXT: stp q10, q11, [sp, #80] // 32-byte Folded Spill 501; CHECK-NEXT: .seh_save_any_reg_p q10, 80 502; CHECK-NEXT: stp q12, q13, [sp, #112] // 32-byte Folded Spill 503; CHECK-NEXT: .seh_save_any_reg_p q12, 112 504; CHECK-NEXT: stp q14, q15, [sp, #144] // 32-byte Folded Spill 505; CHECK-NEXT: .seh_save_any_reg_p q14, 144 506; CHECK-NEXT: stp x29, x30, [sp, #176] // 16-byte Folded Spill 507; CHECK-NEXT: .seh_save_fplr 176 508; CHECK-NEXT: add x29, sp, #176 509; CHECK-NEXT: .seh_add_fp 176 510; CHECK-NEXT: .seh_endprologue 511; CHECK-NEXT: str w0, [sp, #12] 512; CHECK-NEXT: ldr s0, [sp, #12] 513; CHECK-NEXT: ushll v0.8h, v0.8b, #0 514; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0 515; CHECK-NEXT: blr x9 516; CHECK-NEXT: uzp1 v0.8b, v0.8b, v0.8b 517; CHECK-NEXT: adrp x9, __os_arm64x_dispatch_ret 518; CHECK-NEXT: str s0, [sp, #8] 519; CHECK-NEXT: fmov w8, s0 520; CHECK-NEXT: ldr x0, [x9, :lo12:__os_arm64x_dispatch_ret] 521; CHECK-NEXT: .seh_startepilogue 522; CHECK-NEXT: ldp x29, x30, [sp, #176] // 16-byte Folded Reload 523; CHECK-NEXT: .seh_save_fplr 176 524; CHECK-NEXT: ldp q14, q15, [sp, #144] // 32-byte Folded Reload 525; CHECK-NEXT: .seh_save_any_reg_p q14, 144 526; CHECK-NEXT: ldp q12, q13, [sp, #112] // 32-byte Folded Reload 527; CHECK-NEXT: .seh_save_any_reg_p q12, 112 528; CHECK-NEXT: ldp q10, q11, [sp, #80] // 32-byte Folded Reload 529; CHECK-NEXT: .seh_save_any_reg_p q10, 80 530; CHECK-NEXT: ldp q8, q9, [sp, #48] // 32-byte Folded Reload 531; CHECK-NEXT: .seh_save_any_reg_p q8, 48 532; CHECK-NEXT: ldp q6, q7, [sp, #16] // 32-byte Folded Reload 533; CHECK-NEXT: .seh_save_any_reg_p q6, 16 534; CHECK-NEXT: add sp, sp, #192 535; CHECK-NEXT: .seh_stackalloc 192 536; CHECK-NEXT: .seh_endepilogue 537; CHECK-NEXT: br x0 538; CHECK-NEXT: .seh_endfunclet 539; CHECK-NEXT: .seh_endproc 540start: 541 ret <4 x i8> %0 542} 543 544define <8 x i16> @large_vector(<8 x i16> %0) { 545; CHECK-LABEL: .def $ientry_thunk$cdecl$m16$m16; 546; CHECK: .section .wowthk$aa,"xr",discard,$ientry_thunk$cdecl$m16$m16 547; CHECK: // %bb.0: 548; CHECK-NEXT: stp q6, q7, [sp, #-192]! // 32-byte Folded Spill 549; CHECK-NEXT: .seh_save_any_reg_px q6, 192 550; CHECK-NEXT: stp q8, q9, [sp, #32] // 32-byte Folded Spill 551; CHECK-NEXT: .seh_save_any_reg_p q8, 32 552; CHECK-NEXT: stp q10, q11, [sp, #64] // 32-byte Folded Spill 553; CHECK-NEXT: .seh_save_any_reg_p q10, 64 554; CHECK-NEXT: stp q12, q13, [sp, #96] // 32-byte Folded Spill 555; CHECK-NEXT: .seh_save_any_reg_p q12, 96 556; CHECK-NEXT: stp q14, q15, [sp, #128] // 32-byte Folded Spill 557; CHECK-NEXT: .seh_save_any_reg_p q14, 128 558; CHECK-NEXT: str x19, [sp, #160] // 8-byte Folded Spill 559; CHECK-NEXT: .seh_save_reg x19, 160 560; CHECK-NEXT: stp x29, x30, [sp, #168] // 16-byte Folded Spill 561; CHECK-NEXT: .seh_save_fplr 168 562; CHECK-NEXT: add x29, sp, #168 563; CHECK-NEXT: .seh_add_fp 168 564; CHECK-NEXT: .seh_endprologue 565; CHECK-NEXT: ldr q0, [x1] 566; CHECK-NEXT: mov x19, x0 567; CHECK-NEXT: blr x9 568; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_ret 569; CHECK-NEXT: str q0, [x19] 570; CHECK-NEXT: ldr x0, [x8, :lo12:__os_arm64x_dispatch_ret] 571; CHECK-NEXT: .seh_startepilogue 572; CHECK-NEXT: ldp x29, x30, [sp, #168] // 16-byte Folded Reload 573; CHECK-NEXT: .seh_save_fplr 168 574; CHECK-NEXT: ldr x19, [sp, #160] // 8-byte Folded Reload 575; CHECK-NEXT: .seh_save_reg x19, 160 576; CHECK-NEXT: ldp q14, q15, [sp, #128] // 32-byte Folded Reload 577; CHECK-NEXT: .seh_save_any_reg_p q14, 128 578; CHECK-NEXT: ldp q12, q13, [sp, #96] // 32-byte Folded Reload 579; CHECK-NEXT: .seh_save_any_reg_p q12, 96 580; CHECK-NEXT: ldp q10, q11, [sp, #64] // 32-byte Folded Reload 581; CHECK-NEXT: .seh_save_any_reg_p q10, 64 582; CHECK-NEXT: ldp q8, q9, [sp, #32] // 32-byte Folded Reload 583; CHECK-NEXT: .seh_save_any_reg_p q8, 32 584; CHECK-NEXT: ldp q6, q7, [sp], #192 // 32-byte Folded Reload 585; CHECK-NEXT: .seh_save_any_reg_px q6, 192 586; CHECK-NEXT: .seh_endepilogue 587; CHECK-NEXT: br x0 588; CHECK-NEXT: .seh_endfunclet 589; CHECK-NEXT: .seh_endproc 590start: 591 ret <8 x i16> %0 592} 593 594; Verify the hybrid bitmap 595; CHECK-LABEL: .section .hybmp$x,"yi" 596; CHECK-NEXT: .symidx "#no_op" 597; CHECK-NEXT: .symidx $ientry_thunk$cdecl$v$v 598; CHECK-NEXT: .word 1 599; CHECK-NEXT: .symidx "#simple_integers" 600; CHECK-NEXT: .symidx $ientry_thunk$cdecl$i8$i8i8i8i8 601; CHECK-NEXT: .word 1 602; CHECK-NEXT: .symidx "#simple_floats" 603; CHECK-NEXT: .symidx $ientry_thunk$cdecl$d$fd 604; CHECK-NEXT: .word 1 605; CHECK-NEXT: .symidx "#has_varargs" 606; CHECK-NEXT: .symidx $ientry_thunk$cdecl$v$varargs 607; CHECK-NEXT: .word 1 608; CHECK-NEXT: .symidx "#has_sret" 609; CHECK-NEXT: .symidx $ientry_thunk$cdecl$m100$v 610; CHECK-NEXT: .word 1 611; CHECK-NEXT: .symidx "#matches_has_sret" 612; CHECK-NEXT: .symidx $ientry_thunk$cdecl$i8$v 613; CHECK-NEXT: .word 1 614; CHECK-NEXT: .symidx "#has_aligned_sret" 615; CHECK-NEXT: .symidx $ientry_thunk$cdecl$m16$i8 616; CHECK-NEXT: .word 1 617; CHECK-NEXT: .symidx "#small_array" 618; CHECK-NEXT: .symidx $ientry_thunk$cdecl$m2$m2F8 619; CHECK-NEXT: .word 1 620; CHECK-NEXT: .symidx "#large_array" 621; CHECK-NEXT: .symidx $ientry_thunk$cdecl$m24$m24D16m32 622; CHECK-NEXT: .word 1 623; CHECK-NEXT: .symidx "#simple_struct" 624; CHECK-NEXT: .symidx $ientry_thunk$cdecl$m8$i8m8m16m24 625; CHECK-NEXT: .word 1 626; CHECK-NEXT: .symidx "#cxx_method" 627; CHECK-NEXT: .symidx $ientry_thunk$cdecl$i8$i8i8 628; CHECK-NEXT: .word 1 629; CHECK-NEXT: .symidx "#small_vector" 630; CHECK-NEXT: .symidx $ientry_thunk$cdecl$m$m 631; CHECK-NEXT: .word 1 632; CHECK-NEXT: .symidx "#large_vector" 633; CHECK-NEXT: .symidx $ientry_thunk$cdecl$m16$m16 634; CHECK-NEXT: .word 1 635