[llvm] 34d381f - [NewGVN] Fix lifetime coercion (#141477)
via llvm-commits
llvm-commits at lists.llvm.org
Mon May 26 09:34:30 PDT 2025
Author: ManuelJBrito
Date: 2025-05-26T17:34:26+01:00
New Revision: 34d381f39d5b3831aee30fe2be0e723dace82297
URL: https://github.com/llvm/llvm-project/commit/34d381f39d5b3831aee30fe2be0e723dace82297
DIFF: https://github.com/llvm/llvm-project/commit/34d381f39d5b3831aee30fe2be0e723dace82297.diff
LOG: [NewGVN] Fix lifetime coercion (#141477)
Before commit 14dee0a, NewGVN would not miscompile the function foo,
because `isMustAlias` would return false for non-pointers, particularly
for `lifetime.start`. We need to check whether the loaded pointer is
defined by`lifetime.start` in order to safely simplify the load to
uninitialized memory.
For `getInitialValueOfAllocation`, the behavior depends on the
allocation function. Therefore, we take a conservative approach: we
check whether it's a pointer type. If it is, then—based on the earlier
check—we know that the allocation function defines the loaded pointer.
Added:
Modified:
llvm/lib/Transforms/Scalar/NewGVN.cpp
llvm/test/Transforms/NewGVN/coercion-different-ptr.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/NewGVN.cpp b/llvm/lib/Transforms/Scalar/NewGVN.cpp
index 3eb118908959f..0a0ea65a1f036 100644
--- a/llvm/lib/Transforms/Scalar/NewGVN.cpp
+++ b/llvm/lib/Transforms/Scalar/NewGVN.cpp
@@ -1529,10 +1529,19 @@ NewGVN::performSymbolicLoadCoercion(Type *LoadType, Value *LoadPtr,
}
}
+ if (auto *II = dyn_cast<IntrinsicInst>(DepInst)) {
+ auto *LifetimePtr = II->getOperand(1);
+ if (II->getIntrinsicID() == Intrinsic::lifetime_start &&
+ (LoadPtr == lookupOperandLeader(LifetimePtr) ||
+ AA->isMustAlias(LoadPtr, LifetimePtr)))
+ return createConstantExpression(UndefValue::get(LoadType));
+ }
+
// All of the below are only true if the loaded pointer is produced
// by the dependent instruction.
- if (LoadPtr != lookupOperandLeader(DepInst) &&
- DepInst->getType()->isPointerTy() && !AA->isMustAlias(LoadPtr, DepInst))
+ if (!DepInst->getType()->isPointerTy() ||
+ (LoadPtr != lookupOperandLeader(DepInst) &&
+ !AA->isMustAlias(LoadPtr, DepInst)))
return nullptr;
// If this load really doesn't depend on anything, then we must be loading an
// undef value. This can happen when loading for a fresh allocation with no
@@ -1540,12 +1549,6 @@ NewGVN::performSymbolicLoadCoercion(Type *LoadType, Value *LoadPtr,
// that the result of the allocation is pointer equal to the load ptr.
if (isa<AllocaInst>(DepInst)) {
return createConstantExpression(UndefValue::get(LoadType));
- }
- // If this load occurs either right after a lifetime begin,
- // then the loaded value is undefined.
- else if (auto *II = dyn_cast<IntrinsicInst>(DepInst)) {
- if (II->getIntrinsicID() == Intrinsic::lifetime_start)
- return createConstantExpression(UndefValue::get(LoadType));
} else if (auto *InitVal =
getInitialValueOfAllocation(DepInst, TLI, LoadType))
return createConstantExpression(InitVal);
diff --git a/llvm/test/Transforms/NewGVN/coercion-
diff erent-ptr.ll b/llvm/test/Transforms/NewGVN/coercion-
diff erent-ptr.ll
index 61a6a633788e1..dfd6d7d9f53a5 100644
--- a/llvm/test/Transforms/NewGVN/coercion-
diff erent-ptr.ll
+++ b/llvm/test/Transforms/NewGVN/coercion-
diff erent-ptr.ll
@@ -2,7 +2,7 @@
; RUN: opt -S -passes=newgvn < %s | FileCheck %s
-; FIXME: MemorySSA says that load1 depends on the lifetime start.
+; MemorySSA says that load1 depends on the lifetime start.
; That's OK since MemorySSA is may-alias; however, NewGVN should
; check whether the lifetime start *actually* defines the loaded pointer
; before simplifying to uninitialized memory.
@@ -13,7 +13,8 @@ define void @foo(ptr %arg) {
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca i8, align 16
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 1, ptr [[ALLOCA]])
; CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr [[ARG]], align 8
-; CHECK-NEXT: [[CALL:%.*]] = call ptr undef(ptr [[ALLOCA]])
+; CHECK-NEXT: [[LOAD1:%.*]] = load ptr, ptr [[LOAD]], align 8
+; CHECK-NEXT: [[CALL:%.*]] = call ptr [[LOAD1]](ptr [[ALLOCA]])
; CHECK-NEXT: ret void
;
bb:
More information about the llvm-commits
mailing list