Home | History | Annotate | Download | only in X86
      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