Skip to content

Commit c6973ad

Browse files
authored
[Mem2Reg] Generate non-terminator unreachable for !noundef undef (#96639)
When performing a load from uninitialized memory using !noundef, insert a non-terminator unreachable instruction, which will be converted to a proper unreachable by SimplifyCFG. This way we retain the fact that UB occurred on this code path.
1 parent fb463e1 commit c6973ad

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,15 @@ static void addAssumeNonNull(AssumptionCache *AC, LoadInst *LI) {
453453
static void convertMetadataToAssumes(LoadInst *LI, Value *Val,
454454
const DataLayout &DL, AssumptionCache *AC,
455455
const DominatorTree *DT) {
456+
if (isa<UndefValue>(Val) && LI->hasMetadata(LLVMContext::MD_noundef)) {
457+
// Insert non-terminator unreachable.
458+
LLVMContext &Ctx = LI->getContext();
459+
new StoreInst(ConstantInt::getTrue(Ctx),
460+
PoisonValue::get(PointerType::getUnqual(Ctx)),
461+
/*isVolatile=*/false, Align(1), LI);
462+
return;
463+
}
464+
456465
// If the load was marked as nonnull we don't want to lose that information
457466
// when we erase this Load. So we preserve it with an assume. As !nonnull
458467
// returns poison while assume violations are immediate undefined behavior,

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

+6-6
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ fin:
143143
define ptr @no_store_single_load_noundef() {
144144
; CHECK-LABEL: @no_store_single_load_noundef(
145145
; CHECK-NEXT: entry:
146+
; CHECK-NEXT: store i1 true, ptr poison, align 1
146147
; CHECK-NEXT: ret ptr undef
147148
;
148149
entry:
@@ -156,8 +157,10 @@ define ptr @no_store_multiple_loads_noundef(i1 %c) {
156157
; CHECK-NEXT: entry:
157158
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
158159
; CHECK: if:
160+
; CHECK-NEXT: store i1 true, ptr poison, align 1
159161
; CHECK-NEXT: ret ptr undef
160162
; CHECK: else:
163+
; CHECK-NEXT: store i1 true, ptr poison, align 1
161164
; CHECK-NEXT: ret ptr undef
162165
;
163166
entry:
@@ -176,8 +179,7 @@ if:
176179
define ptr @no_store_single_load_nonnull_noundef() {
177180
; CHECK-LABEL: @no_store_single_load_nonnull_noundef(
178181
; CHECK-NEXT: entry:
179-
; CHECK-NEXT: [[TMP0:%.*]] = icmp ne ptr undef, null
180-
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
182+
; CHECK-NEXT: store i1 true, ptr poison, align 1
181183
; CHECK-NEXT: ret ptr undef
182184
;
183185
entry:
@@ -191,12 +193,10 @@ define ptr @no_store_multiple_loads_nonnull_noundef(i1 %c) {
191193
; CHECK-NEXT: entry:
192194
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
193195
; CHECK: if:
194-
; CHECK-NEXT: [[TMP0:%.*]] = icmp ne ptr undef, null
195-
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
196+
; CHECK-NEXT: store i1 true, ptr poison, align 1
196197
; CHECK-NEXT: ret ptr undef
197198
; CHECK: else:
198-
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne ptr undef, null
199-
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
199+
; CHECK-NEXT: store i1 true, ptr poison, align 1
200200
; CHECK-NEXT: ret ptr undef
201201
;
202202
entry:

0 commit comments

Comments
 (0)