llvm-project/llvm/test/CodeGen/X86/vaargs-win32.ll
Phoebe Wang 2aa732a918 [X86][MS] Fix the wrong alignment of vector variable arguments on Win32
D108887 fixed alignment mismatch by changing the caller's alignment in
ABI. However, we found some cases that still assume the alignment is
vector size. This patch fixes them to avoid the runtime crash.

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D114536
2022-02-13 10:23:18 +08:00

105 lines
3.6 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --no_x86_scrub_sp --no_x86_scrub_mem_shuffle
; RUN: llc -mcpu=generic -mtriple=i686-pc-windows-msvc -mattr=+sse2 < %s | FileCheck %s --check-prefix=MSVC
; RUN: llc -mcpu=generic -mtriple=i686-pc-mingw32 -mattr=+sse2 < %s | FileCheck %s --check-prefix=MINGW
@a = external dso_local global <4 x float>, align 16
define dso_local void @testPastArguments() nounwind {
; MSVC-LABEL: testPastArguments:
; MSVC: # %bb.0: # %entry
; MSVC-NEXT: subl $20, %esp
; MSVC-NEXT: movaps _a, %xmm0
; MSVC-NEXT: movups %xmm0, 4(%esp)
; MSVC-NEXT: movl $1, (%esp)
; MSVC-NEXT: calll _testm128
; MSVC-NEXT: addl $20, %esp
; MSVC-NEXT: retl
;
; MINGW-LABEL: testPastArguments:
; MINGW: # %bb.0: # %entry
; MINGW-NEXT: pushl %ebp
; MINGW-NEXT: movl %esp, %ebp
; MINGW-NEXT: andl $-16, %esp
; MINGW-NEXT: subl $48, %esp
; MINGW-NEXT: movaps _a, %xmm0
; MINGW-NEXT: movaps %xmm0, 16(%esp)
; MINGW-NEXT: movl $1, (%esp)
; MINGW-NEXT: calll _testm128
; MINGW-NEXT: movl %ebp, %esp
; MINGW-NEXT: popl %ebp
; MINGW-NEXT: retl
entry:
%0 = load <4 x float>, <4 x float>* @a, align 16
%call = tail call i32 (i32, ...) @testm128(i32 1, <4 x float> inreg %0)
ret void
}
define <4 x i32> @foo(<4 x float> inreg %0, ...) nounwind {
; MSVC-LABEL: foo:
; MSVC: # %bb.0:
; MSVC-NEXT: pushl %eax
; MSVC-NEXT: movups 8(%esp), %xmm0
; MSVC-NEXT: movups 24(%esp), %xmm1
; MSVC-NEXT: cmpltps %xmm1, %xmm0
; MSVC-NEXT: popl %eax
; MSVC-NEXT: retl
;
; MINGW-LABEL: foo:
; MINGW: # %bb.0:
; MINGW-NEXT: pushl %ebp
; MINGW-NEXT: movl %esp, %ebp
; MINGW-NEXT: andl $-16, %esp
; MINGW-NEXT: subl $16, %esp
; MINGW-NEXT: movaps 8(%ebp), %xmm0
; MINGW-NEXT: movups 24(%ebp), %xmm1
; MINGW-NEXT: cmpltps %xmm1, %xmm0
; MINGW-NEXT: movl %ebp, %esp
; MINGW-NEXT: popl %ebp
; MINGW-NEXT: retl
%2 = alloca <4 x float>*, align 4
%3 = bitcast <4 x float>** %2 to i8*
call void @llvm.lifetime.start.p0i8(i64 4, i8* %3)
call void @llvm.va_start(i8* %3)
%4 = load <4 x float>*, <4 x float>** %2, align 4
%5 = load <4 x float>, <4 x float>* %4, align 4
%6 = fcmp ogt <4 x float> %5, %0
%7 = sext <4 x i1> %6 to <4 x i32>
call void @llvm.lifetime.end.p0i8(i64 4, i8* %3)
ret <4 x i32> %7
}
define <4 x i32> @bar() nounwind {
; MSVC-LABEL: bar:
; MSVC: # %bb.0:
; MSVC-NEXT: subl $32, %esp
; MSVC-NEXT: movaps {{.*#+}} xmm0 = [5.0E+0,6.0E+0,7.0E+0,8.0E+0]
; MSVC-NEXT: movups %xmm0, 16(%esp)
; MSVC-NEXT: movaps {{.*#+}} xmm0 = [1.0E+0,2.0E+0,3.0E+0,4.0E+0]
; MSVC-NEXT: movups %xmm0, (%esp)
; MSVC-NEXT: calll _foo
; MSVC-NEXT: addl $32, %esp
; MSVC-NEXT: retl
;
; MINGW-LABEL: bar:
; MINGW: # %bb.0:
; MINGW-NEXT: pushl %ebp
; MINGW-NEXT: movl %esp, %ebp
; MINGW-NEXT: andl $-16, %esp
; MINGW-NEXT: subl $48, %esp
; MINGW-NEXT: movaps {{.*#+}} xmm0 = [5.0E+0,6.0E+0,7.0E+0,8.0E+0]
; MINGW-NEXT: movaps %xmm0, 16(%esp)
; MINGW-NEXT: movaps {{.*#+}} xmm0 = [1.0E+0,2.0E+0,3.0E+0,4.0E+0]
; MINGW-NEXT: movaps %xmm0, (%esp)
; MINGW-NEXT: calll _foo
; MINGW-NEXT: movl %ebp, %esp
; MINGW-NEXT: popl %ebp
; MINGW-NEXT: retl
%1 = tail call <4 x i32> (<4 x float>, ...) @foo(<4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00>, <4 x float> <float 5.000000e+00, float 6.000000e+00, float 7.000000e+00, float 8.000000e+00>)
ret <4 x i32> %1
}
declare i32 @testm128(i32, ...) nounwind
declare void @llvm.va_start(i8*)
declare void @llvm.lifetime.start.p0i8(i64, i8*)
declare void @llvm.lifetime.end.p0i8(i64, i8*)