[PATCH] D78749: [CodeExtractor] Fix extraction of a value used only by intrinsics outside of region

Ehud Katz via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 23 13:00:56 PDT 2020


ekatz created this revision.
ekatz added reviewers: vsk, aprantl, kachkov98, lattner.
ekatz added a project: LLVM.
Herald added subscribers: llvm-commits, hiraditya.

We should only skip lifetime and dbg intrinsics when searching for users.
Other intrinsics are legit users that can't be ignored.

Without this fix, the testcase would result in an invalid IR. `memcpy` will have a reference to the, now, external value (local to the extracted loop function).

Fix PR42194


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D78749

Files:
  llvm/lib/Transforms/Utils/CodeExtractor.cpp
  llvm/test/Transforms/CodeExtractor/LoopExtractor_alloca.ll


Index: llvm/test/Transforms/CodeExtractor/LoopExtractor_alloca.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/CodeExtractor/LoopExtractor_alloca.ll
@@ -0,0 +1,56 @@
+; RUN: opt -loop-extract -S < %s | FileCheck %s
+
+; This tests 2 cases:
+; 1. loop1 should be extracted into a function, without extracting %v1 alloca.
+; 2. loop2 should be extracted into a function, with the %v2 alloca.
+;
+; This used to produce an invalid IR, where `memcpy` will have a reference to
+; the, now, external value (local to the extracted loop function).
+
+; CHECK-LABEL: @test() {
+; CHECK-NEXT: entry:
+; CHECK-NEXT:   %v1 = alloca i32
+; CHECK-NEXT:   %p1 = bitcast i32* %v1 to i8*
+; CHECK-NEXT:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 undef, i8* %p1, i64 4, i1 true)
+
+; CHECK-LABEL: @test.loop2() {
+; CHECK-NEXT: newFuncRoot:
+; CHECK-NEXT:   %v2 = alloca i32
+; CHECK-NEXT:   %p2 = bitcast i32* %v2 to i8*
+
+; CHECK-LABEL: @test.loop1(i8* %p1) {
+; CHECK-NEXT: newFuncRoot:
+; CHECK-NOT:    alloca
+
+define void @test() {
+entry:
+  %v1 = alloca i32, align 4
+  %v2 = alloca i32, align 4
+  %p1 = bitcast i32* %v1 to i8*
+  %p2 = bitcast i32* %v2 to i8*
+  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 undef, i8* %p1, i64 4, i1 true)
+  br label %loop1
+
+loop1:
+  call void @llvm.lifetime.start.p0i8(i64 4, i8* %p1)
+  %r1 = call i32 @foo(i8* %p1)
+  call void @llvm.lifetime.end.p0i8(i64 4, i8* %p1)
+  %cmp1 = icmp ne i32 %r1, 0
+  br i1 %cmp1, label %loop1, label %loop2
+
+loop2:
+  call void @llvm.lifetime.start.p0i8(i64 4, i8* %p2)
+  %r2 = call i32 @foo(i8* %p2)
+  call void @llvm.lifetime.end.p0i8(i64 4, i8* %p2)
+  %cmp2 = icmp ne i32 %r2, 0
+  br i1 %cmp2, label %loop2, label %exit
+
+exit:
+  ret void
+}
+
+declare i32 @foo(i8*)
+
+declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)
+declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg)
Index: llvm/lib/Transforms/Utils/CodeExtractor.cpp
===================================================================
--- llvm/lib/Transforms/Utils/CodeExtractor.cpp
+++ llvm/lib/Transforms/Utils/CodeExtractor.cpp
@@ -456,13 +456,16 @@
         if (Info.LifeStart)
           return {};
         Info.LifeStart = IntrInst;
+        continue;
       }
       if (IntrInst->getIntrinsicID() == Intrinsic::lifetime_end) {
         if (Info.LifeEnd)
           return {};
         Info.LifeEnd = IntrInst;
+        continue;
       }
-      continue;
+      if (isa<DbgInfoIntrinsic>(IntrInst))
+        continue;
     }
     // Find untracked uses of the address, bail.
     if (!definedInRegion(Blocks, U))


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D78749.259679.patch
Type: text/x-patch
Size: 2783 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200423/73611f9c/attachment.bin>


More information about the llvm-commits mailing list