This is an archive of the discontinued LLVM Phabricator instance.

[ImplicitNullChecks] Check for rewrite of register used in 'test' instruction
ClosedPublic

Authored by jskumari on Jun 27 2018, 3:27 AM.

Details

Summary

The following code pattern:

mov %rax, %rcx
test %rax, %rax
%rax = ....
je  throw_npe
mov(%rcx), %r9
mov(%rax), %r10

gets transformed into the following incorrect code after implicit null check pass:

 mov %rax, %rcx
%rax = ....
faulting_load_op("movl (%rax), %r10", throw_npe)
mov(%rcx), %r9

For implicit null check pass, if the register that is checked for null value (ie, the register used in the 'test' instruction) is written into before the condition jump, we should avoid doing the optimization.

Diff Detail

Repository
rL LLVM

Event Timeline

jskumari created this revision.Jun 27 2018, 3:27 AM
skatkov added inline comments.Jun 27 2018, 10:00 PM
lib/CodeGen/ImplicitNullChecks.cpp
503

This form of comment is useful for understanding the reasoning of the bug but after it is landed it will be difficult to read this comment..
why it is converted in this way?!

I would suggest to re-phrase it. Something like, to prevent the invalid transformation ... we must ensure that ...

512

There is also the same assignment later:
const unsigned PointerReg.

514

I would suggest to move this check after "if (NotNullSucc->pred_size() != 1)" because the later seems simpler.

514

I would add an assert that MBP.ConditionDef is in MBB.

Test, actually can be simplified bit if you do not mind.

test/CodeGen/X86/implicit-null-chk-reg-rewrite.mir
50

Why do you need this?

52

I guess you do not need this CMP for reproducing the failure? just return result of the and will be enough?
Do I miss anything?

jskumari updated this revision to Diff 153461.Jun 29 2018, 3:29 AM

Incorporated review comments.

skatkov accepted this revision.Jul 1 2018, 7:30 PM
This revision is now accepted and ready to land.Jul 1 2018, 7:30 PM
This revision was automatically updated to reflect the committed changes.