Skip to content

Commit 412a010

Browse files
committed
[Attributor][FIX] Do not derive nonnull and dereferenceable w/o access
An inbounds GEP results in poison if the value is not "inbounds", not in UB. We accidentally derived nonnull and dereferenceable from these inbounds GEPs even in the absence of accesses that would make the poison to UB.
1 parent a4b3588 commit 412a010

File tree

5 files changed

+23
-18
lines changed

5 files changed

+23
-18
lines changed

llvm/lib/Transforms/IPO/Attributor.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,20 +1792,6 @@ static int64_t getKnownNonNullAndDerefBytesForUse(
17921792
return std::max(int64_t(0), DerefBytes);
17931793
}
17941794
}
1795-
if (const Value *Base =
1796-
GetPointerBaseWithConstantOffset(UseV, Offset, DL,
1797-
/*AllowNonInbounds*/ false)) {
1798-
if (Base == &AssociatedValue) {
1799-
// As long as we only use known information there is no need to track
1800-
// dependences here.
1801-
auto &DerefAA = A.getAAFor<AADereferenceable>(
1802-
QueryingAA, IRPosition::value(*Base), /* TrackDependence */ false);
1803-
IsNonNull |= (!NullPointerIsDefined && DerefAA.isKnownNonNull());
1804-
IsNonNull |= (!NullPointerIsDefined && (Offset != 0));
1805-
int64_t DerefBytes = DerefAA.getKnownDereferenceableBytes();
1806-
return std::max(int64_t(0), DerefBytes - std::max(int64_t(0), Offset));
1807-
}
1808-
}
18091795

18101796
return 0;
18111797
}

llvm/test/Transforms/Attributor/dereferenceable-1.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ define i32* @test3_1(i32* dereferenceable(8) %0) local_unnamed_addr {
3030
}
3131

3232
define i32* @test3_2(i32* dereferenceable_or_null(32) %0) local_unnamed_addr {
33-
; ATTRIBUTOR: define nonnull dereferenceable(16) i32* @test3_2(i32* nofree nonnull readnone dereferenceable(32) "no-capture-maybe-returned" %0)
33+
; ATTRIBUTOR: define nonnull dereferenceable(16) i32* @test3_2(i32* nofree readnone dereferenceable_or_null(32) "no-capture-maybe-returned" %0)
3434
%ret = getelementptr inbounds i32, i32* %0, i64 4
3535
ret i32* %ret
3636
}

llvm/test/Transforms/Attributor/nocapture-1.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,15 +288,15 @@ define i1 @captureICmpRev(i32* %x) {
288288
ret i1 %1
289289
}
290290

291-
; ATTRIBUTOR: define i1 @nocaptureInboundsGEPICmp(i32* nocapture nofree nonnull readnone %x)
291+
; ATTRIBUTOR: define i1 @nocaptureInboundsGEPICmp(i32* nocapture nofree readnone %x)
292292
define i1 @nocaptureInboundsGEPICmp(i32* %x) {
293293
%1 = getelementptr inbounds i32, i32* %x, i32 5
294294
%2 = bitcast i32* %1 to i8*
295295
%3 = icmp eq i8* %2, null
296296
ret i1 %3
297297
}
298298

299-
; ATTRIBUTOR: define i1 @nocaptureInboundsGEPICmpRev(i32* nocapture nofree nonnull readnone %x)
299+
; ATTRIBUTOR: define i1 @nocaptureInboundsGEPICmpRev(i32* nocapture nofree readnone %x)
300300
define i1 @nocaptureInboundsGEPICmpRev(i32* %x) {
301301
%1 = getelementptr inbounds i32, i32* %x, i32 5
302302
%2 = bitcast i32* %1 to i8*

llvm/test/Transforms/Attributor/nonnull.ll

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,5 +817,24 @@ define void @PR43833_simple(i32* %0, i32 %1) {
817817
br i1 %11, label %7, label %8
818818
}
819819

820+
declare i8* @strrchr(i8* %0, i32 %1) nofree nounwind readonly
821+
822+
; We should not mark the return of @strrchr as `nonnull`, it may well be NULL!
823+
define i8* @mybasename(i8* nofree readonly %str) {
824+
; ATTRIBUTOR-LABEL: define {{[^@]+}}@mybasename
825+
; ATTRIBUTOR-SAME: (i8* nofree readonly [[STR:%.*]])
826+
; ATTRIBUTOR-NEXT: [[CALL:%.*]] = call i8* @strrchr(i8* nofree readonly [[STR]], i32 47)
827+
; ATTRIBUTOR-NEXT: [[TOBOOL:%.*]] = icmp ne i8* [[CALL]], null
828+
; ATTRIBUTOR-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 1
829+
; ATTRIBUTOR-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i8* [[ADD_PTR]], i8* [[STR]]
830+
; ATTRIBUTOR-NEXT: ret i8* [[COND]]
831+
;
832+
%call = call i8* @strrchr(i8* %str, i32 47)
833+
%tobool = icmp ne i8* %call, null
834+
%add.ptr = getelementptr inbounds i8, i8* %call, i64 1
835+
%cond = select i1 %tobool, i8* %add.ptr, i8* %str
836+
ret i8* %cond
837+
}
838+
820839
attributes #0 = { "null-pointer-is-valid"="true" }
821840
attributes #1 = { nounwind willreturn}

llvm/test/Transforms/Attributor/nosync.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2525
%struct.ST = type { i32, double, %struct.RT }
2626

2727
; ATTRIBUTOR: Function Attrs: nofree nosync nounwind optsize readnone ssp uwtable
28-
; ATTRIBUTOR-NEXT: define nonnull i32* @foo(%struct.ST* nofree nonnull readnone "no-capture-maybe-returned" %s)
28+
; ATTRIBUTOR-NEXT: define nonnull i32* @foo(%struct.ST* nofree readnone "no-capture-maybe-returned" %s)
2929
define i32* @foo(%struct.ST* %s) nounwind uwtable readnone optsize ssp {
3030
entry:
3131
%arrayidx = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 1, i32 2, i32 1, i64 5, i64 13

0 commit comments

Comments
 (0)