xref: /llvm-project/llvm/test/Analysis/ValueTracking/knownbits-sat-addsub.ll (revision 877cb9a2edc9057d70321e436e5ea8ccc1a87140)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=instsimplify -S < %s | FileCheck %s
3
4declare i8 @llvm.sadd.sat.i8(i8, i8)
5declare i8 @llvm.ssub.sat.i8(i8, i8)
6declare i8 @llvm.uadd.sat.i8(i8, i8)
7declare i8 @llvm.usub.sat.i8(i8, i8)
8
9define i1 @uadd_sat_overflow(i8 %x, i8 %y) {
10; CHECK-LABEL: @uadd_sat_overflow(
11; CHECK-NEXT:    ret i1 false
12;
13  %lhs = or i8 %x, 128
14  %rhs = or i8 %y, 128
15  %exp = call i8 @llvm.uadd.sat.i8(i8 %lhs, i8 %rhs)
16  %r = icmp eq i8 %exp, 254
17  ret i1 %r
18}
19
20define i1 @uadd_sat_overflow_fail(i8 %x, i8 %y) {
21; CHECK-LABEL: @uadd_sat_overflow_fail(
22; CHECK-NEXT:    [[LHS:%.*]] = or i8 [[X:%.*]], -128
23; CHECK-NEXT:    [[RHS:%.*]] = or i8 [[Y:%.*]], 126
24; CHECK-NEXT:    [[EXP:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[LHS]], i8 [[RHS]])
25; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[EXP]], -2
26; CHECK-NEXT:    ret i1 [[R]]
27;
28  %lhs = or i8 %x, 128
29  %rhs = or i8 %y, 126
30  %exp = call i8 @llvm.uadd.sat.i8(i8 %lhs, i8 %rhs)
31  %r = icmp eq i8 %exp, 254
32  ret i1 %r
33}
34
35define i1 @usub_sat_overflow(i8 %x, i8 %y) {
36; CHECK-LABEL: @usub_sat_overflow(
37; CHECK-NEXT:    ret i1 false
38;
39  %lhs = and i8 %x, 127
40  %rhs = or i8 %y, 128
41  %exp = call i8 @llvm.usub.sat.i8(i8 %lhs, i8 %rhs)
42  %r = icmp eq i8 %exp, 1
43  ret i1 %r
44}
45
46define i1 @usub_sat_overflow_fail(i8 %x, i8 %y) {
47; CHECK-LABEL: @usub_sat_overflow_fail(
48; CHECK-NEXT:    [[LHS:%.*]] = and i8 [[X:%.*]], 127
49; CHECK-NEXT:    [[RHS:%.*]] = or i8 [[Y:%.*]], 126
50; CHECK-NEXT:    [[EXP:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[LHS]], i8 [[RHS]])
51; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[EXP]], 1
52; CHECK-NEXT:    ret i1 [[R]]
53;
54  %lhs = and i8 %x, 127
55  %rhs = or i8 %y, 126
56  %exp = call i8 @llvm.usub.sat.i8(i8 %lhs, i8 %rhs)
57  %r = icmp eq i8 %exp, 1
58  ret i1 %r
59}
60
61define i1 @sadd_sat_overflow_pos(i8 %x, i8 %y) {
62; CHECK-LABEL: @sadd_sat_overflow_pos(
63; CHECK-NEXT:    ret i1 false
64;
65  %xx = and i8 %x, 127
66  %yy = and i8 %y, 127
67  %lhs = or i8 %xx, 64
68  %rhs = or i8 %yy, 65
69  %exp = call i8 @llvm.sadd.sat.i8(i8 %lhs, i8 %rhs)
70  %r = icmp eq i8 %exp, 128
71  ret i1 %r
72}
73
74define i1 @sadd_sat_low_bits(i8 %x, i8 %y) {
75; CHECK-LABEL: @sadd_sat_low_bits(
76; CHECK-NEXT:    ret i1 false
77;
78  %xx = and i8 %x, 15
79  %yy = and i8 %y, 15
80  %lhs = or i8 %xx, 1
81  %rhs = and i8 %yy, -2
82  %exp = call i8 @llvm.sadd.sat.i8(i8 %lhs, i8 %rhs)
83  %and = and i8 %exp, 1
84  %r = icmp eq i8 %and, 0
85  ret i1 %r
86}
87
88define i1 @sadd_sat_fail_may_overflow(i8 %x, i8 %y) {
89; CHECK-LABEL: @sadd_sat_fail_may_overflow(
90; CHECK-NEXT:    [[LHS:%.*]] = or i8 [[X:%.*]], 1
91; CHECK-NEXT:    [[RHS:%.*]] = and i8 [[Y:%.*]], -2
92; CHECK-NEXT:    [[EXP:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[LHS]], i8 [[RHS]])
93; CHECK-NEXT:    [[AND:%.*]] = and i8 [[EXP]], 1
94; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[AND]], 0
95; CHECK-NEXT:    ret i1 [[R]]
96;
97  %lhs = or i8 %x, 1
98  %rhs = and i8 %y, -2
99  %exp = call i8 @llvm.sadd.sat.i8(i8 %lhs, i8 %rhs)
100  %and = and i8 %exp, 1
101  %r = icmp eq i8 %and, 0
102  ret i1 %r
103}
104
105define i1 @sadd_sat_overflow_neg(i8 %x, i8 %y) {
106; CHECK-LABEL: @sadd_sat_overflow_neg(
107; CHECK-NEXT:    ret i1 false
108;
109  %lhs = or i8 %x, 192
110  %rhs = or i8 %y, 191
111  %exp = call i8 @llvm.sadd.sat.i8(i8 %lhs, i8 %rhs)
112  %r = icmp eq i8 %exp, 127
113  ret i1 %r
114}
115
116define i1 @ssub_sat_overflow_neg(i8 %x, i8 %y) {
117; CHECK-LABEL: @ssub_sat_overflow_neg(
118; CHECK-NEXT:    ret i1 false
119;
120  %xx = and i8 %x, 112
121  %yy = and i8 %y, 127
122  %lhs = or i8 %xx, 128
123  %rhs = or i8 %yy, 126
124  %exp = call i8 @llvm.ssub.sat.i8(i8 %lhs, i8 %rhs)
125  %r = icmp eq i8 %exp, 32
126  ret i1 %r
127}
128
129define i1 @ssub_sat_low_bits(i8 %x, i8 %y) {
130; CHECK-LABEL: @ssub_sat_low_bits(
131; CHECK-NEXT:    ret i1 false
132;
133  %xx = and i8 %x, 15
134  %yy = and i8 %y, 15
135  %lhs = or i8 %xx, 17
136  %rhs = and i8 %yy, -2
137  %exp = call i8 @llvm.ssub.sat.i8(i8 %lhs, i8 %rhs)
138  %and = and i8 %exp, 1
139  %r = icmp eq i8 %and, 0
140  ret i1 %r
141}
142
143define i1 @ssub_sat_fail_may_overflow(i8 %x, i8 %y) {
144; CHECK-LABEL: @ssub_sat_fail_may_overflow(
145; CHECK-NEXT:    ret i1 false
146;
147  %xx = and i8 %x, 15
148  %yy = and i8 %y, 15
149  %lhs = or i8 %xx, 1
150  %rhs = and i8 %yy, -2
151  %exp = call i8 @llvm.ssub.sat.i8(i8 %lhs, i8 %rhs)
152  %and = and i8 %exp, 1
153  %r = icmp eq i8 %and, 0
154  ret i1 %r
155}
156
157define i1 @ssub_sat_overflow_pos(i8 %x, i8 %y) {
158; CHECK-LABEL: @ssub_sat_overflow_pos(
159; CHECK-NEXT:    ret i1 false
160;
161  %xx = and i8 %x, 24
162  %yy = and i8 %y, 3
163  %lhs = or i8 %xx, 8
164  %rhs = or i8 %yy, 128
165  %exp = call i8 @llvm.ssub.sat.i8(i8 %lhs, i8 %rhs)
166  %r = icmp eq i8 %exp, 128
167  ret i1 %r
168}
169