mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
OpaquePtr: Require byval on x86_intrcc parameter 0
Currently the backend special cases x86_intrcc and treats the first parameter as byval. Make the IR require byval for this parameter to remove this special case, and avoid the dependence on the pointee element type. Fixes bug 46672. I'm not sure the IR is enforcing all the calling convention constraints. clang seems to ignore the attribute for empty parameter lists, but the IR tolerates it.
This commit is contained in:
parent
2bd2c2e5a1
commit
4c16866a59
@ -9846,14 +9846,6 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Type *ArgMemTy = nullptr;
|
Type *ArgMemTy = nullptr;
|
||||||
if (F.getCallingConv() == CallingConv::X86_INTR) {
|
|
||||||
// IA Interrupt passes frame (1st parameter) by value in the stack.
|
|
||||||
if (ArgNo == 0) {
|
|
||||||
Flags.setByVal();
|
|
||||||
// FIXME: Dependence on pointee element type. See bug 46672.
|
|
||||||
ArgMemTy = Arg.getType()->getPointerElementType();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Flags.isByVal() || Flags.isInAlloca() || Flags.isPreallocated() ||
|
if (Flags.isByVal() || Flags.isInAlloca() || Flags.isPreallocated() ||
|
||||||
Flags.isByRef()) {
|
Flags.isByRef()) {
|
||||||
if (!ArgMemTy)
|
if (!ArgMemTy)
|
||||||
|
@ -4315,6 +4315,13 @@ void llvm::UpgradeFunctionAttributes(Function &F) {
|
|||||||
StrictFPUpgradeVisitor SFPV;
|
StrictFPUpgradeVisitor SFPV;
|
||||||
SFPV.visit(F);
|
SFPV.visit(F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (F.getCallingConv() == CallingConv::X86_INTR &&
|
||||||
|
!F.arg_empty() && !F.hasParamAttribute(0, Attribute::ByVal)) {
|
||||||
|
Type *ByValTy = cast<PointerType>(F.getArg(0)->getType())->getElementType();
|
||||||
|
Attribute NewAttr = Attribute::getWithByValType(F.getContext(), ByValTy);
|
||||||
|
F.addParamAttr(0, NewAttr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isOldLoopArgument(Metadata *MD) {
|
static bool isOldLoopArgument(Metadata *MD) {
|
||||||
|
@ -2327,6 +2327,11 @@ void Verifier::visitFunction(const Function &F) {
|
|||||||
default:
|
default:
|
||||||
case CallingConv::C:
|
case CallingConv::C:
|
||||||
break;
|
break;
|
||||||
|
case CallingConv::X86_INTR: {
|
||||||
|
Assert(F.arg_empty() || Attrs.hasParamAttribute(0, Attribute::ByVal),
|
||||||
|
"Calling convention parameter requires byval", &F);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CallingConv::AMDGPU_KERNEL:
|
case CallingConv::AMDGPU_KERNEL:
|
||||||
case CallingConv::SPIR_KERNEL:
|
case CallingConv::SPIR_KERNEL:
|
||||||
Assert(F.getReturnType()->isVoidTy(),
|
Assert(F.getReturnType()->isVoidTy(),
|
||||||
|
13
test/Assembler/x86_intrcc.ll
Normal file
13
test/Assembler/x86_intrcc.ll
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
|
||||||
|
; RUN: verify-uselistorder %s
|
||||||
|
|
||||||
|
; Make sure no arguments is accepted
|
||||||
|
; CHECK: define x86_intrcc void @no_args() {
|
||||||
|
define x86_intrcc void @no_args() {
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK: define x86_intrcc void @byval_arg(i32* byval(i32) %0) {
|
||||||
|
define x86_intrcc void @byval_arg(i32* byval(i32)) {
|
||||||
|
ret void
|
||||||
|
}
|
BIN
test/Bitcode/Inputs/x86_intrcc_upgrade.bc
Normal file
BIN
test/Bitcode/Inputs/x86_intrcc_upgrade.bc
Normal file
Binary file not shown.
@ -436,7 +436,7 @@ declare cc82 void @f.cc82()
|
|||||||
; CHECK: declare hhvm_ccc void @f.cc82()
|
; CHECK: declare hhvm_ccc void @f.cc82()
|
||||||
declare hhvm_ccc void @f.hhvm_ccc()
|
declare hhvm_ccc void @f.hhvm_ccc()
|
||||||
; CHECK: declare hhvm_ccc void @f.hhvm_ccc()
|
; CHECK: declare hhvm_ccc void @f.hhvm_ccc()
|
||||||
declare cc83 void @f.cc83()
|
declare cc83 void @f.cc83(i8* byval(i8))
|
||||||
; CHECK: declare x86_intrcc void @f.cc83()
|
; CHECK: declare x86_intrcc void @f.cc83()
|
||||||
declare x86_intrcc void @f.x86_intrcc()
|
declare x86_intrcc void @f.x86_intrcc()
|
||||||
; CHECK: declare x86_intrcc void @f.x86_intrcc()
|
; CHECK: declare x86_intrcc void @f.x86_intrcc()
|
||||||
|
@ -450,10 +450,10 @@ declare cc82 void @f.cc82()
|
|||||||
; CHECK: declare hhvm_ccc void @f.cc82()
|
; CHECK: declare hhvm_ccc void @f.cc82()
|
||||||
declare hhvm_ccc void @f.hhvm_ccc()
|
declare hhvm_ccc void @f.hhvm_ccc()
|
||||||
; CHECK: declare hhvm_ccc void @f.hhvm_ccc()
|
; CHECK: declare hhvm_ccc void @f.hhvm_ccc()
|
||||||
declare cc83 void @f.cc83()
|
declare cc83 void @f.cc83(i8* byval(i8))
|
||||||
; CHECK: declare x86_intrcc void @f.cc83()
|
; CHECK: declare x86_intrcc void @f.cc83(i8* byval(i8))
|
||||||
declare x86_intrcc void @f.x86_intrcc()
|
declare x86_intrcc void @f.x86_intrcc(i8* byval(i8))
|
||||||
; CHECK: declare x86_intrcc void @f.x86_intrcc()
|
; CHECK: declare x86_intrcc void @f.x86_intrcc(i8* byval(i8))
|
||||||
declare cc84 void @f.cc84()
|
declare cc84 void @f.cc84()
|
||||||
; CHECK: declare avr_intrcc void @f.cc84()
|
; CHECK: declare avr_intrcc void @f.cc84()
|
||||||
declare avr_intrcc void @f.avr_intrcc()
|
declare avr_intrcc void @f.avr_intrcc()
|
||||||
|
11
test/Bitcode/x86_intr-upgrade.test
Normal file
11
test/Bitcode/x86_intr-upgrade.test
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
RUN: llvm-dis %p/Inputs/x86_intrcc_upgrade.bc -o - | FileCheck %s
|
||||||
|
|
||||||
|
Make sure we upgrade x86_intrcc to a byval with explicit type
|
||||||
|
|
||||||
|
CHECK: define x86_intrcc void @no_args() {
|
||||||
|
CHECK: define x86_intrcc void @non_byval_ptr_arg0(i32* byval(i32) %0)
|
||||||
|
CHECK: define x86_intrcc void @non_byval_ptr_struct(%struct* byval(%struct) %0)
|
||||||
|
|
||||||
|
CHECK: declare x86_intrcc void @no_args_decl()
|
||||||
|
CHECK: declare x86_intrcc void @non_byval_ptr_arg0_decl(i32* byval(i32))
|
||||||
|
CHECK: declare x86_intrcc void @non_byval_ptr_struct_decl(%struct* byval(%struct))
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
; Spills eax, putting original esp at +4.
|
; Spills eax, putting original esp at +4.
|
||||||
; No stack adjustment if declared with no error code
|
; No stack adjustment if declared with no error code
|
||||||
define x86_intrcc void @test_isr_no_ecode(%struct.interrupt_frame* %frame) {
|
define x86_intrcc void @test_isr_no_ecode(%struct.interrupt_frame* byval(%struct.interrupt_frame) %frame) {
|
||||||
; CHECK-LABEL: test_isr_no_ecode:
|
; CHECK-LABEL: test_isr_no_ecode:
|
||||||
; CHECK: pushl %eax
|
; CHECK: pushl %eax
|
||||||
; CHECK: movl 12(%esp), %eax
|
; CHECK: movl 12(%esp), %eax
|
||||||
@ -29,7 +29,7 @@ define x86_intrcc void @test_isr_no_ecode(%struct.interrupt_frame* %frame) {
|
|||||||
|
|
||||||
; Spills eax and ecx, putting original esp at +8. Stack is adjusted up another 4 bytes
|
; Spills eax and ecx, putting original esp at +8. Stack is adjusted up another 4 bytes
|
||||||
; before return, popping the error code.
|
; before return, popping the error code.
|
||||||
define x86_intrcc void @test_isr_ecode(%struct.interrupt_frame* %frame, i32 %ecode) {
|
define x86_intrcc void @test_isr_ecode(%struct.interrupt_frame* byval(%struct.interrupt_frame) %frame, i32 %ecode) {
|
||||||
; CHECK-LABEL: test_isr_ecode
|
; CHECK-LABEL: test_isr_ecode
|
||||||
; CHECK: pushl %ecx
|
; CHECK: pushl %ecx
|
||||||
; CHECK: pushl %eax
|
; CHECK: pushl %eax
|
||||||
@ -56,7 +56,7 @@ define x86_intrcc void @test_isr_ecode(%struct.interrupt_frame* %frame, i32 %eco
|
|||||||
}
|
}
|
||||||
|
|
||||||
; All clobbered registers must be saved
|
; All clobbered registers must be saved
|
||||||
define x86_intrcc void @test_isr_clobbers(%struct.interrupt_frame* %frame, i32 %ecode) {
|
define x86_intrcc void @test_isr_clobbers(%struct.interrupt_frame* byval(%struct.interrupt_frame) %frame, i32 %ecode) {
|
||||||
call void asm sideeffect "", "~{eax},~{ebx},~{ebp}"()
|
call void asm sideeffect "", "~{eax},~{ebx},~{ebp}"()
|
||||||
; CHECK-LABEL: test_isr_clobbers
|
; CHECK-LABEL: test_isr_clobbers
|
||||||
; CHECK: pushl %ebp
|
; CHECK: pushl %ebp
|
||||||
@ -82,7 +82,7 @@ define x86_intrcc void @test_isr_clobbers(%struct.interrupt_frame* %frame, i32 %
|
|||||||
@f80 = common global x86_fp80 0xK00000000000000000000, align 4
|
@f80 = common global x86_fp80 0xK00000000000000000000, align 4
|
||||||
|
|
||||||
; Test that the presence of x87 does not crash the FP stackifier
|
; Test that the presence of x87 does not crash the FP stackifier
|
||||||
define x86_intrcc void @test_isr_x87(%struct.interrupt_frame* %frame) {
|
define x86_intrcc void @test_isr_x87(%struct.interrupt_frame* byval(%struct.interrupt_frame) %frame) {
|
||||||
; CHECK-LABEL: test_isr_x87
|
; CHECK-LABEL: test_isr_x87
|
||||||
; CHECK-DAG: fldt f80
|
; CHECK-DAG: fldt f80
|
||||||
; CHECK-DAG: fld1
|
; CHECK-DAG: fld1
|
||||||
@ -98,7 +98,7 @@ entry:
|
|||||||
|
|
||||||
; Use a frame pointer to check the offsets. No return address, arguments start
|
; Use a frame pointer to check the offsets. No return address, arguments start
|
||||||
; at EBP+4.
|
; at EBP+4.
|
||||||
define dso_local x86_intrcc void @test_fp_1(%struct.interrupt_frame* %p) #0 {
|
define dso_local x86_intrcc void @test_fp_1(%struct.interrupt_frame* byval(%struct.interrupt_frame) %p) #0 {
|
||||||
; CHECK-LABEL: test_fp_1:
|
; CHECK-LABEL: test_fp_1:
|
||||||
; CHECK: # %bb.0: # %entry
|
; CHECK: # %bb.0: # %entry
|
||||||
; CHECK-NEXT: pushl %ebp
|
; CHECK-NEXT: pushl %ebp
|
||||||
@ -119,7 +119,7 @@ entry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
; The error code is between EBP and the interrupt_frame.
|
; The error code is between EBP and the interrupt_frame.
|
||||||
define dso_local x86_intrcc void @test_fp_2(%struct.interrupt_frame* %p, i32 %err) #0 {
|
define dso_local x86_intrcc void @test_fp_2(%struct.interrupt_frame* byval(%struct.interrupt_frame) %p, i32 %err) #0 {
|
||||||
; CHECK-LABEL: test_fp_2:
|
; CHECK-LABEL: test_fp_2:
|
||||||
; CHECK: # %bb.0: # %entry
|
; CHECK: # %bb.0: # %entry
|
||||||
; CHECK-NEXT: pushl %ebp
|
; CHECK-NEXT: pushl %ebp
|
||||||
@ -143,7 +143,7 @@ entry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
; Test argument copy elision when copied to a local alloca.
|
; Test argument copy elision when copied to a local alloca.
|
||||||
define x86_intrcc void @test_copy_elide(%struct.interrupt_frame* %frame, i32 %err) #0 {
|
define x86_intrcc void @test_copy_elide(%struct.interrupt_frame* byval(%struct.interrupt_frame) %frame, i32 %err) #0 {
|
||||||
; CHECK-LABEL: test_copy_elide:
|
; CHECK-LABEL: test_copy_elide:
|
||||||
; CHECK: # %bb.0: # %entry
|
; CHECK: # %bb.0: # %entry
|
||||||
; CHECK-NEXT: pushl %ebp
|
; CHECK-NEXT: pushl %ebp
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
@llvm.used = appending global [1 x i8*] [i8* bitcast (void (%struct.interrupt_frame*, i64)* @test_isr_sse_clobbers to i8*)], section "llvm.metadata"
|
@llvm.used = appending global [1 x i8*] [i8* bitcast (void (%struct.interrupt_frame*, i64)* @test_isr_sse_clobbers to i8*)], section "llvm.metadata"
|
||||||
|
|
||||||
; Clobbered SSE must not be saved when the target doesn't support SSE
|
; Clobbered SSE must not be saved when the target doesn't support SSE
|
||||||
define x86_intrcc void @test_isr_sse_clobbers(%struct.interrupt_frame* %frame, i64 %ecode) {
|
define x86_intrcc void @test_isr_sse_clobbers(%struct.interrupt_frame* byval(%struct.interrupt_frame) %frame, i64 %ecode) {
|
||||||
; CHECK-LABEL: test_isr_sse_clobbers:
|
; CHECK-LABEL: test_isr_sse_clobbers:
|
||||||
; CHECK: # %bb.0:
|
; CHECK: # %bb.0:
|
||||||
; CHECK-NEXT: pushq %rax
|
; CHECK-NEXT: pushq %rax
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
; Spills rax, putting original esp at +8.
|
; Spills rax, putting original esp at +8.
|
||||||
; No stack adjustment if declared with no error code
|
; No stack adjustment if declared with no error code
|
||||||
define x86_intrcc void @test_isr_no_ecode(%struct.interrupt_frame* %frame) {
|
define x86_intrcc void @test_isr_no_ecode(%struct.interrupt_frame* byval(%struct.interrupt_frame) %frame) {
|
||||||
; CHECK-LABEL: test_isr_no_ecode:
|
; CHECK-LABEL: test_isr_no_ecode:
|
||||||
; CHECK: pushq %rax
|
; CHECK: pushq %rax
|
||||||
; CHECK: movq 24(%rsp), %rax
|
; CHECK: movq 24(%rsp), %rax
|
||||||
@ -28,7 +28,7 @@ define x86_intrcc void @test_isr_no_ecode(%struct.interrupt_frame* %frame) {
|
|||||||
|
|
||||||
; Spills rax and rcx, putting original rsp at +16. Stack is adjusted up another 8 bytes
|
; Spills rax and rcx, putting original rsp at +16. Stack is adjusted up another 8 bytes
|
||||||
; before return, popping the error code.
|
; before return, popping the error code.
|
||||||
define x86_intrcc void @test_isr_ecode(%struct.interrupt_frame* %frame, i64 %ecode) {
|
define x86_intrcc void @test_isr_ecode(%struct.interrupt_frame* byval(%struct.interrupt_frame) %frame, i64 %ecode) {
|
||||||
; CHECK-LABEL: test_isr_ecode
|
; CHECK-LABEL: test_isr_ecode
|
||||||
; CHECK: pushq %rax
|
; CHECK: pushq %rax
|
||||||
; CHECK: pushq %rax
|
; CHECK: pushq %rax
|
||||||
@ -57,7 +57,7 @@ define x86_intrcc void @test_isr_ecode(%struct.interrupt_frame* %frame, i64 %eco
|
|||||||
}
|
}
|
||||||
|
|
||||||
; All clobbered registers must be saved
|
; All clobbered registers must be saved
|
||||||
define x86_intrcc void @test_isr_clobbers(%struct.interrupt_frame* %frame, i64 %ecode) {
|
define x86_intrcc void @test_isr_clobbers(%struct.interrupt_frame* byval(%struct.interrupt_frame) %frame, i64 %ecode) {
|
||||||
call void asm sideeffect "", "~{rax},~{rbx},~{rbp},~{r11},~{xmm0}"()
|
call void asm sideeffect "", "~{rax},~{rbx},~{rbp},~{r11},~{xmm0}"()
|
||||||
; CHECK-LABEL: test_isr_clobbers
|
; CHECK-LABEL: test_isr_clobbers
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ define x86_intrcc void @test_isr_clobbers(%struct.interrupt_frame* %frame, i64 %
|
|||||||
@f80 = common global x86_fp80 0xK00000000000000000000, align 4
|
@f80 = common global x86_fp80 0xK00000000000000000000, align 4
|
||||||
|
|
||||||
; Test that the presence of x87 does not crash the FP stackifier
|
; Test that the presence of x87 does not crash the FP stackifier
|
||||||
define x86_intrcc void @test_isr_x87(%struct.interrupt_frame* %frame) {
|
define x86_intrcc void @test_isr_x87(%struct.interrupt_frame* byval(%struct.interrupt_frame) %frame) {
|
||||||
; CHECK-LABEL: test_isr_x87
|
; CHECK-LABEL: test_isr_x87
|
||||||
; CHECK-DAG: fldt f80
|
; CHECK-DAG: fldt f80
|
||||||
; CHECK-DAG: fld1
|
; CHECK-DAG: fld1
|
||||||
@ -109,7 +109,7 @@ entry:
|
|||||||
|
|
||||||
; Use a frame pointer to check the offsets. No return address, arguments start
|
; Use a frame pointer to check the offsets. No return address, arguments start
|
||||||
; at RBP+4.
|
; at RBP+4.
|
||||||
define dso_local x86_intrcc void @test_fp_1(%struct.interrupt_frame* %p) #0 {
|
define dso_local x86_intrcc void @test_fp_1(%struct.interrupt_frame* byval(%struct.interrupt_frame) %p) #0 {
|
||||||
; CHECK-LABEL: test_fp_1:
|
; CHECK-LABEL: test_fp_1:
|
||||||
; CHECK: # %bb.0: # %entry
|
; CHECK: # %bb.0: # %entry
|
||||||
; CHECK-NEXT: pushq %rbp
|
; CHECK-NEXT: pushq %rbp
|
||||||
@ -130,7 +130,7 @@ entry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
; The error code is between RBP and the interrupt_frame.
|
; The error code is between RBP and the interrupt_frame.
|
||||||
define dso_local x86_intrcc void @test_fp_2(%struct.interrupt_frame* %p, i64 %err) #0 {
|
define dso_local x86_intrcc void @test_fp_2(%struct.interrupt_frame* byval(%struct.interrupt_frame) %p, i64 %err) #0 {
|
||||||
; CHECK-LABEL: test_fp_2:
|
; CHECK-LABEL: test_fp_2:
|
||||||
; CHECK: # %bb.0: # %entry
|
; CHECK: # %bb.0: # %entry
|
||||||
; This RAX push is just to align the stack.
|
; This RAX push is just to align the stack.
|
||||||
@ -159,7 +159,7 @@ entry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
; Test argument copy elision when copied to a local alloca.
|
; Test argument copy elision when copied to a local alloca.
|
||||||
define x86_intrcc void @test_copy_elide(%struct.interrupt_frame* %frame, i64 %err) #0 {
|
define x86_intrcc void @test_copy_elide(%struct.interrupt_frame* byval(%struct.interrupt_frame) %frame, i64 %err) #0 {
|
||||||
; CHECK-LABEL: test_copy_elide:
|
; CHECK-LABEL: test_copy_elide:
|
||||||
; CHECK: # %bb.0: # %entry
|
; CHECK: # %bb.0: # %entry
|
||||||
; This RAX push is just to align the stack.
|
; This RAX push is just to align the stack.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
; Make sure we spill the high numbered zmm registers and K registers with the right encoding.
|
; Make sure we spill the high numbered zmm registers and K registers with the right encoding.
|
||||||
|
|
||||||
define x86_intrcc void @foo(i8* %frame) {
|
define x86_intrcc void @foo(i8* byval(i8) %frame) {
|
||||||
; CHECK64-KNL-LABEL: foo:
|
; CHECK64-KNL-LABEL: foo:
|
||||||
; CHECK64-KNL: ## %bb.0:
|
; CHECK64-KNL: ## %bb.0:
|
||||||
; CHECK64-KNL-NEXT: pushq %rax ## encoding: [0x50]
|
; CHECK64-KNL-NEXT: pushq %rax ## encoding: [0x50]
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
; CHECK: cld
|
; CHECK: cld
|
||||||
; CHECK: call
|
; CHECK: call
|
||||||
|
|
||||||
define x86_intrcc void @foo(i8* %frame) {
|
define x86_intrcc void @foo(i8* byval(i8) %frame) {
|
||||||
call void @bar()
|
call void @bar()
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
; CHECK-NOT: vzeroupper
|
; CHECK-NOT: vzeroupper
|
||||||
; CHECK: iret
|
; CHECK: iret
|
||||||
|
|
||||||
define x86_intrcc void @foo(i8* %frame) {
|
define x86_intrcc void @foo(i8* byval(i8) %frame) {
|
||||||
call void @bar()
|
call void @bar()
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ define i32 @bar(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i
|
|||||||
ret i32 1
|
ret i32 1
|
||||||
}
|
}
|
||||||
|
|
||||||
define x86_intrcc void @foo(i8* nocapture readnone %c) {
|
define x86_intrcc void @foo(i8* byval(i8) nocapture readnone %c) {
|
||||||
; CHECK-LABEL: foo
|
; CHECK-LABEL: foo
|
||||||
; CHECK-NOT: xmm
|
; CHECK-NOT: xmm
|
||||||
entry:
|
entry:
|
||||||
|
21
test/Verifier/x86_intr.ll
Normal file
21
test/Verifier/x86_intr.ll
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
; RUN: not llvm-as < %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK: Calling convention parameter requires byval
|
||||||
|
; CHECK-NEXT: void (i32)* @non_ptr_arg0
|
||||||
|
define x86_intrcc void @non_ptr_arg0(i32) {
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK: Calling convention parameter requires byval
|
||||||
|
; CHECK-NEXT: void (i32*)* @non_byval_ptr_arg0
|
||||||
|
define x86_intrcc void @non_byval_ptr_arg0(i32*) {
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK: Calling convention parameter requires byval
|
||||||
|
; CHECK-NEXT: void (i32)* @non_ptr_arg0_decl
|
||||||
|
declare x86_intrcc void @non_ptr_arg0_decl(i32)
|
||||||
|
|
||||||
|
; CHECK: Calling convention parameter requires byval
|
||||||
|
; CHECK-NEXT: void (i32*)* @non_byval_ptr_arg0_decl
|
||||||
|
declare x86_intrcc void @non_byval_ptr_arg0_decl(i32*)
|
Loading…
Reference in New Issue
Block a user