[llvm] 055779a - Revert "[InstCombine] keep assumption before sinking calls"

Bob Haarman via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 5 10:48:51 PST 2019


Author: Bob Haarman
Date: 2019-12-05T10:39:34-08:00
New Revision: 055779a9ac11e56442cbcdc73da59f8bce7ce57d

URL: https://github.com/llvm/llvm-project/commit/055779a9ac11e56442cbcdc73da59f8bce7ce57d
DIFF: https://github.com/llvm/llvm-project/commit/055779a9ac11e56442cbcdc73da59f8bce7ce57d.diff

LOG: Revert "[InstCombine] keep assumption before sinking calls"

Summary:
This reverts commit c3b06d0c393e533eab712922911d14e5a079fa5d.

Reason for revert: Caused miscompiles when inserting assume for undef.

Also adds a test to prevent similar breakage in future.

Fixes PR44154.

Reviewers: rnk, jdoerfert, efriedma, xbolva00

Reviewed By: rnk

Subscribers: thakis, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D70933

Added: 
    llvm/test/Transforms/InstCombine/unused-nonnull.ll

Modified: 
    llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Removed: 
    llvm/test/Transforms/InstCombine/assume-replacing-call.ll


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index faaf5dcb2a45..5383da8fd869 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3147,8 +3147,7 @@ Instruction *InstCombiner::visitFreeze(FreezeInst &I) {
 /// beginning of DestBlock, which can only happen if it's safe to move the
 /// instruction past all of the instructions between it and the end of its
 /// block.
-static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock,
-                                 InstCombiner::BuilderTy &Builder) {
+static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock) {
   assert(I->hasOneUse() && "Invariants didn't hold!");
   BasicBlock *SrcBlock = I->getParent();
 
@@ -3182,24 +3181,6 @@ static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock,
       if (Scan->mayWriteToMemory())
         return false;
   }
-
-  // If this instruction was providing nonnull guarantees insert assumptions for
-  // nonnull call site arguments.
-  if (auto CS = dyn_cast<CallBase>(I)) {
-    for (unsigned Idx = 0; Idx != CS->getNumArgOperands(); Idx++)
-      if (CS->paramHasAttr(Idx, Attribute::NonNull) ||
-          (CS->paramHasAttr(Idx, Attribute::Dereferenceable) &&
-           !llvm::NullPointerIsDefined(CS->getFunction(),
-                                       CS->getArgOperand(Idx)
-                                           ->getType()
-                                           ->getPointerAddressSpace()))) {
-        Value *V = CS->getArgOperand(Idx);
-
-        Builder.SetInsertPoint(I->getParent(), I->getIterator());
-        Builder.CreateAssumption(Builder.CreateIsNotNull(V));
-      }
-  }
-
   BasicBlock::iterator InsertPos = DestBlock->getFirstInsertionPt();
   I->moveBefore(&*InsertPos);
   ++NumSunkInst;
@@ -3334,7 +3315,7 @@ bool InstCombiner::run() {
         // otherwise), we can keep going.
         if (UserIsSuccessor && UserParent->getUniquePredecessor()) {
           // Okay, the CFG is simple enough, try to sink this instruction.
-          if (TryToSinkInstruction(I, UserParent, Builder)) {
+          if (TryToSinkInstruction(I, UserParent)) {
             LLVM_DEBUG(dbgs() << "IC: Sink: " << *I << '\n');
             MadeIRChange = true;
             // We'll add uses of the sunk instruction below, but since sinking

diff  --git a/llvm/test/Transforms/InstCombine/assume-replacing-call.ll b/llvm/test/Transforms/InstCombine/assume-replacing-call.ll
deleted file mode 100644
index e039f61f67e8..000000000000
--- a/llvm/test/Transforms/InstCombine/assume-replacing-call.ll
+++ /dev/null
@@ -1,192 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -instcombine -S | FileCheck %s
-target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-unknown-linux-gnu"
-
-define i32 @test_sink_replacement1(i8* %p) {
-; CHECK-LABEL: @test_sink_replacement1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne i8* [[P:%.*]], null
-; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
-; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8* [[P]], null
-; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
-; CHECK:       if.then:
-; CHECK-NEXT:    br label [[CLEANUP:%.*]]
-; CHECK:       if.end:
-; CHECK-NEXT:    [[CALL:%.*]] = call i64 @func_test(i8* nonnull [[P]]) #2
-; CHECK-NEXT:    [[CONV:%.*]] = trunc i64 [[CALL]] to i32
-; CHECK-NEXT:    br label [[CLEANUP]]
-; CHECK:       cleanup:
-; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[CONV]], [[IF_END]] ], [ -1, [[IF_THEN]] ]
-; CHECK-NEXT:    ret i32 [[RETVAL_0]]
-;
-entry:
-  %call = call i64 @func_test(i8* nonnull %p) #2
-  %conv = trunc i64 %call to i32
-  %tobool = icmp ne i8* %p, null
-  br i1 %tobool, label %if.end, label %if.then
-
-if.then:
-  br label %cleanup
-
-if.end:
-  br label %cleanup
-
-cleanup:
-  %retval.0 = phi i32 [ %conv, %if.end ], [ -1, %if.then ]
-  ret i32 %retval.0
-}
-
-define i32 @test_sink_replacement2(i8* %p) {
-; CHECK-LABEL: @test_sink_replacement2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne i8* [[P:%.*]], null
-; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
-; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8* [[P]], null
-; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
-; CHECK:       if.then:
-; CHECK-NEXT:    br label [[CLEANUP:%.*]]
-; CHECK:       if.end:
-; CHECK-NEXT:    [[CALL:%.*]] = call i64 @func_test(i8* nonnull dereferenceable(1) [[P]]) #2
-; CHECK-NEXT:    [[CONV:%.*]] = trunc i64 [[CALL]] to i32
-; CHECK-NEXT:    br label [[CLEANUP]]
-; CHECK:       cleanup:
-; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[CONV]], [[IF_END]] ], [ -1, [[IF_THEN]] ]
-; CHECK-NEXT:    ret i32 [[RETVAL_0]]
-;
-entry:
-  %call = call i64 @func_test(i8* dereferenceable(1) %p) #2
-  %conv = trunc i64 %call to i32
-  %tobool = icmp ne i8* %p, null
-  br i1 %tobool, label %if.end, label %if.then
-
-if.then:
-  br label %cleanup
-
-if.end:
-  br label %cleanup
-
-cleanup:
-  %retval.0 = phi i32 [ %conv, %if.end ], [ -1, %if.then ]
-  ret i32 %retval.0
-}
-
-define i32 @test_sink_replacement3(i8* %p) {
-; CHECK-LABEL: @test_sink_replacement3(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne i8* [[P:%.*]], null
-; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
-; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8* [[P]], null
-; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
-; CHECK:       if.then:
-; CHECK-NEXT:    br label [[CLEANUP:%.*]]
-; CHECK:       if.end:
-; CHECK-NEXT:    [[CALL:%.*]] = call i64 @func_test_nonnull(i8* [[P]]) #2
-; CHECK-NEXT:    [[CONV:%.*]] = trunc i64 [[CALL]] to i32
-; CHECK-NEXT:    br label [[CLEANUP]]
-; CHECK:       cleanup:
-; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[CONV]], [[IF_END]] ], [ -1, [[IF_THEN]] ]
-; CHECK-NEXT:    ret i32 [[RETVAL_0]]
-;
-entry:
-  %call = call i64 @func_test_nonnull(i8* %p) #2
-  %conv = trunc i64 %call to i32
-  %tobool = icmp ne i8* %p, null
-  br i1 %tobool, label %if.end, label %if.then
-
-if.then:
-  br label %cleanup
-
-if.end:
-  br label %cleanup
-
-cleanup:
-  %retval.0 = phi i32 [ %conv, %if.end ], [ -1, %if.then ]
-  ret i32 %retval.0
-}
-
-define i32 @test_sink_replacement4(i8* %p) {
-; CHECK-LABEL: @test_sink_replacement4(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    br label [[A:%.*]]
-; CHECK:       a:
-; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne i8* [[P:%.*]], null
-; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
-; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8* [[P]], null
-; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
-; CHECK:       if.then:
-; CHECK-NEXT:    br label [[CLEANUP:%.*]]
-; CHECK:       if.end:
-; CHECK-NEXT:    [[CALL:%.*]] = call i64 @func_test(i8* nonnull dereferenceable(1) [[P]]) #2
-; CHECK-NEXT:    [[CONV:%.*]] = trunc i64 [[CALL]] to i32
-; CHECK-NEXT:    br label [[CLEANUP]]
-; CHECK:       cleanup:
-; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[CONV]], [[IF_END]] ], [ -1, [[IF_THEN]] ]
-; CHECK-NEXT:    ret i32 [[RETVAL_0]]
-;
-entry:
-  br label %a
-a:
-  %call = call i64 @func_test(i8* dereferenceable(1) %p) #2
-  %conv = trunc i64 %call to i32
-  %tobool = icmp ne i8* %p, null
-  br i1 %tobool, label %if.end, label %if.then
-
-if.then:
-  br label %cleanup
-
-if.end:
-  br label %cleanup
-
-cleanup:
-  %retval.0 = phi i32 [ %conv, %if.end ], [ -1, %if.then ]
-  ret i32 %retval.0
-}
-
-define i32 @test_sink_replacement5(i64 %i) {
-; CHECK-LABEL: @test_sink_replacement5(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[P:%.*]] = inttoptr i64 [[I:%.*]] to i8*
-; CHECK-NEXT:    br label [[A:%.*]]
-; CHECK:       a:
-; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne i64 [[I]], 0
-; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
-; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[I]], 0
-; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
-; CHECK:       if.then:
-; CHECK-NEXT:    br label [[CLEANUP:%.*]]
-; CHECK:       if.end:
-; CHECK-NEXT:    [[CALL:%.*]] = call i64 @func_test(i8* nonnull dereferenceable(1) [[P]]) #2
-; CHECK-NEXT:    [[CONV:%.*]] = trunc i64 [[CALL]] to i32
-; CHECK-NEXT:    br label [[CLEANUP]]
-; CHECK:       cleanup:
-; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[CONV]], [[IF_END]] ], [ -1, [[IF_THEN]] ]
-; CHECK-NEXT:    ret i32 [[RETVAL_0]]
-;
-entry:
-  %p = inttoptr i64 %i to i8*
-  br label %a
-a:
-  %call = call i64 @func_test(i8* dereferenceable(1) %p) #2
-  %conv = trunc i64 %call to i32
-  %tobool = icmp ne i8* %p, null
-  br i1 %tobool, label %if.end, label %if.then
-
-if.then:
-  br label %cleanup
-
-if.end:
-  br label %cleanup
-
-cleanup:
-  %retval.0 = phi i32 [ %conv, %if.end ], [ -1, %if.then ]
-  ret i32 %retval.0
-}
-
-declare i64 @func_test(i8* %0) #1
-
-declare i64 @func_test_nonnull(i8* nonnull %0) #3
-
-attributes #1 = { readonly }
-attributes #2 = { nounwind }
-attributes #3 = { readonly }

diff  --git a/llvm/test/Transforms/InstCombine/unused-nonnull.ll b/llvm/test/Transforms/InstCombine/unused-nonnull.ll
new file mode 100644
index 000000000000..518cd268ea1c
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/unused-nonnull.ll
@@ -0,0 +1,45 @@
+; PR44154: LLVM c3b06d0c393e caused the body of @main to be replaced with
+; unreachable. Check that we perform the expected calls and optimizations.
+;
+; RUN: opt -S -O3 -o - %s | FileCheck %s
+; CHECK-LABEL: @main
+; CHECK:       %0 = icmp slt i32 %argc, 2
+; CHECK-NEXT:  br i1 %0, label %done, label %do_work
+; CHECK-LABEL: do_work:
+; CHECK:       %1 = tail call i32 @compute(
+; CHECK-LABEL: done:
+; CHECK:       %retval = phi i32 [ 0, %entry ], [ %1, %do_work ]
+; CHECK-NEXT:  ret i32 %retval
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @main(i32 %argc, i8** %argv) #0 {
+entry:
+  %0 = getelementptr inbounds i8*, i8** %argv, i32 0
+  %ptr = load i8*, i8** %0
+  %1 = call i32 @compute(i8* %ptr, i32 %argc)
+  %2 = icmp slt i32 %argc, 2
+  br i1 %2, label %done, label %do_work
+
+do_work:
+  %3 = icmp eq i8* %ptr, null
+  br i1 %3, label %null, label %done
+
+null:
+  call void @call_if_null(i8* %ptr)
+  br label %done
+
+done:
+  %retval = phi i32 [0, %entry], [%1, %do_work], [%1, %null]
+  ret i32 %retval
+}
+
+define i32 @compute(i8* nonnull %ptr, i32 %x) #1 {
+  ret i32 %x
+}
+
+declare void @call_if_null(i8* %ptr) #0
+
+attributes #0 = { nounwind }
+attributes #1 = { noinline nounwind readonly }


        


More information about the llvm-commits mailing list