[llvm] b4d945b - Fixing an infinite loop problem in InstCombine

Andy Kaylor via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 29 13:05:01 PDT 2021


Author: Andy Kaylor
Date: 2021-07-29T12:57:17-07:00
New Revision: b4d945bacdaf2c60dd5fdb119b90cced73c41beb

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

LOG: Fixing an infinite loop problem in InstCombine

Patch by Mohammad Fawaz

This issues started happening after
https://github.com/llvm/llvm-project/commit/b373b5990d5991a920c421b21a352e4ccf4c4993
Basically, if the memcpy is volatile, the collectUsers() function should
return false, just like we do for volatile loads.

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

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
    llvm/test/Transforms/InstCombine/memcpy-from-global.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
index a8474e27383de..80abc775299a5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -261,8 +261,8 @@ class PointerReplacer {
 
 bool PointerReplacer::collectUsers(Instruction &I) {
   for (auto U : I.users()) {
-    Instruction *Inst = cast<Instruction>(&*U);
-    if (LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
+    auto *Inst = cast<Instruction>(&*U);
+    if (auto *Load = dyn_cast<LoadInst>(Inst)) {
       if (Load->isVolatile())
         return false;
       Worklist.insert(Load);
@@ -270,7 +270,9 @@ bool PointerReplacer::collectUsers(Instruction &I) {
       Worklist.insert(Inst);
       if (!collectUsers(*Inst))
         return false;
-    } else if (isa<MemTransferInst>(Inst)) {
+    } else if (auto *MI = dyn_cast<MemTransferInst>(Inst)) {
+      if (MI->isVolatile())
+        return false;
       Worklist.insert(Inst);
     } else if (Inst->isLifetimeStartOrEnd()) {
       continue;

diff  --git a/llvm/test/Transforms/InstCombine/memcpy-from-global.ll b/llvm/test/Transforms/InstCombine/memcpy-from-global.ll
index e5f197f94dab5..7fe49f56f8dd3 100644
--- a/llvm/test/Transforms/InstCombine/memcpy-from-global.ll
+++ b/llvm/test/Transforms/InstCombine/memcpy-from-global.ll
@@ -342,4 +342,22 @@ entry:
   ret float %r
 }
 
+; If the memcpy is volatile, it should not be removed
+define float @test11_volatile(i64 %i) {
+; CHECK-LABEL: @test11_volatile(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: alloca
+; CHECK: call void @llvm.lifetime.start.p0i8
+; CHECK: call void @llvm.memcpy
+
+entry:
+  %a = alloca [4 x float], align 4
+  %b = bitcast [4 x float]* %a to i8*
+  call void @llvm.lifetime.start.p0i8(i64 16, i8* %b)
+  call void @llvm.memcpy.p0i8.p1i8.i64(i8* align 4 %b, i8 addrspace(1)* align 4 bitcast ([4 x float] addrspace(1)* @I to i8 addrspace(1)*), i64 16, i1 true)
+  %g = getelementptr inbounds [4 x float], [4 x float]* %a, i64 0, i64 %i
+  %r = load float, float* %g, align 4
+  ret float %r
+}
+
 attributes #0 = { null_pointer_is_valid }


        


More information about the llvm-commits mailing list