diff options
author | Hideto Ueno <uenoku.tokotoko@gmail.com> | 2019-10-08 15:25:56 +0000 |
---|---|---|
committer | Hideto Ueno <uenoku.tokotoko@gmail.com> | 2019-10-08 15:25:56 +0000 |
commit | 96e6ce4cd3613527107ed0fc762c510e9d18a860 (patch) | |
tree | 0f7a2c1e5bef513a9c4efff26aa20623427f453c /llvm/test/Transforms/InferFunctionAttrs | |
parent | fb92ef1e55d7371c29d695889d0b4d026627637d (diff) | |
download | bcm5719-llvm-96e6ce4cd3613527107ed0fc762c510e9d18a860.tar.gz bcm5719-llvm-96e6ce4cd3613527107ed0fc762c510e9d18a860.zip |
[Attributor][MustExec] Deduce dereferenceable and nonnull attribute using MustBeExecutedContextExplorer
Summary:
In D65186 and related patches, MustBeExecutedContextExplorer is introduced. This enables us to traverse instructions guaranteed to execute from function entry. If we can know the argument is used as `dereferenceable` or `nonnull` in these instructions, we can mark `dereferenceable` or `nonnull` in the argument definition:
1. Memory instruction (similar to D64258)
Trace memory instruction pointer operand. Currently, only inbounds GEPs are traced.
```
define i64* @f(i64* %a) {
entry:
%add.ptr = getelementptr inbounds i64, i64* %a, i64 1
; (because of inbounds GEP we can know that %a is at least dereferenceable(16))
store i64 1, i64* %add.ptr, align 8
ret i64* %add.ptr ; dereferenceable 8 (because above instruction stores into it)
}
```
2. Propagation from callsite (similar to D27855)
If `deref` or `nonnull` are known in call site parameter attributes we can also say that argument also that attribute.
```
declare void @use3(i8* %x, i8* %y, i8* %z);
declare void @use3nonnull(i8* nonnull %x, i8* nonnull %y, i8* nonnull %z);
define void @parent1(i8* %a, i8* %b, i8* %c) {
call void @use3nonnull(i8* %b, i8* %c, i8* %a)
; Above instruction is always executed so we can say that@parent1(i8* nonnnull %a, i8* nonnull %b, i8* nonnull %c)
call void @use3(i8* %c, i8* %a, i8* %b)
ret void
}
```
Reviewers: jdoerfert, sstefan1, spatel, reames
Reviewed By: jdoerfert
Subscribers: xbolva00, hiraditya, jfb, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D65402
llvm-svn: 374063
Diffstat (limited to 'llvm/test/Transforms/InferFunctionAttrs')
-rw-r--r-- | llvm/test/Transforms/InferFunctionAttrs/dereferenceable.ll | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/llvm/test/Transforms/InferFunctionAttrs/dereferenceable.ll b/llvm/test/Transforms/InferFunctionAttrs/dereferenceable.ll index f6580826bd1..17c76f11d6c 100644 --- a/llvm/test/Transforms/InferFunctionAttrs/dereferenceable.ll +++ b/llvm/test/Transforms/InferFunctionAttrs/dereferenceable.ll @@ -1,10 +1,17 @@ ; RUN: opt < %s -inferattrs -S | FileCheck %s +; RUN: opt < %s -attributor --attributor-disable=false -S | FileCheck %s --check-prefix=ATTRIBUTOR + + ; Determine dereference-ability before unused loads get deleted: ; https://bugs.llvm.org/show_bug.cgi?id=21780 define <4 x double> @PR21780(double* %ptr) { ; CHECK-LABEL: @PR21780(double* %ptr) +; FIXME: this should be @PR21780(double* nonnull dereferenceable(32) %ptr) +; trakcing use of GEP in Attributor would fix this problem. +; ATTRIBUTOR-LABEL: @PR21780(double* nocapture nonnull readonly dereferenceable(8) %ptr) + ; GEP of index 0 is simplified away. %arrayidx1 = getelementptr inbounds double, double* %ptr, i64 1 %arrayidx2 = getelementptr inbounds double, double* %ptr, i64 2 @@ -23,6 +30,43 @@ define <4 x double> @PR21780(double* %ptr) { ret <4 x double> %shuffle } + +define double @PR21780_only_access3_with_inbounds(double* %ptr) { +; CHECK-LABEL: @PR21780_only_access3_with_inbounds(double* %ptr) +; FIXME: this should be @PR21780_only_access3_with_inbounds(double* nonnull dereferenceable(32) %ptr) +; trakcing use of GEP in Attributor would fix this problem. +; ATTRIBUTOR-LABEL: @PR21780_only_access3_with_inbounds(double* nocapture readonly %ptr) + + %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 3 + %t3 = load double, double* %arrayidx3, align 8 + ret double %t3 +} + +define double @PR21780_only_access3_without_inbounds(double* %ptr) { +; CHECK-LABEL: @PR21780_only_access3_without_inbounds(double* %ptr) +; ATTRIBUTOR-LABEL: @PR21780_only_access3_without_inbounds(double* nocapture readonly %ptr) + %arrayidx3 = getelementptr double, double* %ptr, i64 3 + %t3 = load double, double* %arrayidx3, align 8 + ret double %t3 +} + +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 nonnull readonly dereferenceable(8) %ptr) + + %arrayidx1 = getelementptr double, double* %ptr, i64 1 + %arrayidx2 = getelementptr double, double* %ptr, i64 2 + %arrayidx3 = getelementptr double, double* %ptr, i64 3 + + %t0 = load double, double* %ptr, align 8 + %t1 = load double, double* %arrayidx1, align 8 + %t2 = load double, double* %arrayidx2, align 8 + %t3 = load double, double* %arrayidx3, align 8 + + ret double %t3 +} + ; Unsimplified, but still valid. Also, throw in some bogus arguments. define void @gep0(i8* %unused, i8* %other, i8* %ptr) { |