[llvm] afb526b - [LICM] Handle store of pointer to itself (PR54495)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 22 06:00:23 PDT 2022


Author: Nikita Popov
Date: 2022-03-22T14:00:07+01:00
New Revision: afb526b3f49e06d1b72986d3bc4c5d445cfda05b

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

LOG: [LICM] Handle store of pointer to itself (PR54495)

Rather than iterating over users and comparing operands, iterate
over uses and check operand number. Otherwise, we'll end up
promoting a store twice if it has two equal operands.

This can only happen with opaque pointers, as otherwise both
operands differ by a level of indirection, so a bitcast would have
to be involved.

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

Added: 
    llvm/test/Transforms/LICM/pr54495.ll

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index 88d9eed187654..b463ce478b40f 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -2061,9 +2061,9 @@ bool llvm::promoteLoopAccessesToScalars(
   // 
diff erent sizes.  While we are at it, collect alignment and AA info.
   Type *AccessTy = nullptr;
   for (Value *ASIV : PointerMustAliases) {
-    for (User *U : ASIV->users()) {
+    for (Use &U : ASIV->uses()) {
       // Ignore instructions that are outside the loop.
-      Instruction *UI = dyn_cast<Instruction>(U);
+      Instruction *UI = dyn_cast<Instruction>(U.getUser());
       if (!UI || !CurLoop->contains(UI))
         continue;
 
@@ -2093,7 +2093,7 @@ bool llvm::promoteLoopAccessesToScalars(
       } else if (const StoreInst *Store = dyn_cast<StoreInst>(UI)) {
         // Stores *of* the pointer are not interesting, only stores *to* the
         // pointer.
-        if (UI->getOperand(1) != ASIV)
+        if (U.getOperandNo() != StoreInst::getPointerOperandIndex())
           continue;
         if (!Store->isUnordered())
           return false;

diff  --git a/llvm/test/Transforms/LICM/pr54495.ll b/llvm/test/Transforms/LICM/pr54495.ll
new file mode 100644
index 0000000000000..f4ad586ffb168
--- /dev/null
+++ b/llvm/test/Transforms/LICM/pr54495.ll
@@ -0,0 +1,31 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -licm < %s | FileCheck %s
+
+; Make sure that a store of a pointer to itself is handled correctly.
+
+define void @test(ptr %p1, ptr %p2, ptr noalias %p3) {
+; CHECK-LABEL: @test(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[P1:%.*]], [[ENTRY:%.*]] ], [ [[P2:%.*]], [[LOOP]] ]
+; CHECK-NEXT:    [[V:%.*]] = load i64, ptr [[P]], align 4
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[V]], 0
+; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[LOOP_EXIT:%.*]]
+; CHECK:       loop.exit:
+; CHECK-NEXT:    store ptr [[P3:%.*]], ptr [[P3]], align 8
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %loop
+
+loop:
+  %p = phi ptr [ %p1, %entry ], [ %p2, %loop ]
+  %v = load i64, ptr %p
+  %cmp = icmp eq i64 %v, 0
+  store ptr %p3, ptr %p3
+  br i1 %cmp, label %loop, label %loop.exit
+
+loop.exit:
+  ret void
+}


        


More information about the llvm-commits mailing list