[llvm] 7a1029f - Reland "[LoopUnswitch] Fix incorrect Modified status"

David Stenberg via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 20 02:53:35 PDT 2020


Author: David Stenberg
Date: 2020-08-20T11:52:09+02:00
New Revision: 7a1029fd1e415d3e21430fc18ed5cc2e79756e3c

URL: https://github.com/llvm/llvm-project/commit/7a1029fd1e415d3e21430fc18ed5cc2e79756e3c
DIFF: https://github.com/llvm/llvm-project/commit/7a1029fd1e415d3e21430fc18ed5cc2e79756e3c.diff

LOG: Reland "[LoopUnswitch] Fix incorrect Modified status"

Relanded since the buildbot issue was unrelated to this commit.

When hoisting simple values out from a loop, and an optsize attribute, a
convergent call, or an invoke instruction hindered the pass from
unswitching the loop, the pass would return an incorrect Modified
status.

This was caught using the check introduced by D80916.

Reviewed By: asbirlea

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

Added: 
    llvm/test/Transforms/LoopUnswitch/convergent-hoist-modified.ll
    llvm/test/Transforms/LoopUnswitch/invoke-hoist-modified.ll
    llvm/test/Transforms/LoopUnswitch/optsize-hoist-modified.ll

Modified: 
    llvm/lib/Transforms/Scalar/LoopUnswitch.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
index 645a89bbd0ff..d83b7b05f88b 100644
--- a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
@@ -661,7 +661,7 @@ bool LoopUnswitch::processCurrentLoop() {
   // FIXME: Use Function::hasOptSize().
   if (OptimizeForSize ||
       LoopHeader->getParent()->hasFnAttribute(Attribute::OptimizeForSize))
-    return false;
+    return Changed;
 
   // Run through the instructions in the loop, keeping track of three things:
   //
@@ -685,10 +685,10 @@ bool LoopUnswitch::processCurrentLoop() {
       if (!CB)
         continue;
       if (CB->isConvergent())
-        return false;
+        return Changed;
       if (auto *II = dyn_cast<InvokeInst>(&I))
         if (!II->getUnwindDest()->canSplitPredecessors())
-          return false;
+          return Changed;
       if (auto *II = dyn_cast<IntrinsicInst>(&I))
         if (II->getIntrinsicID() == Intrinsic::experimental_guard)
           Guards.push_back(II);

diff  --git a/llvm/test/Transforms/LoopUnswitch/convergent-hoist-modified.ll b/llvm/test/Transforms/LoopUnswitch/convergent-hoist-modified.ll
new file mode 100644
index 000000000000..bb77f4ca8b75
--- /dev/null
+++ b/llvm/test/Transforms/LoopUnswitch/convergent-hoist-modified.ll
@@ -0,0 +1,42 @@
+; RUN: opt -loop-unswitch -enable-new-pm=0 %s -S | FileCheck %s
+
+; When hoisting simple values out from a loop, and not being able to unswitch
+; the loop due to the convergent call, the pass would return an incorrect
+; Modified status. This was caught by the pass return status check that is
+; hidden under EXPENSIVE_CHECKS.
+
+; CHECK-LABEL: entry:
+; CHECK-NEXT: %0 = call i32 @llvm.objectsize.i32.p0i8(i8* bitcast (%struct.anon* @b to i8*), i1 false, i1 false, i1 false)
+; CHECK-NEXT: %1 = icmp uge i32 %0, 1
+; CHECK-NEXT: br label %for.cond
+
+%struct.anon = type { i16 }
+
+ at b = global %struct.anon zeroinitializer, align 1
+
+; Function Attrs: nounwind
+define i16 @c() #0 {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %cont, %entry
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.cond
+  %0 = call i32 @llvm.objectsize.i32.p0i8(i8* bitcast (%struct.anon* @b to i8*), i1 false, i1 false, i1 false)
+  %1 = icmp uge i32 %0, 1
+  br i1 %1, label %cont, label %cont
+
+cont:                                             ; preds = %for.inc
+  call void @conv() convergent
+  %2 = load i16, i16* getelementptr inbounds (%struct.anon, %struct.anon* @b, i32 0, i32 0), align 1
+  br label %for.cond
+}
+
+; Function Attrs: nounwind readnone speculatable willreturn
+declare i32 @llvm.objectsize.i32.p0i8(i8*, i1 immarg, i1 immarg, i1 immarg) #1
+
+declare void @conv() convergent
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readnone speculatable willreturn }

diff  --git a/llvm/test/Transforms/LoopUnswitch/invoke-hoist-modified.ll b/llvm/test/Transforms/LoopUnswitch/invoke-hoist-modified.ll
new file mode 100644
index 000000000000..367bae21e89a
--- /dev/null
+++ b/llvm/test/Transforms/LoopUnswitch/invoke-hoist-modified.ll
@@ -0,0 +1,53 @@
+; RUN: opt -loop-unswitch -enable-new-pm=0 %s -S | FileCheck %s
+
+; When hoisting simple values out from a loop, and not being able to unswitch
+; the loop due to the invoke instruction, the pass would return an incorrect
+; Modified status. This was caught by the pass return status check that is
+; hidden under EXPENSIVE_CHECKS.
+
+; CHECK-LABEL: for.cond:
+; CHECK-NEXT: %0 = call i32 @llvm.objectsize.i32.p0i8(i8* bitcast (%struct.anon* @b to i8*), i1 false, i1 false, i1 false)
+; CHECK-NEXT: %1 = icmp uge i32 %0, 1
+; CHECK-NEXT: br label %for.inc
+
+%struct.anon = type { i16 }
+
+ at b = global %struct.anon zeroinitializer, align 1
+
+; Function Attrs: nounwind
+define i32 @c() #0 personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %cont, %entry
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.cond
+  %0 = call i32 @llvm.objectsize.i32.p0i8(i8* bitcast (%struct.anon* @b to i8*), i1 false, i1 false, i1 false)
+  %1 = icmp uge i32 %0, 1
+  br i1 %1, label %delete.notnull, label %delete.notnull
+
+delete.notnull:                                   ; preds = %for.inc
+  invoke void @g() to label %invoke.cont unwind label %lpad
+
+invoke.cont:                                      ; preds = %delete.notnull
+  br label %for.inc
+
+lpad:                                             ; preds = %delete.notnull
+  %cp = cleanuppad within none []
+  cleanupret from %cp unwind to caller
+
+cont:                                             ; preds = %for.inc
+  %2 = load i16, i16* getelementptr inbounds (%struct.anon, %struct.anon* @b, i32 0, i32 0), align 1
+  br label %for.cond
+}
+
+; Function Attrs: nounwind readnone speculatable willreturn
+declare i32 @llvm.objectsize.i32.p0i8(i8*, i1 immarg, i1 immarg, i1 immarg) #1
+
+declare void @g()
+
+declare i32 @__CxxFrameHandler3(...)
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readnone speculatable willreturn }

diff  --git a/llvm/test/Transforms/LoopUnswitch/optsize-hoist-modified.ll b/llvm/test/Transforms/LoopUnswitch/optsize-hoist-modified.ll
new file mode 100644
index 000000000000..9ec1f40703cd
--- /dev/null
+++ b/llvm/test/Transforms/LoopUnswitch/optsize-hoist-modified.ll
@@ -0,0 +1,39 @@
+; RUN: opt -loop-unswitch -enable-new-pm=0 %s -S | FileCheck %s
+
+; When hoisting simple values out from a loop, and not being able to attempt to
+; non-trivally unswitch the loop, due to the optsize attribute, the pass would
+; return an incorrect Modified status. This was caught by the pass return
+; status check that is hidden under EXPENSIVE_CHECKS.
+
+; CHECK-LABEL: entry:
+; CHECK-NEXT: %0 = call i32 @llvm.objectsize.i32.p0i8(i8* bitcast (%struct.anon* @b to i8*), i1 false, i1 false, i1 false)
+; CHECK-NEXT: %1 = icmp uge i32 %0, 1
+; CHECK-NEXT: br label %for.cond
+
+%struct.anon = type { i16 }
+
+ at b = global %struct.anon zeroinitializer, align 1
+
+; Function Attrs: minsize nounwind optsize
+define i16 @c() #0 {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %cont, %entry
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.cond
+  %0 = call i32 @llvm.objectsize.i32.p0i8(i8* bitcast (%struct.anon* @b to i8*), i1 false, i1 false, i1 false)
+  %1 = icmp uge i32 %0, 1
+  br i1 %1, label %cont, label %cont
+
+cont:                                             ; preds = %for.inc
+  %2 = load i16, i16* getelementptr inbounds (%struct.anon, %struct.anon* @b, i32 0, i32 0), align 1
+  br label %for.cond
+}
+
+; Function Attrs: nounwind readnone speculatable willreturn
+declare i32 @llvm.objectsize.i32.p0i8(i8*, i1 immarg, i1 immarg, i1 immarg) #1
+
+attributes #0 = { minsize nounwind optsize }
+attributes #1 = { nounwind readnone speculatable willreturn }


        


More information about the llvm-commits mailing list