[PATCH] D48627: [ImplicitNullChecks] Check for rewrite of register used in 'test' instruction

Surya Kumari Jangala via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 29 03:29:48 PDT 2018


jskumari updated this revision to Diff 153461.
jskumari added a comment.

Incorporated review comments.


Repository:
  rL LLVM

https://reviews.llvm.org/D48627

Files:
  lib/CodeGen/ImplicitNullChecks.cpp
  test/CodeGen/X86/implicit-null-chk-reg-rewrite.mir


Index: test/CodeGen/X86/implicit-null-chk-reg-rewrite.mir
===================================================================
--- /dev/null
+++ test/CodeGen/X86/implicit-null-chk-reg-rewrite.mir
@@ -0,0 +1,49 @@
+# RUN: llc -mtriple=x86_64 -run-pass=implicit-null-checks %s -o - | FileCheck %s
+--- |
+
+  define i32 @reg-rewrite(i32* %x) {
+  entry:
+    br i1 undef, label %is_null, label %not_null, !make.implicit !0
+
+  is_null:
+    ret i32 42
+
+  not_null:
+    ret i32 100
+  }
+
+  !0 = !{}
+
+...
+---
+# Check that the TEST instruction is replaced with 
+# FAULTING_OP only if there are no instructions
+# between the TEST and conditional jump
+# that clobber the register used in TEST.
+name:            reg-rewrite
+
+alignment:       4
+tracksRegLiveness: true
+liveins:
+  - { reg: '$rdi' }
+
+body:             |
+  bb.0.entry:
+    liveins: $rdi
+
+    TEST64rr $rdi, $rdi, implicit-def $eflags
+    ; CHECK-LABEL: bb.0.entry
+    ; CHECK-NOT: FAULTING_OP
+    renamable $rdi = MOV64ri 5000
+    JE_1 %bb.2, implicit $eflags
+
+  bb.1.not_null:
+    liveins: $rdi, $rsi
+    
+    $rax = MOV64rm renamable $rdi, 1, $noreg, 4, $noreg
+    RETQ $eax
+
+  bb.2.is_null:
+    $eax = MOV32ri 200
+    RETQ $eax
+...
Index: lib/CodeGen/ImplicitNullChecks.cpp
===================================================================
--- lib/CodeGen/ImplicitNullChecks.cpp
+++ lib/CodeGen/ImplicitNullChecks.cpp
@@ -496,6 +496,32 @@
   if (NotNullSucc->pred_size() != 1)
     return false;
 
+  // To prevent the invalid transformation of the following code:
+  //
+  //   mov %rax, %rcx
+  //   test %rax, %rax
+  //   %rax = ...
+  //   je throw_npe
+  //   mov(%rcx), %r9
+  //   mov(%rax), %r10
+  //
+  // into:
+  //
+  //   mov %rax, %rcx
+  //   %rax = ....
+  //   faulting_load_op("movl (%rax), %r10", throw_npe)
+  //   mov(%rcx), %r9
+  //
+  // we must ensure that there are no instructions between the 'test' and
+  // conditional jump that modify %rax.
+  const unsigned PointerReg = MBP.LHS.getReg();
+
+  assert(MBP.ConditionDef->getParent() ==  &MBB && "Should be in basic block");
+
+  for (auto I = MBB.rbegin(); MBP.ConditionDef != &*I; ++I)
+    if (I->modifiesRegister(PointerReg, TRI))
+      return false;
+
   // Starting with a code fragment like:
   //
   //   test %rax, %rax
@@ -550,8 +576,6 @@
   // ptr could be some non-null invalid reference that never gets loaded from
   // because some_cond is always true.
 
-  const unsigned PointerReg = MBP.LHS.getReg();
-
   SmallVector<MachineInstr *, 8> InstsSeenSoFar;
 
   for (auto &MI : *NotNullSucc) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D48627.153461.patch
Type: text/x-patch
Size: 2589 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180629/42d805d8/attachment.bin>


More information about the llvm-commits mailing list