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