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