1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -S -indvars | FileCheck %s
3
4declare i32 @llvm.uadd.sat.i32(i32, i32)
5declare i32 @llvm.sadd.sat.i32(i32, i32)
6declare i32 @llvm.usub.sat.i32(i32, i32)
7declare i32 @llvm.ssub.sat.i32(i32, i32)
8
9define void @uadd_sat(i32* %p) {
10; CHECK-LABEL: @uadd_sat(
11; CHECK-NEXT:  entry:
12; CHECK-NEXT:    br label [[LOOP:%.*]]
13; CHECK:       loop:
14; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[LOOP]] ]
15; CHECK-NEXT:    [[SAT1:%.*]] = add nuw nsw i32 [[I]], 1
16; CHECK-NEXT:    store volatile i32 [[SAT1]], i32* [[P:%.*]]
17; CHECK-NEXT:    [[I_INC]] = add nuw nsw i32 [[I]], 1
18; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[I_INC]], 100
19; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[END:%.*]]
20; CHECK:       end:
21; CHECK-NEXT:    ret void
22;
23entry:
24  br label %loop
25
26loop:
27  %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
28  %sat = call i32 @llvm.uadd.sat.i32(i32 %i, i32 1)
29  store volatile i32 %sat, i32* %p
30  %i.inc = add nuw nsw i32 %i, 1
31  %cmp = icmp ne i32 %i.inc, 100
32  br i1 %cmp, label %loop, label %end
33
34end:
35  ret void
36}
37
38define void @sadd_sat(i32* %p) {
39; CHECK-LABEL: @sadd_sat(
40; CHECK-NEXT:  entry:
41; CHECK-NEXT:    br label [[LOOP:%.*]]
42; CHECK:       loop:
43; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[LOOP]] ]
44; CHECK-NEXT:    [[SAT1:%.*]] = add nuw nsw i32 [[I]], 1
45; CHECK-NEXT:    store volatile i32 [[SAT1]], i32* [[P:%.*]]
46; CHECK-NEXT:    [[I_INC]] = add nuw nsw i32 [[I]], 1
47; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[I_INC]], 100
48; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[END:%.*]]
49; CHECK:       end:
50; CHECK-NEXT:    ret void
51;
52entry:
53  br label %loop
54
55loop:
56  %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
57  %sat = call i32 @llvm.sadd.sat.i32(i32 %i, i32 1)
58  store volatile i32 %sat, i32* %p
59  %i.inc = add nuw nsw i32 %i, 1
60  %cmp = icmp ne i32 %i.inc, 100
61  br i1 %cmp, label %loop, label %end
62
63end:
64  ret void
65}
66
67define void @usub_sat(i32* %p) {
68; CHECK-LABEL: @usub_sat(
69; CHECK-NEXT:  entry:
70; CHECK-NEXT:    br label [[LOOP:%.*]]
71; CHECK:       loop:
72; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[LOOP]] ]
73; CHECK-NEXT:    [[SAT1:%.*]] = sub nuw nsw i32 [[I]], 1
74; CHECK-NEXT:    store volatile i32 [[SAT1]], i32* [[P:%.*]]
75; CHECK-NEXT:    [[I_INC]] = add nuw nsw i32 [[I]], 1
76; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[I_INC]], 100
77; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[END:%.*]]
78; CHECK:       end:
79; CHECK-NEXT:    ret void
80;
81entry:
82  br label %loop
83
84loop:
85  %i = phi i32 [ 1, %entry ], [ %i.inc, %loop ]
86  %sat = call i32 @llvm.usub.sat.i32(i32 %i, i32 1)
87  store volatile i32 %sat, i32* %p
88  %i.inc = add nuw nsw i32 %i, 1
89  %cmp = icmp ne i32 %i.inc, 100
90  br i1 %cmp, label %loop, label %end
91
92end:
93  ret void
94}
95
96define void @ssub_sat(i32* %p) {
97; CHECK-LABEL: @ssub_sat(
98; CHECK-NEXT:  entry:
99; CHECK-NEXT:    br label [[LOOP:%.*]]
100; CHECK:       loop:
101; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[LOOP]] ]
102; CHECK-NEXT:    [[SAT1:%.*]] = sub nsw i32 [[I]], 1
103; CHECK-NEXT:    store volatile i32 [[SAT1]], i32* [[P:%.*]]
104; CHECK-NEXT:    [[I_INC]] = add nuw nsw i32 [[I]], 1
105; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[I_INC]], 100
106; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[END:%.*]]
107; CHECK:       end:
108; CHECK-NEXT:    ret void
109;
110entry:
111  br label %loop
112
113loop:
114  %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
115  %sat = call i32 @llvm.ssub.sat.i32(i32 %i, i32 1)
116  store volatile i32 %sat, i32* %p
117  %i.inc = add nuw nsw i32 %i, 1
118  %cmp = icmp ne i32 %i.inc, 100
119  br i1 %cmp, label %loop, label %end
120
121end:
122  ret void
123}
124