This is an archive of the discontinued LLVM Phabricator instance.

[ImplicitNullChecks] Be smarter in picking the memory op.
ClosedPublic

Authored by sanjoy on Jul 8 2015, 2:34 PM.

Details

Summary

Before this change ImplicitNullChecks would only pick loads of the form:

  test Reg, Reg
  jz elsewhere
fallthrough:
  movl 32(Reg), Reg2

but not (say)

  test Reg, Reg
  jz elsewhere
fallthrough:
  inc Reg3
  movl 32(Reg), Reg2

This change teaches ImplicitNullChecks to look through "unrelated"
instructions like inc Reg3 when searching for a load instruction
to convert to a trapping load.

Diff Detail

Event Timeline

sanjoy updated this revision to Diff 29288.Jul 8 2015, 2:34 PM
sanjoy retitled this revision from to [ImplicitNullChecks] Be smarter in picking the memory op..
sanjoy updated this object.
sanjoy added reviewers: atrick, JosephTremoulet, reames.
sanjoy added a subscriber: llvm-commits.
reames added inline comments.Jul 8 2015, 10:50 PM
lib/CodeGen/ImplicitNullChecks.cpp
212

Naming wise, this is a bit confusing. It's specifically whether the instruction is safe to reorder past the previously saved information. At first, I had expected this predicate to by applied to each instruction skipped.

255

If one of these loads potentially overlap with the value we eventually load from, don't we end up with a faulting instruction not recorded in the side table?

(To say this differently, I think you need to account for aliasing in your loads.)

sanjoy added inline comments.Jul 8 2015, 11:58 PM
lib/CodeGen/ImplicitNullChecks.cpp
212

Makes sense, I'll try and come up with a better name tomorrow.

255

The faulting instruction is reordered to where the original branch was, so the control flow remains intact. So if I start with

test reg, reg
jz throw_NPE
maybe_aliasing_load
candidate_load

I'll end up with

candidate_load ;; handler_pc = throw_NPE
maybe_aliasing_load

so maybe_aliasing_load won't execute if reg was null.

Does this answer your question?

LGTM, aside from the one question.

lib/CodeGen/ImplicitNullChecks.cpp
274–278

This may just be my ignorance of machine instruction modeling, but this reads like you're taking care to skip explicit use operands; why is that?

This revision was automatically updated to reflect the committed changes.