diff --git a/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp b/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp index b56834eb03e30..fb21d1fd3f7bd 100644 --- a/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp @@ -339,10 +339,18 @@ ThunkArgInfo AArch64Arm64ECCallLowering::canonicalizeThunkType( return direct(T); } + if (T->isFP128Ty()) { + // Prefix with `llvm` since MSVC doesn't specify `_Float128` + Out << "__llvm_q__"; + // On windows f128 is passed indirectly, and Clang/LLVM + // returns using sret for compatibility with GCC. + return pointerIndirection(T); + } + if (T->isFloatingPointTy()) { report_fatal_error( - "Only half, bfloat16, float, and double are supported for ARM64EC " - "thunks"); + "Only half, bfloat16, float, double, and fp128 are supported " + "for ARM64EC thunks"); } auto &DL = M->getDataLayout(); @@ -357,7 +365,8 @@ ThunkArgInfo AArch64Arm64ECCallLowering::canonicalizeThunkType( uint64_t ElementSizePerBytes = DL.getTypeSizeInBits(ElementTy) / 8; uint64_t TotalSizeBytes = ElementCnt * ElementSizePerBytes; if (ElementTy->isHalfTy() || ElementTy->isBFloatTy() || - ElementTy->isFloatTy() || ElementTy->isDoubleTy()) { + ElementTy->isFloatTy() || ElementTy->isDoubleTy() || + ElementTy->isFP128Ty()) { if (ElementTy->isHalfTy()) // Prefix with `llvm` since MSVC doesn't specify `_Float16` Out << "__llvm_H__"; @@ -368,6 +377,9 @@ ThunkArgInfo AArch64Arm64ECCallLowering::canonicalizeThunkType( Out << "F"; else if (ElementTy->isDoubleTy()) Out << "D"; + else if (ElementTy->isFP128Ty()) + // Prefix with `llvm` since MSVC doesn't specify `_Float128` + Out << "__llvm_Q__"; Out << TotalSizeBytes; if (Alignment.value() >= 16 && !Ret) Out << "a" << Alignment.value(); @@ -381,8 +393,8 @@ ThunkArgInfo AArch64Arm64ECCallLowering::canonicalizeThunkType( } } else if (ElementTy->isFloatingPointTy()) { report_fatal_error( - "Only half, bfloat16, float, and double are supported for ARM64EC " - "thunks"); + "Only half, bfloat16, float, double, and fp128 are supported " + "for ARM64EC thunks"); } } diff --git a/llvm/test/CodeGen/AArch64/arm64ec-entry-thunks.ll b/llvm/test/CodeGen/AArch64/arm64ec-entry-thunks.ll index 27f84dbdaf39d..eafb401a1f705 100644 --- a/llvm/test/CodeGen/AArch64/arm64ec-entry-thunks.ll +++ b/llvm/test/CodeGen/AArch64/arm64ec-entry-thunks.ll @@ -85,10 +85,10 @@ define i64 @simple_integers(i8, i16, i32, i64) nounwind { ret i64 0 } -; NOTE: Half, bfloat16, float, and double are supported. -define double @simple_floats(half, float, double) nounwind { -; CHECK-LABEL: .def $ientry_thunk$cdecl$d$__llvm_h__fd; -; CHECK: .section .wowthk$aa,"xr",discard,$ientry_thunk$cdecl$d$__llvm_h__fd +; NOTE: Only half, bfloat16, float, double, and fp128 are supported. +define double @simple_floats(half, float, double, fp128) nounwind { +; CHECK-LABEL: .def $ientry_thunk$cdecl$d$__llvm_h__fd__llvm_q__; +; CHECK: .section .wowthk$aa,"xr",discard,$ientry_thunk$cdecl$d$__llvm_h__fd__llvm_q__ ; CHECK: // %bb.0: ; CHECK-NEXT: stp q6, q7, [sp, #-176]! // 32-byte Folded Spill ; CHECK-NEXT: .seh_save_any_reg_px q6, 176 @@ -105,6 +105,7 @@ define double @simple_floats(half, float, double) nounwind { ; CHECK-NEXT: add x29, sp, #160 ; CHECK-NEXT: .seh_add_fp 160 ; CHECK-NEXT: .seh_endprologue +; CHECK-NEXT: ldr q3, [x3] ; CHECK-NEXT: blr x9 ; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_ret ; CHECK-NEXT: ldr x0, [x8, :lo12:__os_arm64x_dispatch_ret] @@ -128,6 +129,97 @@ define double @simple_floats(half, float, double) nounwind { ret double 0.0 } +define half @return_half() nounwind { +; CHECK-LABEL: .def $ientry_thunk$cdecl$__llvm_h__$v; +; CHECK: .section .wowthk$aa,"xr",discard,$ientry_thunk$cdecl$__llvm_h__$v +; CHECK: // %bb.0: +; CHECK-NEXT: stp q6, q7, [sp, #-176]! // 32-byte Folded Spill +; CHECK-NEXT: .seh_save_any_reg_px q6, 176 +; CHECK-NEXT: stp q8, q9, [sp, #32] // 32-byte Folded Spill +; CHECK-NEXT: .seh_save_any_reg_p q8, 32 +; CHECK-NEXT: stp q10, q11, [sp, #64] // 32-byte Folded Spill +; CHECK-NEXT: .seh_save_any_reg_p q10, 64 +; CHECK-NEXT: stp q12, q13, [sp, #96] // 32-byte Folded Spill +; CHECK-NEXT: .seh_save_any_reg_p q12, 96 +; CHECK-NEXT: stp q14, q15, [sp, #128] // 32-byte Folded Spill +; CHECK-NEXT: .seh_save_any_reg_p q14, 128 +; CHECK-NEXT: stp x29, x30, [sp, #160] // 16-byte Folded Spill +; CHECK-NEXT: .seh_save_fplr 160 +; CHECK-NEXT: add x29, sp, #160 +; CHECK-NEXT: .seh_add_fp 160 +; CHECK-NEXT: .seh_endprologue +; CHECK-NEXT: blr x9 +; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_ret +; CHECK-NEXT: ldr x0, [x8, :lo12:__os_arm64x_dispatch_ret] +; CHECK-NEXT: .seh_startepilogue +; CHECK-NEXT: ldp x29, x30, [sp, #160] // 16-byte Folded Reload +; CHECK-NEXT: .seh_save_fplr 160 +; CHECK-NEXT: ldp q14, q15, [sp, #128] // 32-byte Folded Reload +; CHECK-NEXT: .seh_save_any_reg_p q14, 128 +; CHECK-NEXT: ldp q12, q13, [sp, #96] // 32-byte Folded Reload +; CHECK-NEXT: .seh_save_any_reg_p q12, 96 +; CHECK-NEXT: ldp q10, q11, [sp, #64] // 32-byte Folded Reload +; CHECK-NEXT: .seh_save_any_reg_p q10, 64 +; CHECK-NEXT: ldp q8, q9, [sp, #32] // 32-byte Folded Reload +; CHECK-NEXT: .seh_save_any_reg_p q8, 32 +; CHECK-NEXT: ldp q6, q7, [sp], #176 // 32-byte Folded Reload +; CHECK-NEXT: .seh_save_any_reg_px q6, 176 +; CHECK-NEXT: .seh_endepilogue +; CHECK-NEXT: br x0 +; CHECK-NEXT: .seh_endfunclet +; CHECK-NEXT: .seh_endproc + ret half 3.14 +} + +define fp128 @return_fp128() nounwind { +; CHECK-LABEL: .def $ientry_thunk$cdecl$__llvm_q__$v; +; CHECK: .section .wowthk$aa,"xr",discard,$ientry_thunk$cdecl$__llvm_q__$v +; CHECK: // %bb.0: +; CHECK-NEXT: stp q6, q7, [sp, #-192]! // 32-byte Folded Spill +; CHECK-NEXT: .seh_save_any_reg_px q6, 192 +; CHECK-NEXT: stp q8, q9, [sp, #32] // 32-byte Folded Spill +; CHECK-NEXT: .seh_save_any_reg_p q8, 32 +; CHECK-NEXT: stp q10, q11, [sp, #64] // 32-byte Folded Spill +; CHECK-NEXT: .seh_save_any_reg_p q10, 64 +; CHECK-NEXT: stp q12, q13, [sp, #96] // 32-byte Folded Spill +; CHECK-NEXT: .seh_save_any_reg_p q12, 96 +; CHECK-NEXT: stp q14, q15, [sp, #128] // 32-byte Folded Spill +; CHECK-NEXT: .seh_save_any_reg_p q14, 128 +; CHECK-NEXT: str x19, [sp, #160] // 8-byte Spill +; CHECK-NEXT: .seh_save_reg x19, 160 +; CHECK-NEXT: stp x29, x30, [sp, #168] // 16-byte Folded Spill +; CHECK-NEXT: .seh_save_fplr 168 +; CHECK-NEXT: add x29, sp, #168 +; CHECK-NEXT: .seh_add_fp 168 +; CHECK-NEXT: .seh_endprologue +; CHECK-NEXT: mov x19, x0 +; CHECK-NEXT: blr x9 +; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_ret +; CHECK-NEXT: str q0, [x19] +; CHECK-NEXT: ldr x0, [x8, :lo12:__os_arm64x_dispatch_ret] +; CHECK-NEXT: mov x8, x19 +; CHECK-NEXT: .seh_startepilogue +; CHECK-NEXT: ldp x29, x30, [sp, #168] // 16-byte Folded Reload +; CHECK-NEXT: .seh_save_fplr 168 +; CHECK-NEXT: ldr x19, [sp, #160] // 8-byte Reload +; CHECK-NEXT: .seh_save_reg x19, 160 +; CHECK-NEXT: ldp q14, q15, [sp, #128] // 32-byte Folded Reload +; CHECK-NEXT: .seh_save_any_reg_p q14, 128 +; CHECK-NEXT: ldp q12, q13, [sp, #96] // 32-byte Folded Reload +; CHECK-NEXT: .seh_save_any_reg_p q12, 96 +; CHECK-NEXT: ldp q10, q11, [sp, #64] // 32-byte Folded Reload +; CHECK-NEXT: .seh_save_any_reg_p q10, 64 +; CHECK-NEXT: ldp q8, q9, [sp, #32] // 32-byte Folded Reload +; CHECK-NEXT: .seh_save_any_reg_p q8, 32 +; CHECK-NEXT: ldp q6, q7, [sp], #192 // 32-byte Folded Reload +; CHECK-NEXT: .seh_save_any_reg_px q6, 192 +; CHECK-NEXT: .seh_endepilogue +; CHECK-NEXT: br x0 +; CHECK-NEXT: .seh_endfunclet +; CHECK-NEXT: .seh_endproc + ret fp128 3.14 +} + define bfloat @simple_bfloat(bfloat %0, bfloat %1) nounwind { ; CHECK-LABEL: .def $ientry_thunk$cdecl$__llvm_bf16__$__llvm_bf16____llvm_bf16__; ; CHECK: .section .wowthk$aa,"xr",discard,$ientry_thunk$cdecl$__llvm_bf16__$__llvm_bf16____llvm_bf16__ @@ -748,7 +840,13 @@ start: ; CHECK-NEXT: .symidx $ientry_thunk$cdecl$i8$i8i8i8i8 ; CHECK-NEXT: .word 1 ; CHECK-NEXT: .symidx "#simple_floats" -; CHECK-NEXT: .symidx $ientry_thunk$cdecl$d$__llvm_h__fd +; CHECK-NEXT: .symidx $ientry_thunk$cdecl$d$__llvm_h__fd__llvm_q__ +; CHECK-NEXT: .word 1 +; CHECK-NEXT: .symidx "#return_half" +; CHECK-NEXT: .symidx $ientry_thunk$cdecl$__llvm_h__$v +; CHECK-NEXT: .word 1 +; CHECK-NEXT: .symidx "#return_fp128" +; CHECK-NEXT: .symidx $ientry_thunk$cdecl$__llvm_q__$v ; CHECK-NEXT: .word 1 ; CHECK-NEXT: .symidx "#simple_bfloat" ; CHECK-NEXT: .symidx $ientry_thunk$cdecl$__llvm_bf16__$__llvm_bf16____llvm_bf16__ diff --git a/llvm/test/CodeGen/AArch64/arm64ec-exit-thunks.ll b/llvm/test/CodeGen/AArch64/arm64ec-exit-thunks.ll index 6c341c105a236..991b9c291da09 100644 --- a/llvm/test/CodeGen/AArch64/arm64ec-exit-thunks.ll +++ b/llvm/test/CodeGen/AArch64/arm64ec-exit-thunks.ll @@ -93,26 +93,28 @@ declare i64 @simple_integers(i8, i16, i32, i64) nounwind; ; CHECK-NEXT: .seh_endfunclet ; CHECK-NEXT: .seh_endproc -; NOTE: Half, bfloat16, float, and double are supported. -declare double @simple_floats(half, float, double) nounwind; -; CHECK-LABEL: .def $iexit_thunk$cdecl$d$__llvm_h__fd; -; CHECK: .section .wowthk$aa,"xr",discard,$iexit_thunk$cdecl$d$__llvm_h__fd +; NOTE: Only half, bfloat16, float, double, and fp128 are supported. +declare double @simple_floats(half, float, double, fp128) nounwind; +; CHECK-LABEL: .def $iexit_thunk$cdecl$d$__llvm_h__fd__llvm_q__; +; CHECK: .section .wowthk$aa,"xr",discard,$iexit_thunk$cdecl$d$__llvm_h__fd__llvm_q__ ; CHECK: // %bb.0: -; CHECK-NEXT: sub sp, sp, #48 -; CHECK-NEXT: .seh_stackalloc 48 -; CHECK-NEXT: stp x29, x30, [sp, #32] // 16-byte Folded Spill -; CHECK-NEXT: .seh_save_fplr 32 -; CHECK-NEXT: add x29, sp, #32 -; CHECK-NEXT: .seh_add_fp 32 +; CHECK-NEXT: sub sp, sp, #64 +; CHECK-NEXT: .seh_stackalloc 64 +; CHECK-NEXT: stp x29, x30, [sp, #48] // 16-byte Folded Spill +; CHECK-NEXT: .seh_save_fplr 48 +; CHECK-NEXT: add x29, sp, #48 +; CHECK-NEXT: .seh_add_fp 48 ; CHECK-NEXT: .seh_endprologue ; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_call_no_redirect +; CHECK-NEXT: sub x3, x29, #16 +; CHECK-NEXT: stur q3, [x29, #-16] ; CHECK-NEXT: ldr x16, [x8, :lo12:__os_arm64x_dispatch_call_no_redirect] ; CHECK-NEXT: blr x16 ; CHECK-NEXT: .seh_startepilogue -; CHECK-NEXT: ldp x29, x30, [sp, #32] // 16-byte Folded Reload -; CHECK-NEXT: .seh_save_fplr 32 -; CHECK-NEXT: add sp, sp, #48 -; CHECK-NEXT: .seh_stackalloc 48 +; CHECK-NEXT: ldp x29, x30, [sp, #48] // 16-byte Folded Reload +; CHECK-NEXT: .seh_save_fplr 48 +; CHECK-NEXT: add sp, sp, #64 +; CHECK-NEXT: .seh_stackalloc 64 ; CHECK-NEXT: .seh_endepilogue ; CHECK-NEXT: ret ; CHECK-NEXT: .seh_endfunclet @@ -129,8 +131,8 @@ declare double @simple_floats(half, float, double) nounwind; ; CHECK-NEXT: adrp x11, simple_floats ; CHECK-NEXT: add x11, x11, :lo12:simple_floats ; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall] -; CHECK-NEXT: adrp x10, $iexit_thunk$cdecl$d$__llvm_h__fd -; CHECK-NEXT: add x10, x10, :lo12:$iexit_thunk$cdecl$d$__llvm_h__fd +; CHECK-NEXT: adrp x10, $iexit_thunk$cdecl$d$__llvm_h__fd__llvm_q__ +; CHECK-NEXT: add x10, x10, :lo12:$iexit_thunk$cdecl$d$__llvm_h__fd__llvm_q__ ; CHECK-NEXT: blr x8 ; CHECK-NEXT: .seh_startepilogue ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload @@ -186,6 +188,100 @@ declare bfloat @simple_bfloat(bfloat, bfloat) nounwind; ; CHECK-NEXT: .seh_endfunclet ; CHECK-NEXT: .seh_endproc +declare half @return_half() nounwind; +; CHECK-LABEL: .def $iexit_thunk$cdecl$__llvm_h__$v; +; CHECK: .section .wowthk$aa,"xr",discard,$iexit_thunk$cdecl$__llvm_h__$v +; CHECK: // %bb.0: +; CHECK-NEXT: sub sp, sp, #48 +; CHECK-NEXT: .seh_stackalloc 48 +; CHECK-NEXT: stp x29, x30, [sp, #32] // 16-byte Folded Spill +; CHECK-NEXT: .seh_save_fplr 32 +; CHECK-NEXT: add x29, sp, #32 +; CHECK-NEXT: .seh_add_fp 32 +; CHECK-NEXT: .seh_endprologue +; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_call_no_redirect +; CHECK-NEXT: ldr x16, [x8, :lo12:__os_arm64x_dispatch_call_no_redirect] +; CHECK-NEXT: blr x16 +; CHECK-NEXT: .seh_startepilogue +; CHECK-NEXT: ldp x29, x30, [sp, #32] // 16-byte Folded Reload +; CHECK-NEXT: .seh_save_fplr 32 +; CHECK-NEXT: add sp, sp, #48 +; CHECK-NEXT: .seh_stackalloc 48 +; CHECK-NEXT: .seh_endepilogue +; CHECK-NEXT: ret +; CHECK-NEXT: .seh_endfunclet +; CHECK-NEXT: .seh_endproc +; CHECK-LABEL: .def "#return_half$exit_thunk"; +; CHECK: .section .wowthk$aa,"xr",discard,"#return_half$exit_thunk" +; CHECK: .weak_anti_dep return_half +; CHECK: .weak_anti_dep "#return_half" +; CHECK: // %bb.0: +; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: .seh_save_reg_x x30, 16 +; CHECK-NEXT: .seh_endprologue +; CHECK-NEXT: adrp x8, __os_arm64x_check_icall +; CHECK-NEXT: adrp x11, return_half +; CHECK-NEXT: add x11, x11, :lo12:return_half +; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall] +; CHECK-NEXT: adrp x10, $iexit_thunk$cdecl$__llvm_h__$v +; CHECK-NEXT: add x10, x10, :lo12:$iexit_thunk$cdecl$__llvm_h__$v +; CHECK-NEXT: blr x8 +; CHECK-NEXT: .seh_startepilogue +; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; CHECK-NEXT: .seh_save_reg_x x30, 16 +; CHECK-NEXT: .seh_endepilogue +; CHECK-NEXT: br x11 +; CHECK-NEXT: .seh_endfunclet +; CHECK-NEXT: .seh_endproc + +declare fp128 @return_fp128() nounwind; +; CHECK-LABEL: .def $iexit_thunk$cdecl$__llvm_q__$v; +; CHECK: .section .wowthk$aa,"xr",discard,$iexit_thunk$cdecl$__llvm_q__$v +; CHECK: // %bb.0: +; CHECK-NEXT: sub sp, sp, #64 +; CHECK-NEXT: .seh_stackalloc 64 +; CHECK-NEXT: stp x29, x30, [sp, #48] // 16-byte Folded Spill +; CHECK-NEXT: .seh_save_fplr 48 +; CHECK-NEXT: add x29, sp, #48 +; CHECK-NEXT: .seh_add_fp 48 +; CHECK-NEXT: .seh_endprologue +; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_call_no_redirect +; CHECK-NEXT: sub x0, x29, #16 +; CHECK-NEXT: ldr x16, [x8, :lo12:__os_arm64x_dispatch_call_no_redirect] +; CHECK-NEXT: blr x16 +; CHECK-NEXT: ldur q0, [x29, #-16] +; CHECK-NEXT: .seh_startepilogue +; CHECK-NEXT: ldp x29, x30, [sp, #48] // 16-byte Folded Reload +; CHECK-NEXT: .seh_save_fplr 48 +; CHECK-NEXT: add sp, sp, #64 +; CHECK-NEXT: .seh_stackalloc 64 +; CHECK-NEXT: .seh_endepilogue +; CHECK-NEXT: ret +; CHECK-NEXT: .seh_endfunclet +; CHECK-NEXT: .seh_endproc +; CHECK-LABEL: .def "#return_fp128$exit_thunk"; +; CHECK: .section .wowthk$aa,"xr",discard,"#return_fp128$exit_thunk" +; CHECK: .weak_anti_dep return_fp128 +; CHECK: .weak_anti_dep "#return_fp128" +; CHECK: // %bb.0: +; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: .seh_save_reg_x x30, 16 +; CHECK-NEXT: .seh_endprologue +; CHECK-NEXT: adrp x8, __os_arm64x_check_icall +; CHECK-NEXT: adrp x11, return_fp128 +; CHECK-NEXT: add x11, x11, :lo12:return_fp128 +; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall] +; CHECK-NEXT: adrp x10, $iexit_thunk$cdecl$__llvm_q__$v +; CHECK-NEXT: add x10, x10, :lo12:$iexit_thunk$cdecl$__llvm_q__$v +; CHECK-NEXT: blr x8 +; CHECK-NEXT: .seh_startepilogue +; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; CHECK-NEXT: .seh_save_reg_x x30, 16 +; CHECK-NEXT: .seh_endepilogue +; CHECK-NEXT: br x11 +; CHECK-NEXT: .seh_endfunclet +; CHECK-NEXT: .seh_endproc + declare void @has_varargs(...) nounwind; ; CHECK-LABEL: .def $iexit_thunk$cdecl$v$varargs; ; CHECK: .section .wowthk$aa,"xr",discard,$iexit_thunk$cdecl$v$varargs @@ -328,36 +424,38 @@ declare void @has_aligned_sret(ptr align 32 sret(%TSRet)) nounwind; ; CHECK: .seh_endfunclet ; CHECK: .seh_endproc -declare [2 x i8] @small_array([2 x i8], [2 x half], [2 x float]) nounwind; -; CHECK-LABEL: .def $iexit_thunk$cdecl$m2$m2__llvm_H__4F8; -; CHECK: .section .wowthk$aa,"xr",discard,$iexit_thunk$cdecl$m2$m2__llvm_H__4F8 +declare [2 x i8] @small_array([2 x i8], [2 x half], [2 x fp128], [2 x float]) nounwind; +; CHECK-LABEL: .def $iexit_thunk$cdecl$m2$m2__llvm_H__4__llvm_Q__32F8; +; CHECK: .section .wowthk$aa,"xr",discard,$iexit_thunk$cdecl$m2$m2__llvm_H__4__llvm_Q__32F8 ; CHECK: // %bb.0: -; CHECK-NEXT: sub sp, sp, #80 -; CHECK-NEXT: .seh_stackalloc 80 -; CHECK-NEXT: stp x29, x30, [sp, #64] // 16-byte Folded Spill -; CHECK-NEXT: .seh_save_fplr 64 -; CHECK-NEXT: add x29, sp, #64 -; CHECK-NEXT: .seh_add_fp 64 +; CHECK-NEXT: sub sp, sp, #112 +; CHECK-NEXT: .seh_stackalloc 112 +; CHECK-NEXT: stp x29, x30, [sp, #96] // 16-byte Folded Spill +; CHECK-NEXT: .seh_save_fplr 96 +; CHECK-NEXT: add x29, sp, #96 +; CHECK-NEXT: .seh_add_fp 96 ; CHECK-NEXT: .seh_endprologue ; CHECK-NEXT: sturb w0, [x29, #-2] ; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_call_no_redirect +; CHECK-NEXT: add x2, sp, #48 ; CHECK-NEXT: sturb w1, [x29, #-1] ; CHECK-NEXT: ldr x16, [x8, :lo12:__os_arm64x_dispatch_call_no_redirect] ; CHECK-NEXT: stur h0, [x29, #-6] ; CHECK-NEXT: ldurh w0, [x29, #-2] ; CHECK-NEXT: stur h1, [x29, #-4] -; CHECK-NEXT: stp s2, s3, [x29, #-16] +; CHECK-NEXT: stp s4, s5, [sp, #40] ; CHECK-NEXT: ldur w1, [x29, #-6] -; CHECK-NEXT: ldur x2, [x29, #-16] +; CHECK-NEXT: ldr x3, [sp, #40] +; CHECK-NEXT: stp q2, q3, [sp, #48] ; CHECK-NEXT: blr x16 ; CHECK-NEXT: mov w0, w8 -; CHECK-NEXT: sturh w8, [x29, #-18] +; CHECK-NEXT: strh w8, [sp, #38] ; CHECK-NEXT: ubfx w1, w8, #8, #8 ; CHECK-NEXT: .seh_startepilogue -; CHECK-NEXT: ldp x29, x30, [sp, #64] // 16-byte Folded Reload -; CHECK-NEXT: .seh_save_fplr 64 -; CHECK-NEXT: add sp, sp, #80 -; CHECK-NEXT: .seh_stackalloc 80 +; CHECK-NEXT: ldp x29, x30, [sp, #96] // 16-byte Folded Reload +; CHECK-NEXT: .seh_save_fplr 96 +; CHECK-NEXT: add sp, sp, #112 +; CHECK-NEXT: .seh_stackalloc 112 ; CHECK-NEXT: .seh_endepilogue ; CHECK-NEXT: ret ; CHECK-NEXT: .seh_endfunclet @@ -374,8 +472,8 @@ declare [2 x i8] @small_array([2 x i8], [2 x half], [2 x float]) nounwind; ; CHECK-NEXT: adrp x11, small_array ; CHECK-NEXT: add x11, x11, :lo12:small_array ; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall] -; CHECK-NEXT: adrp x10, $iexit_thunk$cdecl$m2$m2__llvm_H__4F8 -; CHECK-NEXT: add x10, x10, :lo12:$iexit_thunk$cdecl$m2$m2__llvm_H__4F8 +; CHECK-NEXT: adrp x10, $iexit_thunk$cdecl$m2$m2__llvm_H__4__llvm_Q__32F8 +; CHECK-NEXT: add x10, x10, :lo12:$iexit_thunk$cdecl$m2$m2__llvm_H__4__llvm_Q__32F8 ; CHECK-NEXT: blr x8 ; CHECK-NEXT: .seh_startepilogue ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload @@ -661,7 +759,7 @@ declare void @"??@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@"() ; CHECK-NEXT: .symidx simple_integers ; CHECK-NEXT: .word 0 ; CHECK-NEXT: .symidx simple_floats -; CHECK-NEXT: .symidx $iexit_thunk$cdecl$d$__llvm_h__fd +; CHECK-NEXT: .symidx $iexit_thunk$cdecl$d$__llvm_h__fd__llvm_q__ ; CHECK-NEXT: .word 4 ; CHECK-NEXT: .symidx "#simple_floats$exit_thunk" ; CHECK-NEXT: .symidx simple_floats @@ -672,6 +770,18 @@ declare void @"??@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@"() ; CHECK-NEXT: .symidx "#simple_bfloat$exit_thunk" ; CHECK-NEXT: .symidx simple_bfloat ; CHECK-NEXT: .word 0 +; CHECK-NEXT: .symidx return_half +; CHECK-NEXT: .symidx $iexit_thunk$cdecl$__llvm_h__$v +; CHECK-NEXT: .word 4 +; CHECK-NEXT: .symidx "#return_half$exit_thunk" +; CHECK-NEXT: .symidx return_half +; CHECK-NEXT: .word 0 +; CHECK-NEXT: .symidx return_fp128 +; CHECK-NEXT: .symidx $iexit_thunk$cdecl$__llvm_q__$v +; CHECK-NEXT: .word 4 +; CHECK-NEXT: .symidx "#return_fp128$exit_thunk" +; CHECK-NEXT: .symidx return_fp128 +; CHECK-NEXT: .word 0 ; CHECK-NEXT: .symidx has_varargs ; CHECK-NEXT: .symidx $iexit_thunk$cdecl$v$varargs ; CHECK-NEXT: .word 4 @@ -691,7 +801,7 @@ declare void @"??@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@"() ; CHECK-NEXT: .symidx has_aligned_sret ; CHECK-NEXT: .word 0 ; CHECK-NEXT: .symidx small_array -; CHECK-NEXT: .symidx $iexit_thunk$cdecl$m2$m2__llvm_H__4F8 +; CHECK-NEXT: .symidx $iexit_thunk$cdecl$m2$m2__llvm_H__4__llvm_Q__32F8 ; CHECK-NEXT: .word 4 ; CHECK-NEXT: .symidx "#small_array$exit_thunk" ; CHECK-NEXT: .symidx small_array @@ -730,15 +840,17 @@ declare void @"??@md5mangleaaaaaaaaaaaaaaaaaaaaaaa@"() define void @func_caller() nounwind { call void @no_op() call i64 @simple_integers(i8 0, i16 0, i32 0, i64 0) - call double @simple_floats(half 0.0, float 0.0, double 0.0) + call double @simple_floats(half 0.0, float 0.0, double 0.0, fp128 0.0) call bfloat @simple_bfloat(bfloat 0xR0000, bfloat 0xR0000) + call half @return_half() + call fp128 @return_fp128() call void (...) @has_varargs() %c = alloca i8 call void @has_sret(ptr sret([100 x i8]) %c) %aligned = alloca %TSRet, align 32 store %TSRet { i64 0, i64 0 }, ptr %aligned, align 32 call void @has_aligned_sret(ptr align 32 sret(%TSRet) %aligned) - call [2 x i8] @small_array([2 x i8] [i8 0, i8 0], [2 x half] [half 0.0, half 0.0], [2 x float] [float 0.0, float 0.0]) + call [2 x i8] @small_array([2 x i8] [i8 0, i8 0], [2 x half] [half 0.0, half 0.0], [2 x fp128] [fp128 0.0, fp128 0.0], [2 x float] [float 0.0, float 0.0]) 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]]) 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 }) call <4 x i8> @small_vector(<4 x i8> ) diff --git a/llvm/test/CodeGen/Generic/fp128-exp10-libcall.ll b/llvm/test/CodeGen/Generic/fp128-exp10-libcall.ll index 5e97f03c2bc3b..50956b5e93f38 100644 --- a/llvm/test/CodeGen/Generic/fp128-exp10-libcall.ll +++ b/llvm/test/CodeGen/Generic/fp128-exp10-libcall.ll @@ -13,7 +13,10 @@ ; RUN: %if x86-registered-target %{ llc < %s -mtriple=i686-unknown-linux-musl | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} ; RUN: %if x86-registered-target %{ llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} ; RUN: %if x86-registered-target %{ llc < %s -mtriple=x86_64-unknown-linux-musl | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} -; RUN %if x86-registered-target %{ llc < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} + +; FIXME(#144006): Windows-MSVC should also be run but has a ldexp selection failure. +; %if x86-registered-target %{ llc < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} +; %if aarch64-registered-target %{ llc < %s -mtriple=arm64ec-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} ; ERR: error: no libcall available for fexp10 define fp128 @test_exp10(fp128 %a) { diff --git a/llvm/test/CodeGen/Generic/fp128-math-libcalls.ll b/llvm/test/CodeGen/Generic/fp128-math-libcalls.ll index f759c94621381..ed8b9b0789c2e 100644 --- a/llvm/test/CodeGen/Generic/fp128-math-libcalls.ll +++ b/llvm/test/CodeGen/Generic/fp128-math-libcalls.ll @@ -30,10 +30,10 @@ ; RUN: %if x86-registered-target %{ llc < %s -mtriple=i686-unknown-linux-musl | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} ; RUN: %if x86-registered-target %{ llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} ; RUN: %if x86-registered-target %{ llc < %s -mtriple=x86_64-unknown-linux-musl | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %} -; -; FIXME(#144006): Windows-MSVC should also be run but has a ldexp selection -; failure. -; %if x86-registered-target %{ llc < %s -mtriple=x86_64-pc-windows-msvc -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} + +; FIXME(#144006): Windows-MSVC should also be run but has a ldexp selection failure. +; %if x86-registered-target %{ llc < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} +; %if aarch64-registered-target %{ llc < %s -mtriple=arm64ec-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128 %} define fp128 @test_acos(fp128 %a) { ; CHECK-ALL-LABEL: test_acos: