Skip to content

Commit a58dcc5

Browse files
committed
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 a0c1b5b commit a58dcc5

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
@@ -7395,7 +7395,16 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu
73957395
// Look through GEPs. A load from a GEP derived from NULL is still undefined
73967396
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Use))
73977397
if (GEP->getPointerOperand() == I) {
7398-
if (!GEP->isInBounds() || !GEP->hasAllZeroIndices())
7398+
// The current base address is null, there are four cases to consider:
7399+
// getelementptr (TY, null, 0) -> null
7400+
// getelementptr (TY, null, not zero) -> may be modified
7401+
// getelementptr inbounds (TY, null, 0) -> null
7402+
// getelementptr inbounds (TY, null, not zero) -> poison iff null is
7403+
// undefined?
7404+
if (!GEP->hasAllZeroIndices() &&
7405+
(!GEP->isInBounds() ||
7406+
NullPointerIsDefined(GEP->getFunction(),
7407+
GEP->getPointerAddressSpace())))
73997408
PtrValueMayBeModified = true;
74007409
return passingValueIsAlwaysUndefined(V, GEP, PtrValueMayBeModified);
74017410
}

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)