summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms/JumpThreading/guards.ll
diff options
context:
space:
mode:
authorAnna Thomas <anna@azul.com>2017-05-18 13:12:18 +0000
committerAnna Thomas <anna@azul.com>2017-05-18 13:12:18 +0000
commit7bca59152adcc521f97a4e13128b214198e6d6df (patch)
tree090d5f026cf716e3f7da03c9bb2a1273f772252f /llvm/test/Transforms/JumpThreading/guards.ll
parenta24a3a30d00a43a5aa7e6cdf7b7046438735347c (diff)
downloadbcm5719-llvm-7bca59152adcc521f97a4e13128b214198e6d6df.tar.gz
bcm5719-llvm-7bca59152adcc521f97a4e13128b214198e6d6df.zip
[JumpThreading] Dont RAUW condition incorrectly
Summary: We have a bug when RAUWing the condition if experimental.guard or assumes is a use of that condition. This is because LazyValueInfo may have used the guards/assumes to identify the value of the condition at the end of the block. RAUW replaces the uses at the guard/assume as well as uses before the guard/assume. Both of these are incorrect. For now, disable RAUW for conditions and fix the logic as a next step: https://reviews.llvm.org/D33257 Reviewers: sanjoy, reames, trentxintong Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D33279 llvm-svn: 303349
Diffstat (limited to 'llvm/test/Transforms/JumpThreading/guards.ll')
-rw-r--r--llvm/test/Transforms/JumpThreading/guards.ll94
1 files changed, 94 insertions, 0 deletions
diff --git a/llvm/test/Transforms/JumpThreading/guards.ll b/llvm/test/Transforms/JumpThreading/guards.ll
index eac2b5dcd85..c5f72b113ef 100644
--- a/llvm/test/Transforms/JumpThreading/guards.ll
+++ b/llvm/test/Transforms/JumpThreading/guards.ll
@@ -181,3 +181,97 @@ Exit:
; CHECK-NEXT: ret void
ret void
}
+
+declare void @never_called()
+
+; Assume the guard is always taken and we deoptimize, so we never reach the
+; branch below that guard. We should *never* change the behaviour of a guard from
+; `must deoptimize` to `may deoptimize`, since this affects the program
+; semantics.
+define void @dont_fold_guard(i8* %addr, i32 %i, i32 %length) {
+; CHECK-LABEL: dont_fold_guard
+; CHECK: experimental.guard(i1 %wide.chk)
+
+entry:
+ br label %BBPred
+
+BBPred:
+ %cond = icmp eq i8* %addr, null
+ br i1 %cond, label %zero, label %not_zero
+
+zero:
+ unreachable
+
+not_zero:
+ %c1 = icmp ult i32 %i, %length
+ %c2 = icmp eq i32 %i, 0
+ %wide.chk = and i1 %c1, %c2
+ call void(i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ]
+ br i1 %c2, label %unreachedBB2, label %unreachedBB1
+
+unreachedBB2:
+ call void @never_called()
+ ret void
+
+unreachedBB1:
+ ret void
+}
+
+
+; same as dont_fold_guard1 but condition %cmp is not an instruction.
+; We cannot fold the guard under any circumstance.
+; FIXME: We can merge unreachableBB2 into not_zero.
+define void @dont_fold_guard2(i8* %addr, i1 %cmp, i32 %i, i32 %length) {
+; CHECK-LABEL: dont_fold_guard2
+; CHECK: guard(i1 %cmp)
+
+entry:
+ br label %BBPred
+
+BBPred:
+ %cond = icmp eq i8* %addr, null
+ br i1 %cond, label %zero, label %not_zero
+
+zero:
+ unreachable
+
+not_zero:
+ call void(i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
+ br i1 %cmp, label %unreachedBB2, label %unreachedBB1
+
+unreachedBB2:
+ call void @never_called()
+ ret void
+
+unreachedBB1:
+ ret void
+}
+
+; Same as dont_fold_guard1 but use switch instead of branch.
+; triggers source code `ProcessThreadableEdges`.
+declare void @f(i1)
+define void @dont_fold_guard3(i1 %cmp1, i32 %i) nounwind {
+; CHECK-LABEL: dont_fold_guard3
+; CHECK-LABEL: L2:
+; CHECK-NEXT: %cmp = icmp eq i32 %i, 0
+; CHECK-NEXT: guard(i1 %cmp)
+; CHECK-NEXT: @f(i1 %cmp)
+; CHECK-NEXT: ret void
+entry:
+ br i1 %cmp1, label %L0, label %L3
+L0:
+ %cmp = icmp eq i32 %i, 0
+ call void(i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
+ switch i1 %cmp, label %L3 [
+ i1 false, label %L1
+ i1 true, label %L2
+ ]
+
+L1:
+ ret void
+L2:
+ call void @f(i1 %cmp)
+ ret void
+L3:
+ ret void
+}
OpenPOWER on IntegriCloud