mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-06 03:38:34 +00:00
[ImplicitNullCheck] Fix the bug when dependent instruction accesses memory
It is possible that dependent instruction may access memory. In this case we must reject optimization because the memory change will be visible in null handler basic block. So we will execute an instruction which we must not execute if check fails. Reviewers: sanjoy, reames Reviewed By: sanjoy Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D36392 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310443 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
00a76938ff
commit
0c0ee9fbca
@ -390,8 +390,10 @@ bool ImplicitNullChecks::canHoistInst(MachineInstr *FaultingMI,
|
||||
// We don't want to reason about speculating loads. Note -- at this point
|
||||
// we should have already filtered out all of the other non-speculatable
|
||||
// things, like calls and stores.
|
||||
// We also do not want to hoist stores because it might change the memory
|
||||
// while the FaultingMI may result in faulting.
|
||||
assert(canHandle(DependenceMI) && "Should never have reached here!");
|
||||
if (DependenceMI->mayLoad())
|
||||
if (DependenceMI->mayLoadOrStore())
|
||||
return false;
|
||||
|
||||
for (auto &DependenceMO : DependenceMI->operands()) {
|
||||
|
@ -365,6 +365,18 @@
|
||||
ret i32 undef
|
||||
}
|
||||
|
||||
define i32 @inc_spill_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
|
||||
}
|
||||
|
||||
attributes #0 = { "target-features"="+bmi,+bmi2" }
|
||||
|
||||
!0 = !{}
|
||||
@ -1265,3 +1277,41 @@ body: |
|
||||
RETQ %eax
|
||||
|
||||
...
|
||||
---
|
||||
name: inc_spill_dep
|
||||
# CHECK-LABEL: inc_spill_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
|
||||
stack:
|
||||
- { id: 0, type: spill-slot, offset: -8, size: 8, alignment: 8}
|
||||
liveins:
|
||||
- { reg: '%rdi' }
|
||||
- { reg: '%rsi' }
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: %rdi, %rsi
|
||||
|
||||
%rsp = frame-setup SUB64ri8 %rsp, 8, implicit-def dead %eflags
|
||||
MOV32mr %rsp, 1, %noreg, 0, %noreg, %esi :: (store 4 into %stack.0)
|
||||
TEST64rr %rdi, %rdi, implicit-def %eflags
|
||||
JE_1 %bb.2.is_null, implicit killed %eflags
|
||||
|
||||
bb.1.not_null:
|
||||
liveins: %rdi, %rsi
|
||||
|
||||
%r14d = MOV32rm %rsp, 1, %noreg, 0, %noreg :: (load 4 from %stack.0)
|
||||
MOV64mr %rsp, 1, %noreg, 0, %noreg, %rdi :: (store 8 into %stack.0)
|
||||
%edi = MOV32rm %rdi, 1, %noreg, 8, %noreg :: (load 4 from %ir.ptr)
|
||||
%eax = MOV32rr %edi
|
||||
RETQ %eax
|
||||
|
||||
bb.2.is_null:
|
||||
%eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags
|
||||
RETQ %eax
|
||||
|
||||
...
|
||||
|
Loading…
Reference in New Issue
Block a user