[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / LoopUnswitch / guards.ll
blobe4aa9679b65cad5516acd0cd1097c14b49f2dbda
1 ; RUN: opt -S -loop-unswitch -enable-new-pm=0 -verify-memoryssa < %s | FileCheck %s
3 declare void @llvm.experimental.guard(i1, ...)
5 define void @f_0(i32 %n, i32* %ptr, i1 %c) {
6 ; CHECK-LABEL: @f_0(
7 ; CHECK: loop.us:
8 ; CHECK-NOT: guard
9 ; CHECK: loop:
10 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
11 entry:
12   br label %loop
14 loop:
15   %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
16   %iv.inc = add i32 %iv, 1
17   call void(i1, ...) @llvm.experimental.guard(i1 %c) [ "deopt"() ]
18   store volatile i32 0, i32* %ptr
19   %becond = icmp ult i32 %iv.inc, %n
20   br i1 %becond, label %leave, label %loop
22 leave:
23   ret void
26 define void @f_1(i32 %n, i32* %ptr, i1 %c_0, i1 %c_1) {
27 ; CHECK-LABEL: @f_1(
28 ; CHECK: loop.us.us:
29 ; CHECK-NOT: guard
30 ; CHECK: loop.us:
31 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"(i32 2) ]
32 ; CHECK-NOT: guard
33 ; CHECK: loop.us1:
34 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"(i32 1) ]
35 ; CHECK-NOT: guard
36 ; CHECK: loop:
37 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"(i32 1) ]
38 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"(i32 2) ]
39 entry:
40   br label %loop
42 loop:
43   %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
44   %iv.inc = add i32 %iv, 1
45   call void(i1, ...) @llvm.experimental.guard(i1 %c_0) [ "deopt"(i32 1) ]
46   store volatile i32 0, i32* %ptr
47   call void(i1, ...) @llvm.experimental.guard(i1 %c_1) [ "deopt"(i32 2) ]
48   %becond = icmp ult i32 %iv.inc, %n
49   br i1 %becond, label %leave, label %loop
51 leave:
52   ret void
55 ; Basic negative test
57 define void @f_3(i32 %n, i32* %ptr, i1* %c_ptr) {
58 ; CHECK-LABEL: @f_3(
59 ; CHECK-NOT: loop.us:
60 entry:
61   br label %loop
63 loop:
64   %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
65   %iv.inc = add i32 %iv, 1
66   %c = load volatile i1, i1* %c_ptr
67   call void(i1, ...) @llvm.experimental.guard(i1 %c) [ "deopt"() ]
68   store volatile i32 0, i32* %ptr
69   %becond = icmp ult i32 %iv.inc, %n
70   br i1 %becond, label %leave, label %loop
72 leave:
73   ret void
76 define void @f_4(i32 %n, i32* %ptr, i1 %c) {
77 ; CHECK-LABEL: @f_4(
79 ; Demonstrate that unswitching on one guard can cause another guard to
80 ; be erased (this has implications on what guards we can keep raw
81 ; pointers to).
82 entry:
83   br label %loop
85 loop:
86   %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
87   %iv.inc = add i32 %iv, 1
88   call void(i1, ...) @llvm.experimental.guard(i1 %c) [ "deopt"(i32 1) ]
89   store volatile i32 0, i32* %ptr
90   %neg = xor i1 %c, 1
91   call void(i1, ...) @llvm.experimental.guard(i1 %neg) [ "deopt"(i32 2) ]
92   %becond = icmp ult i32 %iv.inc, %n
93   br i1 %becond, label %leave, label %loop
95 leave:
96   ret void