Home | History | Annotate | Download | only in X86
      1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
      2 ; Check that 32-bit division is bypassed correctly.
      3 ; RUN: llc < %s -mattr=+idivl-to-divb -mtriple=i686-linux | FileCheck %s
      4 
      5 define i32 @Test_get_quotient(i32 %a, i32 %b) nounwind {
      6 ; CHECK-LABEL: Test_get_quotient:
      7 ; CHECK:       # %bb.0:
      8 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
      9 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
     10 ; CHECK-NEXT:    movl %eax, %edx
     11 ; CHECK-NEXT:    orl %ecx, %edx
     12 ; CHECK-NEXT:    testl $-256, %edx
     13 ; CHECK-NEXT:    je .LBB0_1
     14 ; CHECK-NEXT:  # %bb.2:
     15 ; CHECK-NEXT:    cltd
     16 ; CHECK-NEXT:    idivl %ecx
     17 ; CHECK-NEXT:    retl
     18 ; CHECK-NEXT:  .LBB0_1:
     19 ; CHECK-NEXT:    movzbl %al, %eax
     20 ; CHECK-NEXT:    # kill: def $eax killed $eax def $ax
     21 ; CHECK-NEXT:    divb %cl
     22 ; CHECK-NEXT:    movzbl %al, %eax
     23 ; CHECK-NEXT:    retl
     24   %result = sdiv i32 %a, %b
     25   ret i32 %result
     26 }
     27 
     28 define i32 @Test_get_remainder(i32 %a, i32 %b) nounwind {
     29 ; CHECK-LABEL: Test_get_remainder:
     30 ; CHECK:       # %bb.0:
     31 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
     32 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
     33 ; CHECK-NEXT:    movl %eax, %edx
     34 ; CHECK-NEXT:    orl %ecx, %edx
     35 ; CHECK-NEXT:    testl $-256, %edx
     36 ; CHECK-NEXT:    je .LBB1_1
     37 ; CHECK-NEXT:  # %bb.2:
     38 ; CHECK-NEXT:    cltd
     39 ; CHECK-NEXT:    idivl %ecx
     40 ; CHECK-NEXT:    movl %edx, %eax
     41 ; CHECK-NEXT:    retl
     42 ; CHECK-NEXT:  .LBB1_1:
     43 ; CHECK-NEXT:    movzbl %al, %eax
     44 ; CHECK-NEXT:    # kill: def $eax killed $eax def $ax
     45 ; CHECK-NEXT:    divb %cl
     46 ; CHECK-NEXT:    movzbl %ah, %eax
     47 ; CHECK-NEXT:    retl
     48   %result = srem i32 %a, %b
     49   ret i32 %result
     50 }
     51 
     52 define i32 @Test_get_quotient_and_remainder(i32 %a, i32 %b) nounwind {
     53 ; CHECK-LABEL: Test_get_quotient_and_remainder:
     54 ; CHECK:       # %bb.0:
     55 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
     56 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
     57 ; CHECK-NEXT:    movl %eax, %edx
     58 ; CHECK-NEXT:    orl %ecx, %edx
     59 ; CHECK-NEXT:    testl $-256, %edx
     60 ; CHECK-NEXT:    je .LBB2_1
     61 ; CHECK-NEXT:  # %bb.2:
     62 ; CHECK-NEXT:    cltd
     63 ; CHECK-NEXT:    idivl %ecx
     64 ; CHECK-NEXT:    addl %edx, %eax
     65 ; CHECK-NEXT:    retl
     66 ; CHECK-NEXT:  .LBB2_1:
     67 ; CHECK-NEXT:    movzbl %al, %eax
     68 ; CHECK-NEXT:    # kill: def $eax killed $eax def $ax
     69 ; CHECK-NEXT:    divb %cl
     70 ; CHECK-NEXT:    movzbl %ah, %edx
     71 ; CHECK-NEXT:    movzbl %al, %eax
     72 ; CHECK-NEXT:    addl %edx, %eax
     73 ; CHECK-NEXT:    retl
     74   %resultdiv = sdiv i32 %a, %b
     75   %resultrem = srem i32 %a, %b
     76   %result = add i32 %resultdiv, %resultrem
     77   ret i32 %result
     78 }
     79 
     80 define i32 @Test_use_div_and_idiv(i32 %a, i32 %b) nounwind {
     81 ; CHECK-LABEL: Test_use_div_and_idiv:
     82 ; CHECK:       # %bb.0:
     83 ; CHECK-NEXT:    pushl %ebx
     84 ; CHECK-NEXT:    pushl %edi
     85 ; CHECK-NEXT:    pushl %esi
     86 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ebx
     87 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
     88 ; CHECK-NEXT:    movl %ecx, %edi
     89 ; CHECK-NEXT:    orl %ebx, %edi
     90 ; CHECK-NEXT:    testl $-256, %edi
     91 ; CHECK-NEXT:    je .LBB3_1
     92 ; CHECK-NEXT:  # %bb.2:
     93 ; CHECK-NEXT:    movl %ecx, %eax
     94 ; CHECK-NEXT:    cltd
     95 ; CHECK-NEXT:    idivl %ebx
     96 ; CHECK-NEXT:    movl %eax, %esi
     97 ; CHECK-NEXT:    testl $-256, %edi
     98 ; CHECK-NEXT:    je .LBB3_4
     99 ; CHECK-NEXT:  .LBB3_5:
    100 ; CHECK-NEXT:    xorl %edx, %edx
    101 ; CHECK-NEXT:    movl %ecx, %eax
    102 ; CHECK-NEXT:    divl %ebx
    103 ; CHECK-NEXT:    jmp .LBB3_6
    104 ; CHECK-NEXT:  .LBB3_1:
    105 ; CHECK-NEXT:    movzbl %cl, %eax
    106 ; CHECK-NEXT:    # kill: def $eax killed $eax def $ax
    107 ; CHECK-NEXT:    divb %bl
    108 ; CHECK-NEXT:    movzbl %al, %esi
    109 ; CHECK-NEXT:    testl $-256, %edi
    110 ; CHECK-NEXT:    jne .LBB3_5
    111 ; CHECK-NEXT:  .LBB3_4:
    112 ; CHECK-NEXT:    movzbl %cl, %eax
    113 ; CHECK-NEXT:    # kill: def $eax killed $eax def $ax
    114 ; CHECK-NEXT:    divb %bl
    115 ; CHECK-NEXT:    movzbl %al, %eax
    116 ; CHECK-NEXT:  .LBB3_6:
    117 ; CHECK-NEXT:    addl %eax, %esi
    118 ; CHECK-NEXT:    movl %esi, %eax
    119 ; CHECK-NEXT:    popl %esi
    120 ; CHECK-NEXT:    popl %edi
    121 ; CHECK-NEXT:    popl %ebx
    122 ; CHECK-NEXT:    retl
    123   %resultidiv = sdiv i32 %a, %b
    124   %resultdiv = udiv i32 %a, %b
    125   %result = add i32 %resultidiv, %resultdiv
    126   ret i32 %result
    127 }
    128 
    129 define i32 @Test_use_div_imm_imm() nounwind {
    130 ; CHECK-LABEL: Test_use_div_imm_imm:
    131 ; CHECK:       # %bb.0:
    132 ; CHECK-NEXT:    movl $64, %eax
    133 ; CHECK-NEXT:    retl
    134   %resultdiv = sdiv i32 256, 4
    135   ret i32 %resultdiv
    136 }
    137 
    138 define i32 @Test_use_div_reg_imm(i32 %a) nounwind {
    139 ; CHECK-LABEL: Test_use_div_reg_imm:
    140 ; CHECK:       # %bb.0:
    141 ; CHECK-NEXT:    movl $1041204193, %eax # imm = 0x3E0F83E1
    142 ; CHECK-NEXT:    imull {{[0-9]+}}(%esp)
    143 ; CHECK-NEXT:    movl %edx, %eax
    144 ; CHECK-NEXT:    shrl $31, %eax
    145 ; CHECK-NEXT:    sarl $3, %edx
    146 ; CHECK-NEXT:    leal (%edx,%eax), %eax
    147 ; CHECK-NEXT:    retl
    148   %resultdiv = sdiv i32 %a, 33
    149   ret i32 %resultdiv
    150 }
    151 
    152 define i32 @Test_use_rem_reg_imm(i32 %a) nounwind {
    153 ; CHECK-LABEL: Test_use_rem_reg_imm:
    154 ; CHECK:       # %bb.0:
    155 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
    156 ; CHECK-NEXT:    movl $1041204193, %edx # imm = 0x3E0F83E1
    157 ; CHECK-NEXT:    movl %ecx, %eax
    158 ; CHECK-NEXT:    imull %edx
    159 ; CHECK-NEXT:    movl %edx, %eax
    160 ; CHECK-NEXT:    shrl $31, %eax
    161 ; CHECK-NEXT:    sarl $3, %edx
    162 ; CHECK-NEXT:    addl %eax, %edx
    163 ; CHECK-NEXT:    movl %edx, %eax
    164 ; CHECK-NEXT:    shll $5, %eax
    165 ; CHECK-NEXT:    addl %edx, %eax
    166 ; CHECK-NEXT:    subl %eax, %ecx
    167 ; CHECK-NEXT:    movl %ecx, %eax
    168 ; CHECK-NEXT:    retl
    169   %resultrem = srem i32 %a, 33
    170   ret i32 %resultrem
    171 }
    172 
    173 define i32 @Test_use_divrem_reg_imm(i32 %a) nounwind {
    174 ; CHECK-LABEL: Test_use_divrem_reg_imm:
    175 ; CHECK:       # %bb.0:
    176 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
    177 ; CHECK-NEXT:    movl $1041204193, %edx # imm = 0x3E0F83E1
    178 ; CHECK-NEXT:    movl %ecx, %eax
    179 ; CHECK-NEXT:    imull %edx
    180 ; CHECK-NEXT:    movl %edx, %eax
    181 ; CHECK-NEXT:    shrl $31, %eax
    182 ; CHECK-NEXT:    sarl $3, %edx
    183 ; CHECK-NEXT:    addl %eax, %edx
    184 ; CHECK-NEXT:    movl %edx, %eax
    185 ; CHECK-NEXT:    shll $5, %eax
    186 ; CHECK-NEXT:    addl %edx, %eax
    187 ; CHECK-NEXT:    subl %eax, %ecx
    188 ; CHECK-NEXT:    addl %edx, %ecx
    189 ; CHECK-NEXT:    movl %ecx, %eax
    190 ; CHECK-NEXT:    retl
    191   %resultdiv = sdiv i32 %a, 33
    192   %resultrem = srem i32 %a, 33
    193   %result = add i32 %resultdiv, %resultrem
    194   ret i32 %result
    195 }
    196 
    197 define i32 @Test_use_div_imm_reg(i32 %a) nounwind {
    198 ; CHECK-LABEL: Test_use_div_imm_reg:
    199 ; CHECK:       # %bb.0:
    200 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
    201 ; CHECK-NEXT:    testl $-256, %ecx
    202 ; CHECK-NEXT:    je .LBB8_1
    203 ; CHECK-NEXT:  # %bb.2:
    204 ; CHECK-NEXT:    movl $4, %eax
    205 ; CHECK-NEXT:    xorl %edx, %edx
    206 ; CHECK-NEXT:    idivl %ecx
    207 ; CHECK-NEXT:    retl
    208 ; CHECK-NEXT:  .LBB8_1:
    209 ; CHECK-NEXT:    movb $4, %al
    210 ; CHECK-NEXT:    movzbl %al, %eax
    211 ; CHECK-NEXT:    # kill: def $eax killed $eax def $ax
    212 ; CHECK-NEXT:    divb %cl
    213 ; CHECK-NEXT:    movzbl %al, %eax
    214 ; CHECK-NEXT:    retl
    215   %resultdiv = sdiv i32 4, %a
    216   ret i32 %resultdiv
    217 }
    218 
    219 define i32 @Test_use_rem_imm_reg(i32 %a) nounwind {
    220 ; CHECK-LABEL: Test_use_rem_imm_reg:
    221 ; CHECK:       # %bb.0:
    222 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
    223 ; CHECK-NEXT:    testl $-256, %ecx
    224 ; CHECK-NEXT:    je .LBB9_1
    225 ; CHECK-NEXT:  # %bb.2:
    226 ; CHECK-NEXT:    movl $4, %eax
    227 ; CHECK-NEXT:    xorl %edx, %edx
    228 ; CHECK-NEXT:    idivl %ecx
    229 ; CHECK-NEXT:    retl
    230 ; CHECK-NEXT:  .LBB9_1:
    231 ; CHECK-NEXT:    movb $4, %al
    232 ; CHECK-NEXT:    movzbl %al, %eax
    233 ; CHECK-NEXT:    # kill: def $eax killed $eax def $ax
    234 ; CHECK-NEXT:    divb %cl
    235 ; CHECK-NEXT:    movzbl %al, %eax
    236 ; CHECK-NEXT:    retl
    237   %resultdiv = sdiv i32 4, %a
    238   ret i32 %resultdiv
    239 }
    240