diff options
author | Hideto Ueno <uenoku.tokotoko@gmail.com> | 2019-11-29 06:55:58 +0000 |
---|---|---|
committer | Hideto Ueno <uenoku.tokotoko@gmail.com> | 2019-11-29 06:55:58 +0000 |
commit | 6c742fdbf48ee3ae9afb2ab1568397a3b89276e5 (patch) | |
tree | 9e9441fd9400cd1422e19499496ae8925927bb76 /llvm/test/Transforms/InferFunctionAttrs | |
parent | dfedae50018f321cb2189a95936511b2506e5bce (diff) | |
download | bcm5719-llvm-6c742fdbf48ee3ae9afb2ab1568397a3b89276e5.tar.gz bcm5719-llvm-6c742fdbf48ee3ae9afb2ab1568397a3b89276e5.zip |
[Attributor] Deduce dereferenceable based on accessed bytes map
Summary:
This patch introduces the deduction based on load/store instructions whose pointer operand is a non-inbounds GEP instruction.
For example if we have,
```
void f(int *u){
u[0] = 0;
u[1] = 1;
u[2] = 2;
}
```
then u must be dereferenceable(12).
This patch is inspired by D64258
Reviewers: jdoerfert, spatel, hfinkel, RKSimon, sstefan1, xbolva00, dtemirbulatov
Reviewed By: jdoerfert
Subscribers: jfb, lebedev.ri, xbolva00, hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D70714
Diffstat (limited to 'llvm/test/Transforms/InferFunctionAttrs')
-rw-r--r-- | llvm/test/Transforms/InferFunctionAttrs/dereferenceable.ll | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/llvm/test/Transforms/InferFunctionAttrs/dereferenceable.ll b/llvm/test/Transforms/InferFunctionAttrs/dereferenceable.ll index bf7daba40d4..b6b699fac85 100644 --- a/llvm/test/Transforms/InferFunctionAttrs/dereferenceable.ll +++ b/llvm/test/Transforms/InferFunctionAttrs/dereferenceable.ll @@ -48,8 +48,7 @@ define double @PR21780_only_access3_without_inbounds(double* %ptr) { define double @PR21780_without_inbounds(double* %ptr) { ; CHECK-LABEL: @PR21780_without_inbounds(double* %ptr) -; FIXME: this should be @PR21780_without_inbounds(double* nonnull dereferenceable(32) %ptr) -; ATTRIBUTOR-LABEL: @PR21780_without_inbounds(double* nocapture nofree nonnull readonly align 8 dereferenceable(8) %ptr) +; ATTRIBUTOR-LABEL: @PR21780_without_inbounds(double* nocapture nofree nonnull readonly align 8 dereferenceable(32) %ptr) %arrayidx1 = getelementptr double, double* %ptr, i64 1 %arrayidx2 = getelementptr double, double* %ptr, i64 2 @@ -67,6 +66,7 @@ define double @PR21780_without_inbounds(double* %ptr) { define void @gep0(i8* %unused, i8* %other, i8* %ptr) { ; CHECK-LABEL: @gep0(i8* %unused, i8* %other, i8* %ptr) +; ATTRIBUTOR-LABEL: @gep0(i8* nocapture nofree readnone %unused, i8* nocapture nofree nonnull writeonly dereferenceable(1) %other, i8* nocapture nofree nonnull readonly dereferenceable(3) %ptr) %arrayidx0 = getelementptr i8, i8* %ptr, i64 0 %arrayidx1 = getelementptr i8, i8* %ptr, i64 1 %arrayidx2 = getelementptr i8, i8* %ptr, i64 2 @@ -82,6 +82,7 @@ define void @gep0(i8* %unused, i8* %other, i8* %ptr) { define void @ordering(i8* %ptr1, i32* %ptr2) { ; CHECK-LABEL: @ordering(i8* %ptr1, i32* %ptr2) +; ATTRIBUTOR-LABEL: @ordering(i8* nocapture nofree nonnull readonly dereferenceable(3) %ptr1, i32* nocapture nofree nonnull readonly dereferenceable(8) %ptr2) %a20 = getelementptr i32, i32* %ptr2, i64 0 %a12 = getelementptr i8, i8* %ptr1, i64 2 %t12 = load i8, i8* %a12 @@ -99,6 +100,7 @@ define void @ordering(i8* %ptr1, i32* %ptr2) { define void @not_entry_but_guaranteed_to_execute(i8* %ptr) { ; CHECK-LABEL: @not_entry_but_guaranteed_to_execute(i8* %ptr) +; ATTRIBUTOR-LABEL: @not_entry_but_guaranteed_to_execute(i8* nocapture nofree nonnull readonly dereferenceable(3) %ptr) entry: br label %exit exit: @@ -115,6 +117,7 @@ exit: define void @not_entry_not_guaranteed_to_execute(i8* %ptr, i1 %cond) { ; CHECK-LABEL: @not_entry_not_guaranteed_to_execute(i8* %ptr, i1 %cond) +; ATTRIBUTOR-LABEL: @not_entry_not_guaranteed_to_execute(i8* nocapture nofree readonly %ptr, i1 %cond) entry: br i1 %cond, label %loads, label %exit loads: @@ -133,6 +136,7 @@ exit: define void @partial_in_entry(i16* %ptr, i1 %cond) { ; CHECK-LABEL: @partial_in_entry(i16* %ptr, i1 %cond) +; ATTRIBUTOR-LABEL: @partial_in_entry(i16* nocapture nofree nonnull readonly dereferenceable(4) %ptr, i1 %cond) entry: %arrayidx0 = getelementptr i16, i16* %ptr, i64 0 %arrayidx1 = getelementptr i16, i16* %ptr, i64 1 @@ -152,6 +156,7 @@ exit: define void @volatile_is_not_dereferenceable(i16* %ptr) { ; CHECK-LABEL: @volatile_is_not_dereferenceable(i16* %ptr) +; ATTRIBUTOR-LABEL: @volatile_is_not_dereferenceable(i16* nofree %ptr) %arrayidx0 = getelementptr i16, i16* %ptr, i64 0 %arrayidx1 = getelementptr i16, i16* %ptr, i64 1 %arrayidx2 = getelementptr i16, i16* %ptr, i64 2 @@ -165,6 +170,7 @@ define void @volatile_is_not_dereferenceable(i16* %ptr) { define void @atomic_is_alright(i16* %ptr) { ; CHECK-LABEL: @atomic_is_alright(i16* %ptr) +; ATTRIBUTOR-LABEL: @atomic_is_alright(i16* nocapture nofree nonnull readonly align 2 dereferenceable(6) %ptr) %arrayidx0 = getelementptr i16, i16* %ptr, i64 0 %arrayidx1 = getelementptr i16, i16* %ptr, i64 1 %arrayidx2 = getelementptr i16, i16* %ptr, i64 2 @@ -178,6 +184,7 @@ declare void @may_not_return() define void @not_guaranteed_to_transfer_execution(i16* %ptr) { ; CHECK-LABEL: @not_guaranteed_to_transfer_execution(i16* %ptr) +; ATTRIBUTOR-LABEL: @not_guaranteed_to_transfer_execution(i16* nocapture nonnull readonly dereferenceable(2) %ptr) %arrayidx0 = getelementptr i16, i16* %ptr, i64 0 %arrayidx1 = getelementptr i16, i16* %ptr, i64 1 %arrayidx2 = getelementptr i16, i16* %ptr, i64 2 @@ -192,6 +199,7 @@ define void @not_guaranteed_to_transfer_execution(i16* %ptr) { define void @variable_gep_index(i8* %unused, i8* %ptr, i64 %variable_index) { ; CHECK-LABEL: @variable_gep_index(i8* %unused, i8* %ptr, i64 %variable_index) +; ATTRIBUTOR-LABEL: @variable_gep_index(i8* nocapture nofree readnone %unused, i8* nocapture nofree nonnull readonly dereferenceable(1) %ptr, i64 %variable_index) %arrayidx1 = getelementptr i8, i8* %ptr, i64 %variable_index %arrayidx2 = getelementptr i8, i8* %ptr, i64 2 %t0 = load i8, i8* %ptr @@ -204,6 +212,8 @@ define void @variable_gep_index(i8* %unused, i8* %ptr, i64 %variable_index) { define void @multi_index_gep(<4 x i8>* %ptr) { ; CHECK-LABEL: @multi_index_gep(<4 x i8>* %ptr) +; FIXME: %ptr should be dereferenceable(4) +; ATTRIBUTOR-LABEL: @multi_index_gep(<4 x i8>* nocapture nofree nonnull readonly dereferenceable(1) %ptr) %arrayidx00 = getelementptr <4 x i8>, <4 x i8>* %ptr, i64 0, i64 0 %t0 = load i8, i8* %arrayidx00 ret void @@ -213,6 +223,7 @@ define void @multi_index_gep(<4 x i8>* %ptr) { define void @not_byte_multiple(i9* %ptr) { ; CHECK-LABEL: @not_byte_multiple(i9* %ptr) +; ATTRIBUTOR-LABEL: @not_byte_multiple(i9* nocapture nofree nonnull readonly dereferenceable(2) %ptr) %arrayidx0 = getelementptr i9, i9* %ptr, i64 0 %t0 = load i9, i9* %arrayidx0 ret void @@ -222,6 +233,7 @@ define void @not_byte_multiple(i9* %ptr) { define void @no_pointer_deref(i16* %ptr) { ; CHECK-LABEL: @no_pointer_deref(i16* %ptr) +; ATTRIBUTOR-LABEL: @no_pointer_deref(i16* nocapture nofree readonly %ptr) %arrayidx1 = getelementptr i16, i16* %ptr, i64 1 %arrayidx2 = getelementptr i16, i16* %ptr, i64 2 %t1 = load i16, i16* %arrayidx1 @@ -233,6 +245,7 @@ define void @no_pointer_deref(i16* %ptr) { define void @non_consecutive(i32* %ptr) { ; CHECK-LABEL: @non_consecutive(i32* %ptr) +; ATTRIBUTOR-LABEL: @non_consecutive(i32* nocapture nofree nonnull readonly dereferenceable(8) %ptr) %arrayidx1 = getelementptr i32, i32* %ptr, i64 1 %arrayidx0 = getelementptr i32, i32* %ptr, i64 0 %arrayidx3 = getelementptr i32, i32* %ptr, i64 3 @@ -246,6 +259,7 @@ define void @non_consecutive(i32* %ptr) { define void @more_bytes(i32* dereferenceable(8) %ptr) { ; CHECK-LABEL: @more_bytes(i32* dereferenceable(8) %ptr) +; ATTRIBUTOR-LABEL: @more_bytes(i32* nocapture nofree nonnull readonly dereferenceable(16) %ptr) %arrayidx3 = getelementptr i32, i32* %ptr, i64 3 %arrayidx1 = getelementptr i32, i32* %ptr, i64 1 %arrayidx0 = getelementptr i32, i32* %ptr, i64 0 @@ -261,6 +275,7 @@ define void @more_bytes(i32* dereferenceable(8) %ptr) { define void @more_bytes_and_not_null(i32* dereferenceable_or_null(8) %ptr) { ; CHECK-LABEL: @more_bytes_and_not_null(i32* dereferenceable_or_null(8) %ptr) +; ATTRIBUTOR-LABEL: @more_bytes_and_not_null(i32* nocapture nofree nonnull readonly dereferenceable(16) %ptr) %arrayidx3 = getelementptr i32, i32* %ptr, i64 3 %arrayidx1 = getelementptr i32, i32* %ptr, i64 1 %arrayidx0 = getelementptr i32, i32* %ptr, i64 0 @@ -276,6 +291,7 @@ define void @more_bytes_and_not_null(i32* dereferenceable_or_null(8) %ptr) { define void @better_bytes(i32* dereferenceable(100) %ptr) { ; CHECK-LABEL: @better_bytes(i32* dereferenceable(100) %ptr) +; ATTRIBUTOR-LABEL: @better_bytes(i32* nocapture nofree nonnull readonly dereferenceable(100) %ptr) %arrayidx3 = getelementptr i32, i32* %ptr, i64 3 %arrayidx1 = getelementptr i32, i32* %ptr, i64 1 %arrayidx0 = getelementptr i32, i32* %ptr, i64 0 @@ -289,6 +305,7 @@ define void @better_bytes(i32* dereferenceable(100) %ptr) { define void @bitcast(i32* %arg) { ; CHECK-LABEL: @bitcast(i32* %arg) +; ATTRIBUTOR-LABEL: @bitcast(i32* nocapture nofree nonnull readonly dereferenceable(8) %arg) %ptr = bitcast i32* %arg to float* %arrayidx0 = getelementptr float, float* %ptr, i64 0 %arrayidx1 = getelementptr float, float* %ptr, i64 1 @@ -299,6 +316,7 @@ define void @bitcast(i32* %arg) { define void @bitcast_different_sizes(double* %arg1, i8* %arg2) { ; CHECK-LABEL: @bitcast_different_sizes(double* %arg1, i8* %arg2) +; ATTRIBUTOR-LABEL: @bitcast_different_sizes(double* nocapture nofree nonnull readonly dereferenceable(12) %arg1, i8* nocapture nofree nonnull readonly dereferenceable(16) %arg2) %ptr1 = bitcast double* %arg1 to float* %a10 = getelementptr float, float* %ptr1, i64 0 %a11 = getelementptr float, float* %ptr1, i64 1 @@ -317,6 +335,7 @@ define void @bitcast_different_sizes(double* %arg1, i8* %arg2) { define void @negative_offset(i32* %arg) { ; CHECK-LABEL: @negative_offset(i32* %arg) +; ATTRIBUTOR-LABEL: @negative_offset(i32* nocapture nofree nonnull readonly dereferenceable(4) %arg) %ptr = bitcast i32* %arg to float* %arrayidx0 = getelementptr float, float* %ptr, i64 0 %arrayidx1 = getelementptr float, float* %ptr, i64 -1 @@ -327,6 +346,7 @@ define void @negative_offset(i32* %arg) { define void @stores(i32* %arg) { ; CHECK-LABEL: @stores(i32* %arg) +; ATTRIBUTOR-LABEL: @stores(i32* nocapture nofree nonnull writeonly dereferenceable(8) %arg) %ptr = bitcast i32* %arg to float* %arrayidx0 = getelementptr float, float* %ptr, i64 0 %arrayidx1 = getelementptr float, float* %ptr, i64 1 @@ -337,6 +357,7 @@ define void @stores(i32* %arg) { define void @load_store(i32* %arg) { ; CHECK-LABEL: @load_store(i32* %arg) +; ATTRIBUTOR-LABEL: @load_store(i32* nocapture nofree nonnull dereferenceable(8) %arg) %ptr = bitcast i32* %arg to float* %arrayidx0 = getelementptr float, float* %ptr, i64 0 %arrayidx1 = getelementptr float, float* %ptr, i64 1 @@ -344,3 +365,21 @@ define void @load_store(i32* %arg) { store float 2.0, float* %arrayidx1 ret void } + +define void @different_size1(i32* %arg) { +; CHECK-LABEL: @different_size1(i32* %arg) +; ATTRIBUTOR-LABEL: @different_size1(i32* nocapture nofree nonnull writeonly dereferenceable(8) %arg) + %arg-cast = bitcast i32* %arg to double* + store double 0.000000e+00, double* %arg-cast + store i32 0, i32* %arg + ret void +} + +define void @different_size2(i32* %arg) { +; CHECK-LABEL: @different_size2(i32* %arg) +; ATTRIBUTOR-LABEL: @different_size2(i32* nocapture nofree nonnull writeonly dereferenceable(8) %arg) + store i32 0, i32* %arg + %arg-cast = bitcast i32* %arg to double* + store double 0.000000e+00, double* %arg-cast + ret void +} |