diff options
| author | Sanjoy Das <sanjoy@playingwithpointers.com> | 2017-02-07 19:19:49 +0000 |
|---|---|---|
| committer | Sanjoy Das <sanjoy@playingwithpointers.com> | 2017-02-07 19:19:49 +0000 |
| commit | 2f63cbcc0c508c502e1f59cd911a36f73d1c460a (patch) | |
| tree | 922f8ec26ff5fdcd0b29a58cda5655b363933aad /llvm/test | |
| parent | ef6d573f67466494fd65dfce650908043527da37 (diff) | |
| download | bcm5719-llvm-2f63cbcc0c508c502e1f59cd911a36f73d1c460a.tar.gz bcm5719-llvm-2f63cbcc0c508c502e1f59cd911a36f73d1c460a.zip | |
[ImplicitNullCheck] Extend Implicit Null Check scope by using stores
Summary:
This change allows usage of store instruction for implicit null check.
Memory Aliasing Analisys is not used and change conservatively supposes
that any store and load may access the same memory. As a result
re-ordering of store-store, store-load and load-store is prohibited.
Patch by Serguei Katkov!
Reviewers: reames, sanjoy
Reviewed By: sanjoy
Subscribers: atrick, llvm-commits
Differential Revision: https://reviews.llvm.org/D29400
llvm-svn: 294338
Diffstat (limited to 'llvm/test')
| -rw-r--r-- | llvm/test/CodeGen/X86/block-placement.mir | 4 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/implicit-null-check.ll | 41 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/implicit-null-checks.mir | 658 |
3 files changed, 689 insertions, 14 deletions
diff --git a/llvm/test/CodeGen/X86/block-placement.mir b/llvm/test/CodeGen/X86/block-placement.mir index 7d13c3e529c..c0cd7057d5c 100644 --- a/llvm/test/CodeGen/X86/block-placement.mir +++ b/llvm/test/CodeGen/X86/block-placement.mir @@ -46,7 +46,7 @@ liveins: - { reg: '%rdi' } - { reg: '%esi' } -# CHECK: %eax = FAULTING_LOAD_OP %bb.3.null, 1684, killed %rdi, 1, _, 0, _ :: (load 4 from %ir.ptr) +# CHECK: %eax = FAULTING_OP 1, %bb.3.null, 1684, killed %rdi, 1, _, 0, _ :: (load 4 from %ir.ptr) # CHECK-NEXT: JMP_1 %bb.2.not_null # CHECK: bb.3.null: # CHECK: bb.4.right: @@ -66,7 +66,7 @@ body: | successors: %bb.2.null(0x7ffff800), %bb.4.not_null(0x00000800) liveins: %rdi - %eax = FAULTING_LOAD_OP %bb.2.null, 1684, killed %rdi, 1, _, 0, _ :: (load 4 from %ir.ptr) + %eax = FAULTING_OP 1, %bb.2.null, 1684, killed %rdi, 1, _, 0, _ :: (load 4 from %ir.ptr) JMP_1 %bb.4.not_null bb.4.not_null: diff --git a/llvm/test/CodeGen/X86/implicit-null-check.ll b/llvm/test/CodeGen/X86/implicit-null-check.ll index 286b4fa7a81..ee795667cdb 100644 --- a/llvm/test/CodeGen/X86/implicit-null-check.ll +++ b/llvm/test/CodeGen/X86/implicit-null-check.ll @@ -162,6 +162,26 @@ define i32 @imp_null_check_gep_load_with_use_dep(i32* %x, i32 %a) { ret i32 %z } +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 + + 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: @@ -174,7 +194,7 @@ define i32 @imp_null_check_gep_load_with_use_dep(i32* %x, i32 %a) { ; CHECK-NEXT: .short 0 ; # functions: -; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 7 ; FunctionAddr: ; CHECK-NEXT: .quad _imp_null_check_add_result @@ -242,6 +262,19 @@ define i32 @imp_null_check_gep_load_with_use_dep(i32* %x, i32 %a) { ; 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 + +; FunctionAddr: ; CHECK-NEXT: .quad _imp_null_check_via_mem_comparision ; NumFaultingPCs ; CHECK-NEXT: .long 1 @@ -256,7 +289,7 @@ define i32 @imp_null_check_gep_load_with_use_dep(i32* %x, i32 %a) { ; OBJDUMP: FaultMap table: ; OBJDUMP-NEXT: Version: 0x1 -; OBJDUMP-NEXT: NumFunctions: 6 +; OBJDUMP-NEXT: NumFunctions: 7 ; 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 @@ -267,3 +300,7 @@ define i32 @imp_null_check_gep_load_with_use_dep(i32* %x, i32 %a) { ; 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: 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 diff --git a/llvm/test/CodeGen/X86/implicit-null-checks.mir b/llvm/test/CodeGen/X86/implicit-null-checks.mir index 97a1d6fff7c..e5cab151bf7 100644 --- a/llvm/test/CodeGen/X86/implicit-null-checks.mir +++ b/llvm/test/CodeGen/X86/implicit-null-checks.mir @@ -143,8 +143,6 @@ ret i32 0 } - attributes #0 = { "target-features"="+bmi,+bmi2" } - define i32 @imp_null_check_gep_load_with_use_dep(i32* %x, i32 %a) { entry: %c = icmp eq i32* %x, null @@ -174,6 +172,177 @@ ret i32 undef } + define void @inc_store(i32* %ptr, i32 %val) { + entry: + %ptr_is_null = icmp eq i32* %ptr, null + br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 + + not_null: + ret void + + is_null: + ret void + } + + define void @inc_store_plus_offset(i32* %ptr, i32 %val) { + entry: + %ptr_is_null = icmp eq i32* %ptr, null + br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 + + not_null: + ret void + + is_null: + ret void + } + + define void @inc_store_with_dep(i32* %ptr, i32 %val) { + entry: + %ptr_is_null = icmp eq i32* %ptr, null + br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 + + not_null: + ret void + + is_null: + ret void + } + + define i32 @inc_store_with_dep_in_null(i32* %ptr, i32 %val) { + entry: + %ptr_is_null = icmp eq i32* %ptr, null + br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 + + not_null: + ret i32 undef + + is_null: + ret i32 undef + } + + define void @inc_store_with_volatile(i32* %ptr, i32 %val) { + entry: + %ptr_is_null = icmp eq i32* %ptr, null + br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 + + not_null: + ret void + + is_null: + ret void + } + + define void @inc_store_with_two_dep(i32* %ptr, i32 %val) { + entry: + %ptr_is_null = icmp eq i32* %ptr, null + br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 + + not_null: + ret void + + is_null: + ret void + } + + define void @inc_store_with_redefined_base(i32* %ptr, i32 %val) { + entry: + %ptr_is_null = icmp eq i32* %ptr, null + br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 + + not_null: + ret void + + is_null: + ret void + } + + define i32 @inc_store_with_reused_base(i32* %ptr, i32 %val) { + entry: + %ptr_is_null = icmp eq i32* %ptr, null + br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 + + not_null: + ret i32 undef + + is_null: + ret i32 undef + } + + define i32 @inc_store_across_call(i32* %ptr) { + entry: + %ptr_is_null = icmp eq i32* %ptr, null + br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 + + not_null: + call void @f() + ret i32 undef + + is_null: + ret i32 undef + } + + define i32 @inc_store_with_dep_in_dep(i32* %ptr, i32 %val) { + entry: + %ptr_is_null = icmp eq i32* %ptr, null + br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 + + not_null: + ret i32 undef + + is_null: + ret i32 undef + } + + define i32 @inc_store_with_load_over_store(i32* %ptr, i32* %ptr2) { + entry: + %ptr_is_null = icmp eq i32* %ptr, null + br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 + + not_null: + ret i32 undef + + is_null: + ret i32 undef + } + + define i32 @inc_store_with_store_over_load(i32* %ptr, i32* %ptr2) { + entry: + %ptr_is_null = icmp eq i32* %ptr, null + br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 + + not_null: + ret i32 undef + + is_null: + ret i32 undef + } + + define void @inc_store_with_store_over_store(i32* %ptr, i32* %ptr2) { + entry: + %ptr_is_null = icmp eq i32* %ptr, null + br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 + + not_null: + ret void + + is_null: + ret void + } + + define void @inc_store_with_load_and_store(i32* %ptr, i32* %ptr2) { + entry: + %ptr_is_null = icmp eq i32* %ptr, null + br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 + + not_null: + ret void + + is_null: + ret void + } + + attributes #0 = { "target-features"="+bmi,+bmi2" } + !0 = !{} ... --- @@ -186,7 +355,7 @@ liveins: - { reg: '%esi' } # CHECK: bb.0.entry: # CHECK: %eax = MOV32ri 2200000 -# CHECK-NEXT: %eax = FAULTING_LOAD_OP %bb.3.is_null, {{[0-9]+}}, killed %eax, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x) +# CHECK-NEXT: %eax = FAULTING_OP 1, %bb.3.is_null, {{[0-9]+}}, killed %eax, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x) # CHECK-NEXT: JMP_1 %bb.1.not_null body: | @@ -360,7 +529,7 @@ liveins: - { reg: '%rsi' } # CHECK: bb.0.entry: # CHECK: %rbx = MOV64rr %rdx -# CHECK-NEXT: %rdi = FAULTING_LOAD_OP %bb.3.is_null, {{[0-9]+}}, killed %rbx, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x) +# CHECK-NEXT: %rdi = FAULTING_OP 1, %bb.3.is_null, {{[0-9]+}}, killed %rbx, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x) body: | bb.0.entry: @@ -405,7 +574,7 @@ calleeSavedRegisters: [ '%bh', '%bl', '%bp', '%bpl', '%bx', '%ebp', '%ebx', '%r12b', '%r13b', '%r14b', '%r15b', '%r12d', '%r13d', '%r14d', '%r15d', '%r12w', '%r13w', '%r14w', '%r15w' ] # CHECK: body: -# CHECK-NOT: FAULTING_LOAD_OP +# CHECK-NOT: FAULTING_OP # CHECK: bb.1.stay: # CHECK: CALL64pcrel32 body: | @@ -438,7 +607,7 @@ body: | name: dependency_live_in_hazard # CHECK-LABEL: name: dependency_live_in_hazard # CHECK: bb.0.entry: -# CHECK-NOT: FAULTING_LOAD_OP +# CHECK-NOT: FAULTING_OP # CHECK: bb.1.not_null: # Make sure that the BEXTR32rm instruction below is not used to emit @@ -474,9 +643,9 @@ body: | ... --- name: use_alternate_load_op -# CHECK-LABEL: use_alternate_load_op +# CHECK-LABEL: name: use_alternate_load_op # CHECK: bb.0.entry: -# CHECK: %r10 = FAULTING_LOAD_OP %bb.2.is_null, {{[0-9]+}}, killed %rdi, 1, _, 0, _ +# CHECK: %r10 = FAULTING_OP 1, %bb.2.is_null, {{[0-9]+}}, killed %rdi, 1, _, 0, _ # CHECK-NEXT: JMP_1 %bb.1.not_null # CHECK: bb.1.not_null @@ -508,8 +677,9 @@ body: | ... --- name: imp_null_check_gep_load_with_use_dep +# CHECK-LABEL: name: imp_null_check_gep_load_with_use_dep # CHECK: bb.0.entry: -# CHECK: %eax = FAULTING_LOAD_OP %bb.2.is_null, {{[0-9]+}}, killed %rdi, 1, _, 0, _, implicit-def %rax :: (load 4 from %ir.x) +# CHECK: %eax = FAULTING_OP 1, %bb.2.is_null, {{[0-9]+}}, killed %rdi, 1, _, 0, _, implicit-def %rax :: (load 4 from %ir.x) # CHECK-NEXT: JMP_1 %bb.1.not_null alignment: 4 tracksRegLiveness: true @@ -539,9 +709,10 @@ body: | ... --- name: imp_null_check_load_with_base_sep +# CHECK-LABEL: name: imp_null_check_load_with_base_sep # CHECK: bb.0.entry: # CHECK: %rsi = ADD64rr %rsi, %rdi, implicit-def dead %eflags -# CHECK-NEXT: %esi = FAULTING_LOAD_OP %bb.2.is_null, {{[0-9]+}}, killed %esi, %rdi, 1, _, 0, _, implicit-def dead %eflags +# CHECK-NEXT: %esi = FAULTING_OP 1, %bb.2.is_null, {{[0-9]+}}, killed %esi, %rdi, 1, _, 0, _, implicit-def dead %eflags # CHECK-NEXT: JMP_1 %bb.1.not_null alignment: 4 tracksRegLiveness: true @@ -569,3 +740,470 @@ body: | RETQ %eax ... +--- +name: inc_store +# CHECK-LABEL: name: inc_store +# CHECK: bb.0.entry: +# CHECK: _ = FAULTING_OP 3, %bb.2.is_null, {{[0-9]+}}, killed %rdi, 1, _, 0, _, killed %rsi +# CHECK-NEXT: JMP_1 %bb.1.not_null +# CHECK: bb.1.not_null + +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '%rdi' } + - { reg: '%rsi' } +body: | + bb.0.entry: + successors: %bb.2.is_null, %bb.1.not_null + liveins: %rdi, %rsi + + TEST64rr %rdi, %rdi, implicit-def %eflags + JE_1 %bb.2.is_null, implicit killed %eflags + + bb.1.not_null: + liveins: %rdi, %rsi + + MOV64mr killed %rdi, 1, _, 0, _, killed %rsi + RETQ + + bb.2.is_null: + RETQ + +... +--- +name: inc_store_plus_offset +# CHECK-LABEL: inc_store_plus_offset +# CHECK: bb.0.entry: +# CHECK: _ = FAULTING_OP 3, %bb.2.is_null, {{[0-9]+}}, killed %rdi, 1, _, 16, _, killed %rsi +# CHECK-NEXT: JMP_1 %bb.1.not_null +# CHECK: bb.1.not_null + +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '%rdi' } + - { reg: '%rsi' } +body: | + bb.0.entry: + successors: %bb.2.is_null, %bb.1.not_null + liveins: %rdi, %rsi + + TEST64rr %rdi, %rdi, implicit-def %eflags + JE_1 %bb.2.is_null, implicit killed %eflags + + bb.1.not_null: + liveins: %rdi, %rsi + + MOV64mr killed %rdi, 1, _, 16, _, killed %rsi + RETQ + + bb.2.is_null: + RETQ + +... +--- +name: inc_store_with_dep +# CHECK-LABEL: inc_store_with_dep +# CHECK: bb.0.entry: +# CHECK: %esi = ADD32rr killed %esi, killed %esi, implicit-def dead %eflags +# CHECK-NEXT: _ = FAULTING_OP 3, %bb.2.is_null, {{[0-9]+}}, killed %rdi, 1, _, 16, _, killed %esi +# CHECK-NEXT: JMP_1 %bb.1.not_null +# CHECK: bb.1.not_null + +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '%rdi' } + - { reg: '%rsi' } +body: | + bb.0.entry: + successors: %bb.2.is_null, %bb.1.not_null + liveins: %rdi, %rsi + + TEST64rr %rdi, %rdi, implicit-def %eflags + JE_1 %bb.2.is_null, implicit killed %eflags + + bb.1.not_null: + liveins: %rdi, %rsi + + %esi = ADD32rr killed %esi, killed %esi, implicit-def dead %eflags + MOV32mr killed %rdi, 1, _, 16, _, killed %esi + RETQ + + bb.2.is_null: + RETQ + +... +--- +name: inc_store_with_dep_in_null +# CHECK-LABEL: inc_store_with_dep_in_null +# CHECK: bb.0.entry: +# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags +# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags +# CHECK: bb.1.not_null + +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '%rdi' } + - { reg: '%rsi' } +body: | + bb.0.entry: + successors: %bb.2.is_null, %bb.1.not_null + liveins: %rdi, %rsi + + TEST64rr %rdi, %rdi, implicit-def %eflags + JE_1 %bb.2.is_null, implicit killed %eflags + + bb.1.not_null: + liveins: %rdi, %rsi + + %esi = ADD32rr %esi, %esi, implicit-def dead %eflags + MOV32mr killed %rdi, 1, _, 0, _, %esi + %eax = MOV32rr killed %esi + RETQ %eax + + bb.2.is_null: + liveins: %rsi + + %eax = MOV32rr killed %esi + RETQ %eax + +... +--- +name: inc_store_with_volatile +# CHECK-LABEL: inc_store_with_volatile +# CHECK: bb.0.entry: +# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags +# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags +# CHECK: bb.1.not_null + +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '%rdi' } + - { reg: '%rsi' } +body: | + bb.0.entry: + successors: %bb.2.is_null, %bb.1.not_null + liveins: %rdi, %rsi + + TEST64rr %rdi, %rdi, implicit-def %eflags + JE_1 %bb.2.is_null, implicit killed %eflags + + bb.1.not_null: + liveins: %rdi, %rsi + + MOV32mr killed %rdi, 1, _, 0, _, killed %esi :: (volatile store 4 into %ir.ptr) + RETQ + + bb.2.is_null: + RETQ + +... +--- +name: inc_store_with_two_dep +# CHECK-LABEL: inc_store_with_two_dep +# CHECK: bb.0.entry: +# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags +# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags +# CHECK: bb.1.not_null + +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '%rdi' } + - { reg: '%rsi' } +body: | + bb.0.entry: + successors: %bb.2.is_null, %bb.1.not_null + liveins: %rdi, %rsi + + TEST64rr %rdi, %rdi, implicit-def %eflags + JE_1 %bb.2.is_null, implicit killed %eflags + + bb.1.not_null: + liveins: %rdi, %rsi + + %esi = ADD32rr killed %esi, killed %esi, implicit-def dead %eflags + %esi = ADD32ri killed %esi, 15, implicit-def dead %eflags + MOV32mr killed %rdi, 1, _, 16, _, killed %esi + RETQ + + bb.2.is_null: + RETQ + +... +--- +name: inc_store_with_redefined_base +# CHECK-LABEL: inc_store_with_redefined_base +# CHECK: bb.0.entry: +# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags +# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags +# CHECK: bb.1.not_null + +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '%rdi' } + - { reg: '%rsi' } +body: | + bb.0.entry: + successors: %bb.2.is_null, %bb.1.not_null + liveins: %rdi, %rsi + + TEST64rr %rdi, %rdi, implicit-def %eflags + JE_1 %bb.2.is_null, implicit killed %eflags + + bb.1.not_null: + liveins: %rdi, %rsi + + %rdi = ADD64rr killed %rdi, killed %rdi, implicit-def dead %eflags + MOV32mr killed %rdi, 1, _, 16, _, killed %esi + RETQ + + bb.2.is_null: + RETQ + +... +--- +name: inc_store_with_reused_base +# CHECK-LABEL: inc_store_with_reused_base +# CHECK: bb.0.entry: +# CHECK: _ = FAULTING_OP 3, %bb.2.is_null, {{[0-9]+}}, killed %rdi, 1, _, 16, _, killed %esi +# CHECK-NEXT: JMP_1 %bb.1.not_null +# CHECK: bb.1.not_null + +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '%rdi' } + - { reg: '%rsi' } +body: | + bb.0.entry: + successors: %bb.2.is_null, %bb.1.not_null + liveins: %rdi, %rsi + + TEST64rr %rdi, %rdi, implicit-def %eflags + JE_1 %bb.2.is_null, implicit killed %eflags + + bb.1.not_null: + liveins: %rdi, %rsi + + %rax = MOV64rr %rdi + MOV32mr killed %rdi, 1, _, 16, _, killed %esi + RETQ %eax + + bb.2.is_null: + %rax = XOR64rr undef %rax, undef %rax, implicit-def dead %eflags + RETQ %eax + +... +--- +name: inc_store_across_call +# CHECK-LABEL: inc_store_across_call +# CHECK: bb.0.entry: +# CHECK: TEST64rr %rbx, %rbx, implicit-def %eflags +# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags +# CHECK: bb.1.not_null + +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '%rdi' } +calleeSavedRegisters: [ '%bh', '%bl', '%bp', '%bpl', '%bx', '%ebp', '%ebx', + '%rbp', '%rbx', '%r12', '%r13', '%r14', '%r15', + '%r12b', '%r13b', '%r14b', '%r15b', '%r12d', '%r13d', + '%r14d', '%r15d', '%r12w', '%r13w', '%r14w', '%r15w' ] +body: | + bb.0.entry: + successors: %bb.2.is_null, %bb.1.not_null + liveins: %rdi, %rbx + + frame-setup PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp + CFI_INSTRUCTION def_cfa_offset 16 + CFI_INSTRUCTION offset %rbx, -16 + %rbx = MOV64rr killed %rdi + TEST64rr %rbx, %rbx, implicit-def %eflags + JE_1 %bb.2.is_null, implicit killed %eflags + + bb.1.not_null: + liveins: %rbx + + CALL64pcrel32 @f, csr_64, implicit %rsp, implicit-def %rsp + MOV32mi %rbx, 1, _, 0, _, 20 + %rax = MOV64rr killed %rbx + %rbx = POP64r implicit-def %rsp, implicit %rsp + RETQ %eax + + bb.2.is_null: + %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags + %rbx = POP64r implicit-def %rsp, implicit %rsp + RETQ %eax + +... +--- +name: inc_store_with_dep_in_dep +# CHECK-LABEL: inc_store_with_dep_in_dep +# CHECK: bb.0.entry: +# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags +# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags +# CHECK: bb.1.not_null + +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '%rdi' } + - { reg: '%rsi' } +body: | + bb.0.entry: + successors: %bb.2.is_null, %bb.1.not_null + liveins: %rdi, %rsi + + TEST64rr %rdi, %rdi, implicit-def %eflags + JE_1 %bb.2.is_null, implicit killed %eflags + + bb.1.not_null: + liveins: %rdi, %rsi + + %eax = MOV32rr %esi + %esi = ADD32ri killed %esi, 15, implicit-def dead %eflags + MOV32mr killed %rdi, 1, _, 0, _, killed %esi + RETQ %eax + + bb.2.is_null: + %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags + RETQ %eax + +... +--- +name: inc_store_with_load_over_store +# CHECK-LABEL: inc_store_with_load_over_store +# CHECK: bb.0.entry: +# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags +# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags +# CHECK: bb.1.not_null + +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '%rdi' } + - { reg: '%rsi' } +body: | + bb.0.entry: + successors: %bb.2.is_null, %bb.1.not_null + liveins: %rdi, %rsi + + TEST64rr %rdi, %rdi, implicit-def %eflags + JE_1 %bb.2.is_null, implicit killed %eflags + + bb.1.not_null: + liveins: %rdi, %rsi + + MOV32mi killed %rsi, 1, _, 0, _, 2 + %eax = MOV32rm killed %rdi, 1, _, 0, _ + RETQ %eax + + bb.2.is_null: + %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags + RETQ %eax + +... +--- +name: inc_store_with_store_over_load +# CHECK-LABEL: inc_store_with_store_over_load +# CHECK: bb.0.entry: +# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags +# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags +# CHECK: bb.1.not_null + +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '%rdi' } + - { reg: '%rsi' } +body: | + bb.0.entry: + successors: %bb.2.is_null, %bb.1.not_null + liveins: %rdi, %rsi + + TEST64rr %rdi, %rdi, implicit-def %eflags + JE_1 %bb.2.is_null, implicit killed %eflags + + bb.1.not_null: + liveins: %rdi, %rsi + + %eax = MOV32rm killed %rsi, 1, _, 0, _ + MOV32mi killed %rdi, 1, _, 0, _, 2 + RETQ %eax + + bb.2.is_null: + %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags + RETQ %eax + +... +--- +name: inc_store_with_store_over_store +# CHECK-LABEL: inc_store_with_store_over_store +# CHECK: bb.0.entry: +# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags +# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags +# CHECK: bb.1.not_null + +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '%rdi' } + - { reg: '%rsi' } +body: | + bb.0.entry: + successors: %bb.2.is_null, %bb.1.not_null + liveins: %rdi, %rsi + + TEST64rr %rdi, %rdi, implicit-def %eflags + JE_1 %bb.2.is_null, implicit killed %eflags + + bb.1.not_null: + liveins: %rdi, %rsi + + MOV32mi killed %rsi, 1, _, 0, _, 3 + MOV32mi killed %rdi, 1, _, 0, _, 2 + RETQ + + bb.2.is_null: + RETQ + +... +--- +name: inc_store_with_load_and_store +# CHECK-LABEL: inc_store_with_load_and_store +# CHECK: bb.0.entry: +# CHECK: _ = FAULTING_OP 2, %bb.2.is_null, {{[0-9]+}}, killed %rdi, 1, _, 0, _, killed %esi, implicit-def dead %eflags +# CHECK-NEXT: JMP_1 %bb.1.not_null +# CHECK: bb.1.not_null + +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '%rdi' } + - { reg: '%rsi' } +body: | + bb.0.entry: + successors: %bb.2.is_null, %bb.1.not_null + liveins: %rdi, %rsi + + TEST64rr %rdi, %rdi, implicit-def %eflags + JE_1 %bb.2.is_null, implicit killed %eflags + + bb.1.not_null: + liveins: %rdi, %rsi + + %esi = ADD32rr %esi, %esi, implicit-def dead %eflags + ADD32mr killed %rdi, 1, _, 0, _, killed %esi, implicit-def dead %eflags + RETQ + + bb.2.is_null: + RETQ + +... |

