Home | History | Annotate | Download | only in X86
      1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
      2 ; RUN: llc < %s -mtriple=i686-unknown | FileCheck %s --check-prefix=X86
      3 ; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s  --check-prefix=X64
      4 
      5 ; Shift i64 integers on 32-bit target
      6 
      7 define i64 @test1(i64 %X, i8 %C) nounwind {
      8 ; X86-LABEL: test1:
      9 ; X86:       # %bb.0:
     10 ; X86-NEXT:    pushl %esi
     11 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
     12 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
     13 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
     14 ; X86-NEXT:    movl %esi, %eax
     15 ; X86-NEXT:    shll %cl, %eax
     16 ; X86-NEXT:    shldl %cl, %esi, %edx
     17 ; X86-NEXT:    testb $32, %cl
     18 ; X86-NEXT:    je .LBB0_2
     19 ; X86-NEXT:  # %bb.1:
     20 ; X86-NEXT:    movl %eax, %edx
     21 ; X86-NEXT:    xorl %eax, %eax
     22 ; X86-NEXT:  .LBB0_2:
     23 ; X86-NEXT:    popl %esi
     24 ; X86-NEXT:    retl
     25 ;
     26 ; X64-LABEL: test1:
     27 ; X64:       # %bb.0:
     28 ; X64-NEXT:    movl %esi, %ecx
     29 ; X64-NEXT:    shlq %cl, %rdi
     30 ; X64-NEXT:    movq %rdi, %rax
     31 ; X64-NEXT:    retq
     32         %shift.upgrd.1 = zext i8 %C to i64              ; <i64> [#uses=1]
     33         %Y = shl i64 %X, %shift.upgrd.1         ; <i64> [#uses=1]
     34         ret i64 %Y
     35 }
     36 
     37 define i64 @test2(i64 %X, i8 %C) nounwind {
     38 ; X86-LABEL: test2:
     39 ; X86:       # %bb.0:
     40 ; X86-NEXT:    pushl %esi
     41 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
     42 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
     43 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
     44 ; X86-NEXT:    movl %esi, %edx
     45 ; X86-NEXT:    sarl %cl, %edx
     46 ; X86-NEXT:    shrdl %cl, %esi, %eax
     47 ; X86-NEXT:    testb $32, %cl
     48 ; X86-NEXT:    je .LBB1_2
     49 ; X86-NEXT:  # %bb.1:
     50 ; X86-NEXT:    sarl $31, %esi
     51 ; X86-NEXT:    movl %edx, %eax
     52 ; X86-NEXT:    movl %esi, %edx
     53 ; X86-NEXT:  .LBB1_2:
     54 ; X86-NEXT:    popl %esi
     55 ; X86-NEXT:    retl
     56 ;
     57 ; X64-LABEL: test2:
     58 ; X64:       # %bb.0:
     59 ; X64-NEXT:    movl %esi, %ecx
     60 ; X64-NEXT:    sarq %cl, %rdi
     61 ; X64-NEXT:    movq %rdi, %rax
     62 ; X64-NEXT:    retq
     63         %shift.upgrd.2 = zext i8 %C to i64              ; <i64> [#uses=1]
     64         %Y = ashr i64 %X, %shift.upgrd.2                ; <i64> [#uses=1]
     65         ret i64 %Y
     66 }
     67 
     68 define i64 @test3(i64 %X, i8 %C) nounwind {
     69 ; X86-LABEL: test3:
     70 ; X86:       # %bb.0:
     71 ; X86-NEXT:    pushl %esi
     72 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
     73 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
     74 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
     75 ; X86-NEXT:    movl %esi, %edx
     76 ; X86-NEXT:    shrl %cl, %edx
     77 ; X86-NEXT:    shrdl %cl, %esi, %eax
     78 ; X86-NEXT:    testb $32, %cl
     79 ; X86-NEXT:    je .LBB2_2
     80 ; X86-NEXT:  # %bb.1:
     81 ; X86-NEXT:    movl %edx, %eax
     82 ; X86-NEXT:    xorl %edx, %edx
     83 ; X86-NEXT:  .LBB2_2:
     84 ; X86-NEXT:    popl %esi
     85 ; X86-NEXT:    retl
     86 ;
     87 ; X64-LABEL: test3:
     88 ; X64:       # %bb.0:
     89 ; X64-NEXT:    movl %esi, %ecx
     90 ; X64-NEXT:    shrq %cl, %rdi
     91 ; X64-NEXT:    movq %rdi, %rax
     92 ; X64-NEXT:    retq
     93         %shift.upgrd.3 = zext i8 %C to i64              ; <i64> [#uses=1]
     94         %Y = lshr i64 %X, %shift.upgrd.3                ; <i64> [#uses=1]
     95         ret i64 %Y
     96 }
     97 
     98 ; Combine 2xi32/2xi16 shifts into SHLD
     99 
    100 define i32 @test4(i32 %A, i32 %B, i8 %C) nounwind {
    101 ; X86-LABEL: test4:
    102 ; X86:       # %bb.0:
    103 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
    104 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
    105 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
    106 ; X86-NEXT:    shldl %cl, %edx, %eax
    107 ; X86-NEXT:    retl
    108 ;
    109 ; X64-LABEL: test4:
    110 ; X64:       # %bb.0:
    111 ; X64-NEXT:    movl %edx, %ecx
    112 ; X64-NEXT:    shldl %cl, %esi, %edi
    113 ; X64-NEXT:    movl %edi, %eax
    114 ; X64-NEXT:    retq
    115         %shift.upgrd.4 = zext i8 %C to i32              ; <i32> [#uses=1]
    116         %X = shl i32 %A, %shift.upgrd.4         ; <i32> [#uses=1]
    117         %Cv = sub i8 32, %C             ; <i8> [#uses=1]
    118         %shift.upgrd.5 = zext i8 %Cv to i32             ; <i32> [#uses=1]
    119         %Y = lshr i32 %B, %shift.upgrd.5                ; <i32> [#uses=1]
    120         %Z = or i32 %Y, %X              ; <i32> [#uses=1]
    121         ret i32 %Z
    122 }
    123 
    124 define i16 @test5(i16 %A, i16 %B, i8 %C) nounwind {
    125 ; X86-LABEL: test5:
    126 ; X86:       # %bb.0:
    127 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
    128 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
    129 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
    130 ; X86-NEXT:    shldw %cl, %dx, %ax
    131 ; X86-NEXT:    retl
    132 ;
    133 ; X64-LABEL: test5:
    134 ; X64:       # %bb.0:
    135 ; X64-NEXT:    movl %edx, %ecx
    136 ; X64-NEXT:    shldw %cl, %si, %di
    137 ; X64-NEXT:    movl %edi, %eax
    138 ; X64-NEXT:    retq
    139         %shift.upgrd.6 = zext i8 %C to i16              ; <i16> [#uses=1]
    140         %X = shl i16 %A, %shift.upgrd.6         ; <i16> [#uses=1]
    141         %Cv = sub i8 16, %C             ; <i8> [#uses=1]
    142         %shift.upgrd.7 = zext i8 %Cv to i16             ; <i16> [#uses=1]
    143         %Y = lshr i16 %B, %shift.upgrd.7                ; <i16> [#uses=1]
    144         %Z = or i16 %Y, %X              ; <i16> [#uses=1]
    145         ret i16 %Z
    146 }
    147 
    148 ; Combine 2xi32/2xi16 shifts into SHRD
    149 
    150 define i32 @test6(i32 %A, i32 %B, i8 %C) nounwind {
    151 ; X86-LABEL: test6:
    152 ; X86:       # %bb.0:
    153 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
    154 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
    155 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
    156 ; X86-NEXT:    shrdl %cl, %edx, %eax
    157 ; X86-NEXT:    retl
    158 ;
    159 ; X64-LABEL: test6:
    160 ; X64:       # %bb.0:
    161 ; X64-NEXT:    movl %edx, %ecx
    162 ; X64-NEXT:    shrdl %cl, %esi, %edi
    163 ; X64-NEXT:    movl %edi, %eax
    164 ; X64-NEXT:    retq
    165         %shift.upgrd.4 = zext i8 %C to i32              ; <i32> [#uses=1]
    166         %X = lshr i32 %A, %shift.upgrd.4         ; <i32> [#uses=1]
    167         %Cv = sub i8 32, %C             ; <i8> [#uses=1]
    168         %shift.upgrd.5 = zext i8 %Cv to i32             ; <i32> [#uses=1]
    169         %Y = shl i32 %B, %shift.upgrd.5                ; <i32> [#uses=1]
    170         %Z = or i32 %Y, %X              ; <i32> [#uses=1]
    171         ret i32 %Z
    172 }
    173 
    174 define i16 @test7(i16 %A, i16 %B, i8 %C) nounwind {
    175 ; X86-LABEL: test7:
    176 ; X86:       # %bb.0:
    177 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
    178 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
    179 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
    180 ; X86-NEXT:    shrdw %cl, %dx, %ax
    181 ; X86-NEXT:    retl
    182 ;
    183 ; X64-LABEL: test7:
    184 ; X64:       # %bb.0:
    185 ; X64-NEXT:    movl %edx, %ecx
    186 ; X64-NEXT:    shrdw %cl, %si, %di
    187 ; X64-NEXT:    movl %edi, %eax
    188 ; X64-NEXT:    retq
    189         %shift.upgrd.6 = zext i8 %C to i16              ; <i16> [#uses=1]
    190         %X = lshr i16 %A, %shift.upgrd.6         ; <i16> [#uses=1]
    191         %Cv = sub i8 16, %C             ; <i8> [#uses=1]
    192         %shift.upgrd.7 = zext i8 %Cv to i16             ; <i16> [#uses=1]
    193         %Y = shl i16 %B, %shift.upgrd.7                ; <i16> [#uses=1]
    194         %Z = or i16 %Y, %X              ; <i16> [#uses=1]
    195         ret i16 %Z
    196 }
    197 
    198 ; Shift i64 integers on 32-bit target by shift value less then 32 (PR14593)
    199 
    200 define i64 @test8(i64 %val, i32 %bits) nounwind {
    201 ; X86-LABEL: test8:
    202 ; X86:       # %bb.0:
    203 ; X86-NEXT:    pushl %esi
    204 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
    205 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
    206 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
    207 ; X86-NEXT:    movl %esi, %eax
    208 ; X86-NEXT:    shll %cl, %eax
    209 ; X86-NEXT:    shldl %cl, %esi, %edx
    210 ; X86-NEXT:    popl %esi
    211 ; X86-NEXT:    retl
    212 ;
    213 ; X64-LABEL: test8:
    214 ; X64:       # %bb.0:
    215 ; X64-NEXT:    andb $31, %sil
    216 ; X64-NEXT:    movl %esi, %ecx
    217 ; X64-NEXT:    shlq %cl, %rdi
    218 ; X64-NEXT:    movq %rdi, %rax
    219 ; X64-NEXT:    retq
    220   %and = and i32 %bits, 31
    221   %sh_prom = zext i32 %and to i64
    222   %shl = shl i64 %val, %sh_prom
    223   ret i64 %shl
    224 }
    225 
    226 define i64 @test9(i64 %val, i32 %bits) nounwind {
    227 ; X86-LABEL: test9:
    228 ; X86:       # %bb.0:
    229 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
    230 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
    231 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
    232 ; X86-NEXT:    shrdl %cl, %edx, %eax
    233 ; X86-NEXT:    sarl %cl, %edx
    234 ; X86-NEXT:    retl
    235 ;
    236 ; X64-LABEL: test9:
    237 ; X64:       # %bb.0:
    238 ; X64-NEXT:    andb $31, %sil
    239 ; X64-NEXT:    movl %esi, %ecx
    240 ; X64-NEXT:    sarq %cl, %rdi
    241 ; X64-NEXT:    movq %rdi, %rax
    242 ; X64-NEXT:    retq
    243   %and = and i32 %bits, 31
    244   %sh_prom = zext i32 %and to i64
    245   %ashr = ashr i64 %val, %sh_prom
    246   ret i64 %ashr
    247 }
    248 
    249 define i64 @test10(i64 %val, i32 %bits) nounwind {
    250 ; X86-LABEL: test10:
    251 ; X86:       # %bb.0:
    252 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
    253 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
    254 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
    255 ; X86-NEXT:    shrdl %cl, %edx, %eax
    256 ; X86-NEXT:    shrl %cl, %edx
    257 ; X86-NEXT:    retl
    258 ;
    259 ; X64-LABEL: test10:
    260 ; X64:       # %bb.0:
    261 ; X64-NEXT:    andb $31, %sil
    262 ; X64-NEXT:    movl %esi, %ecx
    263 ; X64-NEXT:    shrq %cl, %rdi
    264 ; X64-NEXT:    movq %rdi, %rax
    265 ; X64-NEXT:    retq
    266   %and = and i32 %bits, 31
    267   %sh_prom = zext i32 %and to i64
    268   %lshr = lshr i64 %val, %sh_prom
    269   ret i64 %lshr
    270 }
    271 
    272 ; SHLD/SHRD manual shifts
    273 
    274 define i32 @test11(i32 %hi, i32 %lo, i32 %bits) nounwind {
    275 ; X86-LABEL: test11:
    276 ; X86:       # %bb.0:
    277 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
    278 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
    279 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
    280 ; X86-NEXT:    andl $31, %ecx
    281 ; X86-NEXT:    # kill: def $cl killed $cl killed $ecx
    282 ; X86-NEXT:    shldl %cl, %edx, %eax
    283 ; X86-NEXT:    retl
    284 ;
    285 ; X64-LABEL: test11:
    286 ; X64:       # %bb.0:
    287 ; X64-NEXT:    andl $31, %edx
    288 ; X64-NEXT:    movl %edx, %ecx
    289 ; X64-NEXT:    shldl %cl, %esi, %edi
    290 ; X64-NEXT:    movl %edi, %eax
    291 ; X64-NEXT:    retq
    292   %and = and i32 %bits, 31
    293   %and32 = sub i32 32, %and
    294   %sh_lo = lshr i32 %lo, %and32
    295   %sh_hi = shl i32 %hi, %and
    296   %sh = or i32 %sh_lo, %sh_hi
    297   ret i32 %sh
    298 }
    299 
    300 define i32 @test12(i32 %hi, i32 %lo, i32 %bits) nounwind {
    301 ; X86-LABEL: test12:
    302 ; X86:       # %bb.0:
    303 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
    304 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
    305 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
    306 ; X86-NEXT:    andl $31, %ecx
    307 ; X86-NEXT:    # kill: def $cl killed $cl killed $ecx
    308 ; X86-NEXT:    shrdl %cl, %edx, %eax
    309 ; X86-NEXT:    retl
    310 ;
    311 ; X64-LABEL: test12:
    312 ; X64:       # %bb.0:
    313 ; X64-NEXT:    andl $31, %edx
    314 ; X64-NEXT:    movl %edx, %ecx
    315 ; X64-NEXT:    shrdl %cl, %edi, %esi
    316 ; X64-NEXT:    movl %esi, %eax
    317 ; X64-NEXT:    retq
    318   %and = and i32 %bits, 31
    319   %and32 = sub i32 32, %and
    320   %sh_lo = shl i32 %hi, %and32
    321   %sh_hi = lshr i32 %lo, %and
    322   %sh = or i32 %sh_lo, %sh_hi
    323   ret i32 %sh
    324 }
    325 
    326 define i32 @test13(i32 %hi, i32 %lo, i32 %bits) nounwind {
    327 ; X86-LABEL: test13:
    328 ; X86:       # %bb.0:
    329 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
    330 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
    331 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
    332 ; X86-NEXT:    shldl %cl, %edx, %eax
    333 ; X86-NEXT:    retl
    334 ;
    335 ; X64-LABEL: test13:
    336 ; X64:       # %bb.0:
    337 ; X64-NEXT:    movl %edx, %ecx
    338 ; X64-NEXT:    shldl %cl, %esi, %edi
    339 ; X64-NEXT:    movl %edi, %eax
    340 ; X64-NEXT:    retq
    341   %bits32 = sub i32 32, %bits
    342   %sh_lo = lshr i32 %lo, %bits32
    343   %sh_hi = shl i32 %hi, %bits
    344   %sh = or i32 %sh_lo, %sh_hi
    345   ret i32 %sh
    346 }
    347 
    348 define i32 @test14(i32 %hi, i32 %lo, i32 %bits) nounwind {
    349 ; X86-LABEL: test14:
    350 ; X86:       # %bb.0:
    351 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
    352 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
    353 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
    354 ; X86-NEXT:    shrdl %cl, %edx, %eax
    355 ; X86-NEXT:    retl
    356 ;
    357 ; X64-LABEL: test14:
    358 ; X64:       # %bb.0:
    359 ; X64-NEXT:    movl %edx, %ecx
    360 ; X64-NEXT:    shrdl %cl, %edi, %esi
    361 ; X64-NEXT:    movl %esi, %eax
    362 ; X64-NEXT:    retq
    363   %bits32 = sub i32 32, %bits
    364   %sh_lo = shl i32 %hi, %bits32
    365   %sh_hi = lshr i32 %lo, %bits
    366   %sh = or i32 %sh_lo, %sh_hi
    367   ret i32 %sh
    368 }
    369 
    370 define i32 @test15(i32 %hi, i32 %lo, i32 %bits) nounwind {
    371 ; X86-LABEL: test15:
    372 ; X86:       # %bb.0:
    373 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
    374 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
    375 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
    376 ; X86-NEXT:    shldl %cl, %edx, %eax
    377 ; X86-NEXT:    retl
    378 ;
    379 ; X64-LABEL: test15:
    380 ; X64:       # %bb.0:
    381 ; X64-NEXT:    movl %edx, %ecx
    382 ; X64-NEXT:    shldl %cl, %esi, %edi
    383 ; X64-NEXT:    movl %edi, %eax
    384 ; X64-NEXT:    retq
    385   %bits32 = xor i32 %bits, 31
    386   %lo2 = lshr i32 %lo, 1
    387   %sh_lo = lshr i32 %lo2, %bits32
    388   %sh_hi = shl i32 %hi, %bits
    389   %sh = or i32 %sh_lo, %sh_hi
    390   ret i32 %sh
    391 }
    392 
    393 define i32 @test16(i32 %hi, i32 %lo, i32 %bits) nounwind {
    394 ; X86-LABEL: test16:
    395 ; X86:       # %bb.0:
    396 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
    397 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
    398 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
    399 ; X86-NEXT:    shrdl %cl, %edx, %eax
    400 ; X86-NEXT:    retl
    401 ;
    402 ; X64-LABEL: test16:
    403 ; X64:       # %bb.0:
    404 ; X64-NEXT:    movl %edx, %ecx
    405 ; X64-NEXT:    shrdl %cl, %esi, %edi
    406 ; X64-NEXT:    movl %edi, %eax
    407 ; X64-NEXT:    retq
    408   %bits32 = xor i32 %bits, 31
    409   %lo2 = shl i32 %lo, 1
    410   %sh_lo = shl i32 %lo2, %bits32
    411   %sh_hi = lshr i32 %hi, %bits
    412   %sh = or i32 %sh_lo, %sh_hi
    413   ret i32 %sh
    414 }
    415 
    416 define i32 @test17(i32 %hi, i32 %lo, i32 %bits) nounwind {
    417 ; X86-LABEL: test17:
    418 ; X86:       # %bb.0:
    419 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
    420 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
    421 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
    422 ; X86-NEXT:    shrdl %cl, %edx, %eax
    423 ; X86-NEXT:    retl
    424 ;
    425 ; X64-LABEL: test17:
    426 ; X64:       # %bb.0:
    427 ; X64-NEXT:    movl %edx, %ecx
    428 ; X64-NEXT:    shrdl %cl, %esi, %edi
    429 ; X64-NEXT:    movl %edi, %eax
    430 ; X64-NEXT:    retq
    431   %bits32 = xor i32 %bits, 31
    432   %lo2 = add i32 %lo, %lo
    433   %sh_lo = shl i32 %lo2, %bits32
    434   %sh_hi = lshr i32 %hi, %bits
    435   %sh = or i32 %sh_lo, %sh_hi
    436   ret i32 %sh
    437 }
    438