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 ce6bdaf..4b62085 100644
--- a/lib/Target/X86/X86MCInstLower.cpp
+++ b/lib/Target/X86/X86MCInstLower.cpp
@@ -962,6 +962,7 @@
     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 0000000..1701b0f
--- /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 8cfc9c6..d3d2fff 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_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_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_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_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_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 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 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 @@
 }
 
 !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