[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