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 30define i32 @sdiv1(i32 signext %a0, i32 signext %a1) nounwind readnone { 31entry: 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 57define i32 @srem1(i32 signext %a0, i32 signext %a1) nounwind readnone { 58entry: 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 84define i32 @udiv1(i32 zeroext %a0, i32 zeroext %a1) nounwind readnone { 85entry: 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 110define i32 @urem1(i32 zeroext %a0, i32 zeroext %a1) nounwind readnone { 111entry: 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 137define i32 @sdivrem1(i32 signext %a0, i32 signext %a1, i32* nocapture %r) nounwind { 138entry: 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 178define i32 @udivrem1(i32 zeroext %a0, i32 zeroext %a1, i32* nocapture %r) nounwind { 179entry: 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. 221define i32 @killFlags() { 222entry: 223 %0 = load i32, i32* @g0, align 4 224 %1 = load i32, i32* @g1, align 4 225 %div = sdiv i32 %0, %1 226 ret i32 %div 227} 228 229define i64 @sdiv2(i64 %a0, i64 %a1) nounwind readnone { 230entry: 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 252define i64 @srem2(i64 %a0, i64 %a1) nounwind readnone { 253entry: 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 275define i64 @udiv2(i64 %a0, i64 %a1) nounwind readnone { 276entry: 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 297define i64 @urem2(i64 %a0, i64 %a1) nounwind readnone { 298entry: 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 320define i64 @sdivrem2(i64 %a0, i64 %a1, i64* nocapture %r) nounwind { 321entry: 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 355define i64 @udivrem2(i64 %a0, i64 %a1, i64* nocapture %r) nounwind { 356entry: 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