[llvm] b27bdf9 - [Attributor][FIX] Handle function pointers properly in AANonNull
Johannes Doerfert via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 17 21:39:27 PDT 2020
Author: Johannes Doerfert
Date: 2020-08-17T23:36:35-05:00
New Revision: b27bdf955a74e1050645ef5482498a834e9dfc1e
URL: https://github.com/llvm/llvm-project/commit/b27bdf955a74e1050645ef5482498a834e9dfc1e
DIFF: https://github.com/llvm/llvm-project/commit/b27bdf955a74e1050645ef5482498a834e9dfc1e.diff
LOG: [Attributor][FIX] Handle function pointers properly in AANonNull
Before we tired to create a dominator tree for a declaration when we
wanted to determine if the function pointer is `nonnull`. We now avoid
looking at global values if `Value::getPointerDereferenceableBytes` not
already determined `nonnull`.
Added:
Modified:
llvm/lib/Transforms/IPO/AttributorAttributes.cpp
llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll
llvm/test/Transforms/Attributor/callbacks.ll
llvm/test/Transforms/Attributor/liveness.ll
llvm/test/Transforms/Attributor/misc.ll
llvm/test/Transforms/Attributor/nonnull.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 762d4a111515..13f56ec9d50d 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -1687,21 +1687,33 @@ struct AANonNullImpl : AANonNull {
Value &V = getAssociatedValue();
if (!NullIsDefined &&
hasAttr({Attribute::NonNull, Attribute::Dereferenceable},
- /* IgnoreSubsumingPositions */ false, &A))
+ /* IgnoreSubsumingPositions */ false, &A)) {
indicateOptimisticFixpoint();
- else if (isa<ConstantPointerNull>(V))
+ return;
+ }
+
+ if (isa<ConstantPointerNull>(V)) {
indicatePessimisticFixpoint();
- else
- AANonNull::initialize(A);
+ return;
+ }
+
+ AANonNull::initialize(A);
bool CanBeNull = true;
- if (V.getPointerDereferenceableBytes(A.getDataLayout(), CanBeNull))
- if (!CanBeNull)
+ if (V.getPointerDereferenceableBytes(A.getDataLayout(), CanBeNull)) {
+ if (!CanBeNull) {
indicateOptimisticFixpoint();
+ return;
+ }
+ }
- if (!getState().isAtFixpoint())
- if (Instruction *CtxI = getCtxI())
- followUsesInMBEC(*this, A, getState(), *CtxI);
+ if (isa<GlobalValue>(&getAssociatedValue())) {
+ indicatePessimisticFixpoint();
+ return;
+ }
+
+ if (Instruction *CtxI = getCtxI())
+ followUsesInMBEC(*this, A, getState(), *CtxI);
}
/// See followUsesInMBEC
@@ -1778,9 +1790,14 @@ struct AANonNullFloating : public AANonNullImpl {
/// NonNull attribute for function return value.
struct AANonNullReturned final
- : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl> {
+ : AAReturnedFromReturnedValues<AANonNull, AANonNull> {
AANonNullReturned(const IRPosition &IRP, Attributor &A)
- : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl>(IRP, A) {}
+ : AAReturnedFromReturnedValues<AANonNull, AANonNull>(IRP, A) {}
+
+ /// See AbstractAttribute::getAsStr().
+ const std::string getAsStr() const override {
+ return getAssumed() ? "nonnull" : "may-null";
+ }
/// See AbstractAttribute::trackStatistics()
void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll b/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll
index 83990224bdda..137193b972ca 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll
@@ -36,7 +36,7 @@ define dso_local void @foo(i32 %N) {
; IS__TUNIT_OPM-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4
; IS__TUNIT_OPM-NEXT: store float 3.000000e+00, float* [[P]], align 4
; IS__TUNIT_OPM-NEXT: store i32 7, i32* [[N_ADDR]], align 4
-; IS__TUNIT_OPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8 dereferenceable(24) [[GLOB1:@.*]], i32 3, void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* nocapture nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* nocapture nonnull readonly align 4 dereferenceable(4) [[P]], i64 undef)
+; IS__TUNIT_OPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8 dereferenceable(24) [[GLOB1:@.*]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* nocapture nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* nocapture nonnull readonly align 4 dereferenceable(4) [[P]], i64 undef)
; IS__TUNIT_OPM-NEXT: ret void
;
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@foo
@@ -47,7 +47,7 @@ define dso_local void @foo(i32 %N) {
; IS__TUNIT_NPM-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4
; IS__TUNIT_NPM-NEXT: store float 3.000000e+00, float* [[P]], align 4
; IS__TUNIT_NPM-NEXT: store i32 7, i32* [[N_ADDR]], align 4
-; IS__TUNIT_NPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8 dereferenceable(24) [[GLOB1:@.*]], i32 3, void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[P]], i64 undef)
+; IS__TUNIT_NPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8 dereferenceable(24) [[GLOB1:@.*]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[P]], i64 undef)
; IS__TUNIT_NPM-NEXT: ret void
;
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@foo
diff --git a/llvm/test/Transforms/Attributor/callbacks.ll b/llvm/test/Transforms/Attributor/callbacks.ll
index 951f9830ae59..f1dfacea8a96 100644
--- a/llvm/test/Transforms/Attributor/callbacks.ll
+++ b/llvm/test/Transforms/Attributor/callbacks.ll
@@ -25,7 +25,7 @@ define void @t0_caller(i32* %a) {
; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32
; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64
-; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias nocapture align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
+; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias nocapture align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
; IS__TUNIT_OPM-NEXT: ret void
;
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t0_caller
@@ -37,7 +37,7 @@ define void @t0_caller(i32* %a) {
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32
; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64
-; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias nocapture align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
+; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias nocapture align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
; IS__TUNIT_NPM-NEXT: ret void
;
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t0_caller
@@ -124,7 +124,7 @@ define void @t1_caller(i32* noalias %a) {
; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32
; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64
-; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias nocapture align 536870912 null, i32* nocapture nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
+; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias nocapture align 536870912 null, i32* nocapture nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
; IS__TUNIT_OPM-NEXT: ret void
;
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t1_caller
@@ -136,7 +136,7 @@ define void @t1_caller(i32* noalias %a) {
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32
; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64
-; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias nocapture align 536870912 null, i32* noalias nocapture nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
+; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias nocapture align 536870912 null, i32* noalias nocapture nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
; IS__TUNIT_NPM-NEXT: ret void
;
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t1_caller
@@ -224,7 +224,7 @@ define void @t2_caller(i32* noalias %a) {
; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32
; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64
-; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias nocapture align 536870912 null, i32* nocapture nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
+; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias nocapture align 536870912 null, i32* nocapture nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
; IS__TUNIT_OPM-NEXT: ret void
;
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t2_caller
@@ -236,7 +236,7 @@ define void @t2_caller(i32* noalias %a) {
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32
; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64
-; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias nocapture align 536870912 null, i32* noalias nocapture nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
+; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias nocapture align 536870912 null, i32* noalias nocapture nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
; IS__TUNIT_NPM-NEXT: ret void
;
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t2_caller
@@ -324,8 +324,8 @@ define void @t3_caller(i32* noalias %a) {
; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32
; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64
-; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias nocapture align 536870912 null, i32* nocapture nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
-; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias nocapture align 536870912 null, i32* nocapture nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
+; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias nocapture align 536870912 null, i32* nocapture nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
+; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias nocapture align 536870912 null, i32* nocapture nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
; IS__TUNIT_OPM-NEXT: ret void
;
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t3_caller
@@ -337,8 +337,8 @@ define void @t3_caller(i32* noalias %a) {
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32
; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64
-; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias nocapture align 536870912 null, i32* noalias nocapture nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
-; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias nocapture align 536870912 null, i32* noalias nocapture nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
+; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias nocapture align 536870912 null, i32* noalias nocapture nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
+; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias nocapture align 536870912 null, i32* noalias nocapture nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
; IS__TUNIT_NPM-NEXT: ret void
;
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t3_caller
diff --git a/llvm/test/Transforms/Attributor/liveness.ll b/llvm/test/Transforms/Attributor/liveness.ll
index 2a24a168263c..57017c50af52 100644
--- a/llvm/test/Transforms/Attributor/liveness.ll
+++ b/llvm/test/Transforms/Attributor/liveness.ll
@@ -1785,17 +1785,29 @@ define internal void @call_via_pointer_with_dead_args_internal_b(i32* %a, i32* %
ret void
}
define void @call_via_pointer_with_dead_args_caller(i32* %a, i32* %b) {
-; CHECK-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_caller
-; CHECK-SAME: (i32* [[A:%.*]], i32* [[B:%.*]])
-; CHECK-NEXT: [[PTR1:%.*]] = alloca i32, align 128
-; CHECK-NEXT: [[PTR2:%.*]] = alloca i32, align 128
-; CHECK-NEXT: [[PTR3:%.*]] = alloca i32, align 128
-; CHECK-NEXT: [[PTR4:%.*]] = alloca i32, align 128
-; CHECK-NEXT: call void @call_via_pointer_with_dead_args(i32* [[A]], i32* nonnull align 128 dereferenceable(4) [[PTR1]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree nonnull @called_via_pointer)
-; CHECK-NEXT: call void @call_via_pointer_with_dead_args(i32* [[A]], i32* nonnull align 128 dereferenceable(4) [[PTR2]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree nonnull @called_via_pointer_internal_1)
-; CHECK-NEXT: call void @call_via_pointer_with_dead_args_internal_a(i32* [[B]], i32* nonnull align 128 dereferenceable(4) [[PTR3]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree nonnull @called_via_pointer)
-; CHECK-NEXT: call void @call_via_pointer_with_dead_args_internal_b(i32* [[B]], i32* nonnull align 128 dereferenceable(4) [[PTR4]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree nonnull @called_via_pointer_internal_2)
-; CHECK-NEXT: ret void
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_caller
+; NOT_CGSCC_NPM-SAME: (i32* [[A:%.*]], i32* [[B:%.*]])
+; NOT_CGSCC_NPM-NEXT: [[PTR1:%.*]] = alloca i32, align 128
+; NOT_CGSCC_NPM-NEXT: [[PTR2:%.*]] = alloca i32, align 128
+; NOT_CGSCC_NPM-NEXT: [[PTR3:%.*]] = alloca i32, align 128
+; NOT_CGSCC_NPM-NEXT: [[PTR4:%.*]] = alloca i32, align 128
+; NOT_CGSCC_NPM-NEXT: call void @call_via_pointer_with_dead_args(i32* [[A]], i32* nonnull align 128 dereferenceable(4) [[PTR1]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree @called_via_pointer)
+; NOT_CGSCC_NPM-NEXT: call void @call_via_pointer_with_dead_args(i32* [[A]], i32* nonnull align 128 dereferenceable(4) [[PTR2]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree @called_via_pointer_internal_1)
+; NOT_CGSCC_NPM-NEXT: call void @call_via_pointer_with_dead_args_internal_a(i32* [[B]], i32* nonnull align 128 dereferenceable(4) [[PTR3]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree @called_via_pointer)
+; NOT_CGSCC_NPM-NEXT: call void @call_via_pointer_with_dead_args_internal_b(i32* [[B]], i32* nonnull align 128 dereferenceable(4) [[PTR4]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree @called_via_pointer_internal_2)
+; NOT_CGSCC_NPM-NEXT: ret void
+;
+; IS__CGSCC____-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_caller
+; IS__CGSCC____-SAME: (i32* [[A:%.*]], i32* [[B:%.*]])
+; IS__CGSCC____-NEXT: [[PTR1:%.*]] = alloca i32, align 128
+; IS__CGSCC____-NEXT: [[PTR2:%.*]] = alloca i32, align 128
+; IS__CGSCC____-NEXT: [[PTR3:%.*]] = alloca i32, align 128
+; IS__CGSCC____-NEXT: [[PTR4:%.*]] = alloca i32, align 128
+; IS__CGSCC____-NEXT: call void @call_via_pointer_with_dead_args(i32* [[A]], i32* nonnull align 128 dereferenceable(4) [[PTR1]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree nonnull @called_via_pointer)
+; IS__CGSCC____-NEXT: call void @call_via_pointer_with_dead_args(i32* [[A]], i32* nonnull align 128 dereferenceable(4) [[PTR2]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree nonnull @called_via_pointer_internal_1)
+; IS__CGSCC____-NEXT: call void @call_via_pointer_with_dead_args_internal_a(i32* [[B]], i32* nonnull align 128 dereferenceable(4) [[PTR3]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree nonnull @called_via_pointer)
+; IS__CGSCC____-NEXT: call void @call_via_pointer_with_dead_args_internal_b(i32* [[B]], i32* nonnull align 128 dereferenceable(4) [[PTR4]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree nonnull @called_via_pointer_internal_2)
+; IS__CGSCC____-NEXT: ret void
;
%ptr1 = alloca i32, align 128
%ptr2 = alloca i32, align 128
diff --git a/llvm/test/Transforms/Attributor/misc.ll b/llvm/test/Transforms/Attributor/misc.ll
index 46a0449e5be6..80a6948ca6dc 100644
--- a/llvm/test/Transforms/Attributor/misc.ll
+++ b/llvm/test/Transforms/Attributor/misc.ll
@@ -9,31 +9,18 @@
define internal void @internal(void (i8*)* %fp) {
;
;
-; IS__TUNIT____-LABEL: define {{[^@]+}}@internal
-; IS__TUNIT____-SAME: (void (i8*)* nonnull [[FP:%.*]])
-; IS__TUNIT____-NEXT: entry:
-; IS__TUNIT____-NEXT: [[A:%.*]] = alloca i32, align 4
-; IS__TUNIT____-NEXT: call void @foo(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A]])
-; IS__TUNIT____-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
-; IS__TUNIT____-NEXT: call void @callback1(void (i32*)* nonnull @foo)
-; IS__TUNIT____-NEXT: call void @callback2(void (i8*)* nonnull bitcast (void (i32*)* @foo to void (i8*)*))
-; IS__TUNIT____-NEXT: call void @callback2(void (i8*)* nonnull [[FP]])
-; IS__TUNIT____-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
-; IS__TUNIT____-NEXT: call void [[FP]](i8* [[TMP1]])
-; IS__TUNIT____-NEXT: ret void
-;
-; IS__CGSCC____-LABEL: define {{[^@]+}}@internal
-; IS__CGSCC____-SAME: (void (i8*)* nonnull [[FP:%.*]])
-; IS__CGSCC____-NEXT: entry:
-; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32, align 4
-; IS__CGSCC____-NEXT: call void @foo(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A]])
-; IS__CGSCC____-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
-; IS__CGSCC____-NEXT: call void @callback1(void (i32*)* nonnull @foo)
-; IS__CGSCC____-NEXT: call void @callback2(void (i8*)* bitcast (void (i32*)* @foo to void (i8*)*))
-; IS__CGSCC____-NEXT: call void @callback2(void (i8*)* nonnull [[FP]])
-; IS__CGSCC____-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
-; IS__CGSCC____-NEXT: call void [[FP]](i8* [[TMP1]])
-; IS__CGSCC____-NEXT: ret void
+; CHECK-LABEL: define {{[^@]+}}@internal
+; CHECK-SAME: (void (i8*)* nonnull [[FP:%.*]])
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
+; CHECK-NEXT: call void @foo(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A]])
+; CHECK-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
+; CHECK-NEXT: call void @callback1(void (i32*)* nonnull @foo)
+; CHECK-NEXT: call void @callback2(void (i8*)* bitcast (void (i32*)* @foo to void (i8*)*))
+; CHECK-NEXT: call void @callback2(void (i8*)* nonnull [[FP]])
+; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
+; CHECK-NEXT: call void [[FP]](i8* [[TMP1]])
+; CHECK-NEXT: ret void
;
entry:
%a = alloca i32, align 4
@@ -51,33 +38,19 @@ entry:
define void @external(void (i8*)* %fp) {
;
;
-; IS__TUNIT____-LABEL: define {{[^@]+}}@external
-; IS__TUNIT____-SAME: (void (i8*)* [[FP:%.*]])
-; IS__TUNIT____-NEXT: entry:
-; IS__TUNIT____-NEXT: [[A:%.*]] = alloca i32, align 4
-; IS__TUNIT____-NEXT: call void @foo(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A]])
-; IS__TUNIT____-NEXT: call void @callback1(void (i32*)* nonnull @foo)
-; IS__TUNIT____-NEXT: call void @callback2(void (i8*)* nonnull bitcast (void (i32*)* @foo to void (i8*)*))
-; IS__TUNIT____-NEXT: call void @callback2(void (i8*)* [[FP]])
-; IS__TUNIT____-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
-; IS__TUNIT____-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
-; IS__TUNIT____-NEXT: call void [[FP]](i8* [[TMP1]])
-; IS__TUNIT____-NEXT: call void @internal(void (i8*)* nonnull [[FP]])
-; IS__TUNIT____-NEXT: ret void
-;
-; IS__CGSCC____-LABEL: define {{[^@]+}}@external
-; IS__CGSCC____-SAME: (void (i8*)* [[FP:%.*]])
-; IS__CGSCC____-NEXT: entry:
-; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32, align 4
-; IS__CGSCC____-NEXT: call void @foo(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A]])
-; IS__CGSCC____-NEXT: call void @callback1(void (i32*)* nonnull @foo)
-; IS__CGSCC____-NEXT: call void @callback2(void (i8*)* bitcast (void (i32*)* @foo to void (i8*)*))
-; IS__CGSCC____-NEXT: call void @callback2(void (i8*)* [[FP]])
-; IS__CGSCC____-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
-; IS__CGSCC____-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
-; IS__CGSCC____-NEXT: call void [[FP]](i8* [[TMP1]])
-; IS__CGSCC____-NEXT: call void @internal(void (i8*)* nonnull [[FP]])
-; IS__CGSCC____-NEXT: ret void
+; CHECK-LABEL: define {{[^@]+}}@external
+; CHECK-SAME: (void (i8*)* [[FP:%.*]])
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
+; CHECK-NEXT: call void @foo(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A]])
+; CHECK-NEXT: call void @callback1(void (i32*)* nonnull @foo)
+; CHECK-NEXT: call void @callback2(void (i8*)* bitcast (void (i32*)* @foo to void (i8*)*))
+; CHECK-NEXT: call void @callback2(void (i8*)* [[FP]])
+; CHECK-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
+; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
+; CHECK-NEXT: call void [[FP]](i8* [[TMP1]])
+; CHECK-NEXT: call void @internal(void (i8*)* nonnull [[FP]])
+; CHECK-NEXT: ret void
;
entry:
%a = alloca i32, align 4
diff --git a/llvm/test/Transforms/Attributor/nonnull.ll b/llvm/test/Transforms/Attributor/nonnull.ll
index 9290d32453ba..4add5a5c1f5a 100644
--- a/llvm/test/Transforms/Attributor/nonnull.ll
+++ b/llvm/test/Transforms/Attributor/nonnull.ll
@@ -1364,5 +1364,36 @@ define void @nonnull_assume_neg(i8* %arg) {
declare void @use_i8_ptr(i8* nofree nocapture readnone) nounwind
declare void @use_i8_ptr_ret(i8* nofree nocapture readnone) nounwind willreturn
+define i8* @nonnull_function_ptr_1() {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@nonnull_function_ptr_1()
+; IS__TUNIT____-NEXT: [[BC:%.*]] = bitcast i8* ()* @nonnull_function_ptr_1 to i8*
+; IS__TUNIT____-NEXT: ret i8* [[BC]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@nonnull_function_ptr_1()
+; IS__CGSCC____-NEXT: [[BC:%.*]] = bitcast i8* ()* @nonnull_function_ptr_1 to i8*
+; IS__CGSCC____-NEXT: ret i8* [[BC]]
+;
+ %bc = bitcast i8*()* @nonnull_function_ptr_1 to i8*
+ ret i8* %bc
+}
+
+declare i8* @function_decl()
+define i8* @nonnull_function_ptr_2() {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@nonnull_function_ptr_2()
+; IS__TUNIT____-NEXT: [[BC:%.*]] = bitcast i8* ()* @function_decl to i8*
+; IS__TUNIT____-NEXT: ret i8* [[BC]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@nonnull_function_ptr_2()
+; IS__CGSCC____-NEXT: [[BC:%.*]] = bitcast i8* ()* @function_decl to i8*
+; IS__CGSCC____-NEXT: ret i8* [[BC]]
+;
+ %bc = bitcast i8*()* @function_decl to i8*
+ ret i8* %bc
+}
+
attributes #0 = { null_pointer_is_valid }
attributes #1 = { nounwind willreturn}
More information about the llvm-commits
mailing list