mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
241 lines
4.8 KiB
LLVM
241 lines
4.8 KiB
LLVM
;
|
|
; This file is distributed under the MIT License. See LICENSE.md for details.
|
|
;
|
|
|
|
; RUN: %revngopt %s -select-scope -S -o - | FileCheck %s
|
|
|
|
; function tags metadata needed for all the tests
|
|
declare !revng.tags !0 void @scope_closer(ptr)
|
|
declare !revng.tags !1 void @goto_block()
|
|
!0 = !{!"marker", !"scope-closer"}
|
|
!1 = !{!"marker", !"goto-block"}
|
|
|
|
; decided diamond test
|
|
|
|
define void @f(i1 noundef %a) {
|
|
block_a:
|
|
br i1 %a, label %block_b, label %block_c
|
|
|
|
block_b:
|
|
br label %block_d
|
|
|
|
block_d:
|
|
br label %block_f
|
|
|
|
block_c:
|
|
br label %block_e
|
|
|
|
block_e:
|
|
br label %block_f
|
|
|
|
block_f:
|
|
ret void
|
|
}
|
|
|
|
; CHECK-LABEL: define void @f(i1 noundef %a)
|
|
; CHECK: block_a:
|
|
; CHECK-NEXT: br i1 %a, label %block_b, label %block_c
|
|
; CHECK: block_b:
|
|
; CHECK-NEXT: br label %block_d
|
|
; CHECK: block_d:
|
|
; CHECK-NEXT: br label %block_f
|
|
; CHECK: block_c:
|
|
; CHECK-NEXT: br label %block_e
|
|
; CHECK: block_e:
|
|
; CHECK-NEXT: br label %block_f
|
|
; CHECK: block_f:
|
|
; CHECK-NEXT: ret void
|
|
|
|
; crossed diamonds test
|
|
|
|
define void @g(i1 noundef %a, i1 noundef %b, i1 noundef %c) {
|
|
block_a:
|
|
br i1 %a, label %block_b, label %block_c
|
|
|
|
block_b:
|
|
br i1 %b, label %block_d, label %block_e
|
|
|
|
block_d:
|
|
br label %block_f
|
|
|
|
block_c:
|
|
br i1 %c, label %block_e, label %block_d
|
|
|
|
block_e:
|
|
br label %block_f
|
|
|
|
block_f:
|
|
ret void
|
|
}
|
|
|
|
; CHECK-LABEL: define void @g(i1 noundef %a, i1 noundef %b, i1 noundef %c)
|
|
; CHECK: block_a:
|
|
; CHECK-NEXT: br i1 %a, label %block_b, label %block_c
|
|
; CHECK: block_b:
|
|
; CHECK-NEXT: br i1 %b, label %block_d, label %block_e
|
|
; CHECK: block_d:
|
|
; CHECK-NEXT: br label %block_f
|
|
; CHECK: block_c:
|
|
; CHECK-NEXT: br i1 %c, label %goto_block_e, label %goto_block_d
|
|
; CHECK: block_e:
|
|
; CHECK-NEXT: br label %block_f
|
|
; CHECK: block_f:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: goto_block_e:
|
|
; CHECK-NEXT: call void @goto_block()
|
|
; CHECK-NEXT: br label %block_e
|
|
; CHECK: goto_block_d:
|
|
; CHECK-NEXT: call void @goto_block()
|
|
; CHECK-NEXT: br label %block_d
|
|
|
|
; double edge if test
|
|
|
|
define void @h(i1 noundef %a) {
|
|
block_a:
|
|
br i1 %a, label %block_b, label %block_b
|
|
|
|
block_b:
|
|
br label %block_c
|
|
|
|
block_c:
|
|
ret void
|
|
}
|
|
|
|
; CHECK-LABEL: define void @h(i1 noundef %a)
|
|
; CHECK: block_a:
|
|
; CHECK-NEXT: br i1 %a, label %block_b, label %block_b
|
|
; CHECK: block_b:
|
|
; CHECK-NEXT: br label %block_c
|
|
; CHECK: block_c:
|
|
; CHECK-NEXT: ret void
|
|
|
|
; double edge switch test
|
|
|
|
define void @i(i1 noundef %a) {
|
|
block_a:
|
|
switch i1 %a, label %block_b [
|
|
i1 0, label %block_c
|
|
i1 1, label %block_c
|
|
]
|
|
|
|
block_b:
|
|
br label %block_d
|
|
|
|
block_c:
|
|
br label %block_d
|
|
|
|
block_d:
|
|
ret void
|
|
}
|
|
|
|
; CHECK-LABEL: define void @i(i1 noundef %a)
|
|
; CHECK: block_a:
|
|
; CHECK-NEXT: switch i1 %a, label %block_b [
|
|
; CHECK-NEXT: i1 false, label %block_c
|
|
; CHECK-NEXT: i1 true, label %block_c
|
|
; CHECK-NEXT: ]
|
|
; CHECK: block_b:
|
|
; CHECK-NEXT: br label %block_d
|
|
; CHECK: block_c:
|
|
; CHECK-NEXT: br label %block_d
|
|
; CHECK: block_d:
|
|
; CHECK-NEXT: ret void
|
|
|
|
; short-circuit test
|
|
|
|
define void @l(i1 noundef %a, i1 noundef %b) {
|
|
block_a:
|
|
br i1 %a, label %block_b, label %block_c
|
|
|
|
block_b:
|
|
br i1 %b, label %block_d, label %block_e
|
|
|
|
block_d:
|
|
br label %block_f
|
|
|
|
block_c:
|
|
br label %block_e
|
|
|
|
block_e:
|
|
br label %block_f
|
|
|
|
block_f:
|
|
ret void
|
|
}
|
|
|
|
; CHECK-LABEL: define void @l(i1 noundef %a, i1 noundef %b)
|
|
; CHECK: block_a:
|
|
; CHECK-NEXT: br i1 %a, label %block_b, label %block_c
|
|
; CHECK: block_b:
|
|
; CHECK-NEXT: br i1 %b, label %block_d, label %block_e
|
|
; CHECK: block_d:
|
|
; CHECK-NEXT: br label %block_f
|
|
; CHECK: block_c:
|
|
; CHECK-NEXT: br label %goto_block_e
|
|
; CHECK: block_e:
|
|
; CHECK-NEXT: br label %block_f
|
|
; CHECK: block_f:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: goto_block_e:
|
|
; CHECK-NEXT: call void @goto_block()
|
|
; CHECK-NEXT: br label %block_e
|
|
|
|
; short-circuit with decided tail
|
|
|
|
define void @m(i1 noundef %a, i1 noundef %b, i1 noundef %c) {
|
|
block_a:
|
|
br i1 %a, label %block_b, label %block_c
|
|
|
|
block_b:
|
|
br i1 %b, label %block_d, label %block_e
|
|
|
|
block_d:
|
|
br label %block_f
|
|
|
|
block_c:
|
|
br label %block_e
|
|
|
|
block_e:
|
|
br label %block_f
|
|
|
|
block_f:
|
|
br label %block_g
|
|
|
|
block_g:
|
|
br i1 %c, label %block_h, label %block_i
|
|
|
|
block_h:
|
|
br label %block_l
|
|
|
|
block_i:
|
|
br label %block_l
|
|
|
|
block_l:
|
|
ret void
|
|
}
|
|
|
|
; CHECK: define void @m(i1 noundef %a, i1 noundef %b, i1 noundef %c)
|
|
; CHECK: block_a:
|
|
; CHECK-NEXT: br i1 %a, label %block_b, label %block_c
|
|
; CHECK: block_b:
|
|
; CHECK-NEXT: br i1 %b, label %block_d, label %block_e
|
|
; CHECK: block_d:
|
|
; CHECK-NEXT: br label %block_f
|
|
; CHECK: block_c:
|
|
; CHECK-NEXT: br label %goto_block_e
|
|
; CHECK: block_e:
|
|
; CHECK-NEXT: br label %block_f
|
|
; CHECK: block_f:
|
|
; CHECK-NEXT: br label %block_g
|
|
; CHECK: block_g:
|
|
; CHECK-NEXT: br i1 %c, label %block_h, label %block_i
|
|
; CHECK: block_h:
|
|
; CHECK-NEXT: br label %block_l
|
|
; CHECK: block_i:
|
|
; CHECK-NEXT: br label %block_l
|
|
; CHECK: block_l:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: goto_block_e:
|
|
; CHECK-NEXT: call void @goto_block()
|
|
; CHECK-NEXT: br label %block_e
|