1 ; RUN: llc -march=mips -mcpu=mips32 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC32 -check-prefix=ACC32-TRAP 2 ; RUN: llc -march=mips -mcpu=mips32r2 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC32 -check-prefix=ACC32-TRAP 3 ; RUN: llc -march=mips -mcpu=mips32r6 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=GPR32-TRAP 4 ; RUN: llc -march=mips64 -mcpu=mips64 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC64 -check-prefix=ACC64-TRAP 5 ; RUN: llc -march=mips64 -mcpu=mips64r2 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC64 -check-prefix=ACC64-TRAP 6 ; RUN: llc -march=mips64 -mcpu=mips64r6 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=GPR64-TRAP 7 8 ; RUN: llc -march=mips -mcpu=mips32 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC32 -check-prefix=NOCHECK 9 ; RUN: llc -march=mips -mcpu=mips32r2 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC32 -check-prefix=NOCHECK 10 ; RUN: llc -march=mips -mcpu=mips32r6 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=NOCHECK 11 ; RUN: llc -march=mips64 -mcpu=mips64 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC64 -check-prefix=NOCHECK 12 ; RUN: llc -march=mips64 -mcpu=mips64r2 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC64 -check-prefix=NOCHECK 13 ; RUN: llc -march=mips64 -mcpu=mips64r6 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=NOCHECK 14 15 ; FileCheck Prefixes: 16 ; ALL - All targets 17 ; ACC32 - Accumulator based multiply/divide on 32-bit targets 18 ; ACC64 - Same as ACC32 but only for 64-bit targets 19 ; GPR32 - GPR based multiply/divide on 32-bit targets 20 ; GPR64 - Same as GPR32 but only for 64-bit targets 21 ; ACC32-TRAP - Same as TRAP and ACC32 combined 22 ; ACC64-TRAP - Same as TRAP and ACC64 combined 23 ; GPR32-TRAP - Same as TRAP and GPR32 combined 24 ; GPR64-TRAP - Same as TRAP and GPR64 combined 25 ; NOCHECK - Division by zero will not be detected 26 27 @g0 = common global i32 0, align 4 28 @g1 = common global i32 0, align 4 29 30 define i32 @sdiv1(i32 %a0, i32 %a1) nounwind readnone { 31 entry: 32 ; ALL-LABEL: sdiv1: 33 34 ; ACC32: div $zero, $4, $5 35 ; ACC32-TRAP: teq $5, $zero, 7 36 37 ; ACC64: div $zero, $4, $5 38 ; ACC64-TRAP: teq $5, $zero, 7 39 40 ; GPR32: div $2, $4, $5 41 ; GPR32-TRAP: teq $5, $zero, 7 42 43 ; GPR64: div $2, $4, $5 44 ; GPR64-TRAP: teq $5, $zero, 7 45 46 ; NOCHECK-NOT: teq 47 48 ; ACC32: mflo $2 49 ; ACC64: mflo $2 50 51 ; ALL: .end sdiv1 52 53 %div = sdiv i32 %a0, %a1 54 ret i32 %div 55 } 56 57 define i32 @srem1(i32 %a0, i32 %a1) nounwind readnone { 58 entry: 59 ; ALL-LABEL: srem1: 60 61 ; ACC32: div $zero, $4, $5 62 ; ACC32-TRAP: teq $5, $zero, 7 63 64 ; ACC64: div $zero, $4, $5 65 ; ACC64-TRAP: teq $5, $zero, 7 66 67 ; GPR32: mod $2, $4, $5 68 ; GPR32-TRAP: teq $5, $zero, 7 69 70 ; GPR64: mod $2, $4, $5 71 ; GPR64-TRAP: teq $5, $zero, 7 72 73 ; NOCHECK-NOT: teq 74 75 ; ACC32: mfhi $2 76 ; ACC64: mfhi $2 77 78 ; ALL: .end srem1 79 80 %rem = srem i32 %a0, %a1 81 ret i32 %rem 82 } 83 84 define i32 @udiv1(i32 %a0, i32 %a1) nounwind readnone { 85 entry: 86 ; ALL-LABEL: udiv1: 87 88 ; ACC32: divu $zero, $4, $5 89 ; ACC32-TRAP: teq $5, $zero, 7 90 91 ; ACC64: divu $zero, $4, $5 92 ; ACC64-TRAP: teq $5, $zero, 7 93 94 ; GPR32: divu $2, $4, $5 95 ; GPR32-TRAP: teq $5, $zero, 7 96 97 ; GPR64: divu $2, $4, $5 98 ; GPR64-TRAP: teq $5, $zero, 7 99 100 ; NOCHECK-NOT: teq 101 102 ; ACC32: mflo $2 103 ; ACC64: mflo $2 104 105 ; ALL: .end udiv1 106 %div = udiv i32 %a0, %a1 107 ret i32 %div 108 } 109 110 define i32 @urem1(i32 %a0, i32 %a1) nounwind readnone { 111 entry: 112 ; ALL-LABEL: urem1: 113 114 ; ACC32: divu $zero, $4, $5 115 ; ACC32-TRAP: teq $5, $zero, 7 116 117 ; ACC64: divu $zero, $4, $5 118 ; ACC64-TRAP: teq $5, $zero, 7 119 120 ; GPR32: modu $2, $4, $5 121 ; GPR32-TRAP: teq $5, $zero, 7 122 123 ; GPR64: modu $2, $4, $5 124 ; GPR64-TRAP: teq $5, $zero, 7 125 126 ; NOCHECK-NOT: teq 127 128 ; ACC32: mfhi $2 129 ; ACC64: mfhi $2 130 131 ; ALL: .end urem1 132 133 %rem = urem i32 %a0, %a1 134 ret i32 %rem 135 } 136 137 define i32 @sdivrem1(i32 %a0, i32 %a1, i32* nocapture %r) nounwind { 138 entry: 139 ; ALL-LABEL: sdivrem1: 140 141 ; ACC32: div $zero, $4, $5 142 ; ACC32-TRAP: teq $5, $zero, 7 143 ; NOCHECK-NOT: teq 144 ; ACC32: mflo $2 145 ; ACC32: mfhi $[[R0:[0-9]+]] 146 ; ACC32: sw $[[R0]], 0(${{[0-9]+}}) 147 148 ; ACC64: div $zero, $4, $5 149 ; ACC64-TRAP: teq $5, $zero, 7 150 ; NOCHECK-NOT: teq 151 ; ACC64: mflo $2 152 ; ACC64: mfhi $[[R0:[0-9]+]] 153 ; ACC64: sw $[[R0]], 0(${{[0-9]+}}) 154 155 ; GPR32: mod $[[R0:[0-9]+]], $4, $5 156 ; GPR32-TRAP: teq $5, $zero, 7 157 ; NOCHECK-NOT: teq 158 ; GPR32: sw $[[R0]], 0(${{[0-9]+}}) 159 ; GPR32-DAG: div $2, $4, $5 160 ; GPR32-TRAP: teq $5, $zero, 7 161 162 ; GPR64: mod $[[R0:[0-9]+]], $4, $5 163 ; GPR64-TRAP: teq $5, $zero, 7 164 ; NOCHECK-NOT: teq 165 ; GPR64: sw $[[R0]], 0(${{[0-9]+}}) 166 ; GPR64-DAG: div $2, $4, $5 167 ; GPR64-TRAP: teq $5, $zero, 7 168 ; NOCHECK-NOT: teq 169 170 ; ALL: .end sdivrem1 171 172 %rem = srem i32 %a0, %a1 173 store i32 %rem, i32* %r, align 4 174 %div = sdiv i32 %a0, %a1 175 ret i32 %div 176 } 177 178 define i32 @udivrem1(i32 %a0, i32 %a1, i32* nocapture %r) nounwind { 179 entry: 180 ; ALL-LABEL: udivrem1: 181 182 ; ACC32: divu $zero, $4, $5 183 ; ACC32-TRAP: teq $5, $zero, 7 184 ; NOCHECK-NOT: teq 185 ; ACC32: mflo $2 186 ; ACC32: mfhi $[[R0:[0-9]+]] 187 ; ACC32: sw $[[R0]], 0(${{[0-9]+}}) 188 189 ; ACC64: divu $zero, $4, $5 190 ; ACC64-TRAP: teq $5, $zero, 7 191 ; NOCHECK-NOT: teq 192 ; ACC64: mflo $2 193 ; ACC64: mfhi $[[R0:[0-9]+]] 194 ; ACC64: sw $[[R0]], 0(${{[0-9]+}}) 195 196 ; GPR32: modu $[[R0:[0-9]+]], $4, $5 197 ; GPR32-TRAP: teq $5, $zero, 7 198 ; NOCHECK-NOT: teq 199 ; GPR32: sw $[[R0]], 0(${{[0-9]+}}) 200 ; GPR32-DAG: divu $2, $4, $5 201 ; GPR32-TRAP: teq $5, $zero, 7 202 ; NOCHECK-NOT: teq 203 204 ; GPR64: modu $[[R0:[0-9]+]], $4, $5 205 ; GPR64-TRAP: teq $5, $zero, 7 206 ; NOCHECK-NOT: teq 207 ; GPR64: sw $[[R0]], 0(${{[0-9]+}}) 208 ; GPR64-DAG: divu $2, $4, $5 209 ; GPR64-TRAP: teq $5, $zero, 7 210 ; NOCHECK-NOT: teq 211 212 ; ALL: .end udivrem1 213 214 %rem = urem i32 %a0, %a1 215 store i32 %rem, i32* %r, align 4 216 %div = udiv i32 %a0, %a1 217 ret i32 %div 218 } 219 220 ; FIXME: It's not clear what this is supposed to test. 221 define i32 @killFlags() { 222 entry: 223 %0 = load i32* @g0, align 4 224 %1 = load i32* @g1, align 4 225 %div = sdiv i32 %0, %1 226 ret i32 %div 227 } 228 229 define i64 @sdiv2(i64 %a0, i64 %a1) nounwind readnone { 230 entry: 231 ; ALL-LABEL: sdiv2: 232 233 ; ACC32: lw $25, %call16(__divdi3)( 234 ; ACC32: jalr $25 235 236 ; ACC64: ddiv $zero, $4, $5 237 ; ACC64-TRAP: teq $5, $zero, 7 238 239 ; GPR64: ddiv $2, $4, $5 240 ; GPR64-TRAP: teq $5, $zero, 7 241 242 ; NOCHECK-NOT: teq 243 244 ; ACC64: mflo $2 245 246 ; ALL: .end sdiv2 247 248 %div = sdiv i64 %a0, %a1 249 ret i64 %div 250 } 251 252 define i64 @srem2(i64 %a0, i64 %a1) nounwind readnone { 253 entry: 254 ; ALL-LABEL: srem2: 255 256 ; ACC32: lw $25, %call16(__moddi3)( 257 ; ACC32: jalr $25 258 259 ; ACC64: div $zero, $4, $5 260 ; ACC64-TRAP: teq $5, $zero, 7 261 262 ; GPR64: dmod $2, $4, $5 263 ; GPR64-TRAP: teq $5, $zero, 7 264 265 ; NOCHECK-NOT: teq 266 267 ; ACC64: mfhi $2 268 269 ; ALL: .end srem2 270 271 %rem = srem i64 %a0, %a1 272 ret i64 %rem 273 } 274 275 define i64 @udiv2(i64 %a0, i64 %a1) nounwind readnone { 276 entry: 277 ; ALL-LABEL: udiv2: 278 279 ; ACC32: lw $25, %call16(__udivdi3)( 280 ; ACC32: jalr $25 281 282 ; ACC64: divu $zero, $4, $5 283 ; ACC64-TRAP: teq $5, $zero, 7 284 285 ; GPR64: ddivu $2, $4, $5 286 ; GPR64-TRAP: teq $5, $zero, 7 287 288 ; NOCHECK-NOT: teq 289 290 ; ACC64: mflo $2 291 292 ; ALL: .end udiv2 293 %div = udiv i64 %a0, %a1 294 ret i64 %div 295 } 296 297 define i64 @urem2(i64 %a0, i64 %a1) nounwind readnone { 298 entry: 299 ; ALL-LABEL: urem2: 300 301 ; ACC32: lw $25, %call16(__umoddi3)( 302 ; ACC32: jalr $25 303 304 ; ACC64: divu $zero, $4, $5 305 ; ACC64-TRAP: teq $5, $zero, 7 306 307 ; GPR64: dmodu $2, $4, $5 308 ; GPR64-TRAP: teq $5, $zero, 7 309 310 ; NOCHECK-NOT: teq 311 312 ; ACC64: mfhi $2 313 314 ; ALL: .end urem2 315 316 %rem = urem i64 %a0, %a1 317 ret i64 %rem 318 } 319 320 define i64 @sdivrem2(i64 %a0, i64 %a1, i64* nocapture %r) nounwind { 321 entry: 322 ; ALL-LABEL: sdivrem2: 323 324 ; sdivrem2 is too complex to effectively check. We can at least check for the 325 ; calls though. 326 ; ACC32: lw $25, %call16(__moddi3)( 327 ; ACC32: jalr $25 328 ; ACC32: lw $25, %call16(__divdi3)( 329 ; ACC32: jalr $25 330 331 ; ACC64: ddiv $zero, $4, $5 332 ; ACC64-TRAP: teq $5, $zero, 7 333 ; NOCHECK-NOT: teq 334 ; ACC64: mflo $2 335 ; ACC64: mfhi $[[R0:[0-9]+]] 336 ; ACC64: sd $[[R0]], 0(${{[0-9]+}}) 337 338 ; GPR64: dmod $[[R0:[0-9]+]], $4, $5 339 ; GPR64-TRAP: teq $5, $zero, 7 340 ; NOCHECK-NOT: teq 341 ; GPR64: sd $[[R0]], 0(${{[0-9]+}}) 342 343 ; GPR64-DAG: ddiv $2, $4, $5 344 ; GPR64-TRAP: teq $5, $zero, 7 345 ; NOCHECK-NOT: teq 346 347 ; ALL: .end sdivrem2 348 349 %rem = srem i64 %a0, %a1 350 store i64 %rem, i64* %r, align 8 351 %div = sdiv i64 %a0, %a1 352 ret i64 %div 353 } 354 355 define i64 @udivrem2(i64 %a0, i64 %a1, i64* nocapture %r) nounwind { 356 entry: 357 ; ALL-LABEL: udivrem2: 358 359 ; udivrem2 is too complex to effectively check. We can at least check for the 360 ; calls though. 361 ; ACC32: lw $25, %call16(__umoddi3)( 362 ; ACC32: jalr $25 363 ; ACC32: lw $25, %call16(__udivdi3)( 364 ; ACC32: jalr $25 365 366 ; ACC64: ddivu $zero, $4, $5 367 ; ACC64-TRAP: teq $5, $zero, 7 368 ; NOCHECK-NOT: teq 369 ; ACC64: mflo $2 370 ; ACC64: mfhi $[[R0:[0-9]+]] 371 ; ACC64: sd $[[R0]], 0(${{[0-9]+}}) 372 373 ; GPR64: dmodu $[[R0:[0-9]+]], $4, $5 374 ; GPR64-TRAP: teq $5, $zero, 7 375 ; NOCHECK-NOT: teq 376 ; GPR64: sd $[[R0]], 0(${{[0-9]+}}) 377 378 ; GPR64-DAG: ddivu $2, $4, $5 379 ; GPR64-TRAP: teq $5, $zero, 7 380 ; NOCHECK-NOT: teq 381 382 ; ALL: .end udivrem2 383 384 %rem = urem i64 %a0, %a1 385 store i64 %rem, i64* %r, align 8 386 %div = udiv i64 %a0, %a1 387 ret i64 %div 388 } 389