Skip to content

[WIP] Consider datalayout sentinel pointer value for isKnownNonZero check #91769

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions llvm/lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3098,6 +3098,13 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts,
// Check for pointer simplifications.

if (PointerType *PtrTy = dyn_cast<PointerType>(Ty)) {
const DataLayout &DL = Q.DL;
if (DL.isSentinelValueDefined()) {
unsigned AddrSpace = PtrTy->getPointerAddressSpace();

return (DL.getSentinelPointerValue(AddrSpace) != 0);
}

// A byval, inalloca may not be null in a non-default addres space. A
// nonnull argument is assumed never 0.
if (const Argument *A = dyn_cast<Argument>(V)) {
Expand Down
151 changes: 151 additions & 0 deletions llvm/test/Transforms/Attributor/IPConstantProp/pthreads-dl-sentinel.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -data-layout=z0:1-z2:neg1-z3:neg1-z5:neg1 -S < %s | FileCheck %s --check-prefixes=CHECK-DL,CGSCC-DL
;
; #include <pthread.h>
;
; ptr GlobalVPtr;
;
; static ptr foo(ptr arg) { return arg; }
; static ptr bar(ptr arg) { return arg; }
;
; int main() {
; pthread_t thread;
; pthread_create(&thread, NULL, foo, NULL);
; pthread_create(&thread, NULL, bar, &GlobalVPtr);
; return 0;
; }
;
; Verify the constant values NULL and &GlobalVPtr are propagated into foo and
; bar, respectively.
;

%union.pthread_attr_t = type { i64, [48 x i8] }

@GlobalVPtr = common dso_local global ptr null, align 8

; FIXME: nocapture & noalias for @GlobalVPtr in %call1
; FIXME: nocapture & noalias for %alloc2 in %call3

;.
; CHECK: @GlobalVPtr = common dso_local global ptr null, align 8
;.
; CHECK-DL: @GlobalVPtr = common dso_local global ptr null, align 8
;.
define dso_local i32 @main() {
; CHECK-LABEL: define {{[^@]+}}@main() {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ALLOC1:%.*]] = alloca i8, align 8
; CHECK-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8
; CHECK-NEXT: [[THREAD:%.*]] = alloca i64, align 8
; CHECK-NEXT: [[CALL:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef align 4294967296 null, ptr noundef nonnull @foo, ptr nofree noundef readnone align 4294967296 null)
; CHECK-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef align 4294967296 null, ptr noundef nonnull @bar, ptr noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(8) @GlobalVPtr)
; CHECK-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef align 4294967296 null, ptr noundef nonnull @baz, ptr noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(1) [[ALLOC1]])
; CHECK-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef align 4294967296 null, ptr noundef nonnull @buz, ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(1) [[ALLOC2]])
; CHECK-NEXT: ret i32 0
;
; CHECK-DL-LABEL: define {{[^@]+}}@main() {
; CHECK-DL-NEXT: entry:
; CHECK-DL-NEXT: [[ALLOC1:%.*]] = alloca i8, align 8
; CHECK-DL-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8
; CHECK-DL-NEXT: [[THREAD:%.*]] = alloca i64, align 8
; CHECK-DL-NEXT: unreachable
;
entry:
%alloc1 = alloca i8, align 8
%alloc2 = alloca i8, align 8
%thread = alloca i64, align 8
%call = call i32 @pthread_create(ptr nonnull %thread, ptr null, ptr nonnull @foo, ptr null)
%call1 = call i32 @pthread_create(ptr nonnull %thread, ptr null, ptr nonnull @bar, ptr @GlobalVPtr)
%call2 = call i32 @pthread_create(ptr nonnull %thread, ptr null, ptr nonnull @baz, ptr nocapture %alloc1)
%call3 = call i32 @pthread_create(ptr nonnull %thread, ptr null, ptr nonnull @buz, ptr %alloc2)
ret i32 0
}

declare !callback !0 dso_local i32 @pthread_create(ptr, ptr, ptr, ptr)

define internal ptr @foo(ptr %arg) {
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-LABEL: define {{[^@]+}}@foo
; CHECK-SAME: (ptr noalias nocapture nofree readnone align 4294967296 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret ptr null
;
; CHECK-DL: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-DL-LABEL: define {{[^@]+}}@foo
; CHECK-DL-SAME: (ptr noalias nocapture nofree nonnull readnone align 4294967296 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-DL-NEXT: entry:
; CHECK-DL-NEXT: unreachable
;
entry:
ret ptr %arg
}


define internal ptr @bar(ptr %arg) {
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-LABEL: define {{[^@]+}}@bar
; CHECK-SAME: (ptr noalias nocapture nofree nonnull readnone align 8 dereferenceable(8) [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret ptr @GlobalVPtr
;
; CHECK-DL: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-DL-LABEL: define {{[^@]+}}@bar
; CHECK-DL-SAME: (ptr noalias nocapture nofree nonnull readnone align 8 dereferenceable(8) [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-DL-NEXT: entry:
; CHECK-DL-NEXT: ret ptr @GlobalVPtr
;
entry:
ret ptr %arg
}

define internal ptr @baz(ptr %arg) {
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-LABEL: define {{[^@]+}}@baz
; CHECK-SAME: (ptr noalias nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret ptr [[ARG]]
;
; CHECK-DL: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-DL-LABEL: define {{[^@]+}}@baz
; CHECK-DL-SAME: (ptr noalias nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-DL-NEXT: entry:
; CHECK-DL-NEXT: ret ptr [[ARG]]
;
entry:
ret ptr %arg
}

define internal ptr @buz(ptr %arg) {
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-LABEL: define {{[^@]+}}@buz
; CHECK-SAME: (ptr noalias nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: ret ptr [[ARG]]
;
; CHECK-DL: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-DL-LABEL: define {{[^@]+}}@buz
; CHECK-DL-SAME: (ptr noalias nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-DL-NEXT: entry:
; CHECK-DL-NEXT: ret ptr [[ARG]]
;
entry:
ret ptr %arg
}

!1 = !{i64 2, i64 3, i1 false}
!0 = !{!1}
;.
; CHECK: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
;.
; CHECK-DL: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
;.
; CHECK: [[META0:![0-9]+]] = !{[[META1:![0-9]+]]}
; CHECK: [[META1]] = !{i64 2, i64 3, i1 false}
;.
; CHECK-DL: [[META0:![0-9]+]] = !{[[META1:![0-9]+]]}
; CHECK-DL: [[META1]] = !{i64 2, i64 3, i1 false}
;.
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
; CGSCC: {{.*}}
; CGSCC-DL: {{.*}}
Loading
Loading