[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / LICM / infinite_loops.ll
blob6189bdb1a97444e9d2001f8b181249280a018b27
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -basicaa -licm < %s | FileCheck %s
3 ; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
5 ; Make sure we don't hoist the unsafe division to some executable block.
6 define void @test_impossible_exit_in_untaken_block(i32 %a, i32 %b, i32* %p) {
7 ; CHECK-LABEL: @test_impossible_exit_in_untaken_block(
8 ; CHECK-NEXT:  entry:
9 ; CHECK-NEXT:    br label [[LOOP:%.*]]
10 ; CHECK:       loop:
11 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
12 ; CHECK-NEXT:    br i1 false, label [[NEVER_TAKEN:%.*]], label [[BACKEDGE]]
13 ; CHECK:       never_taken:
14 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[A:%.*]], [[B:%.*]]
15 ; CHECK-NEXT:    store i32 [[DIV]], i32* [[P:%.*]]
16 ; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[EXIT:%.*]]
17 ; CHECK:       backedge:
18 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
19 ; CHECK-NEXT:    br label [[LOOP]]
20 ; CHECK:       exit:
21 ; CHECK-NEXT:    ret void
23 entry:
24   br label %loop
26 loop:
27   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
28   br i1 false, label %never_taken, label %backedge
30 never_taken:
31   %div = sdiv i32 %a, %b
32   store i32 %div, i32* %p
33   br i1 true, label %backedge, label %exit
35 backedge:
36   %iv.next = add i32 %iv, 1
37   br label %loop
39 exit:
40   ret void
43 ; The test above is UB in C++, because there is a requirement that any
44 ; thead should eventually terminate, execute volatile access operation, call IO
45 ; or synchronize. In spite of that, the behavior in the test above *might* be
46 ; correct. This one is equivalent to the test above, but it has a volatile
47 ; memory access in the loop's mustexec block, so the compiler no longer has a
48 ; right to assume that it must terminate. Show that the same problem persists,
49 ; and that it was a bug and not a cool optimization based on loop infinity.
50 ; By the moment when this test was added, it was accidentally correct due to
51 ; reasons not directly related to this piece of logic. Make sure that it keeps
52 ; correct in the future.
53 define void @test_impossible_exit_in_untaken_block_no_ub(i32 %a, i32 %b, i32* noalias %p, i32* noalias %vp) {
54 ; CHECK-LABEL: @test_impossible_exit_in_untaken_block_no_ub(
55 ; CHECK-NEXT:  entry:
56 ; CHECK-NEXT:    br label [[LOOP:%.*]]
57 ; CHECK:       loop:
58 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
59 ; CHECK-NEXT:    [[TMP0:%.*]] = load volatile i32, i32* [[VP:%.*]]
60 ; CHECK-NEXT:    br i1 false, label [[NEVER_TAKEN:%.*]], label [[BACKEDGE]]
61 ; CHECK:       never_taken:
62 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[A:%.*]], [[B:%.*]]
63 ; CHECK-NEXT:    store i32 [[DIV]], i32* [[P:%.*]]
64 ; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[EXIT:%.*]]
65 ; CHECK:       backedge:
66 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
67 ; CHECK-NEXT:    br label [[LOOP]]
68 ; CHECK:       exit:
69 ; CHECK-NEXT:    ret void
71 entry:
72   br label %loop
74 loop:
75   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
76   load volatile i32, i32* %vp
77   br i1 false, label %never_taken, label %backedge
79 never_taken:
80   %div = sdiv i32 %a, %b
81   store i32 %div, i32* %p
82   br i1 true, label %backedge, label %exit
84 backedge:
85   %iv.next = add i32 %iv, 1
86   br label %loop
88 exit:
89   ret void
92 ; Same as above, but the volatile access is in mustexecute backedge block. The
93 ; loop is no longer "finite by specification", make sure we don't hoist sdiv
94 ; from it no matter how general the MustThrow analysis is.
95 define void @test_impossible_exit_in_untaken_block_no_ub_2(i32 %a, i32 %b, i32* noalias %p, i32* noalias %vp) {
96 ; CHECK-LABEL: @test_impossible_exit_in_untaken_block_no_ub_2(
97 ; CHECK-NEXT:  entry:
98 ; CHECK-NEXT:    br label [[LOOP:%.*]]
99 ; CHECK:       loop:
100 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
101 ; CHECK-NEXT:    br i1 false, label [[NEVER_TAKEN:%.*]], label [[BACKEDGE]]
102 ; CHECK:       never_taken:
103 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[A:%.*]], [[B:%.*]]
104 ; CHECK-NEXT:    store i32 [[DIV]], i32* [[P:%.*]]
105 ; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[EXIT:%.*]]
106 ; CHECK:       backedge:
107 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
108 ; CHECK-NEXT:    [[TMP0:%.*]] = load volatile i32, i32* [[VP:%.*]]
109 ; CHECK-NEXT:    br label [[LOOP]]
110 ; CHECK:       exit:
111 ; CHECK-NEXT:    ret void
113 entry:
114   br label %loop
116 loop:
117   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
118   br i1 false, label %never_taken, label %backedge
120 never_taken:
121   %div = sdiv i32 %a, %b
122   store i32 %div, i32* %p
123   br i1 true, label %backedge, label %exit
125 backedge:
126   %iv.next = add i32 %iv, 1
127   load volatile i32, i32* %vp
128   br label %loop
130 exit:
131   ret void