Skip to content

Commit 3d475df

Browse files
committed
[Mem2Reg] Consistently preserve nonnull assume for uninit load
When performing a !nonnull load from uninitialized memory, we should preserve the nonnull assume just like in all other cases. We already do this correctly in the generic mem2reg code, but don't handle this case when using the optimized single-block implementation. Make sure that the optimized implementation exhibits the same behavior as the generic implementation.
1 parent 3cfa32a commit 3d475df

File tree

2 files changed

+18
-14
lines changed

2 files changed

+18
-14
lines changed

llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp

+16-14
Original file line numberDiff line numberDiff line change
@@ -488,31 +488,33 @@ static bool promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info,
488488
StoresByIndex,
489489
std::make_pair(LoadIdx, static_cast<StoreInst *>(nullptr)),
490490
less_first());
491+
Value *ReplVal;
491492
if (I == StoresByIndex.begin()) {
492493
if (StoresByIndex.empty())
493494
// If there are no stores, the load takes the undef value.
494-
LI->replaceAllUsesWith(UndefValue::get(LI->getType()));
495+
ReplVal = UndefValue::get(LI->getType());
495496
else
496497
// There is no store before this load, bail out (load may be affected
497498
// by the following stores - see main comment).
498499
return false;
499500
} else {
500-
// Otherwise, there was a store before this load, the load takes its value.
501-
// Note, if the load was marked as nonnull we don't want to lose that
502-
// information when we erase it. So we preserve it with an assume.
503-
Value *ReplVal = std::prev(I)->second->getOperand(0);
504-
if (AC && LI->getMetadata(LLVMContext::MD_nonnull) &&
505-
!isKnownNonZero(ReplVal, DL, 0, AC, LI, &DT))
506-
addAssumeNonNull(AC, LI);
501+
// Otherwise, there was a store before this load, the load takes its
502+
// value.
503+
ReplVal = std::prev(I)->second->getOperand(0);
504+
}
507505

508-
// If the replacement value is the load, this must occur in unreachable
509-
// code.
510-
if (ReplVal == LI)
511-
ReplVal = PoisonValue::get(LI->getType());
506+
// Note, if the load was marked as nonnull we don't want to lose that
507+
// information when we erase it. So we preserve it with an assume.
508+
if (AC && LI->getMetadata(LLVMContext::MD_nonnull) &&
509+
!isKnownNonZero(ReplVal, DL, 0, AC, LI, &DT))
510+
addAssumeNonNull(AC, LI);
512511

513-
LI->replaceAllUsesWith(ReplVal);
514-
}
512+
// If the replacement value is the load, this must occur in unreachable
513+
// code.
514+
if (ReplVal == LI)
515+
ReplVal = PoisonValue::get(LI->getType());
515516

517+
LI->replaceAllUsesWith(ReplVal);
516518
LI->eraseFromParent();
517519
LBI.deleteValue(LI);
518520
}

llvm/test/Transforms/Mem2Reg/preserve-nonnull-load-metadata.ll

+2
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ fin:
9595
define float* @no_store_single_load() {
9696
; CHECK-LABEL: @no_store_single_load(
9797
; CHECK-NEXT: entry:
98+
; CHECK-NEXT: [[TMP0:%.*]] = icmp ne float* undef, null
99+
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
98100
; CHECK-NEXT: ret float* undef
99101
;
100102
entry:

0 commit comments

Comments
 (0)