summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms/InferFunctionAttrs
diff options
context:
space:
mode:
authorHideto Ueno <uenoku.tokotoko@gmail.com>2019-10-08 15:25:56 +0000
committerHideto Ueno <uenoku.tokotoko@gmail.com>2019-10-08 15:25:56 +0000
commit96e6ce4cd3613527107ed0fc762c510e9d18a860 (patch)
tree0f7a2c1e5bef513a9c4efff26aa20623427f453c /llvm/test/Transforms/InferFunctionAttrs
parentfb92ef1e55d7371c29d695889d0b4d026627637d (diff)
downloadbcm5719-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.ll44
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) {
OpenPOWER on IntegriCloud