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

Commit

Permalink
Merge pull request #119 from glandium/rust-llvm-release-6-0-0
Browse files Browse the repository at this point in the history
[X86] Fix Windows `i1 zeroext` conventions to use i8 instead of i32
  • Loading branch information
alexcrichton committed Jun 29, 2018
2 parents 7a5f6ca + 4ee8485 commit 1c817c7
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 6 deletions.
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

0 comments on commit 1c817c7

Please sign in to comment.