1 ; RUN: llc < %s -mtriple=arm64-eabi -aarch64-enable-atomic-cfg-tidy=0 -disable-post-ra -verify-machineinstrs | FileCheck %s 2 ; RUN: llc < %s -mtriple=arm64-eabi -aarch64-enable-atomic-cfg-tidy=0 -fast-isel -fast-isel-abort=1 -disable-post-ra -verify-machineinstrs | FileCheck %s 3 4 ; 5 ; Get the actual value of the overflow bit. 6 ; 7 define zeroext i1 @saddo1.i32(i32 %v1, i32 %v2, i32* %res) { 8 entry: 9 ; CHECK-LABEL: saddo1.i32 10 ; CHECK: adds {{w[0-9]+}}, w0, w1 11 ; CHECK-NEXT: cset {{w[0-9]+}}, vs 12 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 13 %val = extractvalue {i32, i1} %t, 0 14 %obit = extractvalue {i32, i1} %t, 1 15 store i32 %val, i32* %res 16 ret i1 %obit 17 } 18 19 ; Test the immediate version. 20 define zeroext i1 @saddo2.i32(i32 %v1, i32* %res) { 21 entry: 22 ; CHECK-LABEL: saddo2.i32 23 ; CHECK: adds {{w[0-9]+}}, w0, #4 24 ; CHECK-NEXT: cset {{w[0-9]+}}, vs 25 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 4) 26 %val = extractvalue {i32, i1} %t, 0 27 %obit = extractvalue {i32, i1} %t, 1 28 store i32 %val, i32* %res 29 ret i1 %obit 30 } 31 32 ; Test negative immediates. 33 define zeroext i1 @saddo3.i32(i32 %v1, i32* %res) { 34 entry: 35 ; CHECK-LABEL: saddo3.i32 36 ; CHECK: subs {{w[0-9]+}}, w0, #4 37 ; CHECK-NEXT: cset {{w[0-9]+}}, vs 38 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 -4) 39 %val = extractvalue {i32, i1} %t, 0 40 %obit = extractvalue {i32, i1} %t, 1 41 store i32 %val, i32* %res 42 ret i1 %obit 43 } 44 45 ; Test immediates that are too large to be encoded. 46 define zeroext i1 @saddo4.i32(i32 %v1, i32* %res) { 47 entry: 48 ; CHECK-LABEL: saddo4.i32 49 ; CHECK: adds {{w[0-9]+}}, w0, {{w[0-9]+}} 50 ; CHECK-NEXT: cset {{w[0-9]+}}, vs 51 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 16777215) 52 %val = extractvalue {i32, i1} %t, 0 53 %obit = extractvalue {i32, i1} %t, 1 54 store i32 %val, i32* %res 55 ret i1 %obit 56 } 57 58 ; Test shift folding. 59 define zeroext i1 @saddo5.i32(i32 %v1, i32 %v2, i32* %res) { 60 entry: 61 ; CHECK-LABEL: saddo5.i32 62 ; CHECK: adds {{w[0-9]+}}, w0, w1 63 ; CHECK-NEXT: cset {{w[0-9]+}}, vs 64 %lsl = shl i32 %v2, 16 65 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %lsl) 66 %val = extractvalue {i32, i1} %t, 0 67 %obit = extractvalue {i32, i1} %t, 1 68 store i32 %val, i32* %res 69 ret i1 %obit 70 } 71 72 define zeroext i1 @saddo1.i64(i64 %v1, i64 %v2, i64* %res) { 73 entry: 74 ; CHECK-LABEL: saddo1.i64 75 ; CHECK: adds {{x[0-9]+}}, x0, x1 76 ; CHECK-NEXT: cset {{w[0-9]+}}, vs 77 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 78 %val = extractvalue {i64, i1} %t, 0 79 %obit = extractvalue {i64, i1} %t, 1 80 store i64 %val, i64* %res 81 ret i1 %obit 82 } 83 84 define zeroext i1 @saddo2.i64(i64 %v1, i64* %res) { 85 entry: 86 ; CHECK-LABEL: saddo2.i64 87 ; CHECK: adds {{x[0-9]+}}, x0, #4 88 ; CHECK-NEXT: cset {{w[0-9]+}}, vs 89 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 4) 90 %val = extractvalue {i64, i1} %t, 0 91 %obit = extractvalue {i64, i1} %t, 1 92 store i64 %val, i64* %res 93 ret i1 %obit 94 } 95 96 define zeroext i1 @saddo3.i64(i64 %v1, i64* %res) { 97 entry: 98 ; CHECK-LABEL: saddo3.i64 99 ; CHECK: subs {{x[0-9]+}}, x0, #4 100 ; CHECK-NEXT: cset {{w[0-9]+}}, vs 101 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -4) 102 %val = extractvalue {i64, i1} %t, 0 103 %obit = extractvalue {i64, i1} %t, 1 104 store i64 %val, i64* %res 105 ret i1 %obit 106 } 107 108 define zeroext i1 @uaddo.i32(i32 %v1, i32 %v2, i32* %res) { 109 entry: 110 ; CHECK-LABEL: uaddo.i32 111 ; CHECK: adds {{w[0-9]+}}, w0, w1 112 ; CHECK-NEXT: cset {{w[0-9]+}}, hs 113 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 114 %val = extractvalue {i32, i1} %t, 0 115 %obit = extractvalue {i32, i1} %t, 1 116 store i32 %val, i32* %res 117 ret i1 %obit 118 } 119 120 define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, i64* %res) { 121 entry: 122 ; CHECK-LABEL: uaddo.i64 123 ; CHECK: adds {{x[0-9]+}}, x0, x1 124 ; CHECK-NEXT: cset {{w[0-9]+}}, hs 125 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 126 %val = extractvalue {i64, i1} %t, 0 127 %obit = extractvalue {i64, i1} %t, 1 128 store i64 %val, i64* %res 129 ret i1 %obit 130 } 131 132 define zeroext i1 @ssubo1.i32(i32 %v1, i32 %v2, i32* %res) { 133 entry: 134 ; CHECK-LABEL: ssubo1.i32 135 ; CHECK: subs {{w[0-9]+}}, w0, w1 136 ; CHECK-NEXT: cset {{w[0-9]+}}, vs 137 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 138 %val = extractvalue {i32, i1} %t, 0 139 %obit = extractvalue {i32, i1} %t, 1 140 store i32 %val, i32* %res 141 ret i1 %obit 142 } 143 144 define zeroext i1 @ssubo2.i32(i32 %v1, i32* %res) { 145 entry: 146 ; CHECK-LABEL: ssubo2.i32 147 ; CHECK: adds {{w[0-9]+}}, w0, #4 148 ; CHECK-NEXT: cset {{w[0-9]+}}, vs 149 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 -4) 150 %val = extractvalue {i32, i1} %t, 0 151 %obit = extractvalue {i32, i1} %t, 1 152 store i32 %val, i32* %res 153 ret i1 %obit 154 } 155 156 define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, i64* %res) { 157 entry: 158 ; CHECK-LABEL: ssubo.i64 159 ; CHECK: subs {{x[0-9]+}}, x0, x1 160 ; CHECK-NEXT: cset {{w[0-9]+}}, vs 161 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 162 %val = extractvalue {i64, i1} %t, 0 163 %obit = extractvalue {i64, i1} %t, 1 164 store i64 %val, i64* %res 165 ret i1 %obit 166 } 167 168 define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, i32* %res) { 169 entry: 170 ; CHECK-LABEL: usubo.i32 171 ; CHECK: subs {{w[0-9]+}}, w0, w1 172 ; CHECK-NEXT: cset {{w[0-9]+}}, lo 173 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 174 %val = extractvalue {i32, i1} %t, 0 175 %obit = extractvalue {i32, i1} %t, 1 176 store i32 %val, i32* %res 177 ret i1 %obit 178 } 179 180 define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, i64* %res) { 181 entry: 182 ; CHECK-LABEL: usubo.i64 183 ; CHECK: subs {{x[0-9]+}}, x0, x1 184 ; CHECK-NEXT: cset {{w[0-9]+}}, lo 185 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 186 %val = extractvalue {i64, i1} %t, 0 187 %obit = extractvalue {i64, i1} %t, 1 188 store i64 %val, i64* %res 189 ret i1 %obit 190 } 191 192 define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, i32* %res) { 193 entry: 194 ; CHECK-LABEL: smulo.i32 195 ; CHECK: smull x[[MREG:[0-9]+]], w0, w1 196 ; CHECK-NEXT: lsr x[[SREG:[0-9]+]], x[[MREG]], #32 197 ; CHECK-NEXT: cmp w[[SREG]], w[[MREG]], asr #31 198 ; CHECK-NEXT: cset {{w[0-9]+}}, ne 199 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 200 %val = extractvalue {i32, i1} %t, 0 201 %obit = extractvalue {i32, i1} %t, 1 202 store i32 %val, i32* %res 203 ret i1 %obit 204 } 205 206 define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, i64* %res) { 207 entry: 208 ; CHECK-LABEL: smulo.i64 209 ; CHECK: mul [[MREG:x[0-9]+]], x0, x1 210 ; CHECK-NEXT: smulh [[HREG:x[0-9]+]], x0, x1 211 ; CHECK-NEXT: cmp [[HREG]], [[MREG]], asr #63 212 ; CHECK-NEXT: cset {{w[0-9]+}}, ne 213 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 214 %val = extractvalue {i64, i1} %t, 0 215 %obit = extractvalue {i64, i1} %t, 1 216 store i64 %val, i64* %res 217 ret i1 %obit 218 } 219 220 define zeroext i1 @smulo2.i64(i64 %v1, i64* %res) { 221 entry: 222 ; CHECK-LABEL: smulo2.i64 223 ; CHECK: adds [[MREG:x[0-9]+]], x0, x0 224 ; CHECK-NEXT: cset {{w[0-9]+}}, vs 225 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2) 226 %val = extractvalue {i64, i1} %t, 0 227 %obit = extractvalue {i64, i1} %t, 1 228 store i64 %val, i64* %res 229 ret i1 %obit 230 } 231 232 define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, i32* %res) { 233 entry: 234 ; CHECK-LABEL: umulo.i32 235 ; CHECK: umull [[MREG:x[0-9]+]], w0, w1 236 ; CHECK-NEXT: cmp xzr, [[MREG]], lsr #32 237 ; CHECK-NEXT: cset {{w[0-9]+}}, ne 238 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 239 %val = extractvalue {i32, i1} %t, 0 240 %obit = extractvalue {i32, i1} %t, 1 241 store i32 %val, i32* %res 242 ret i1 %obit 243 } 244 245 define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, i64* %res) { 246 entry: 247 ; CHECK-LABEL: umulo.i64 248 ; CHECK: umulh [[MREG:x[0-9]+]], x0, x1 249 ; CHECK-NEXT: cmp xzr, [[MREG]] 250 ; CHECK-NEXT: cset {{w[0-9]+}}, ne 251 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 252 %val = extractvalue {i64, i1} %t, 0 253 %obit = extractvalue {i64, i1} %t, 1 254 store i64 %val, i64* %res 255 ret i1 %obit 256 } 257 258 define zeroext i1 @umulo2.i64(i64 %v1, i64* %res) { 259 entry: 260 ; CHECK-LABEL: umulo2.i64 261 ; CHECK: adds [[MREG:x[0-9]+]], x0, x0 262 ; CHECK-NEXT: cset {{w[0-9]+}}, hs 263 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2) 264 %val = extractvalue {i64, i1} %t, 0 265 %obit = extractvalue {i64, i1} %t, 1 266 store i64 %val, i64* %res 267 ret i1 %obit 268 } 269 270 271 ; 272 ; Check the use of the overflow bit in combination with a select instruction. 273 ; 274 define i32 @saddo.select.i32(i32 %v1, i32 %v2) { 275 entry: 276 ; CHECK-LABEL: saddo.select.i32 277 ; CHECK: cmn w0, w1 278 ; CHECK-NEXT: csel w0, w0, w1, vs 279 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 280 %obit = extractvalue {i32, i1} %t, 1 281 %ret = select i1 %obit, i32 %v1, i32 %v2 282 ret i32 %ret 283 } 284 285 define i1 @saddo.not.i32(i32 %v1, i32 %v2) { 286 entry: 287 ; CHECK-LABEL: saddo.not.i32 288 ; CHECK: cmn w0, w1 289 ; CHECK-NEXT: cset w0, vc 290 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 291 %obit = extractvalue {i32, i1} %t, 1 292 %ret = xor i1 %obit, true 293 ret i1 %ret 294 } 295 296 define i64 @saddo.select.i64(i64 %v1, i64 %v2) { 297 entry: 298 ; CHECK-LABEL: saddo.select.i64 299 ; CHECK: cmn x0, x1 300 ; CHECK-NEXT: csel x0, x0, x1, vs 301 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 302 %obit = extractvalue {i64, i1} %t, 1 303 %ret = select i1 %obit, i64 %v1, i64 %v2 304 ret i64 %ret 305 } 306 307 define i1 @saddo.not.i64(i64 %v1, i64 %v2) { 308 entry: 309 ; CHECK-LABEL: saddo.not.i64 310 ; CHECK: cmn x0, x1 311 ; CHECK-NEXT: cset w0, vc 312 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 313 %obit = extractvalue {i64, i1} %t, 1 314 %ret = xor i1 %obit, true 315 ret i1 %ret 316 } 317 318 define i32 @uaddo.select.i32(i32 %v1, i32 %v2) { 319 entry: 320 ; CHECK-LABEL: uaddo.select.i32 321 ; CHECK: cmn w0, w1 322 ; CHECK-NEXT: csel w0, w0, w1, hs 323 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 324 %obit = extractvalue {i32, i1} %t, 1 325 %ret = select i1 %obit, i32 %v1, i32 %v2 326 ret i32 %ret 327 } 328 329 define i1 @uaddo.not.i32(i32 %v1, i32 %v2) { 330 entry: 331 ; CHECK-LABEL: uaddo.not.i32 332 ; CHECK: cmn w0, w1 333 ; CHECK-NEXT: cset w0, lo 334 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 335 %obit = extractvalue {i32, i1} %t, 1 336 %ret = xor i1 %obit, true 337 ret i1 %ret 338 } 339 340 define i64 @uaddo.select.i64(i64 %v1, i64 %v2) { 341 entry: 342 ; CHECK-LABEL: uaddo.select.i64 343 ; CHECK: cmn x0, x1 344 ; CHECK-NEXT: csel x0, x0, x1, hs 345 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 346 %obit = extractvalue {i64, i1} %t, 1 347 %ret = select i1 %obit, i64 %v1, i64 %v2 348 ret i64 %ret 349 } 350 351 define i1 @uaddo.not.i64(i64 %v1, i64 %v2) { 352 entry: 353 ; CHECK-LABEL: uaddo.not.i64 354 ; CHECK: cmn x0, x1 355 ; CHECK-NEXT: cset w0, lo 356 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 357 %obit = extractvalue {i64, i1} %t, 1 358 %ret = xor i1 %obit, true 359 ret i1 %ret 360 } 361 362 define i32 @ssubo.select.i32(i32 %v1, i32 %v2) { 363 entry: 364 ; CHECK-LABEL: ssubo.select.i32 365 ; CHECK: cmp w0, w1 366 ; CHECK-NEXT: csel w0, w0, w1, vs 367 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 368 %obit = extractvalue {i32, i1} %t, 1 369 %ret = select i1 %obit, i32 %v1, i32 %v2 370 ret i32 %ret 371 } 372 373 define i1 @ssubo.not.i32(i32 %v1, i32 %v2) { 374 entry: 375 ; CHECK-LABEL: ssubo.not.i32 376 ; CHECK: cmp w0, w1 377 ; CHECK-NEXT: cset w0, vc 378 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 379 %obit = extractvalue {i32, i1} %t, 1 380 %ret = xor i1 %obit, true 381 ret i1 %ret 382 } 383 384 define i64 @ssubo.select.i64(i64 %v1, i64 %v2) { 385 entry: 386 ; CHECK-LABEL: ssubo.select.i64 387 ; CHECK: cmp x0, x1 388 ; CHECK-NEXT: csel x0, x0, x1, vs 389 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 390 %obit = extractvalue {i64, i1} %t, 1 391 %ret = select i1 %obit, i64 %v1, i64 %v2 392 ret i64 %ret 393 } 394 395 define i1 @ssub.not.i64(i64 %v1, i64 %v2) { 396 entry: 397 ; CHECK-LABEL: ssub.not.i64 398 ; CHECK: cmp x0, x1 399 ; CHECK-NEXT: cset w0, vc 400 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 401 %obit = extractvalue {i64, i1} %t, 1 402 %ret = xor i1 %obit, true 403 ret i1 %ret 404 } 405 406 define i32 @usubo.select.i32(i32 %v1, i32 %v2) { 407 entry: 408 ; CHECK-LABEL: usubo.select.i32 409 ; CHECK: cmp w0, w1 410 ; CHECK-NEXT: csel w0, w0, w1, lo 411 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 412 %obit = extractvalue {i32, i1} %t, 1 413 %ret = select i1 %obit, i32 %v1, i32 %v2 414 ret i32 %ret 415 } 416 417 define i1 @usubo.not.i32(i32 %v1, i32 %v2) { 418 entry: 419 ; CHECK-LABEL: usubo.not.i32 420 ; CHECK: cmp w0, w1 421 ; CHECK-NEXT: cset w0, hs 422 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 423 %obit = extractvalue {i32, i1} %t, 1 424 %ret = xor i1 %obit, true 425 ret i1 %ret 426 } 427 428 define i64 @usubo.select.i64(i64 %v1, i64 %v2) { 429 entry: 430 ; CHECK-LABEL: usubo.select.i64 431 ; CHECK: cmp x0, x1 432 ; CHECK-NEXT: csel x0, x0, x1, lo 433 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 434 %obit = extractvalue {i64, i1} %t, 1 435 %ret = select i1 %obit, i64 %v1, i64 %v2 436 ret i64 %ret 437 } 438 439 define i1 @usubo.not.i64(i64 %v1, i64 %v2) { 440 entry: 441 ; CHECK-LABEL: usubo.not.i64 442 ; CHECK: cmp x0, x1 443 ; CHECK-NEXT: cset w0, hs 444 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 445 %obit = extractvalue {i64, i1} %t, 1 446 %ret = xor i1 %obit, true 447 ret i1 %ret 448 } 449 450 define i32 @smulo.select.i32(i32 %v1, i32 %v2) { 451 entry: 452 ; CHECK-LABEL: smulo.select.i32 453 ; CHECK: smull x[[MREG:[0-9]+]], w0, w1 454 ; CHECK-NEXT: lsr x[[SREG:[0-9]+]], x[[MREG]], #32 455 ; CHECK-NEXT: cmp w[[SREG]], w[[MREG]], asr #31 456 ; CHECK-NEXT: csel w0, w0, w1, ne 457 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 458 %obit = extractvalue {i32, i1} %t, 1 459 %ret = select i1 %obit, i32 %v1, i32 %v2 460 ret i32 %ret 461 } 462 463 define i1 @smulo.not.i32(i32 %v1, i32 %v2) { 464 entry: 465 ; CHECK-LABEL: smulo.not.i32 466 ; CHECK: smull x[[MREG:[0-9]+]], w0, w1 467 ; CHECK-NEXT: lsr x[[SREG:[0-9]+]], x[[MREG]], #32 468 ; CHECK-NEXT: cmp w[[SREG]], w[[MREG]], asr #31 469 ; CHECK-NEXT: cset w0, eq 470 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 471 %obit = extractvalue {i32, i1} %t, 1 472 %ret = xor i1 %obit, true 473 ret i1 %ret 474 } 475 476 define i64 @smulo.select.i64(i64 %v1, i64 %v2) { 477 entry: 478 ; CHECK-LABEL: smulo.select.i64 479 ; CHECK: mul [[MREG:x[0-9]+]], x0, x1 480 ; CHECK-NEXT: smulh [[HREG:x[0-9]+]], x0, x1 481 ; CHECK-NEXT: cmp [[HREG]], [[MREG]], asr #63 482 ; CHECK-NEXT: csel x0, x0, x1, ne 483 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 484 %obit = extractvalue {i64, i1} %t, 1 485 %ret = select i1 %obit, i64 %v1, i64 %v2 486 ret i64 %ret 487 } 488 489 define i1 @smulo.not.i64(i64 %v1, i64 %v2) { 490 entry: 491 ; CHECK-LABEL: smulo.not.i64 492 ; CHECK: mul [[MREG:x[0-9]+]], x0, x1 493 ; CHECK-NEXT: smulh [[HREG:x[0-9]+]], x0, x1 494 ; CHECK-NEXT: cmp [[HREG]], [[MREG]], asr #63 495 ; CHECK-NEXT: cset w0, eq 496 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 497 %obit = extractvalue {i64, i1} %t, 1 498 %ret = xor i1 %obit, true 499 ret i1 %ret 500 } 501 502 define i32 @umulo.select.i32(i32 %v1, i32 %v2) { 503 entry: 504 ; CHECK-LABEL: umulo.select.i32 505 ; CHECK: umull [[MREG:x[0-9]+]], w0, w1 506 ; CHECK-NEXT: cmp xzr, [[MREG]], lsr #32 507 ; CHECK-NEXT: csel w0, w0, w1, ne 508 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 509 %obit = extractvalue {i32, i1} %t, 1 510 %ret = select i1 %obit, i32 %v1, i32 %v2 511 ret i32 %ret 512 } 513 514 define i1 @umulo.not.i32(i32 %v1, i32 %v2) { 515 entry: 516 ; CHECK-LABEL: umulo.not.i32 517 ; CHECK: umull [[MREG:x[0-9]+]], w0, w1 518 ; CHECK-NEXT: cmp xzr, [[MREG]], lsr #32 519 ; CHECK-NEXT: cset w0, eq 520 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 521 %obit = extractvalue {i32, i1} %t, 1 522 %ret = xor i1 %obit, true 523 ret i1 %ret 524 } 525 526 define i64 @umulo.select.i64(i64 %v1, i64 %v2) { 527 entry: 528 ; CHECK-LABEL: umulo.select.i64 529 ; CHECK: umulh [[MREG:x[0-9]+]], x0, x1 530 ; CHECK-NEXT: cmp xzr, [[MREG]] 531 ; CHECK-NEXT: csel x0, x0, x1, ne 532 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 533 %obit = extractvalue {i64, i1} %t, 1 534 %ret = select i1 %obit, i64 %v1, i64 %v2 535 ret i64 %ret 536 } 537 538 define i1 @umulo.not.i64(i64 %v1, i64 %v2) { 539 entry: 540 ; CHECK-LABEL: umulo.not.i64 541 ; CHECK: umulh [[MREG:x[0-9]+]], x0, x1 542 ; CHECK-NEXT: cmp xzr, [[MREG]] 543 ; CHECK-NEXT: cset w0, eq 544 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 545 %obit = extractvalue {i64, i1} %t, 1 546 %ret = xor i1 %obit, true 547 ret i1 %ret 548 } 549 550 551 ; 552 ; Check the use of the overflow bit in combination with a branch instruction. 553 ; 554 define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) { 555 entry: 556 ; CHECK-LABEL: saddo.br.i32 557 ; CHECK: cmn w0, w1 558 ; CHECK-NEXT: b.vc 559 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 560 %val = extractvalue {i32, i1} %t, 0 561 %obit = extractvalue {i32, i1} %t, 1 562 br i1 %obit, label %overflow, label %continue 563 564 overflow: 565 ret i1 false 566 567 continue: 568 ret i1 true 569 } 570 571 define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) { 572 entry: 573 ; CHECK-LABEL: saddo.br.i64 574 ; CHECK: cmn x0, x1 575 ; CHECK-NEXT: b.vc 576 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 577 %val = extractvalue {i64, i1} %t, 0 578 %obit = extractvalue {i64, i1} %t, 1 579 br i1 %obit, label %overflow, label %continue 580 581 overflow: 582 ret i1 false 583 584 continue: 585 ret i1 true 586 } 587 588 define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) { 589 entry: 590 ; CHECK-LABEL: uaddo.br.i32 591 ; CHECK: cmn w0, w1 592 ; CHECK-NEXT: b.lo 593 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 594 %val = extractvalue {i32, i1} %t, 0 595 %obit = extractvalue {i32, i1} %t, 1 596 br i1 %obit, label %overflow, label %continue 597 598 overflow: 599 ret i1 false 600 601 continue: 602 ret i1 true 603 } 604 605 define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) { 606 entry: 607 ; CHECK-LABEL: uaddo.br.i64 608 ; CHECK: cmn x0, x1 609 ; CHECK-NEXT: b.lo 610 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 611 %val = extractvalue {i64, i1} %t, 0 612 %obit = extractvalue {i64, i1} %t, 1 613 br i1 %obit, label %overflow, label %continue 614 615 overflow: 616 ret i1 false 617 618 continue: 619 ret i1 true 620 } 621 622 define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) { 623 entry: 624 ; CHECK-LABEL: ssubo.br.i32 625 ; CHECK: cmp w0, w1 626 ; CHECK-NEXT: b.vc 627 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 628 %val = extractvalue {i32, i1} %t, 0 629 %obit = extractvalue {i32, i1} %t, 1 630 br i1 %obit, label %overflow, label %continue 631 632 overflow: 633 ret i1 false 634 635 continue: 636 ret i1 true 637 } 638 639 define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) { 640 entry: 641 ; CHECK-LABEL: ssubo.br.i64 642 ; CHECK: cmp x0, x1 643 ; CHECK-NEXT: b.vc 644 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 645 %val = extractvalue {i64, i1} %t, 0 646 %obit = extractvalue {i64, i1} %t, 1 647 br i1 %obit, label %overflow, label %continue 648 649 overflow: 650 ret i1 false 651 652 continue: 653 ret i1 true 654 } 655 656 define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) { 657 entry: 658 ; CHECK-LABEL: usubo.br.i32 659 ; CHECK: cmp w0, w1 660 ; CHECK-NEXT: b.hs 661 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 662 %val = extractvalue {i32, i1} %t, 0 663 %obit = extractvalue {i32, i1} %t, 1 664 br i1 %obit, label %overflow, label %continue 665 666 overflow: 667 ret i1 false 668 669 continue: 670 ret i1 true 671 } 672 673 define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) { 674 entry: 675 ; CHECK-LABEL: usubo.br.i64 676 ; CHECK: cmp x0, x1 677 ; CHECK-NEXT: b.hs 678 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 679 %val = extractvalue {i64, i1} %t, 0 680 %obit = extractvalue {i64, i1} %t, 1 681 br i1 %obit, label %overflow, label %continue 682 683 overflow: 684 ret i1 false 685 686 continue: 687 ret i1 true 688 } 689 690 define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) { 691 entry: 692 ; CHECK-LABEL: smulo.br.i32 693 ; CHECK: smull x[[MREG:[0-9]+]], w0, w1 694 ; CHECK-NEXT: lsr x[[SREG:[0-9]+]], x8, #32 695 ; CHECK-NEXT: cmp w[[SREG]], w[[MREG]], asr #31 696 ; CHECK-NEXT: b.eq 697 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 698 %val = extractvalue {i32, i1} %t, 0 699 %obit = extractvalue {i32, i1} %t, 1 700 br i1 %obit, label %overflow, label %continue 701 702 overflow: 703 ret i1 false 704 705 continue: 706 ret i1 true 707 } 708 709 define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) { 710 entry: 711 ; CHECK-LABEL: smulo.br.i64 712 ; CHECK: mul [[MREG:x[0-9]+]], x0, x1 713 ; CHECK-NEXT: smulh [[HREG:x[0-9]+]], x0, x1 714 ; CHECK-NEXT: cmp [[HREG]], [[MREG]], asr #63 715 ; CHECK-NEXT: b.eq 716 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 717 %val = extractvalue {i64, i1} %t, 0 718 %obit = extractvalue {i64, i1} %t, 1 719 br i1 %obit, label %overflow, label %continue 720 721 overflow: 722 ret i1 false 723 724 continue: 725 ret i1 true 726 } 727 728 define zeroext i1 @smulo2.br.i64(i64 %v1) { 729 entry: 730 ; CHECK-LABEL: smulo2.br.i64 731 ; CHECK: cmn x0, x0 732 ; CHECK-NEXT: b.vc 733 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2) 734 %val = extractvalue {i64, i1} %t, 0 735 %obit = extractvalue {i64, i1} %t, 1 736 br i1 %obit, label %overflow, label %continue 737 738 overflow: 739 ret i1 false 740 741 continue: 742 ret i1 true 743 } 744 745 define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) { 746 entry: 747 ; CHECK-LABEL: umulo.br.i32 748 ; CHECK: umull [[MREG:x[0-9]+]], w0, w1 749 ; CHECK-NEXT: cmp xzr, [[MREG]], lsr #32 750 ; CHECK-NEXT: b.eq 751 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 752 %val = extractvalue {i32, i1} %t, 0 753 %obit = extractvalue {i32, i1} %t, 1 754 br i1 %obit, label %overflow, label %continue 755 756 overflow: 757 ret i1 false 758 759 continue: 760 ret i1 true 761 } 762 763 define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) { 764 entry: 765 ; CHECK-LABEL: umulo.br.i64 766 ; CHECK: umulh [[REG:x[0-9]+]], x0, x1 767 ; CHECK-NEXT: {{cbz|cmp}} 768 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 769 %val = extractvalue {i64, i1} %t, 0 770 %obit = extractvalue {i64, i1} %t, 1 771 br i1 %obit, label %overflow, label %continue 772 773 overflow: 774 ret i1 false 775 776 continue: 777 ret i1 true 778 } 779 780 define zeroext i1 @umulo2.br.i64(i64 %v1) { 781 entry: 782 ; CHECK-LABEL: umulo2.br.i64 783 ; CHECK: cmn x0, x0 784 ; CHECK-NEXT: b.lo 785 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2) 786 %val = extractvalue {i64, i1} %t, 0 787 %obit = extractvalue {i64, i1} %t, 1 788 br i1 %obit, label %overflow, label %continue 789 790 overflow: 791 ret i1 false 792 793 continue: 794 ret i1 true 795 } 796 797 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone 798 declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone 799 declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone 800 declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone 801 declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone 802 declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone 803 declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone 804 declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone 805 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone 806 declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone 807 declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone 808 declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone 809 810