[PATCH] D111515: [InstCombine] Remove attributes after hoisting free above null check

Shoaib Meenai via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 10 14:11:52 PDT 2021


smeenai created this revision.
smeenai added reviewers: jdoerfert, nikic, lebedev.ri, aqjune.
Herald added a subscriber: hiraditya.
smeenai requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

If the parameter had been annotated as nonnull because of the null
check, we want to remove the attribute, since it may no longer apply and
could result in miscompiles if left. Similarly, we also want to remove
undef-implying attributes, since they may not apply anymore either.

Fixes PR52110.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D111515

Files:
  llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
  llvm/test/Transforms/InstCombine/malloc-free.ll


Index: llvm/test/Transforms/InstCombine/malloc-free.ll
===================================================================
--- llvm/test/Transforms/InstCombine/malloc-free.ll
+++ llvm/test/Transforms/InstCombine/malloc-free.ll
@@ -170,6 +170,55 @@
   ret void
 }
 
+;; Test that undef and poison-implying attributes are stripped from the call
+;; when it's moved, since they may no longer be valid and result in miscompiles
+;; if not dropped.
+define void @test_nonnull_free_move(i8* %foo) minsize {
+; CHECK-LABEL: @test_nonnull_free_move(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8* [[FOO:%.*]], null
+; CHECK-NEXT:    tail call void @free(i8* [[FOO]])
+; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    br label [[IF_END]]
+; CHECK:       if.end:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %tobool = icmp eq i8* %foo, null
+  br i1 %tobool, label %if.end, label %if.then
+
+if.then:                                          ; preds = %entry
+  tail call void @free(i8* nonnull %foo)
+  br label %if.end
+
+if.end:                                           ; preds = %entry, %if.then
+  ret void
+}
+
+define void @test_dereferenceable_free_move(i8* %foo) minsize {
+; CHECK-LABEL: @test_dereferenceable_free_move(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8* [[FOO:%.*]], null
+; CHECK-NEXT:    tail call void @free(i8* [[FOO]])
+; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    br label [[IF_END]]
+; CHECK:       if.end:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %tobool = icmp eq i8* %foo, null
+  br i1 %tobool, label %if.end, label %if.then
+
+if.then:                                          ; preds = %entry
+  tail call void @free(i8* dereferenceable(1) %foo)
+  br label %if.end
+
+if.end:                                           ; preds = %entry, %if.then
+  ret void
+}
+
 ; The next four tests cover the semantics of the nofree attributes.  These
 ; are thought to be legal transforms, but an implementation thereof has
 ; been reverted once due to difficult to isolate fallout.
Index: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2812,6 +2812,15 @@
   }
   assert(FreeInstrBB->size() == 1 &&
          "Only the branch instruction should remain");
+
+  // Now that we've moved the call, its previous attributes might not apply
+  // (e.g. the parameter might have been annotated as nonnull because of the
+  // null check, but we've now hoisted the call above the null check). Remove
+  // any atttributes which may result in undef or poison since they might not
+  // apply anymore and would result in miscompiles if kept.
+  FI.dropUndefImplyingAttrsAndUnknownMetadata();
+  FI.removeParamAttr(0, Attribute::NonNull);
+
   return &FI;
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D111515.378535.patch
Type: text/x-patch
Size: 3061 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211010/02035e5a/attachment.bin>


More information about the llvm-commits mailing list