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