Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit ff1d4d2

Browse files
committed
[X86] Fix Windows i1 zeroext conventions to use i8 instead of i32
Summary: Re-lands r328386 and r328443, reverting r328482. Incorporates fixes from @mstorsjo in D44876 (thanks!) so that small parameters in i8 and i16 do not end up in the SysV register parameters (EDI, ESI, etc). I added tests for how we receive small parameters, since that is the important part. It's always safe to store more bytes than will be read, but the assumptions you make when loading them are what really matter. I also tested this by self-hosting clang and it passed tests on win64. Reviewers: mstorsjo, hans Subscribers: hiraditya, mstorsjo, llvm-commits Differential Revision: https://reviews.llvm.org/D44900 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@328570 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 33b38a2 commit ff1d4d2

File tree

10 files changed

+159
-8
lines changed

10 files changed

+159
-8
lines changed

lib/Target/X86/X86CallingConv.td

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -593,8 +593,8 @@ def CC_X86_Win64_C : CallingConv<[
593593
// FIXME: Handle byval stuff.
594594
// FIXME: Handle varargs.
595595

596-
// Promote i1/i8/i16/v1i1 arguments to i32.
597-
CCIfType<[i1, i8, i16, v1i1], CCPromoteToType<i32>>,
596+
// Promote i1/v1i1 arguments to i8.
597+
CCIfType<[i1, v1i1], CCPromoteToType<i8>>,
598598

599599
// The 'nest' parameter, if any, is passed in R10.
600600
CCIfNest<CCAssignToReg<[R10]>>,
@@ -619,6 +619,10 @@ def CC_X86_Win64_C : CallingConv<[
619619
CCIfType<[x86mmx], CCBitConvertToType<i64>>,
620620

621621
// The first 4 integer arguments are passed in integer registers.
622+
CCIfType<[i8 ], CCAssignToRegWithShadow<[CL , DL , R8B , R9B ],
623+
[XMM0, XMM1, XMM2, XMM3]>>,
624+
CCIfType<[i16], CCAssignToRegWithShadow<[CX , DX , R8W , R9W ],
625+
[XMM0, XMM1, XMM2, XMM3]>>,
622626
CCIfType<[i32], CCAssignToRegWithShadow<[ECX , EDX , R8D , R9D ],
623627
[XMM0, XMM1, XMM2, XMM3]>>,
624628

@@ -638,7 +642,7 @@ def CC_X86_Win64_C : CallingConv<[
638642

639643
// Integer/FP values get stored in stack slots that are 8 bytes in size and
640644
// 8-byte aligned if there are no more registers to hold them.
641-
CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 8>>
645+
CCIfType<[i8, i16, i32, i64, f32, f64], CCAssignToStack<8, 8>>
642646
]>;
643647

644648
def CC_X86_Win64_VectorCall : CallingConv<[
@@ -847,13 +851,15 @@ def CC_X86_32_MCU : CallingConv<[
847851
]>;
848852

849853
def CC_X86_32_FastCall : CallingConv<[
850-
// Promote i1/i8/i16/v1i1 arguments to i32.
851-
CCIfType<[i1, i8, i16, v1i1], CCPromoteToType<i32>>,
854+
// Promote i1 to i8.
855+
CCIfType<[i1], CCPromoteToType<i8>>,
852856

853857
// The 'nest' parameter, if any, is passed in EAX.
854858
CCIfNest<CCAssignToReg<[EAX]>>,
855859

856860
// The first 2 integer arguments are passed in ECX/EDX
861+
CCIfInReg<CCIfType<[ i8], CCAssignToReg<[ CL, DL]>>>,
862+
CCIfInReg<CCIfType<[i16], CCAssignToReg<[ CX, DX]>>>,
857863
CCIfInReg<CCIfType<[i32], CCAssignToReg<[ECX, EDX]>>>,
858864

859865
// Otherwise, same as everything else.

lib/Target/X86/X86ISelLowering.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3034,7 +3034,11 @@ SDValue X86TargetLowering::LowerFormalArguments(
30343034
getv64i1Argument(VA, ArgLocs[++I], Chain, DAG, dl, Subtarget);
30353035
} else {
30363036
const TargetRegisterClass *RC;
3037-
if (RegVT == MVT::i32)
3037+
if (RegVT == MVT::i8)
3038+
RC = &X86::GR8RegClass;
3039+
else if (RegVT == MVT::i16)
3040+
RC = &X86::GR16RegClass;
3041+
else if (RegVT == MVT::i32)
30383042
RC = &X86::GR32RegClass;
30393043
else if (Is64Bit && RegVT == MVT::i64)
30403044
RC = &X86::GR64RegClass;

test/CodeGen/X86/avx512-intel-ocl.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ define <16 x float> @testf16_inp_mask(<16 x float> %a, i16 %mask) {
420420
; WIN64-KNL-NEXT: subq $40, %rsp
421421
; WIN64-KNL-NEXT: .seh_stackalloc 40
422422
; WIN64-KNL-NEXT: .seh_endprologue
423+
; WIN64-KNL-NEXT: # kill: def $dx killed $dx def $edx
423424
; WIN64-KNL-NEXT: vmovaps (%rcx), %zmm0
424425
; WIN64-KNL-NEXT: kmovw %edx, %k1
425426
; WIN64-KNL-NEXT: callq func_float16_mask
@@ -435,6 +436,7 @@ define <16 x float> @testf16_inp_mask(<16 x float> %a, i16 %mask) {
435436
; WIN64-SKX-NEXT: subq $40, %rsp
436437
; WIN64-SKX-NEXT: .seh_stackalloc 40
437438
; WIN64-SKX-NEXT: .seh_endprologue
439+
; WIN64-SKX-NEXT: # kill: def $dx killed $dx def $edx
438440
; WIN64-SKX-NEXT: vmovaps (%rcx), %zmm0
439441
; WIN64-SKX-NEXT: kmovd %edx, %k1
440442
; WIN64-SKX-NEXT: callq func_float16_mask

test/CodeGen/X86/h-registers-0.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ define i16 @qux16(i16 inreg %x) nounwind {
9898
; X86-64: movzbl %ah, %eax
9999

100100
; WIN64-LABEL: qux16:
101-
; WIN64: movzbl %ch, %eax
101+
; WIN64: movzwl %cx, %eax
102+
; WIN64: shrl $8, %eax
102103

103104
; X86-32-LABEL: qux16:
104105
; X86-32: movzbl %ah, %eax

test/CodeGen/X86/test-shrink.ll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ define void @g16xh(i16 inreg %x) nounwind {
186186
; CHECK-WIN32-64-LABEL: g16xh:
187187
; CHECK-WIN32-64: # %bb.0:
188188
; CHECK-WIN32-64-NEXT: subq $40, %rsp
189+
; CHECK-WIN32-64-NEXT: # kill: def $cx killed $cx def $ecx
189190
; CHECK-WIN32-64-NEXT: testl $2048, %ecx # imm = 0x800
190191
; CHECK-WIN32-64-NEXT: jne .LBB4_2
191192
; CHECK-WIN32-64-NEXT: # %bb.1: # %yes
@@ -228,6 +229,7 @@ define void @g16xl(i16 inreg %x) nounwind {
228229
; CHECK-WIN32-64-LABEL: g16xl:
229230
; CHECK-WIN32-64: # %bb.0:
230231
; CHECK-WIN32-64-NEXT: subq $40, %rsp
232+
; CHECK-WIN32-64-NEXT: # kill: def $cx killed $cx def $ecx
231233
; CHECK-WIN32-64-NEXT: testb $8, %cl
232234
; CHECK-WIN32-64-NEXT: jne .LBB5_2
233235
; CHECK-WIN32-64-NEXT: # %bb.1: # %yes
@@ -497,6 +499,7 @@ define void @truncand32(i16 inreg %x) nounwind {
497499
; CHECK-WIN32-64-LABEL: truncand32:
498500
; CHECK-WIN32-64: # %bb.0:
499501
; CHECK-WIN32-64-NEXT: subq $40, %rsp
502+
; CHECK-WIN32-64-NEXT: # kill: def $cx killed $cx def $ecx
500503
; CHECK-WIN32-64-NEXT: testl $2049, %ecx # imm = 0x801
501504
; CHECK-WIN32-64-NEXT: je .LBB11_1
502505
; CHECK-WIN32-64-NEXT: # %bb.2: # %no
@@ -543,6 +546,7 @@ define void @testw(i16 inreg %x) nounwind minsize {
543546
; CHECK-WIN32-64-LABEL: testw:
544547
; CHECK-WIN32-64: # %bb.0:
545548
; CHECK-WIN32-64-NEXT: subq $40, %rsp
549+
; CHECK-WIN32-64-NEXT: # kill: def $cx killed $cx def $ecx
546550
; CHECK-WIN32-64-NEXT: testw $2049, %cx # imm = 0x801
547551
; CHECK-WIN32-64-NEXT: jne .LBB12_2
548552
; CHECK-WIN32-64-NEXT: # %bb.1: # %yes

test/CodeGen/X86/vec_cast.ll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ define <3 x i32> @b(<3 x i16> %a) nounwind {
3737
;
3838
; CHECK-WIN-LABEL: b:
3939
; CHECK-WIN: # %bb.0:
40+
; CHECK-WIN-NEXT: # kill: def $r8w killed $r8w def $r8d
41+
; CHECK-WIN-NEXT: # kill: def $dx killed $dx def $edx
42+
; CHECK-WIN-NEXT: # kill: def $cx killed $cx def $ecx
4043
; CHECK-WIN-NEXT: movd %ecx, %xmm0
4144
; CHECK-WIN-NEXT: pinsrw $1, %edx, %xmm0
4245
; CHECK-WIN-NEXT: pinsrw $2, %r8d, %xmm0
@@ -58,6 +61,7 @@ define <1 x i32> @c(<1 x i16> %a) nounwind {
5861
;
5962
; CHECK-WIN-LABEL: c:
6063
; CHECK-WIN: # %bb.0:
64+
; CHECK-WIN-NEXT: # kill: def $cx killed $cx def $ecx
6165
; CHECK-WIN-NEXT: movd %ecx, %xmm0
6266
; CHECK-WIN-NEXT: pshuflw {{.*#+}} xmm0 = xmm0[0,0,2,1,4,5,6,7]
6367
; CHECK-WIN-NEXT: psrad $16, %xmm0
@@ -100,6 +104,9 @@ define <3 x i32> @e(<3 x i16> %a) nounwind {
100104
;
101105
; CHECK-WIN-LABEL: e:
102106
; CHECK-WIN: # %bb.0:
107+
; CHECK-WIN-NEXT: # kill: def $r8w killed $r8w def $r8d
108+
; CHECK-WIN-NEXT: # kill: def $dx killed $dx def $edx
109+
; CHECK-WIN-NEXT: # kill: def $cx killed $cx def $ecx
103110
; CHECK-WIN-NEXT: movd %ecx, %xmm0
104111
; CHECK-WIN-NEXT: pinsrw $1, %edx, %xmm0
105112
; CHECK-WIN-NEXT: pinsrw $2, %r8d, %xmm0
@@ -121,6 +128,7 @@ define <1 x i32> @f(<1 x i16> %a) nounwind {
121128
;
122129
; CHECK-WIN-LABEL: f:
123130
; CHECK-WIN: # %bb.0:
131+
; CHECK-WIN-NEXT: # kill: def $cx killed $cx def $ecx
124132
; CHECK-WIN-NEXT: movd %ecx, %xmm0
125133
; CHECK-WIN-NEXT: pxor %xmm1, %xmm1
126134
; CHECK-WIN-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]

test/CodeGen/X86/win-smallparams.ll

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
; When we accept small parameters on Windows, make sure we do not assume they
2+
; are zero or sign extended in memory or in registers.
3+
4+
; RUN: llc < %s -mtriple=x86_64-windows-msvc | FileCheck %s --check-prefix=WIN64
5+
; RUN: llc < %s -mtriple=x86_64-windows-gnu | FileCheck %s --check-prefix=WIN64
6+
; RUN: llc < %s -mtriple=i686-windows-msvc | FileCheck %s --check-prefix=WIN32
7+
; RUN: llc < %s -mtriple=i686-windows-gnu | FileCheck %s --check-prefix=WIN32
8+
9+
define void @call() {
10+
entry:
11+
%rv = call i32 @manyargs(i8 1, i16 2, i8 3, i16 4, i8 5, i16 6)
12+
ret void
13+
}
14+
15+
define i32 @manyargs(i8 %a, i16 %b, i8 %c, i16 %d, i8 %e, i16 %f) {
16+
entry:
17+
%aa = sext i8 %a to i32
18+
%bb = sext i16 %b to i32
19+
%cc = zext i8 %c to i32
20+
%dd = zext i16 %d to i32
21+
%ee = zext i8 %e to i32
22+
%ff = zext i16 %f to i32
23+
%t0 = add i32 %aa, %bb
24+
%t1 = add i32 %t0, %cc
25+
%t2 = add i32 %t1, %dd
26+
%t3 = add i32 %t2, %ee
27+
%t4 = add i32 %t3, %ff
28+
ret i32 %t4
29+
}
30+
31+
; WIN64-LABEL: call:
32+
; WIN64-DAG: movw $6, 40(%rsp)
33+
; WIN64-DAG: movb $5, 32(%rsp)
34+
; WIN64-DAG: movb $1, %cl
35+
; WIN64-DAG: movw $2, %dx
36+
; WIN64-DAG: movb $3, %r8b
37+
; WIN64-DAG: movw $4, %r9w
38+
; WIN64: callq manyargs
39+
40+
; WIN64-LABEL: manyargs:
41+
; WIN64-DAG: movsbl %cl,
42+
; WIN64-DAG: movswl %dx,
43+
; WIN64-DAG: movzbl %r8b,
44+
; WIN64-DAG: movzwl %r9w,
45+
; WIN64-DAG: movzbl 40(%rsp),
46+
; WIN64-DAG: movzwl 48(%rsp),
47+
; WIN64: retq
48+
49+
50+
; WIN32-LABEL: _call:
51+
; WIN32: pushl $6
52+
; WIN32: pushl $5
53+
; WIN32: pushl $4
54+
; WIN32: pushl $3
55+
; WIN32: pushl $2
56+
; WIN32: pushl $1
57+
; WIN32: calll _manyargs
58+
59+
; WIN32-LABEL: _manyargs:
60+
; WIN32-DAG: movsbl 4(%esp),
61+
; WIN32-DAG: movswl 8(%esp),
62+
; WIN32-DAG: movzbl 12(%esp),
63+
; WIN32-DAG: movzwl 16(%esp),
64+
; WIN32-DAG: movzbl 20(%esp),
65+
; WIN32-DAG: movzwl 24(%esp),
66+
; WIN32: retl
67+

test/CodeGen/X86/win32-bool.ll

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
; RUN: llc < %s -mtriple=i686-windows-msvc | FileCheck %s
2+
; RUN: llc < %s -mtriple=i686-windows-gnu | FileCheck %s
3+
4+
define x86_fastcallcc i32 @pass_fast_bool(i1 inreg zeroext %b) {
5+
entry:
6+
%cond = select i1 %b, i32 66, i32 0
7+
ret i32 %cond
8+
}
9+
10+
; CHECK-LABEL: @pass_fast_bool@4:
11+
; CHECK-DAG: testb %cl, %cl
12+
; CHECK-DAG: movl $66,
13+
; CHECK: retl
14+
15+
define x86_vectorcallcc i32 @pass_vector_bool(i1 inreg zeroext %b) {
16+
entry:
17+
%cond = select i1 %b, i32 66, i32 0
18+
ret i32 %cond
19+
}
20+
21+
; CHECK-LABEL: pass_vector_bool@@4:
22+
; CHECK-DAG: testb %cl, %cl
23+
; CHECK-DAG: movl $66,
24+
; CHECK: retl
25+
26+
define zeroext i1 @ret_true() {
27+
entry:
28+
ret i1 true
29+
}
30+
31+
; CHECK-LABEL: ret_true:
32+
; CHECK: movb $1, %al
33+
; CHECK: retl

test/CodeGen/X86/win64-bool.ll

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
; RUN: llc < %s -mtriple=x86_64-windows-msvc | FileCheck %s --check-prefix=CHECK
2+
; RUN: llc < %s -mtriple=x86_64-windows-gnu | FileCheck %s --check-prefix=CHECK
3+
4+
define i32 @pass_bool(i1 zeroext %b) {
5+
entry:
6+
%cond = select i1 %b, i32 66, i32 0
7+
ret i32 %cond
8+
}
9+
10+
; CHECK-LABEL: pass_bool:
11+
; CHECK-DAG: testb %cl, %cl
12+
; CHECK-DAG: movl $66,
13+
; CHECK: cmovel {{.*}}, %eax
14+
; CHECK: retq
15+
16+
define zeroext i1 @ret_true() {
17+
entry:
18+
ret i1 true
19+
}
20+
21+
; CHECK-LABEL: ret_true:
22+
; CHECK: movb $1, %al
23+
; CHECK: retq

test/CodeGen/X86/xor.ll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ define i16 @test5(i16 %a, i16 %b) nounwind {
167167
;
168168
; X64-WIN-LABEL: test5:
169169
; X64-WIN: # %bb.0: # %entry
170+
; X64-WIN-NEXT: # kill: def $dx killed $dx def $edx
171+
; X64-WIN-NEXT: # kill: def $cx killed $cx def $ecx
170172
; X64-WIN-NEXT: .p2align 4, 0x90
171173
; X64-WIN-NEXT: .LBB4_1: # %bb
172174
; X64-WIN-NEXT: # =>This Inner Loop Header: Depth=1
@@ -427,7 +429,8 @@ define i32 @PR17487(i1 %tobool) {
427429
;
428430
; X64-WIN-LABEL: PR17487:
429431
; X64-WIN: # %bb.0:
430-
; X64-WIN-NEXT: movd %ecx, %xmm0
432+
; X64-WIN-NEXT: movzbl %cl, %eax
433+
; X64-WIN-NEXT: movd %eax, %xmm0
431434
; X64-WIN-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
432435
; X64-WIN-NEXT: pandn __xmm@{{.*}}(%rip), %xmm0
433436
; X64-WIN-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]

0 commit comments

Comments
 (0)