[llvm] ba3d29f - [LCSSA] Update unreachable uses with poison.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 4 14:36:17 PDT 2022


Author: Florian Hahn
Date: 2022-09-04T22:26:18+01:00
New Revision: ba3d29f871e04c6cfc64ed84c478dd1846e6148d

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

LOG: [LCSSA] Update unreachable uses with poison.

Users of LCSSA may not expect non-phi uses when checking the uses
outside a loop, which may cause crashes. This is due to the fact that we
do not update uses in unreachable blocks.

To ensure all reachable uses outside the loop are phis, update uses in
unreachable blocks to use poison in dead code.

Fixes #57508.

Added: 
    

Modified: 
    llvm/lib/Transforms/Utils/LCSSA.cpp
    llvm/test/Transforms/LCSSA/unreachable-use.ll
    llvm/test/Transforms/LoopVectorize/lcssa-crashes.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/LCSSA.cpp b/llvm/lib/Transforms/Utils/LCSSA.cpp
index 76f268506269..af79dc456ea6 100644
--- a/llvm/lib/Transforms/Utils/LCSSA.cpp
+++ b/llvm/lib/Transforms/Utils/LCSSA.cpp
@@ -107,13 +107,15 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
     if (ExitBlocks.empty())
       continue;
 
-    for (Use &U : I->uses()) {
+    for (Use &U : make_early_inc_range(I->uses())) {
       Instruction *User = cast<Instruction>(U.getUser());
       BasicBlock *UserBB = User->getParent();
 
       // Skip uses in unreachable blocks.
-      if (!DT.isReachableFromEntry(UserBB))
+      if (!DT.isReachableFromEntry(UserBB)) {
+        U.set(PoisonValue::get(I->getType()));
         continue;
+      }
 
       // For practical purposes, we consider that the use in a PHI
       // occurs in the respective predecessor block. For more info,

diff  --git a/llvm/test/Transforms/LCSSA/unreachable-use.ll b/llvm/test/Transforms/LCSSA/unreachable-use.ll
index 0c70f7a3ef9b..ea730257daa1 100644
--- a/llvm/test/Transforms/LCSSA/unreachable-use.ll
+++ b/llvm/test/Transforms/LCSSA/unreachable-use.ll
@@ -42,3 +42,21 @@ bb32:
 bb45:
   unreachable
 }
+
+define void @multiple_unreachable_uses(ptr %A, ptr %B) {
+entry:
+  br label %loop
+
+loop:
+  %gep.A = getelementptr inbounds float, ptr %A, i64 10
+  %gep.B = getelementptr inbounds ptr, ptr %B, i64 20
+  br i1 false, label %exit, label %loop
+
+dead:                 ; No predecessors!
+  %l1 = load float, ptr %gep.A, align 4
+  %l2 = load ptr, ptr %gep.B, align 8
+  br label %exit
+
+exit:
+  ret void
+}

diff  --git a/llvm/test/Transforms/LoopVectorize/lcssa-crashes.ll b/llvm/test/Transforms/LoopVectorize/lcssa-crashes.ll
index 6c466540e708..05d9e027fc22 100644
--- a/llvm/test/Transforms/LoopVectorize/lcssa-crashes.ll
+++ b/llvm/test/Transforms/LoopVectorize/lcssa-crashes.ll
@@ -114,3 +114,54 @@ while.end:
   %add58 = add i32 %inc46, 4
   ret void
 }
+
+; Make sure LV doesn't crash on IR where some LCSSA uses are unreachable.
+define i32 @pr57508(ptr %src) {
+; CHECK-LABEL: @pr57508(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
+; CHECK:       vector.ph:
+; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
+; CHECK:       vector.body:
+; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
+; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
+; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i64 [[INDEX_NEXT]], 2000
+; CHECK-NEXT:    br i1 [[TMP0]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
+; CHECK:       middle.block:
+; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 2001, 2000
+; CHECK-NEXT:    br i1 [[CMP_N]], label [[LOOP_EXIT:%.*]], label [[SCALAR_PH]]
+; CHECK:       scalar.ph:
+; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 2000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[BC_RESUME_VAL1:%.*]] = phi i32 [ 2000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY]] ]
+; CHECK-NEXT:    br label [[LOOP:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
+; CHECK-NEXT:    [[LOCAL:%.*]] = phi i32 [ [[LOCAL_NEXT:%.*]], [[LOOP]] ], [ [[BC_RESUME_VAL1]], [[SCALAR_PH]] ]
+; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-NEXT:    [[LOCAL_NEXT]] = add i32 [[LOCAL]], 1
+; CHECK-NEXT:    [[EC:%.*]] = icmp eq i64 [[IV]], 2000
+; CHECK-NEXT:    br i1 [[EC]], label [[LOOP_EXIT]], label [[LOOP]], !llvm.loop [[LOOP5:![0-9]+]]
+; CHECK:       loop.exit:
+; CHECK-NEXT:    unreachable
+; CHECK:       bb:
+; CHECK-NEXT:    [[LOCAL_USE:%.*]] = add i32 poison, 1
+; CHECK-NEXT:    ret i32 [[LOCAL_USE]]
+;
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
+  %local = phi i32 [ %local.next, %loop ], [ 0, %entry ]
+  %iv.next = add nuw nsw i64 %iv, 1
+  %local.next  = add i32 %local, 1
+  %ec = icmp eq i64 %iv, 2000
+  br i1 %ec, label %loop.exit, label %loop
+
+loop.exit:
+  unreachable
+
+bb:
+  %local.use = add i32 %local, 1
+  ret i32 %local.use
+}


        


More information about the llvm-commits mailing list