1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00
llvm-mirror/test/Transforms/NewGVN/pr31594.ll
Daniel Berlin b15f304291 NewGVN: Fix PR31594, by tracking the store count of congruence
classes, and updating checking to allow for equivalence through
reachability.

(Sadly, the checking here is not perfect, and can't be made perfect,
so we'll have to disable it after we are satisfied with correctness.
Right now it is just "very unlikely" to happen.)

llvm-svn: 291698
2017-01-11 20:22:36 +00:00

120 lines
3.6 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -basicaa -newgvn -S | FileCheck %s
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
define void @patatino(i8* %blah, i32 %choice) {
; CHECK-LABEL: @patatino(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[WHILE_COND:%.*]]
; CHECK: while.cond:
; CHECK-NEXT: [[FOO:%.*]] = phi i8* [ [[BLAH:%.*]], [[ENTRY:%.*]] ], [ null, [[WHILE_BODY:%.*]] ]
; CHECK-NEXT: switch i32 [[CHOICE:%.*]], label [[WHILE_BODY]] [
; CHECK-NEXT: i32 -1, label [[WHILE_END:%.*]]
; CHECK-NEXT: i32 40, label [[LAND_END:%.*]]
; CHECK-NEXT: ]
; CHECK: land.end:
; CHECK-NEXT: br label [[WHILE_END]]
; CHECK: while.body:
; CHECK-NEXT: br label [[WHILE_COND]]
; CHECK: while.end:
; CHECK-NEXT: store i8 0, i8* [[FOO]], align 1
; CHECK-NEXT: store i8 0, i8* [[BLAH]], align 1
; CHECK-NEXT: ret void
;
entry:
br label %while.cond
while.cond:
%foo = phi i8* [ %blah, %entry ], [ null, %while.body ]
switch i32 %choice, label %while.body [
i32 -1, label %while.end
i32 40, label %land.end
]
land.end:
br label %while.end
while.body:
br label %while.cond
while.end:
%foo.lcssa = phi i8* [ %foo, %land.end ], [ %foo, %while.cond ]
;; These two stores will initially be considered equivalent, but then proven not.
;; the second store would previously end up deciding it's equivalent to a previous
;; store, but it was really just finding an optimistic version of itself
;; in the congruence class.
store i8 0, i8* %foo.lcssa, align 1
%0 = load i8, i8* %blah, align 1
%loaded = icmp eq i8 %0, 0
store i8 0, i8* %blah, align 1
ret void
}
;; This is an example of a case where the memory states are equivalent solely due to unreachability,
;; but the stores are not equal.
define void @foo(i8* %arg) {
; CHECK-LABEL: @foo(
; CHECK-NEXT: bb:
; CHECK-NEXT: br label [[BB1:%.*]]
; CHECK: bb1:
; CHECK-NEXT: [[TMP:%.*]] = phi i8* [ [[ARG:%.*]], [[BB:%.*]] ], [ null, [[BB2:%.*]] ]
; CHECK-NEXT: br i1 undef, label [[BB3:%.*]], label [[BB2]]
; CHECK: bb2:
; CHECK-NEXT: br label [[BB1]]
; CHECK: bb3:
; CHECK-NEXT: store i8 0, i8* [[TMP]], !g !0
; CHECK-NEXT: br label [[BB4:%.*]]
; CHECK: bb4:
; CHECK-NEXT: br label [[BB6:%.*]]
; CHECK: bb6:
; CHECK-NEXT: br i1 undef, label [[BB9:%.*]], label [[BB7:%.*]]
; CHECK: bb7:
; CHECK-NEXT: switch i8 0, label [[BB6]] [
; CHECK-NEXT: i8 6, label [[BB8:%.*]]
; CHECK-NEXT: ]
; CHECK: bb8:
; CHECK-NEXT: br label [[BB4]]
; CHECK: bb9:
; CHECK-NEXT: store i8 0, i8* [[ARG]], !g !0
; CHECK-NEXT: unreachable
;
bb:
br label %bb1
bb1: ; preds = %bb2, %bb
%tmp = phi i8* [ %arg, %bb ], [ null, %bb2 ]
br i1 undef, label %bb3, label %bb2
bb2: ; preds = %bb1
br label %bb1
bb3: ; preds = %bb1
store i8 0, i8* %tmp, !g !0
br label %bb4
bb4: ; preds = %bb8, %bb3
%tmp5 = phi i8* [ null, %bb8 ], [ %arg, %bb3 ]
br label %bb6
bb6: ; preds = %bb7, %bb4
br i1 undef, label %bb9, label %bb7
bb7: ; preds = %bb6
switch i8 0, label %bb6 [
i8 6, label %bb8
]
bb8: ; preds = %bb7
store i8 undef, i8* %tmp5, !g !0
br label %bb4
bb9: ; preds = %bb6
%tmp10 = phi i8* [ %tmp5, %bb6 ]
store i8 0, i8* %tmp10, !g !0
unreachable
}
!0 = !{}