1 ; RUN: llc -mtriple=thumbv8m.main -mcpu=cortex-m33 %s -arm-disable-cgp=false -o - | FileCheck %s
7 define zeroext i16 @overflow_add(i16 zeroext %a, i16 zeroext %b) {
10 %cmp = icmp ugt i16 %or, 1024
11 %res = select i1 %cmp, i16 2, i16 5
15 ; CHECK-LABEL: overflow_sub
19 define zeroext i16 @overflow_sub(i16 zeroext %a, i16 zeroext %b) {
22 %cmp = icmp ugt i16 %or, 1024
23 %res = select i1 %cmp, i16 2, i16 5
27 ; CHECK-LABEL: overflow_mul
31 define zeroext i16 @overflow_mul(i16 zeroext %a, i16 zeroext %b) {
34 %cmp = icmp ugt i16 %or, 1024
35 %res = select i1 %cmp, i16 2, i16 5
39 ; CHECK-LABEL: overflow_shl
43 define zeroext i16 @overflow_shl(i16 zeroext %a, i16 zeroext %b) {
46 %cmp = icmp ugt i16 %or, 1024
47 %res = select i1 %cmp, i16 2, i16 5
51 ; CHECK-LABEL: overflow_add_no_consts:
53 ; CHECK: uxtb [[EXT:r[0-9]+]], r0
54 ; CHECK: cmp [[EXT]], r2
56 define i32 @overflow_add_no_consts(i8 zeroext %a, i8 zeroext %b, i8 zeroext %limit) {
58 %cmp = icmp ugt i8 %add, %limit
59 %res = select i1 %cmp, i32 8, i32 16
63 ; CHECK-LABEL: overflow_add_const_limit:
65 ; CHECK: uxtb [[EXT:r[0-9]+]], r0
66 ; CHECK: cmp [[EXT]], #128
68 define i32 @overflow_add_const_limit(i8 zeroext %a, i8 zeroext %b) {
70 %cmp = icmp ugt i8 %add, 128
71 %res = select i1 %cmp, i32 8, i32 16
75 ; CHECK-LABEL: overflow_add_positive_const_limit:
77 ; CHECK: uxtb [[EXT:r[0-9]+]], r0
78 ; CHECK: cmp [[EXT]], #128
80 define i32 @overflow_add_positive_const_limit(i8 zeroext %a) {
82 %cmp = icmp ugt i8 %add, 128
83 %res = select i1 %cmp, i32 8, i32 16
87 ; CHECK-LABEL: unsafe_add_underflow:
89 ; CHECK: uxtb [[EXT:r[0-9]+]], r0
90 ; CHECK: cmp [[EXT]], #255
92 define i32 @unsafe_add_underflow(i8 zeroext %a) {
94 %cmp = icmp ugt i8 %add, 254
95 %res = select i1 %cmp, i32 8, i32 16
99 ; CHECK-LABEL: safe_add_underflow:
100 ; CHECK: subs [[MINUS_1:r[0-9]+]], r0, #1
102 ; CHECK: cmp [[MINUS_1]], #254
103 ; CHECK: movhi r0, #8
104 define i32 @safe_add_underflow(i8 zeroext %a) {
106 %cmp = icmp ugt i8 %add, 254
107 %res = select i1 %cmp, i32 8, i32 16
111 ; CHECK-LABEL: safe_add_underflow_neg:
112 ; CHECK: subs [[MINUS_1:r[0-9]+]], r0, #2
114 ; CHECK: cmp [[MINUS_1]], #251
115 ; CHECK: movlo r0, #8
116 define i32 @safe_add_underflow_neg(i8 zeroext %a) {
118 %cmp = icmp ule i8 %add, -6
119 %res = select i1 %cmp, i32 8, i32 16
123 ; CHECK-LABEL: overflow_sub_negative_const_limit:
125 ; CHECK: uxtb [[EXT:r[0-9]+]], r0
126 ; CHECK: cmp [[EXT]], #128
127 ; CHECK: movhi r0, #8
128 define i32 @overflow_sub_negative_const_limit(i8 zeroext %a) {
130 %cmp = icmp ugt i8 %sub, 128
131 %res = select i1 %cmp, i32 8, i32 16
135 ; CHECK-LABEL: unsafe_sub_underflow:
137 ; CHECK: uxtb [[EXT:r[0-9]+]], r0
138 ; CHECK: cmp [[EXT]], #250
139 ; CHECK: movhi r0, #8
140 define i32 @unsafe_sub_underflow(i8 zeroext %a) {
142 %cmp = icmp ugt i8 %sub, 250
143 %res = select i1 %cmp, i32 8, i32 16
147 ; CHECK-LABEL: safe_sub_underflow:
148 ; CHECK: subs [[MINUS_1:r[0-9]+]], r0, #1
150 ; CHECK: cmp [[MINUS_1]], #255
151 ; CHECK: movlo r0, #8
152 define i32 @safe_sub_underflow(i8 zeroext %a) {
154 %cmp = icmp ule i8 %sub, 254
155 %res = select i1 %cmp, i32 8, i32 16
159 ; CHECK-LABEL: safe_sub_underflow_neg
160 ; CHECK: subs [[MINUS_1:r[0-9]+]], r0, #4
162 ; CHECK: cmp [[MINUS_1]], #250
163 ; CHECK: movhi r0, #8
164 define i32 @safe_sub_underflow_neg(i8 zeroext %a) {
166 %cmp = icmp uge i8 %sub, -5
167 %res = select i1 %cmp, i32 8, i32 16
171 ; CHECK-LABEL: unsafe_sub_underflow_neg
173 ; CHECK: uxtb [[EXT:r[0-9]+]], r0
174 ; CHECK: cmp [[EXT]], #253
175 ; CHECK: movlo r0, #8
176 define i32 @unsafe_sub_underflow_neg(i8 zeroext %a) {
178 %cmp = icmp ult i8 %sub, -3
179 %res = select i1 %cmp, i32 8, i32 16
183 ; CHECK: rsb.w [[RSUB:r[0-9]+]], r0, #248
185 ; CHECK: cmp [[RSUB]], #252
186 define i32 @safe_sub_imm_var(i8* %b) {
188 %0 = load i8, i8* %b, align 1
189 %sub = sub nuw nsw i8 -8, %0
190 %cmp = icmp ugt i8 %sub, 252
191 %conv4 = zext i1 %cmp to i32
195 ; CHECK-LABEL: safe_sub_var_imm
196 ; CHECK: add.w [[ADD:r[0-9]+]], r0, #8
198 ; CHECK: cmp [[ADD]], #252
199 define i32 @safe_sub_var_imm(i8* %b) {
201 %0 = load i8, i8* %b, align 1
202 %sub = sub nuw nsw i8 %0, -8
203 %cmp = icmp ugt i8 %sub, 252
204 %conv4 = zext i1 %cmp to i32
208 ; CHECK-LABEL: safe_add_imm_var
209 ; CHECK: add.w [[ADD:r[0-9]+]], r0, #129
211 ; CHECK: cmp [[ADD]], #127
212 define i32 @safe_add_imm_var(i8* %b) {
214 %0 = load i8, i8* %b, align 1
215 %add = add nuw nsw i8 -127, %0
216 %cmp = icmp ugt i8 %add, 127
217 %conv4 = zext i1 %cmp to i32
221 ; CHECK-LABEL: safe_add_var_imm
222 ; CHECK: sub.w [[SUB:r[0-9]+]], r0, #127
224 ; CHECK: cmp [[SUB]], #127
225 define i32 @safe_add_var_imm(i8* %b) {
227 %0 = load i8, i8* %b, align 1
228 %add = add nuw nsw i8 %0, -127
229 %cmp = icmp ugt i8 %add, 127
230 %conv4 = zext i1 %cmp to i32