[llvm] be1f994 - [Analysis] `isSafeToLoadUnconditionally()`: `lifetime` intrinsics can be ignored
Roman Lebedev via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 17 09:48:56 PST 2022
Author: Roman Lebedev
Date: 2022-11-17T20:48:27+03:00
New Revision: be1f9943119f6012d319f8e4145f260d4bcff933
URL: https://github.com/llvm/llvm-project/commit/be1f9943119f6012d319f8e4145f260d4bcff933
DIFF: https://github.com/llvm/llvm-project/commit/be1f9943119f6012d319f8e4145f260d4bcff933.diff
LOG: [Analysis] `isSafeToLoadUnconditionally()`: `lifetime` intrinsics can be ignored
In practice this means that we can speculate more loads in SROA.
This e.g. comes up in https://godbolt.org/z/G8716s6sj,
although we are missing second half of the puzzle to optimize that.
Added:
Modified:
llvm/include/llvm/IR/IntrinsicInst.h
llvm/lib/Analysis/Loads.cpp
llvm/test/Transforms/SROA/select-load.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h
index f78e45c0e32ee..407ed8ad4ed6a 100644
--- a/llvm/include/llvm/IR/IntrinsicInst.h
+++ b/llvm/include/llvm/IR/IntrinsicInst.h
@@ -123,6 +123,31 @@ class IntrinsicInst : public CallInst {
}
};
+/// Check if \p ID corresponds to a lifetime intrinsic.
+static inline bool isLifetimeIntrinsic(Intrinsic::ID ID) {
+ switch (ID) {
+ case Intrinsic::lifetime_start:
+ case Intrinsic::lifetime_end:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/// This is the common base class for lifetime intrinsics.
+class LifetimeIntrinsic : public IntrinsicInst {
+public:
+ /// \name Casting methods
+ /// @{
+ static bool classof(const IntrinsicInst *I) {
+ return isLifetimeIntrinsic(I->getIntrinsicID());
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ /// @}
+};
+
/// Check if \p ID corresponds to a debug info intrinsic.
static inline bool isDbgInfoIntrinsic(Intrinsic::ID ID) {
switch (ID) {
diff --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp
index 24c4cff8a8ec5..e108df8473210 100644
--- a/llvm/lib/Analysis/Loads.cpp
+++ b/llvm/lib/Analysis/Loads.cpp
@@ -359,7 +359,7 @@ bool llvm::isSafeToLoadUnconditionally(Value *V, Align Alignment, APInt &Size,
// If we see a free or a call which may write to memory (i.e. which might do
// a free) the pointer could be marked invalid.
if (isa<CallInst>(BBI) && BBI->mayWriteToMemory() &&
- !isa<DbgInfoIntrinsic>(BBI))
+ !isa<LifetimeIntrinsic>(BBI) && !isa<DbgInfoIntrinsic>(BBI))
return false;
Value *AccessedPtr;
diff --git a/llvm/test/Transforms/SROA/select-load.ll b/llvm/test/Transforms/SROA/select-load.ll
index 376e44fe2b6ff..6d62a6c774de1 100644
--- a/llvm/test/Transforms/SROA/select-load.ll
+++ b/llvm/test/Transforms/SROA/select-load.ll
@@ -62,16 +62,13 @@ declare void @foo_i32(ptr)
; Lifetime intrinsics should not prevent dereferenceability inferrence.
define i32 @interfering_lifetime(ptr %data, i64 %indvars.iv) {
; CHECK-LABEL: @interfering_lifetime(
-; CHECK-NEXT: [[MIN:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV:%.*]]
; CHECK-NEXT: [[I1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
-; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[MIN]])
-; CHECK-NEXT: store i32 0, ptr [[MIN]], align 4
; CHECK-NEXT: [[CMP_I_I:%.*]] = icmp slt i32 [[I1]], 0
; CHECK-NEXT: [[I2:%.*]] = tail call i32 @llvm.smax.i32(i32 [[I1]], i32 0)
-; CHECK-NEXT: [[__B___A_I_I:%.*]] = select i1 [[CMP_I_I]], ptr [[MIN]], ptr [[ARRAYIDX]]
-; CHECK-NEXT: [[I3:%.*]] = load i32, ptr [[__B___A_I_I]], align 4
-; CHECK-NEXT: ret i32 [[I3]]
+; CHECK-NEXT: [[I3_SROA_SPECULATE_LOAD_FALSE:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-NEXT: [[I3_SROA_SPECULATED:%.*]] = select i1 [[CMP_I_I]], i32 0, i32 [[I3_SROA_SPECULATE_LOAD_FALSE]]
+; CHECK-NEXT: ret i32 [[I3_SROA_SPECULATED]]
;
%min = alloca i32, align 4
%arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv
More information about the llvm-commits
mailing list