[llvm] 733740b - Fix a phase-ordering problem in SimplifyCFG.

Owen Anderson via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 4 15:47:20 PST 2023


Author: Owen Anderson
Date: 2023-01-04T16:47:13-07:00
New Revision: 733740b18936364f20d9858e3a6f08855ec66b8b

URL: https://github.com/llvm/llvm-project/commit/733740b18936364f20d9858e3a6f08855ec66b8b
DIFF: https://github.com/llvm/llvm-project/commit/733740b18936364f20d9858e3a6f08855ec66b8b.diff

LOG: Fix a phase-ordering problem in SimplifyCFG.

Switch simplification could sometimes fail to notice when an
intermediate case removal caused the switch condition to become
constant. This would cause the switch to be simplified into a
conditional branch rather than a direct branch.

Most of the time this didn't matter, except that occasionally
downstream parts of SimplifyCFG expect tautological branches to
already have been eliminated. The missed handling in switch
simplification would cause an assertion failure in the downstream
code.

Triggering the assertion failure is fairly sensitive to the exact
order of various simplifications.

Fixes https://github.com/llvm/llvm-project/issues/59768

Reviewed By: nikic

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

Added: 
    llvm/test/Transforms/SimplifyCFG/switch-simplify-crash2.ll

Modified: 
    llvm/lib/Transforms/Utils/Local.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index d21e35160998b..0b3799c28cbac 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -237,6 +237,14 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions,
         DefaultDest->removePredecessor(ParentBB);
         i = SI->removeCase(i);
         e = SI->case_end();
+
+        // Removing this case may have made the condition constant. In that
+        // case, update CI and restart iteration through the cases.
+        if (auto *NewCI = dyn_cast<ConstantInt>(SI->getCondition())) {
+          CI = NewCI;
+          i = SI->case_begin();
+        }
+
         Changed = true;
         continue;
       }

diff  --git a/llvm/test/Transforms/SimplifyCFG/switch-simplify-crash2.ll b/llvm/test/Transforms/SimplifyCFG/switch-simplify-crash2.ll
new file mode 100644
index 0000000000000..eb0947397a699
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/switch-simplify-crash2.ll
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -passes="simplifycfg<forward-switch-cond;no-keep-loops>" < %s | FileCheck %s
+
+define i8 @test() {
+; CHECK-LABEL: @test(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[LOOP2:%.*]]
+; CHECK:       loop2:
+; CHECK-NEXT:    br label [[LOOP2]]
+;
+entry:
+  br label %loop
+
+loop:
+  %phi1 = phi i8 [ 0, %entry ], [ %phi2, %loop2 ]
+  br label %loop2
+
+loop2:
+  %phi2 = phi i8 [ %phi1, %loop ], [ 0, %loop2 ]
+  switch i8 %phi2, label %loop [
+  i8 0, label %loop2
+  i8 1, label %exit
+  ]
+
+exit:
+  ret i8 0
+}


        


More information about the llvm-commits mailing list