Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / guards.ll
blob8ffbae934d6b3f5673c1f2c425202d0ffdc68bd8
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s
4 declare void @llvm.experimental.guard(i1, ...)
6 define i32 @f_0(i1 %c) {
7 ; CHECK-LABEL: @f_0(
8 ; CHECK-NEXT:  entry:
9 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
10 ; CHECK-NEXT:    unreachable
12 entry:
13   call void(i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
14   ret i32 10
17 define i32 @f_1(i1 %c) {
18 ; Demonstrate that we (intentionally) do not simplify a guard on undef
19 ; CHECK-LABEL: @f_1(
20 ; CHECK-NEXT:  entry:
21 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[TRUE:%.*]], label [[COMMON_RET:%.*]]
22 ; CHECK:       common.ret:
23 ; CHECK-NEXT:    [[COMMON_RET_OP:%.*]] = phi i32 [ 10, [[TRUE]] ], [ 20, [[ENTRY:%.*]] ]
24 ; CHECK-NEXT:    ret i32 [[COMMON_RET_OP]]
25 ; CHECK:       true:
26 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 undef) [ "deopt"() ]
27 ; CHECK-NEXT:    br label [[COMMON_RET]]
30 entry:
31   br i1 %c, label %true, label %false
33 true:
34   call void(i1, ...) @llvm.experimental.guard(i1 undef) [ "deopt"() ]
35   ret i32 10
37 false:
38   ret i32 20
41 define i32 @f_2(i1 %c, ptr %buf) {
42 ; CHECK-LABEL: @f_2(
43 ; CHECK-NEXT:  entry:
44 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[GUARD_BLOCK:%.*]], label [[MERGE_BLOCK:%.*]]
45 ; CHECK:       guard_block:
46 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
47 ; CHECK-NEXT:    unreachable
48 ; CHECK:       merge_block:
49 ; CHECK-NEXT:    ret i32 50
51 entry:
52   br i1 %c, label %guard_block, label %merge_block
54 guard_block:
55   call void(i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
56   %val = load i32, ptr %buf
57   br label %merge_block
59 merge_block:
60   %to.return = phi i32 [ %val, %guard_block ], [ 50, %entry ]
61   ret i32 %to.return
65 define i32 @f_3(ptr %c, ptr %buf) {
66 ; CHECK-LABEL: @f_3(
67 ; CHECK-NEXT:  entry:
68 ; CHECK-NEXT:    [[C0:%.*]] = load volatile i1, ptr [[C:%.*]], align 1
69 ; CHECK-NEXT:    br i1 [[C0]], label [[GUARD_BLOCK:%.*]], label [[MERGE_BLOCK:%.*]]
70 ; CHECK:       guard_block:
71 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
72 ; CHECK-NEXT:    unreachable
73 ; CHECK:       merge_block:
74 ; CHECK-NEXT:    [[C1:%.*]] = load volatile i1, ptr [[C]], align 1
75 ; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[C1]], i32 50, i32 100
76 ; CHECK-NEXT:    ret i32 [[DOT]]
78 entry:
79   %c0 = load volatile i1, ptr %c
80   br i1 %c0, label %guard_block, label %merge_block
82 guard_block:
83   call void(i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
84   %val = load i32, ptr %buf
85   %c2 = load volatile i1, ptr %c
86   br i1 %c2, label %left, label %right
88 merge_block:
89   %c1 = load volatile i1, ptr %c
90   br i1 %c1, label %left, label %right
92 left:
93   %val.left = phi i32 [ %val, %guard_block ], [ 50, %merge_block ]
94   ret i32 %val.left
96 right:
97   %val.right = phi i32 [ %val, %guard_block ], [ 100, %merge_block ]
98   ret i32 %val.right