Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

[X86] Fix Windows i1 zeroext conventions to use i8 instead of i32 #119

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions lib/Target/X86/X86CallingConv.td
Original file line number Diff line number Diff line change
Expand Up @@ -586,8 +586,8 @@ def CC_X86_Win64_C : CallingConv<[
// FIXME: Handle byval stuff.
// FIXME: Handle varargs.

// Promote i1/i8/i16/v1i1 arguments to i32.
CCIfType<[i1, i8, i16, v1i1], CCPromoteToType<i32>>,
// Promote i1/v1i1 arguments to i8.
CCIfType<[i1, v1i1], CCPromoteToType<i8>>,

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

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

Expand All @@ -628,7 +632,7 @@ def CC_X86_Win64_C : CallingConv<[

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

// Long doubles get stack slots whose size and alignment depends on the
// subtarget.
Expand Down Expand Up @@ -841,13 +845,15 @@ def CC_X86_32_MCU : CallingConv<[
]>;

def CC_X86_32_FastCall : CallingConv<[
// Promote i1/i8/i16/v1i1 arguments to i32.
CCIfType<[i1, i8, i16, v1i1], CCPromoteToType<i32>>,
// Promote i1 to i8.
CCIfType<[i1], CCPromoteToType<i8>>,

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

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

// Otherwise, same as everything else.
Expand Down
6 changes: 5 additions & 1 deletion lib/Target/X86/X86ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2993,7 +2993,11 @@ SDValue X86TargetLowering::LowerFormalArguments(
getv64i1Argument(VA, ArgLocs[++I], Chain, DAG, dl, Subtarget);
} else {
const TargetRegisterClass *RC;
if (RegVT == MVT::i32)
if (RegVT == MVT::i8)
RC = &X86::GR8RegClass;
else if (RegVT == MVT::i16)
RC = &X86::GR16RegClass;
else if (RegVT == MVT::i32)
RC = &X86::GR32RegClass;
else if (Is64Bit && RegVT == MVT::i64)
RC = &X86::GR64RegClass;
Expand Down
67 changes: 67 additions & 0 deletions test/CodeGen/X86/win-smallparams.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
; When we accept small parameters on Windows, make sure we do not assume they
; are zero or sign extended in memory or in registers.

; RUN: llc < %s -mtriple=x86_64-windows-msvc | FileCheck %s --check-prefix=WIN64
; RUN: llc < %s -mtriple=x86_64-windows-gnu | FileCheck %s --check-prefix=WIN64
; RUN: llc < %s -mtriple=i686-windows-msvc | FileCheck %s --check-prefix=WIN32
; RUN: llc < %s -mtriple=i686-windows-gnu | FileCheck %s --check-prefix=WIN32

define void @call() {
entry:
%rv = call i32 @manyargs(i8 1, i16 2, i8 3, i16 4, i8 5, i16 6)
ret void
}

define i32 @manyargs(i8 %a, i16 %b, i8 %c, i16 %d, i8 %e, i16 %f) {
entry:
%aa = sext i8 %a to i32
%bb = sext i16 %b to i32
%cc = zext i8 %c to i32
%dd = zext i16 %d to i32
%ee = zext i8 %e to i32
%ff = zext i16 %f to i32
%t0 = add i32 %aa, %bb
%t1 = add i32 %t0, %cc
%t2 = add i32 %t1, %dd
%t3 = add i32 %t2, %ee
%t4 = add i32 %t3, %ff
ret i32 %t4
}

; WIN64-LABEL: call:
; WIN64-DAG: movw $6, 40(%rsp)
; WIN64-DAG: movb $5, 32(%rsp)
; WIN64-DAG: movb $1, %cl
; WIN64-DAG: movw $2, %dx
; WIN64-DAG: movb $3, %r8b
; WIN64-DAG: movw $4, %r9w
; WIN64: callq manyargs

; WIN64-LABEL: manyargs:
; WIN64-DAG: movsbl %cl,
; WIN64-DAG: movswl %dx,
; WIN64-DAG: movzbl %r8b,
; WIN64-DAG: movzwl %r9w,
; WIN64-DAG: movzbl 40(%rsp),
; WIN64-DAG: movzwl 48(%rsp),
; WIN64: retq


; WIN32-LABEL: _call:
; WIN32: pushl $6
; WIN32: pushl $5
; WIN32: pushl $4
; WIN32: pushl $3
; WIN32: pushl $2
; WIN32: pushl $1
; WIN32: calll _manyargs

; WIN32-LABEL: _manyargs:
; WIN32-DAG: movsbl 4(%esp),
; WIN32-DAG: movswl 8(%esp),
; WIN32-DAG: movzbl 12(%esp),
; WIN32-DAG: movzwl 16(%esp),
; WIN32-DAG: movzbl 20(%esp),
; WIN32-DAG: movzwl 24(%esp),
; WIN32: retl

33 changes: 33 additions & 0 deletions test/CodeGen/X86/win32-bool.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
; RUN: llc < %s -mtriple=i686-windows-msvc | FileCheck %s
; RUN: llc < %s -mtriple=i686-windows-gnu | FileCheck %s

define x86_fastcallcc i32 @pass_fast_bool(i1 inreg zeroext %b) {
entry:
%cond = select i1 %b, i32 66, i32 0
ret i32 %cond
}

; CHECK-LABEL: @pass_fast_bool@4:
; CHECK-DAG: testb %cl, %cl
; CHECK-DAG: movl $66,
; CHECK: retl

define x86_vectorcallcc i32 @pass_vector_bool(i1 inreg zeroext %b) {
entry:
%cond = select i1 %b, i32 66, i32 0
ret i32 %cond
}

; CHECK-LABEL: pass_vector_bool@@4:
; CHECK-DAG: testb %cl, %cl
; CHECK-DAG: movl $66,
; CHECK: retl

define zeroext i1 @ret_true() {
entry:
ret i1 true
}

; CHECK-LABEL: ret_true:
; CHECK: movb $1, %al
; CHECK: retl
23 changes: 23 additions & 0 deletions test/CodeGen/X86/win64-bool.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
; RUN: llc < %s -mtriple=x86_64-windows-msvc | FileCheck %s --check-prefix=CHECK
; RUN: llc < %s -mtriple=x86_64-windows-gnu | FileCheck %s --check-prefix=CHECK

define i32 @pass_bool(i1 zeroext %b) {
entry:
%cond = select i1 %b, i32 66, i32 0
ret i32 %cond
}

; CHECK-LABEL: pass_bool:
; CHECK-DAG: testb %cl, %cl
; CHECK-DAG: movl $66,
; CHECK: cmovel {{.*}}, %eax
; CHECK: retq

define zeroext i1 @ret_true() {
entry:
ret i1 true
}

; CHECK-LABEL: ret_true:
; CHECK: movb $1, %al
; CHECK: retq