diff --git a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp --- a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp @@ -564,6 +564,10 @@ if (IsWin64CC) { GPRIdx = MFI.CreateFixedObject(GPRSaveSize, -static_cast(GPRSaveSize), false); + if (GPRSaveSize & 15) + // The extra size here, if triggered, will always be 8. + MFI.CreateFixedObject(16 - (GPRSaveSize & 15), + -(int)alignTo(GPRSaveSize, 16), false); } else GPRIdx = MFI.CreateStackObject(GPRSaveSize, Align(8), false); diff --git a/llvm/test/CodeGen/AArch64/win64_vararg2.ll b/llvm/test/CodeGen/AArch64/win64_vararg2.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/win64_vararg2.ll @@ -0,0 +1,87 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=aarch64-pc-win32 | FileCheck %s +; RUN: llc < %s -global-isel -mtriple=aarch64-pc-win32 | FileCheck %s --check-prefix=GISEL + +%"struct.std::__1::integral_constant" = type { i8 } + +; Function Attrs: mustprogress noinline nounwind optnone uwtable +define dso_local noundef i1 @_Z8_fits_inIcjNSt3__114numeric_limitsIcEEEbT0_NS0_17integral_constantIbLb0EEES5_z(i32 noundef %0, i8 %1, i8 %2, ...) { +; CHECK-LABEL: _Z8_fits_inIcjNSt3__114numeric_limitsIcEEEbT0_NS0_17integral_constantIbLb0EEES5_z: +; CHECK: .seh_proc _Z8_fits_inIcjNSt3__114numeric_limitsIcEEEbT0_NS0_17integral_constantIbLb0EEES5_z +; CHECK-NEXT: // %bb.0: +; CHECK-NEXT: sub sp, sp, #80 +; CHECK-NEXT: .seh_stackalloc 80 +; CHECK-NEXT: str x19, [sp, #16] // 8-byte Folded Spill +; CHECK-NEXT: .seh_save_reg x19, 16 +; CHECK-NEXT: str x30, [sp, #24] // 8-byte Folded Spill +; CHECK-NEXT: .seh_save_reg x30, 24 +; CHECK-NEXT: .seh_endprologue +; CHECK-NEXT: mov w19, w0 +; CHECK-NEXT: stp x3, x4, [sp, #40] +; CHECK-NEXT: stp x5, x6, [sp, #56] +; CHECK-NEXT: str x7, [sp, #72] +; CHECK-NEXT: strb w1, [sp, #15] +; CHECK-NEXT: strb w2, [sp, #14] +; CHECK-NEXT: str w0, [sp, #8] +; CHECK-NEXT: bl _ZNSt3__114numeric_limitsIcE3maxB7v180000Ev +; CHECK-NEXT: cmp w19, w0, uxtb +; CHECK-NEXT: cset w0, ls +; CHECK-NEXT: .seh_startepilogue +; CHECK-NEXT: ldr x30, [sp, #24] // 8-byte Folded Reload +; CHECK-NEXT: .seh_save_reg x30, 24 +; CHECK-NEXT: ldr x19, [sp, #16] // 8-byte Folded Reload +; CHECK-NEXT: .seh_save_reg x19, 16 +; CHECK-NEXT: add sp, sp, #80 +; CHECK-NEXT: .seh_stackalloc 80 +; CHECK-NEXT: .seh_endepilogue +; CHECK-NEXT: ret +; CHECK-NEXT: .seh_endfunclet +; CHECK-NEXT: .seh_endproc +; +; GISEL-LABEL: _Z8_fits_inIcjNSt3__114numeric_limitsIcEEEbT0_NS0_17integral_constantIbLb0EEES5_z: +; GISEL: .seh_proc _Z8_fits_inIcjNSt3__114numeric_limitsIcEEEbT0_NS0_17integral_constantIbLb0EEES5_z +; GISEL-NEXT: // %bb.0: +; GISEL-NEXT: sub sp, sp, #80 +; GISEL-NEXT: .seh_stackalloc 80 +; GISEL-NEXT: str x19, [sp, #16] // 8-byte Folded Spill +; GISEL-NEXT: .seh_save_reg x19, 16 +; GISEL-NEXT: str x30, [sp, #24] // 8-byte Folded Spill +; GISEL-NEXT: .seh_save_reg x30, 24 +; GISEL-NEXT: .seh_endprologue +; GISEL-NEXT: stp x3, x4, [sp, #40] +; GISEL-NEXT: mov w19, w0 +; GISEL-NEXT: stp x5, x6, [sp, #56] +; GISEL-NEXT: str w0, [sp, #8] +; GISEL-NEXT: str x7, [sp, #72] +; GISEL-NEXT: strb w1, [sp, #15] +; GISEL-NEXT: strb w2, [sp, #14] +; GISEL-NEXT: bl _ZNSt3__114numeric_limitsIcE3maxB7v180000Ev +; GISEL-NEXT: cmp w19, w0, uxtb +; GISEL-NEXT: cset w0, ls +; GISEL-NEXT: .seh_startepilogue +; GISEL-NEXT: ldr x30, [sp, #24] // 8-byte Folded Reload +; GISEL-NEXT: .seh_save_reg x30, 24 +; GISEL-NEXT: ldr x19, [sp, #16] // 8-byte Folded Reload +; GISEL-NEXT: .seh_save_reg x19, 16 +; GISEL-NEXT: add sp, sp, #80 +; GISEL-NEXT: .seh_stackalloc 80 +; GISEL-NEXT: .seh_endepilogue +; GISEL-NEXT: ret +; GISEL-NEXT: .seh_endfunclet +; GISEL-NEXT: .seh_endproc + %4 = alloca %"struct.std::__1::integral_constant", align 1 + %5 = alloca %"struct.std::__1::integral_constant", align 1 + %6 = alloca i32, align 4 + %7 = getelementptr inbounds %"struct.std::__1::integral_constant", ptr %4, i32 0, i32 0 + store i8 %1, ptr %7, align 1 + %8 = getelementptr inbounds %"struct.std::__1::integral_constant", ptr %5, i32 0, i32 0 + store i8 %2, ptr %8, align 1 + store i32 %0, ptr %6, align 4 + %9 = load i32, ptr %6, align 4 + %10 = call noundef i8 @_ZNSt3__114numeric_limitsIcE3maxB7v180000Ev() + %11 = zext i8 %10 to i32 + %12 = icmp ule i32 %9, %11 + ret i1 %12 +} + +declare dso_local noundef i8 @_ZNSt3__114numeric_limitsIcE3maxB7v180000Ev()