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