From: Philip Reames Date: Tue, 12 Mar 2019 21:05:31 +0000 (+0000) Subject: For faulting ops, include a comment w/the fault destination X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e74acf4ba7bb2df0b2a04548061b4c886efc368a;p=llvm For faulting ops, include a comment w/the fault destination A faulting_op is one that has specified behavior when a fault occurs, generally redirecting control flow to another location. This change just adds a comment to the assembly output which makes it both human readable, and machine checkable w/o having to parse the FaultMap section. This is used to split a test file into two parts, so that I can (in a near future commit) easily extend the test file to demonstrate another case. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355982 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86MCInstLower.cpp b/lib/Target/X86/X86MCInstLower.cpp index ce6bdafbc27..4b62085f5c3 100644 --- a/lib/Target/X86/X86MCInstLower.cpp +++ b/lib/Target/X86/X86MCInstLower.cpp @@ -962,6 +962,7 @@ void X86AsmPrinter::LowerFAULTING_OP(const MachineInstr &FaultingMI, if (auto MaybeOperand = MCIL.LowerMachineOperand(&FaultingMI, *I)) MI.addOperand(MaybeOperand.getValue()); + OutStreamer->AddComment("on-fault: " + HandlerLabel->getName()); OutStreamer->EmitInstruction(MI, getSubtargetInfo()); } diff --git a/test/CodeGen/X86/implicit-faultmap.ll b/test/CodeGen/X86/implicit-faultmap.ll new file mode 100644 index 00000000000..1701b0fc5fd --- /dev/null +++ b/test/CodeGen/X86/implicit-faultmap.ll @@ -0,0 +1,104 @@ +; RUN: llc -verify-machineinstrs -O3 -mtriple=x86_64-apple-macosx -enable-implicit-null-checks < %s | FileCheck %s + +; RUN: llc < %s -mtriple=x86_64-apple-macosx -enable-implicit-null-checks \ +; RUN: | llvm-mc -triple x86_64-apple-macosx -filetype=obj -o - \ +; RUN: | llvm-objdump -triple x86_64-apple-macosx -fault-map-section - \ +; RUN: | FileCheck %s -check-prefix OBJDUMP + +; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -enable-implicit-null-checks \ +; RUN: | llvm-mc -triple x86_64-unknown-linux-gnu -filetype=obj -o - \ +; RUN: | llvm-objdump -triple x86_64-unknown-linux-gnu -fault-map-section - \ +; RUN: | FileCheck %s -check-prefix OBJDUMP + +;; The tests in this file exist just to check basic validity of the FaultMap +;; section. Please don't add to this file unless you're testing the FaultMap +;; serialization code itself. + +define i32 @imp_null_check_load(i32* %x) { +; CHECK-LABEL: _imp_null_check_load: +; CHECK: [[BB0_imp_null_check_load:L[^:]+]]: +; CHECK: movl (%rdi), %eax +; CHECK: retq +; CHECK: [[BB1_imp_null_check_load:LBB0_[0-9]+]]: +; CHECK: movl $42, %eax +; CHECK: retq + + entry: + %c = icmp eq i32* %x, null + br i1 %c, label %is_null, label %not_null, !make.implicit !0 + + is_null: + ret i32 42 + + not_null: + %t = load i32, i32* %x + ret i32 %t +} + +define void @imp_null_check_store(i32* %x) { +; CHECK-LABEL: _imp_null_check_store: +; CHECK: [[BB0_imp_null_check_store:L[^:]+]]: +; CHECK: movl $1, (%rdi) +; CHECK: retq +; CHECK: [[BB1_imp_null_check_store:LBB1_[0-9]+]]: +; CHECK: retq + + entry: + %c = icmp eq i32* %x, null + br i1 %c, label %is_null, label %not_null, !make.implicit !0 + + is_null: + ret void + + not_null: + store i32 1, i32* %x + ret void +} + +!0 = !{} + +; CHECK-LABEL: __LLVM_FaultMaps: + +; Version: +; CHECK-NEXT: .byte 1 + +; Reserved x2 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .short 0 + +; # functions: +; CHECK-NEXT: .long 2 + +; FunctionAddr: +; CHECK-NEXT: .quad _imp_null_check_load +; NumFaultingPCs +; CHECK-NEXT: .long 1 +; Reserved: +; CHECK-NEXT: .long 0 +; Fault[0].Type: +; CHECK-NEXT: .long 1 +; Fault[0].FaultOffset: +; CHECK-NEXT: .long [[BB0_imp_null_check_load]]-_imp_null_check_load +; Fault[0].HandlerOffset: +; CHECK-NEXT: .long [[BB1_imp_null_check_load]]-_imp_null_check_load + +; FunctionAddr: +; CHECK-NEXT: .quad _imp_null_check_store +; NumFaultingPCs +; CHECK-NEXT: .long 1 +; Reserved: +; CHECK-NEXT: .long 0 +; Fault[0].Type: +; CHECK-NEXT: .long 3 +; Fault[0].FaultOffset: +; CHECK-NEXT: .long [[BB0_imp_null_check_store]]-_imp_null_check_store +; Fault[0].HandlerOffset: +; CHECK-NEXT: .long [[BB1_imp_null_check_store]]-_imp_null_check_store + +; OBJDUMP: FaultMap table: +; OBJDUMP-NEXT: Version: 0x1 +; OBJDUMP-NEXT: NumFunctions: 2 +; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1 +; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 3 +; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1 +; OBJDUMP-NEXT: Fault kind: FaultingStore, faulting PC offset: 0, handling PC offset: 7 diff --git a/test/CodeGen/X86/implicit-null-check.ll b/test/CodeGen/X86/implicit-null-check.ll index 8cfc9c669ad..d3d2fff451c 100644 --- a/test/CodeGen/X86/implicit-null-check.ll +++ b/test/CodeGen/X86/implicit-null-check.ll @@ -1,23 +1,16 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -verify-machineinstrs -O3 -mtriple=x86_64-apple-macosx -enable-implicit-null-checks < %s | FileCheck %s -; RUN: llc < %s -mtriple=x86_64-apple-macosx -enable-implicit-null-checks \ -; RUN: | llvm-mc -triple x86_64-apple-macosx -filetype=obj -o - \ -; RUN: | llvm-objdump -triple x86_64-apple-macosx -fault-map-section - \ -; RUN: | FileCheck %s -check-prefix OBJDUMP - -; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -enable-implicit-null-checks \ -; RUN: | llvm-mc -triple x86_64-unknown-linux-gnu -filetype=obj -o - \ -; RUN: | llvm-objdump -triple x86_64-unknown-linux-gnu -fault-map-section - \ -; RUN: | FileCheck %s -check-prefix OBJDUMP - define i32 @imp_null_check_load(i32* %x) { -; CHECK-LABEL: _imp_null_check_load: -; CHECK: [[BB0_imp_null_check_load:L[^:]+]]: -; CHECK: movl (%rdi), %eax -; CHECK: retq -; CHECK: [[BB1_imp_null_check_load:LBB0_[0-9]+]]: -; CHECK: movl $42, %eax -; CHECK: retq +; CHECK-LABEL: imp_null_check_load: +; CHECK: ## %bb.0: ## %entry +; CHECK-NEXT: Ltmp0: +; CHECK-NEXT: movl (%rdi), %eax ## on-fault: LBB0_1 +; CHECK-NEXT: ## %bb.2: ## %not_null +; CHECK-NEXT: retq +; CHECK-NEXT: LBB0_1: ## %is_null +; CHECK-NEXT: movl $42, %eax +; CHECK-NEXT: retq entry: %c = icmp eq i32* %x, null @@ -32,13 +25,15 @@ define i32 @imp_null_check_load(i32* %x) { } define i32 @imp_null_check_gep_load(i32* %x) { -; CHECK-LABEL: _imp_null_check_gep_load: -; CHECK: [[BB0_imp_null_check_gep_load:L[^:]+]]: -; CHECK: movl 128(%rdi), %eax -; CHECK: retq -; CHECK: [[BB1_imp_null_check_gep_load:LBB1_[0-9]+]]: -; CHECK: movl $42, %eax -; CHECK: retq +; CHECK-LABEL: imp_null_check_gep_load: +; CHECK: ## %bb.0: ## %entry +; CHECK-NEXT: Ltmp1: +; CHECK-NEXT: movl 128(%rdi), %eax ## on-fault: LBB1_1 +; CHECK-NEXT: ## %bb.2: ## %not_null +; CHECK-NEXT: retq +; CHECK-NEXT: LBB1_1: ## %is_null +; CHECK-NEXT: movl $42, %eax +; CHECK-NEXT: retq entry: %c = icmp eq i32* %x, null @@ -54,14 +49,16 @@ define i32 @imp_null_check_gep_load(i32* %x) { } define i32 @imp_null_check_add_result(i32* %x, i32 %p) { -; CHECK-LABEL: _imp_null_check_add_result: -; CHECK: [[BB0_imp_null_check_add_result:L[^:]+]]: -; CHECK: addl (%rdi), %esi -; CHECK: movl %esi, %eax -; CHECK: retq -; CHECK: [[BB1_imp_null_check_add_result:LBB2_[0-9]+]]: -; CHECK: movl $42, %eax -; CHECK: retq +; CHECK-LABEL: imp_null_check_add_result: +; CHECK: ## %bb.0: ## %entry +; CHECK-NEXT: Ltmp2: +; CHECK-NEXT: addl (%rdi), %esi ## on-fault: LBB2_1 +; CHECK-NEXT: ## %bb.2: ## %not_null +; CHECK-NEXT: movl %esi, %eax +; CHECK-NEXT: retq +; CHECK-NEXT: LBB2_1: ## %is_null +; CHECK-NEXT: movl $42, %eax +; CHECK-NEXT: retq entry: %c = icmp eq i32* %x, null @@ -77,15 +74,17 @@ define i32 @imp_null_check_add_result(i32* %x, i32 %p) { } define i32 @imp_null_check_hoist_over_unrelated_load(i32* %x, i32* %y, i32* %z) { -; CHECK-LABEL: _imp_null_check_hoist_over_unrelated_load: -; CHECK: [[BB0_imp_null_check_hoist_over_unrelated_load:L[^:]+]]: -; CHECK: movl (%rdi), %eax -; CHECK: movl (%rsi), %ecx -; CHECK: movl %ecx, (%rdx) -; CHECK: retq -; CHECK: [[BB1_imp_null_check_hoist_over_unrelated_load:LBB3_[0-9]+]]: -; CHECK: movl $42, %eax -; CHECK: retq +; CHECK-LABEL: imp_null_check_hoist_over_unrelated_load: +; CHECK: ## %bb.0: ## %entry +; CHECK-NEXT: Ltmp3: +; CHECK-NEXT: movl (%rdi), %eax ## on-fault: LBB3_1 +; CHECK-NEXT: ## %bb.2: ## %not_null +; CHECK-NEXT: movl (%rsi), %ecx +; CHECK-NEXT: movl %ecx, (%rdx) +; CHECK-NEXT: retq +; CHECK-NEXT: LBB3_1: ## %is_null +; CHECK-NEXT: movl $42, %eax +; CHECK-NEXT: retq entry: %c = icmp eq i32* %x, null @@ -102,18 +101,21 @@ define i32 @imp_null_check_hoist_over_unrelated_load(i32* %x, i32* %y, i32* %z) } define i32 @imp_null_check_via_mem_comparision(i32* %x, i32 %val) { -; CHECK-LABEL: _imp_null_check_via_mem_comparision -; CHECK: [[BB0_imp_null_check_via_mem_comparision:L[^:]+]]: -; CHECK: cmpl %esi, 4(%rdi) -; CHECK: jge LBB4_2 -; CHECK: movl $100, %eax -; CHECK: retq -; CHECK: [[BB1_imp_null_check_via_mem_comparision:LBB4_[0-9]+]]: -; CHECK: movl $42, %eax -; CHECK: retq -; CHECK: LBB4_2: -; CHECK: movl $200, %eax -; CHECK: retq +; CHECK-LABEL: imp_null_check_via_mem_comparision: +; CHECK: ## %bb.0: ## %entry +; CHECK-NEXT: Ltmp4: +; CHECK-NEXT: cmpl %esi, 4(%rdi) ## on-fault: LBB4_3 +; CHECK-NEXT: ## %bb.1: ## %not_null +; CHECK-NEXT: jge LBB4_2 +; CHECK-NEXT: ## %bb.4: ## %ret_100 +; CHECK-NEXT: movl $100, %eax +; CHECK-NEXT: retq +; CHECK-NEXT: LBB4_3: ## %is_null +; CHECK-NEXT: movl $42, %eax +; CHECK-NEXT: retq +; CHECK-NEXT: LBB4_2: ## %ret_200 +; CHECK-NEXT: movl $200, %eax +; CHECK-NEXT: retq entry: %c = icmp eq i32* %x, null @@ -137,14 +139,17 @@ define i32 @imp_null_check_via_mem_comparision(i32* %x, i32 %val) { define i32 @imp_null_check_gep_load_with_use_dep(i32* %x, i32 %a) { ; CHECK-LABEL: imp_null_check_gep_load_with_use_dep: -; CHECK: [[BB0_imp_null_check_gep_load_with_use_dep:L[^:]+]]: -; CHECK: movl (%rdi), %eax -; CHECK: addl %edi, %esi -; CHECK: leal 4(%rax,%rsi), %eax -; CHECK: retq -; CHECK: [[BB1_imp_null_check_gep_load_with_use_dep:LBB5_[0-9]+]]: -; CHECK: movl $42, %eax -; CHECK: retq +; CHECK: ## %bb.0: ## %entry +; CHECK-NEXT: ## kill: def $esi killed $esi def $rsi +; CHECK-NEXT: Ltmp5: +; CHECK-NEXT: movl (%rdi), %eax ## on-fault: LBB5_1 +; CHECK-NEXT: ## %bb.2: ## %not_null +; CHECK-NEXT: addl %edi, %esi +; CHECK-NEXT: leal 4(%rax,%rsi), %eax +; CHECK-NEXT: retq +; CHECK-NEXT: LBB5_1: ## %is_null +; CHECK-NEXT: movl $42, %eax +; CHECK-NEXT: retq entry: %c = icmp eq i32* %x, null @@ -163,12 +168,14 @@ define i32 @imp_null_check_gep_load_with_use_dep(i32* %x, i32 %a) { } define void @imp_null_check_store(i32* %x) { -; CHECK-LABEL: _imp_null_check_store: -; CHECK: [[BB0_imp_null_check_store:L[^:]+]]: -; CHECK: movl $1, (%rdi) -; CHECK: retq -; CHECK: [[BB1_imp_null_check_store:LBB6_[0-9]+]]: -; CHECK: retq +; CHECK-LABEL: imp_null_check_store: +; CHECK: ## %bb.0: ## %entry +; CHECK-NEXT: Ltmp6: +; CHECK-NEXT: movl $1, (%rdi) ## on-fault: LBB6_1 +; CHECK-NEXT: ## %bb.2: ## %not_null +; CHECK-NEXT: retq +; CHECK-NEXT: LBB6_1: ## %is_null +; CHECK-NEXT: retq entry: %c = icmp eq i32* %x, null @@ -183,13 +190,15 @@ define void @imp_null_check_store(i32* %x) { } define i32 @imp_null_check_neg_gep_load(i32* %x) { -; CHECK-LABEL: _imp_null_check_neg_gep_load: -; CHECK: [[BB0_imp_null_check_neg_gep_load:L[^:]+]]: -; CHECK: movl -128(%rdi), %eax -; CHECK: retq -; CHECK: [[BB1_imp_null_check_neg_gep_load:LBB7_[0-9]+]]: -; CHECK: movl $42, %eax -; CHECK: retq +; CHECK-LABEL: imp_null_check_neg_gep_load: +; CHECK: ## %bb.0: ## %entry +; CHECK-NEXT: Ltmp7: +; CHECK-NEXT: movl -128(%rdi), %eax ## on-fault: LBB7_1 +; CHECK-NEXT: ## %bb.2: ## %not_null +; CHECK-NEXT: retq +; CHECK-NEXT: LBB7_1: ## %is_null +; CHECK-NEXT: movl $42, %eax +; CHECK-NEXT: retq entry: %c = icmp eq i32* %x, null @@ -205,139 +214,3 @@ define i32 @imp_null_check_neg_gep_load(i32* %x) { } !0 = !{} - -; CHECK-LABEL: __LLVM_FaultMaps: - -; Version: -; CHECK-NEXT: .byte 1 - -; Reserved x2 -; CHECK-NEXT: .byte 0 -; CHECK-NEXT: .short 0 - -; # functions: -; CHECK-NEXT: .long 8 - -; FunctionAddr: -; CHECK-NEXT: .quad _imp_null_check_add_result -; NumFaultingPCs -; CHECK-NEXT: .long 1 -; Reserved: -; CHECK-NEXT: .long 0 -; Fault[0].Type: -; CHECK-NEXT: .long 1 -; Fault[0].FaultOffset: -; CHECK-NEXT: .long [[BB0_imp_null_check_add_result]]-_imp_null_check_add_result -; Fault[0].HandlerOffset: -; CHECK-NEXT: .long [[BB1_imp_null_check_add_result]]-_imp_null_check_add_result - -; FunctionAddr: -; CHECK-NEXT: .quad _imp_null_check_gep_load -; NumFaultingPCs -; CHECK-NEXT: .long 1 -; Reserved: -; CHECK-NEXT: .long 0 -; Fault[0].Type: -; CHECK-NEXT: .long 1 -; Fault[0].FaultOffset: -; CHECK-NEXT: .long [[BB0_imp_null_check_gep_load]]-_imp_null_check_gep_load -; Fault[0].HandlerOffset: -; CHECK-NEXT: .long [[BB1_imp_null_check_gep_load]]-_imp_null_check_gep_load - -; FunctionAddr: -; CHECK-NEXT: .quad _imp_null_check_gep_load_with_use_dep -; NumFaultingPCs -; CHECK-NEXT: .long 1 -; Reserved: -; CHECK-NEXT: .long 0 -; Fault[0].Type: -; CHECK-NEXT: .long 1 -; Fault[0].FaultOffset: -; CHECK-NEXT: .long [[BB0_imp_null_check_gep_load_with_use_dep]]-_imp_null_check_gep_load_with_use_dep -; Fault[0].HandlerOffset: -; CHECK-NEXT: .long [[BB1_imp_null_check_gep_load_with_use_dep]]-_imp_null_check_gep_load_with_use_dep - -; FunctionAddr: -; CHECK-NEXT: .quad _imp_null_check_hoist_over_unrelated_load -; NumFaultingPCs -; CHECK-NEXT: .long 1 -; Reserved: -; CHECK-NEXT: .long 0 -; Fault[0].Type: -; CHECK-NEXT: .long 1 -; Fault[0].FaultOffset: -; CHECK-NEXT: .long [[BB0_imp_null_check_hoist_over_unrelated_load]]-_imp_null_check_hoist_over_unrelated_load -; Fault[0].HandlerOffset: -; CHECK-NEXT: .long [[BB1_imp_null_check_hoist_over_unrelated_load]]-_imp_null_check_hoist_over_unrelated_load - -; FunctionAddr: -; CHECK-NEXT: .quad _imp_null_check_load -; NumFaultingPCs -; CHECK-NEXT: .long 1 -; Reserved: -; CHECK-NEXT: .long 0 -; Fault[0].Type: -; CHECK-NEXT: .long 1 -; Fault[0].FaultOffset: -; CHECK-NEXT: .long [[BB0_imp_null_check_load]]-_imp_null_check_load -; Fault[0].HandlerOffset: -; CHECK-NEXT: .long [[BB1_imp_null_check_load]]-_imp_null_check_load - -; FunctionAddr: -; CHECK-NEXT: .quad _imp_null_check_neg_gep_load -; NumFaultingPCs -; CHECK-NEXT: .long 1 -; Reserved: -; CHECK-NEXT: .long 0 -; Fault[0].Type: -; CHECK-NEXT: .long 1 -; Fault[0].FaultOffset: -; CHECK-NEXT: .long [[BB0_imp_null_check_neg_gep_load]]-_imp_null_check_neg_gep_load -; Fault[0].HandlerOffset: -; CHECK-NEXT: .long [[BB1_imp_null_check_neg_gep_load]]-_imp_null_check_neg_gep_load - -; FunctionAddr: -; CHECK-NEXT: .quad _imp_null_check_store -; NumFaultingPCs -; CHECK-NEXT: .long 1 -; Reserved: -; CHECK-NEXT: .long 0 -; Fault[0].Type: -; CHECK-NEXT: .long 3 -; Fault[0].FaultOffset: -; CHECK-NEXT: .long [[BB0_imp_null_check_store]]-_imp_null_check_store -; Fault[0].HandlerOffset: -; CHECK-NEXT: .long [[BB1_imp_null_check_store]]-_imp_null_check_store - -; FunctionAddr: -; CHECK-NEXT: .quad _imp_null_check_via_mem_comparision -; NumFaultingPCs -; CHECK-NEXT: .long 1 -; Reserved: -; CHECK-NEXT: .long 0 -; Fault[0].Type: -; CHECK-NEXT: .long 1 -; Fault[0].FaultOffset: -; CHECK-NEXT: .long [[BB0_imp_null_check_via_mem_comparision]]-_imp_null_check_via_mem_comparision -; Fault[0].HandlerOffset: -; CHECK-NEXT: .long [[BB1_imp_null_check_via_mem_comparision]]-_imp_null_check_via_mem_comparision - -; OBJDUMP: FaultMap table: -; OBJDUMP-NEXT: Version: 0x1 -; OBJDUMP-NEXT: NumFunctions: 8 -; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1 -; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 5 -; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1 -; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 7 -; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1 -; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 9 -; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1 -; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 7 -; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1 -; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 3 -; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1 -; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 4 -; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1 -; OBJDUMP-NEXT: Fault kind: FaultingStore, faulting PC offset: 0, handling PC offset: 7 -; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1 -; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 11