Skip to content

Commit b27bdf9

Browse files
committed
[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`.
1 parent 00d7b7d commit b27bdf9

File tree

6 files changed

+119
-86
lines changed

6 files changed

+119
-86
lines changed

llvm/lib/Transforms/IPO/AttributorAttributes.cpp

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,21 +1687,33 @@ struct AANonNullImpl : AANonNull {
16871687
Value &V = getAssociatedValue();
16881688
if (!NullIsDefined &&
16891689
hasAttr({Attribute::NonNull, Attribute::Dereferenceable},
1690-
/* IgnoreSubsumingPositions */ false, &A))
1690+
/* IgnoreSubsumingPositions */ false, &A)) {
16911691
indicateOptimisticFixpoint();
1692-
else if (isa<ConstantPointerNull>(V))
1692+
return;
1693+
}
1694+
1695+
if (isa<ConstantPointerNull>(V)) {
16931696
indicatePessimisticFixpoint();
1694-
else
1695-
AANonNull::initialize(A);
1697+
return;
1698+
}
1699+
1700+
AANonNull::initialize(A);
16961701

16971702
bool CanBeNull = true;
1698-
if (V.getPointerDereferenceableBytes(A.getDataLayout(), CanBeNull))
1699-
if (!CanBeNull)
1703+
if (V.getPointerDereferenceableBytes(A.getDataLayout(), CanBeNull)) {
1704+
if (!CanBeNull) {
17001705
indicateOptimisticFixpoint();
1706+
return;
1707+
}
1708+
}
17011709

1702-
if (!getState().isAtFixpoint())
1703-
if (Instruction *CtxI = getCtxI())
1704-
followUsesInMBEC(*this, A, getState(), *CtxI);
1710+
if (isa<GlobalValue>(&getAssociatedValue())) {
1711+
indicatePessimisticFixpoint();
1712+
return;
1713+
}
1714+
1715+
if (Instruction *CtxI = getCtxI())
1716+
followUsesInMBEC(*this, A, getState(), *CtxI);
17051717
}
17061718

17071719
/// See followUsesInMBEC
@@ -1778,9 +1790,14 @@ struct AANonNullFloating : public AANonNullImpl {
17781790

17791791
/// NonNull attribute for function return value.
17801792
struct AANonNullReturned final
1781-
: AAReturnedFromReturnedValues<AANonNull, AANonNullImpl> {
1793+
: AAReturnedFromReturnedValues<AANonNull, AANonNull> {
17821794
AANonNullReturned(const IRPosition &IRP, Attributor &A)
1783-
: AAReturnedFromReturnedValues<AANonNull, AANonNullImpl>(IRP, A) {}
1795+
: AAReturnedFromReturnedValues<AANonNull, AANonNull>(IRP, A) {}
1796+
1797+
/// See AbstractAttribute::getAsStr().
1798+
const std::string getAsStr() const override {
1799+
return getAssumed() ? "nonnull" : "may-null";
1800+
}
17841801

17851802
/// See AbstractAttribute::trackStatistics()
17861803
void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }

llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ define dso_local void @foo(i32 %N) {
3636
; IS__TUNIT_OPM-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4
3737
; IS__TUNIT_OPM-NEXT: store float 3.000000e+00, float* [[P]], align 4
3838
; IS__TUNIT_OPM-NEXT: store i32 7, i32* [[N_ADDR]], align 4
39-
; 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)
39+
; 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)
4040
; IS__TUNIT_OPM-NEXT: ret void
4141
;
4242
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@foo
@@ -47,7 +47,7 @@ define dso_local void @foo(i32 %N) {
4747
; IS__TUNIT_NPM-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4
4848
; IS__TUNIT_NPM-NEXT: store float 3.000000e+00, float* [[P]], align 4
4949
; IS__TUNIT_NPM-NEXT: store i32 7, i32* [[N_ADDR]], align 4
50-
; 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)
50+
; 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)
5151
; IS__TUNIT_NPM-NEXT: ret void
5252
;
5353
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@foo

llvm/test/Transforms/Attributor/callbacks.ll

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ define void @t0_caller(i32* %a) {
2525
; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
2626
; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32
2727
; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64
28-
; 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]])
28+
; 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]])
2929
; IS__TUNIT_OPM-NEXT: ret void
3030
;
3131
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t0_caller
@@ -37,7 +37,7 @@ define void @t0_caller(i32* %a) {
3737
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
3838
; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32
3939
; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64
40-
; 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]])
40+
; 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]])
4141
; IS__TUNIT_NPM-NEXT: ret void
4242
;
4343
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t0_caller
@@ -124,7 +124,7 @@ define void @t1_caller(i32* noalias %a) {
124124
; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
125125
; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32
126126
; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64
127-
; 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]])
127+
; 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]])
128128
; IS__TUNIT_OPM-NEXT: ret void
129129
;
130130
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t1_caller
@@ -136,7 +136,7 @@ define void @t1_caller(i32* noalias %a) {
136136
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
137137
; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32
138138
; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64
139-
; 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]])
139+
; 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]])
140140
; IS__TUNIT_NPM-NEXT: ret void
141141
;
142142
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t1_caller
@@ -224,7 +224,7 @@ define void @t2_caller(i32* noalias %a) {
224224
; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
225225
; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32
226226
; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64
227-
; 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]])
227+
; 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]])
228228
; IS__TUNIT_OPM-NEXT: ret void
229229
;
230230
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t2_caller
@@ -236,7 +236,7 @@ define void @t2_caller(i32* noalias %a) {
236236
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
237237
; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32
238238
; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64
239-
; 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]])
239+
; 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]])
240240
; IS__TUNIT_NPM-NEXT: ret void
241241
;
242242
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t2_caller
@@ -324,8 +324,8 @@ define void @t3_caller(i32* noalias %a) {
324324
; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
325325
; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32
326326
; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64
327-
; 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]])
328-
; 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]])
327+
; 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]])
328+
; 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]])
329329
; IS__TUNIT_OPM-NEXT: ret void
330330
;
331331
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t3_caller
@@ -337,8 +337,8 @@ define void @t3_caller(i32* noalias %a) {
337337
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
338338
; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32
339339
; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64
340-
; 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]])
341-
; 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]])
340+
; 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]])
341+
; 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]])
342342
; IS__TUNIT_NPM-NEXT: ret void
343343
;
344344
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t3_caller

0 commit comments

Comments
 (0)