arsenm updated this revision to Diff 308354.
arsenm added a comment.
Fix bitcode upgrade after rebase
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D91840/new/
https://reviews.llvm.org/D91840
Files:
clang/lib/CodeGen/TargetInfo.cpp
clang/test/CodeGen/attr-x86-interrupt.c
clang/test/CodeGenCXX/attr-x86-interrupt.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/lib/IR/AutoUpgrade.cpp
llvm/lib/IR/Verifier.cpp
llvm/test/Assembler/x86_intrcc.ll
llvm/test/Bitcode/Inputs/x86_intrcc_upgrade.bc
llvm/test/Bitcode/compatibility-6.0.ll
llvm/test/Bitcode/compatibility.ll
llvm/test/Bitcode/x86_intr-upgrade.test
llvm/test/CodeGen/X86/x86-32-intrcc.ll
llvm/test/CodeGen/X86/x86-64-intrcc-nosse.ll
llvm/test/CodeGen/X86/x86-64-intrcc.ll
llvm/test/CodeGen/X86/x86-interrupt_cc.ll
llvm/test/CodeGen/X86/x86-interrupt_cld.ll
llvm/test/CodeGen/X86/x86-interrupt_vzeroupper.ll
llvm/test/CodeGen/X86/x86-no_caller_saved_registers.ll
llvm/test/Verifier/x86_intr.ll
Index: llvm/test/Verifier/x86_intr.ll
===================================================================
--- /dev/null
+++ llvm/test/Verifier/x86_intr.ll
@@ -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*)
Index: llvm/test/CodeGen/X86/x86-no_caller_saved_registers.ll
===================================================================
--- llvm/test/CodeGen/X86/x86-no_caller_saved_registers.ll
+++ llvm/test/CodeGen/X86/x86-no_caller_saved_registers.ll
@@ -7,7 +7,7 @@
;; In functions with 'no_caller_saved_registers' attribute, all registers should
;; be preserved except for registers used for passing/returning arguments.
;; The test checks that function "bar" preserves xmm0 register.
-;; It also checks that caller function "foo" does not store registers for callee
+;; It also checks that caller function "foo" does not store registers for callee
;; "bar". For example, there is no store/load/access to xmm registers.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -20,7 +20,7 @@
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-NOT: xmm
entry:
Index: llvm/test/CodeGen/X86/x86-interrupt_vzeroupper.ll
===================================================================
--- llvm/test/CodeGen/X86/x86-interrupt_vzeroupper.ll
+++ llvm/test/CodeGen/X86/x86-interrupt_vzeroupper.ll
@@ -10,7 +10,7 @@
; CHECK-NOT: vzeroupper
; CHECK: iret
-define x86_intrcc void @foo(i8* %frame) {
+define x86_intrcc void @foo(i8* byval(i8) %frame) {
call void @bar()
ret void
}
Index: llvm/test/CodeGen/X86/x86-interrupt_cld.ll
===================================================================
--- llvm/test/CodeGen/X86/x86-interrupt_cld.ll
+++ llvm/test/CodeGen/X86/x86-interrupt_cld.ll
@@ -8,7 +8,7 @@
; CHECK: cld
; CHECK: call
-define x86_intrcc void @foo(i8* %frame) {
+define x86_intrcc void @foo(i8* byval(i8) %frame) {
call void @bar()
ret void
}
Index: llvm/test/CodeGen/X86/x86-interrupt_cc.ll
===================================================================
--- llvm/test/CodeGen/X86/x86-interrupt_cc.ll
+++ llvm/test/CodeGen/X86/x86-interrupt_cc.ll
@@ -6,7 +6,7 @@
; 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: ## %bb.0:
; CHECK64-KNL-NEXT: pushq %rax ## encoding: [0x50]
Index: llvm/test/CodeGen/X86/x86-64-intrcc.ll
===================================================================
--- llvm/test/CodeGen/X86/x86-64-intrcc.ll
+++ llvm/test/CodeGen/X86/x86-64-intrcc.ll
@@ -8,7 +8,7 @@
; Spills rax, putting original esp at +8.
; 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: pushq %rax
; CHECK: movq 24(%rsp), %rax
@@ -28,7 +28,7 @@
; Spills rax and rcx, putting original rsp at +16. Stack is adjusted up another 8 bytes
; 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: pushq %rax
; CHECK: pushq %rax
@@ -57,7 +57,7 @@
}
; 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}"()
; CHECK-LABEL: test_isr_clobbers
@@ -93,7 +93,7 @@
@f80 = common global x86_fp80 0xK00000000000000000000, align 4
; 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-DAG: fldt f80
; CHECK-DAG: fld1
@@ -109,7 +109,7 @@
; Use a frame pointer to check the offsets. No return address, arguments start
; 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: # %bb.0: # %entry
; CHECK-NEXT: pushq %rbp
@@ -130,7 +130,7 @@
}
; 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: # %bb.0: # %entry
; This RAX push is just to align the stack.
@@ -159,7 +159,7 @@
}
; 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: # %bb.0: # %entry
; This RAX push is just to align the stack.
Index: llvm/test/CodeGen/X86/x86-64-intrcc-nosse.ll
===================================================================
--- llvm/test/CodeGen/X86/x86-64-intrcc-nosse.ll
+++ llvm/test/CodeGen/X86/x86-64-intrcc-nosse.ll
@@ -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"
; 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: # %bb.0:
; CHECK-NEXT: pushq %rax
Index: llvm/test/CodeGen/X86/x86-32-intrcc.ll
===================================================================
--- llvm/test/CodeGen/X86/x86-32-intrcc.ll
+++ llvm/test/CodeGen/X86/x86-32-intrcc.ll
@@ -9,7 +9,7 @@
; Spills eax, putting original esp at +4.
; 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: pushl %eax
; CHECK: movl 12(%esp), %eax
@@ -29,7 +29,7 @@
; Spills eax and ecx, putting original esp at +8. Stack is adjusted up another 4 bytes
; 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: pushl %ecx
; CHECK: pushl %eax
@@ -56,7 +56,7 @@
}
; 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}"()
; CHECK-LABEL: test_isr_clobbers
; CHECK: pushl %ebp
@@ -82,7 +82,7 @@
@f80 = common global x86_fp80 0xK00000000000000000000, align 4
; 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-DAG: fldt f80
; CHECK-DAG: fld1
@@ -98,7 +98,7 @@
; Use a frame pointer to check the offsets. No return address, arguments start
; 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: # %bb.0: # %entry
; CHECK-NEXT: pushl %ebp
@@ -119,7 +119,7 @@
}
; 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: # %bb.0: # %entry
; CHECK-NEXT: pushl %ebp
@@ -143,7 +143,7 @@
}
; 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: # %bb.0: # %entry
; CHECK-NEXT: pushl %ebp
Index: llvm/test/Bitcode/x86_intr-upgrade.test
===================================================================
--- /dev/null
+++ llvm/test/Bitcode/x86_intr-upgrade.test
@@ -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))
Index: llvm/test/Bitcode/compatibility.ll
===================================================================
--- llvm/test/Bitcode/compatibility.ll
+++ llvm/test/Bitcode/compatibility.ll
@@ -450,10 +450,10 @@
; CHECK: declare hhvm_ccc void @f.cc82()
declare hhvm_ccc void @f.hhvm_ccc()
; CHECK: declare hhvm_ccc void @f.hhvm_ccc()
-declare cc83 void @f.cc83()
-; CHECK: declare x86_intrcc void @f.cc83()
-declare x86_intrcc void @f.x86_intrcc()
-; CHECK: declare x86_intrcc void @f.x86_intrcc()
+declare cc83 void @f.cc83(i8* byval(i8))
+; CHECK: declare x86_intrcc void @f.cc83(i8* byval(i8))
+declare x86_intrcc void @f.x86_intrcc(i8* byval(i8))
+; CHECK: declare x86_intrcc void @f.x86_intrcc(i8* byval(i8))
declare cc84 void @f.cc84()
; CHECK: declare avr_intrcc void @f.cc84()
declare avr_intrcc void @f.avr_intrcc()
Index: llvm/test/Bitcode/compatibility-6.0.ll
===================================================================
--- llvm/test/Bitcode/compatibility-6.0.ll
+++ llvm/test/Bitcode/compatibility-6.0.ll
@@ -436,7 +436,7 @@
; CHECK: declare hhvm_ccc void @f.cc82()
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()
declare x86_intrcc void @f.x86_intrcc()
; CHECK: declare x86_intrcc void @f.x86_intrcc()
Index: llvm/test/Assembler/x86_intrcc.ll
===================================================================
--- /dev/null
+++ llvm/test/Assembler/x86_intrcc.ll
@@ -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
+}
Index: llvm/lib/IR/Verifier.cpp
===================================================================
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -2327,6 +2327,11 @@
default:
case CallingConv::C:
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::SPIR_KERNEL:
Assert(F.getReturnType()->isVoidTy(),
Index: llvm/lib/IR/AutoUpgrade.cpp
===================================================================
--- llvm/lib/IR/AutoUpgrade.cpp
+++ llvm/lib/IR/AutoUpgrade.cpp
@@ -4315,6 +4315,13 @@
StrictFPUpgradeVisitor SFPV;
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) {
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -9766,14 +9766,6 @@
}
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() ||
Flags.isByRef()) {
if (!ArgMemTy)
Index: clang/test/CodeGenCXX/attr-x86-interrupt.cpp
===================================================================
--- clang/test/CodeGenCXX/attr-x86-interrupt.cpp
+++ clang/test/CodeGenCXX/attr-x86-interrupt.cpp
@@ -18,18 +18,18 @@
static void foo9(int *a) __attribute__((interrupt)) {}
};
// X86_64_LINUX: @llvm.used = appending global [3 x i8*] [i8* bitcast (void (i32*, i64)* @{{.*}}foo7{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo8{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo9{{.*}} to i8*)], section "llvm.metadata"
-// X86_64_LINUX: define x86_intrcc void @{{.*}}foo7{{.*}}(i32* %{{.+}}, i64 %{{.+}})
-// X86_64_LINUX: define x86_intrcc void @{{.*}}foo8{{.*}}(i32* %{{.+}})
-// X86_64_LINUX: define linkonce_odr x86_intrcc void @{{.*}}foo9{{.*}}(i32* %{{.+}})
+// X86_64_LINUX: define x86_intrcc void @{{.*}}foo7{{.*}}(i32* byval(i32) %{{.+}}, i64 %{{.+}})
+// X86_64_LINUX: define x86_intrcc void @{{.*}}foo8{{.*}}(i32* byval(i32) %{{.+}})
+// X86_64_LINUX: define linkonce_odr x86_intrcc void @{{.*}}foo9{{.*}}(i32* byval(i32) %{{.+}})
// X86_LINUX: @llvm.used = appending global [3 x i8*] [i8* bitcast (void (i32*, i32)* @{{.*}}foo7{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo8{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo9{{.*}} to i8*)], section "llvm.metadata"
-// X86_LINUX: define x86_intrcc void @{{.*}}foo7{{.*}}(i32* %{{.+}}, i32 %{{.+}})
-// X86_LINUX: define x86_intrcc void @{{.*}}foo8{{.*}}(i32* %{{.+}})
-// X86_LINUX: define linkonce_odr x86_intrcc void @{{.*}}foo9{{.*}}(i32* %{{.+}})
+// X86_LINUX: define x86_intrcc void @{{.*}}foo7{{.*}}(i32* byval(i32) %{{.+}}, i32 %{{.+}})
+// X86_LINUX: define x86_intrcc void @{{.*}}foo8{{.*}}(i32* byval(i32) %{{.+}})
+// X86_LINUX: define linkonce_odr x86_intrcc void @{{.*}}foo9{{.*}}(i32* byval(i32) %{{.+}})
// X86_64_WIN: @llvm.used = appending global [3 x i8*] [i8* bitcast (void (i32*, i64)* @{{.*}}foo7{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo8{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo9{{.*}} to i8*)], section "llvm.metadata"
-// X86_64_WIN: define dso_local x86_intrcc void @{{.*}}foo7{{.*}}(i32* %{{.+}}, i64 %{{.+}})
-// X86_64_WIN: define dso_local x86_intrcc void @{{.*}}foo8{{.*}}(i32* %{{.+}})
-// X86_64_WIN: define linkonce_odr dso_local x86_intrcc void @{{.*}}foo9{{.*}}(i32* %{{.+}})
+// X86_64_WIN: define dso_local x86_intrcc void @{{.*}}foo7{{.*}}(i32* byval(i32) %{{.+}}, i64 %{{.+}})
+// X86_64_WIN: define dso_local x86_intrcc void @{{.*}}foo8{{.*}}(i32* byval(i32) %{{.+}})
+// X86_64_WIN: define linkonce_odr dso_local x86_intrcc void @{{.*}}foo9{{.*}}(i32* byval(i32) %{{.+}})
// X86_WIN: @llvm.used = appending global [3 x i8*] [i8* bitcast (void (i32*, i32)* @{{.*}}foo7{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo8{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo9{{.*}} to i8*)], section "llvm.metadata"
-// X86_WIN: define dso_local x86_intrcc void @{{.*}}foo7{{.*}}(i32* %{{.+}}, i32 %{{.+}})
-// X86_WIN: define dso_local x86_intrcc void @{{.*}}foo8{{.*}}(i32* %{{.+}})
-// X86_WIN: define linkonce_odr dso_local x86_intrcc void @{{.*}}foo9{{.*}}(i32* %{{.+}})
+// X86_WIN: define dso_local x86_intrcc void @{{.*}}foo7{{.*}}(i32* byval(i32) %{{.+}}, i32 %{{.+}})
+// X86_WIN: define dso_local x86_intrcc void @{{.*}}foo8{{.*}}(i32* byval(i32) %{{.+}})
+// X86_WIN: define linkonce_odr dso_local x86_intrcc void @{{.*}}foo9{{.*}}(i32* byval(i32) %{{.+}})
Index: clang/test/CodeGen/attr-x86-interrupt.c
===================================================================
--- clang/test/CodeGen/attr-x86-interrupt.c
+++ clang/test/CodeGen/attr-x86-interrupt.c
@@ -13,22 +13,22 @@
__attribute__((interrupt)) void foo7(int *a, uword b) {}
__attribute__((interrupt)) void foo8(int *a) {}
// X86_64_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata"
-// X86_64_LINUX: define x86_intrcc void @foo7(i32* %{{.+}}, i64 %{{.+}})
-// X86_64_LINUX: define x86_intrcc void @foo8(i32* %{{.+}})
+// X86_64_LINUX: define x86_intrcc void @foo7(i32* byval(i32) %{{.+}}, i64 %{{.+}})
+// X86_64_LINUX: define x86_intrcc void @foo8(i32* byval(i32) %{{.+}})
// X86_64_LINUX: "disable-tail-calls"="true"
// X86_64_LINUX-NOT: "disable-tail-calls"="false"
// X86_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i32)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata"
-// X86_LINUX: define x86_intrcc void @foo7(i32* %{{.+}}, i32 %{{.+}})
-// X86_LINUX: define x86_intrcc void @foo8(i32* %{{.+}})
+// X86_LINUX: define x86_intrcc void @foo7(i32* byval(i32) %{{.+}}, i32 %{{.+}})
+// X86_LINUX: define x86_intrcc void @foo8(i32* byval(i32) %{{.+}})
// X86_LINUX: "disable-tail-calls"="true"
// X86_LINUX-NOT: "disable-tail-calls"="false"
// X86_64_WIN: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata"
-// X86_64_WIN: define dso_local x86_intrcc void @foo7(i32* %{{.+}}, i64 %{{.+}})
-// X86_64_WIN: define dso_local x86_intrcc void @foo8(i32* %{{.+}})
-// X86_64_Win: "disable-tail-calls"="true"
-// X86_64_Win-NOT: "disable-tail-calls"="false"
+// X86_64_WIN: define dso_local x86_intrcc void @foo7(i32* byval(i32) %{{.+}}, i64 %{{.+}})
+// X86_64_WIN: define dso_local x86_intrcc void @foo8(i32* byval(i32) %{{.+}})
+// X86_64_WIN: "disable-tail-calls"="true"
+// X86_64_WIN-NOT: "disable-tail-calls"="false"
// X86_WIN: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i32)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata"
-// X86_WIN: define dso_local x86_intrcc void @foo7(i32* %{{.+}}, i32 %{{.+}})
-// X86_WIN: define dso_local x86_intrcc void @foo8(i32* %{{.+}})
-// X86_Win: "disable-tail-calls"="true"
-// X86_Win-NOT: "disable-tail-calls"="false"
+// X86_WIN: define dso_local x86_intrcc void @foo7(i32* byval(i32) %{{.+}}, i32 %{{.+}})
+// X86_WIN: define dso_local x86_intrcc void @foo8(i32* byval(i32) %{{.+}})
+// X86_WIN: "disable-tail-calls"="true"
+// X86_WIN-NOT: "disable-tail-calls"="false"
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -2097,6 +2097,23 @@
}
}
+static void addX86InterruptAttrs(const FunctionDecl *FD, llvm::GlobalValue *GV,
+ CodeGen::CodeGenModule &CGM) {
+ if (!FD->hasAttr<AnyX86InterruptAttr>())
+ return;
+
+ llvm::Function *Fn = cast<llvm::Function>(GV);
+ Fn->setCallingConv(llvm::CallingConv::X86_INTR);
+ if (FD->getNumParams() == 0)
+ return;
+
+ auto PtrTy = cast<PointerType>(FD->getParamDecl(0)->getType());
+ llvm::Type *ByValTy = CGM.getTypes().ConvertType(PtrTy->getPointeeType());
+ llvm::Attribute NewAttr = llvm::Attribute::getWithByValType(
+ Fn->getContext(), ByValTy);
+ Fn->addParamAttr(0, NewAttr);
+}
+
void X86_32TargetCodeGenInfo::setTargetAttributes(
const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const {
if (GV->isDeclaration())
@@ -2106,10 +2123,8 @@
llvm::Function *Fn = cast<llvm::Function>(GV);
Fn->addFnAttr("stackrealign");
}
- if (FD->hasAttr<AnyX86InterruptAttr>()) {
- llvm::Function *Fn = cast<llvm::Function>(GV);
- Fn->setCallingConv(llvm::CallingConv::X86_INTR);
- }
+
+ addX86InterruptAttrs(FD, GV, CGM);
}
}
@@ -2476,10 +2491,8 @@
llvm::Function *Fn = cast<llvm::Function>(GV);
Fn->addFnAttr("stackrealign");
}
- if (FD->hasAttr<AnyX86InterruptAttr>()) {
- llvm::Function *Fn = cast<llvm::Function>(GV);
- Fn->setCallingConv(llvm::CallingConv::X86_INTR);
- }
+
+ addX86InterruptAttrs(FD, GV, CGM);
}
}
@@ -2689,10 +2702,8 @@
llvm::Function *Fn = cast<llvm::Function>(GV);
Fn->addFnAttr("stackrealign");
}
- if (FD->hasAttr<AnyX86InterruptAttr>()) {
- llvm::Function *Fn = cast<llvm::Function>(GV);
- Fn->setCallingConv(llvm::CallingConv::X86_INTR);
- }
+
+ addX86InterruptAttrs(FD, GV, CGM);
}
addStackProbeTargetAttributes(D, GV, CGM);
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits