Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8228e48

Browse files
committedJan 23, 2024
Reland "[SimplifyCFG] Improve the precision of PtrValueMayBeModified"
This relands commit f890f01. The result value of `getelementptr inbounds (TY, null, not zero)` is a poison value. We can think of it as undefined behavior.
1 parent fa56ca0 commit 8228e48

File tree

3 files changed

+96
-4
lines changed

3 files changed

+96
-4
lines changed
 

‎llvm/lib/Transforms/Utils/SimplifyCFG.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -7386,7 +7386,16 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu
73867386
// Look through GEPs. A load from a GEP derived from NULL is still undefined
73877387
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Use))
73887388
if (GEP->getPointerOperand() == I) {
7389-
if (!GEP->isInBounds() || !GEP->hasAllZeroIndices())
7389+
// The current base address is null, there are four cases to consider:
7390+
// getelementptr (TY, null, 0) -> null
7391+
// getelementptr (TY, null, not zero) -> may be modified
7392+
// getelementptr inbounds (TY, null, 0) -> null
7393+
// getelementptr inbounds (TY, null, not zero) -> poison iff null is
7394+
// undefined?
7395+
if (!GEP->hasAllZeroIndices() &&
7396+
(!GEP->isInBounds() ||
7397+
NullPointerIsDefined(GEP->getFunction(),
7398+
GEP->getPointerAddressSpace())))
73907399
PtrValueMayBeModified = true;
73917400
return passingValueIsAlwaysUndefined(V, GEP, PtrValueMayBeModified);
73927401
}

‎llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll

+66-2
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,28 @@ else:
444444
define void @test9_gep_inbounds_nonzero(i1 %X, ptr %Y) {
445445
; CHECK-LABEL: @test9_gep_inbounds_nonzero(
446446
; CHECK-NEXT: entry:
447+
; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true
448+
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
449+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[Y:%.*]], i64 12
450+
; CHECK-NEXT: [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
451+
; CHECK-NEXT: ret void
452+
;
453+
entry:
454+
br i1 %X, label %if, label %else
455+
456+
if:
457+
br label %else
458+
459+
else:
460+
%phi = phi ptr [ %Y, %entry ], [ null, %if ]
461+
%gep = getelementptr inbounds i8, ptr %phi, i64 12
462+
call ptr @fn_nonnull_noundef_arg(ptr %gep)
463+
ret void
464+
}
465+
466+
define void @test9_gep_inbounds_nonzero_null_defined(i1 %X, ptr %Y) #0 {
467+
; CHECK-LABEL: @test9_gep_inbounds_nonzero_null_defined(
468+
; CHECK-NEXT: entry:
447469
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
448470
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[SPEC_SELECT]], i64 12
449471
; CHECK-NEXT: [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
@@ -462,9 +484,30 @@ else:
462484
ret void
463485
}
464486

487+
define void @test9_gep_inbounds_unknown_null(i1 %X, ptr %Y, i64 %I) {
488+
; CHECK-LABEL: @test9_gep_inbounds_unknown_null(
489+
; CHECK-NEXT: entry:
490+
; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true
491+
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
492+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[Y:%.*]], i64 [[I:%.*]]
493+
; CHECK-NEXT: [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
494+
; CHECK-NEXT: ret void
495+
;
496+
entry:
497+
br i1 %X, label %if, label %else
498+
499+
if:
500+
br label %else
501+
502+
else:
503+
%phi = phi ptr [ %Y, %entry ], [ null, %if ]
504+
%gep = getelementptr inbounds i8, ptr %phi, i64 %I
505+
call ptr @fn_nonnull_noundef_arg(ptr %gep)
506+
ret void
507+
}
465508

466-
define void @test9_gep_inbouds_unknown_null(i1 %X, ptr %Y, i64 %I) {
467-
; CHECK-LABEL: @test9_gep_inbouds_unknown_null(
509+
define void @test9_gep_inbounds_unknown_null_defined(i1 %X, ptr %Y, i64 %I) #0 {
510+
; CHECK-LABEL: @test9_gep_inbounds_unknown_null_defined(
468511
; CHECK-NEXT: entry:
469512
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
470513
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[SPEC_SELECT]], i64 [[I:%.*]]
@@ -484,6 +527,27 @@ else:
484527
ret void
485528
}
486529

530+
define void @test9_gep_inbounds_unknown_null_call_noundef(i1 %X, ptr %Y, i64 %I) {
531+
; CHECK-LABEL: @test9_gep_inbounds_unknown_null_call_noundef(
532+
; CHECK-NEXT: entry:
533+
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
534+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[SPEC_SELECT]], i64 [[I:%.*]]
535+
; CHECK-NEXT: [[TMP0:%.*]] = call ptr @fn_noundef_arg(ptr [[GEP]])
536+
; CHECK-NEXT: ret void
537+
;
538+
entry:
539+
br i1 %X, label %if, label %else
540+
541+
if:
542+
br label %else
543+
544+
else:
545+
%phi = phi ptr [ %Y, %entry ], [ null, %if ]
546+
%gep = getelementptr inbounds i8, ptr %phi, i64 %I
547+
call ptr @fn_noundef_arg(ptr %gep)
548+
ret void
549+
}
550+
487551
define void @test9_gep_unknown_null(i1 %X, ptr %Y, i64 %I) {
488552
; CHECK-LABEL: @test9_gep_unknown_null(
489553
; CHECK-NEXT: entry:

‎llvm/test/Transforms/SimplifyCFG/unreachable-eliminate-on-ret.ll

+20-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,26 @@ define nonnull noundef ptr @test_ret_ptr_nonnull_noundef_gep_nonzero(i1 %cond, p
5555
; CHECK-LABEL: @test_ret_ptr_nonnull_noundef_gep_nonzero(
5656
; CHECK-NEXT: entry:
5757
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[COND:%.*]], ptr [[X:%.*]], ptr null
58-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds ptr, ptr [[SPEC_SELECT]], i64 12
58+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr ptr, ptr [[SPEC_SELECT]], i64 12
59+
; CHECK-NEXT: ret ptr [[GEP]]
60+
;
61+
entry:
62+
br i1 %cond, label %bb1, label %bb2
63+
64+
bb1:
65+
br label %bb2
66+
67+
bb2:
68+
%phi = phi ptr [ null, %entry ], [ %x, %bb1 ]
69+
%gep = getelementptr ptr, ptr %phi, i64 12
70+
ret ptr %gep
71+
}
72+
73+
define nonnull noundef ptr @test_ret_ptr_nonnull_noundef_gep_inbounds_nonzero(i1 %cond, ptr %x) {
74+
; CHECK-LABEL: @test_ret_ptr_nonnull_noundef_gep_inbounds_nonzero(
75+
; CHECK-NEXT: entry:
76+
; CHECK-NEXT: call void @llvm.assume(i1 [[COND:%.*]])
77+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds ptr, ptr [[X:%.*]], i64 12
5978
; CHECK-NEXT: ret ptr [[GEP]]
6079
;
6180
entry:

0 commit comments

Comments
 (0)
Please sign in to comment.