1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ 3; RUN: | FileCheck -check-prefix=RV32I %s 4; RUN: llc -mtriple=riscv32 -mattr=+m -verify-machineinstrs < %s \ 5; RUN: | FileCheck -check-prefix=RV32IM %s 6; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 7; RUN: | FileCheck -check-prefix=RV64I %s 8; RUN: llc -mtriple=riscv64 -mattr=+m -verify-machineinstrs < %s \ 9; RUN: | FileCheck -check-prefix=RV64IM %s 10 11define i32 @udiv(i32 %a, i32 %b) nounwind { 12; RV32I-LABEL: udiv: 13; RV32I: # %bb.0: 14; RV32I-NEXT: addi sp, sp, -16 15; RV32I-NEXT: sw ra, 12(sp) 16; RV32I-NEXT: call __udivsi3 17; RV32I-NEXT: lw ra, 12(sp) 18; RV32I-NEXT: addi sp, sp, 16 19; RV32I-NEXT: ret 20; 21; RV32IM-LABEL: udiv: 22; RV32IM: # %bb.0: 23; RV32IM-NEXT: divu a0, a0, a1 24; RV32IM-NEXT: ret 25; 26; RV64I-LABEL: udiv: 27; RV64I: # %bb.0: 28; RV64I-NEXT: addi sp, sp, -16 29; RV64I-NEXT: sd ra, 8(sp) 30; RV64I-NEXT: slli a0, a0, 32 31; RV64I-NEXT: srli a0, a0, 32 32; RV64I-NEXT: slli a1, a1, 32 33; RV64I-NEXT: srli a1, a1, 32 34; RV64I-NEXT: call __udivdi3 35; RV64I-NEXT: ld ra, 8(sp) 36; RV64I-NEXT: addi sp, sp, 16 37; RV64I-NEXT: ret 38; 39; RV64IM-LABEL: udiv: 40; RV64IM: # %bb.0: 41; RV64IM-NEXT: divuw a0, a0, a1 42; RV64IM-NEXT: ret 43 %1 = udiv i32 %a, %b 44 ret i32 %1 45} 46 47define i32 @udiv_constant(i32 %a) nounwind { 48; RV32I-LABEL: udiv_constant: 49; RV32I: # %bb.0: 50; RV32I-NEXT: addi sp, sp, -16 51; RV32I-NEXT: sw ra, 12(sp) 52; RV32I-NEXT: addi a1, zero, 5 53; RV32I-NEXT: call __udivsi3 54; RV32I-NEXT: lw ra, 12(sp) 55; RV32I-NEXT: addi sp, sp, 16 56; RV32I-NEXT: ret 57; 58; RV32IM-LABEL: udiv_constant: 59; RV32IM: # %bb.0: 60; RV32IM-NEXT: lui a1, 838861 61; RV32IM-NEXT: addi a1, a1, -819 62; RV32IM-NEXT: mulhu a0, a0, a1 63; RV32IM-NEXT: srli a0, a0, 2 64; RV32IM-NEXT: ret 65; 66; RV64I-LABEL: udiv_constant: 67; RV64I: # %bb.0: 68; RV64I-NEXT: addi sp, sp, -16 69; RV64I-NEXT: sd ra, 8(sp) 70; RV64I-NEXT: slli a0, a0, 32 71; RV64I-NEXT: srli a0, a0, 32 72; RV64I-NEXT: addi a1, zero, 5 73; RV64I-NEXT: call __udivdi3 74; RV64I-NEXT: ld ra, 8(sp) 75; RV64I-NEXT: addi sp, sp, 16 76; RV64I-NEXT: ret 77; 78; RV64IM-LABEL: udiv_constant: 79; RV64IM: # %bb.0: 80; RV64IM-NEXT: slli a0, a0, 32 81; RV64IM-NEXT: srli a0, a0, 32 82; RV64IM-NEXT: lui a1, 1035469 83; RV64IM-NEXT: addiw a1, a1, -819 84; RV64IM-NEXT: slli a1, a1, 12 85; RV64IM-NEXT: addi a1, a1, -819 86; RV64IM-NEXT: slli a1, a1, 12 87; RV64IM-NEXT: addi a1, a1, -819 88; RV64IM-NEXT: slli a1, a1, 12 89; RV64IM-NEXT: addi a1, a1, -819 90; RV64IM-NEXT: mulhu a0, a0, a1 91; RV64IM-NEXT: srli a0, a0, 2 92; RV64IM-NEXT: ret 93 %1 = udiv i32 %a, 5 94 ret i32 %1 95} 96 97define i32 @udiv_pow2(i32 %a) nounwind { 98; RV32I-LABEL: udiv_pow2: 99; RV32I: # %bb.0: 100; RV32I-NEXT: srli a0, a0, 3 101; RV32I-NEXT: ret 102; 103; RV32IM-LABEL: udiv_pow2: 104; RV32IM: # %bb.0: 105; RV32IM-NEXT: srli a0, a0, 3 106; RV32IM-NEXT: ret 107; 108; RV64I-LABEL: udiv_pow2: 109; RV64I: # %bb.0: 110; RV64I-NEXT: srliw a0, a0, 3 111; RV64I-NEXT: ret 112; 113; RV64IM-LABEL: udiv_pow2: 114; RV64IM: # %bb.0: 115; RV64IM-NEXT: srliw a0, a0, 3 116; RV64IM-NEXT: ret 117 %1 = udiv i32 %a, 8 118 ret i32 %1 119} 120 121define i64 @udiv64(i64 %a, i64 %b) nounwind { 122; RV32I-LABEL: udiv64: 123; RV32I: # %bb.0: 124; RV32I-NEXT: addi sp, sp, -16 125; RV32I-NEXT: sw ra, 12(sp) 126; RV32I-NEXT: call __udivdi3 127; RV32I-NEXT: lw ra, 12(sp) 128; RV32I-NEXT: addi sp, sp, 16 129; RV32I-NEXT: ret 130; 131; RV32IM-LABEL: udiv64: 132; RV32IM: # %bb.0: 133; RV32IM-NEXT: addi sp, sp, -16 134; RV32IM-NEXT: sw ra, 12(sp) 135; RV32IM-NEXT: call __udivdi3 136; RV32IM-NEXT: lw ra, 12(sp) 137; RV32IM-NEXT: addi sp, sp, 16 138; RV32IM-NEXT: ret 139; 140; RV64I-LABEL: udiv64: 141; RV64I: # %bb.0: 142; RV64I-NEXT: addi sp, sp, -16 143; RV64I-NEXT: sd ra, 8(sp) 144; RV64I-NEXT: call __udivdi3 145; RV64I-NEXT: ld ra, 8(sp) 146; RV64I-NEXT: addi sp, sp, 16 147; RV64I-NEXT: ret 148; 149; RV64IM-LABEL: udiv64: 150; RV64IM: # %bb.0: 151; RV64IM-NEXT: divu a0, a0, a1 152; RV64IM-NEXT: ret 153 %1 = udiv i64 %a, %b 154 ret i64 %1 155} 156 157define i64 @udiv64_constant(i64 %a) nounwind { 158; RV32I-LABEL: udiv64_constant: 159; RV32I: # %bb.0: 160; RV32I-NEXT: addi sp, sp, -16 161; RV32I-NEXT: sw ra, 12(sp) 162; RV32I-NEXT: addi a2, zero, 5 163; RV32I-NEXT: mv a3, zero 164; RV32I-NEXT: call __udivdi3 165; RV32I-NEXT: lw ra, 12(sp) 166; RV32I-NEXT: addi sp, sp, 16 167; RV32I-NEXT: ret 168; 169; RV32IM-LABEL: udiv64_constant: 170; RV32IM: # %bb.0: 171; RV32IM-NEXT: addi sp, sp, -16 172; RV32IM-NEXT: sw ra, 12(sp) 173; RV32IM-NEXT: addi a2, zero, 5 174; RV32IM-NEXT: mv a3, zero 175; RV32IM-NEXT: call __udivdi3 176; RV32IM-NEXT: lw ra, 12(sp) 177; RV32IM-NEXT: addi sp, sp, 16 178; RV32IM-NEXT: ret 179; 180; RV64I-LABEL: udiv64_constant: 181; RV64I: # %bb.0: 182; RV64I-NEXT: addi sp, sp, -16 183; RV64I-NEXT: sd ra, 8(sp) 184; RV64I-NEXT: addi a1, zero, 5 185; RV64I-NEXT: call __udivdi3 186; RV64I-NEXT: ld ra, 8(sp) 187; RV64I-NEXT: addi sp, sp, 16 188; RV64I-NEXT: ret 189; 190; RV64IM-LABEL: udiv64_constant: 191; RV64IM: # %bb.0: 192; RV64IM-NEXT: lui a1, 1035469 193; RV64IM-NEXT: addiw a1, a1, -819 194; RV64IM-NEXT: slli a1, a1, 12 195; RV64IM-NEXT: addi a1, a1, -819 196; RV64IM-NEXT: slli a1, a1, 12 197; RV64IM-NEXT: addi a1, a1, -819 198; RV64IM-NEXT: slli a1, a1, 12 199; RV64IM-NEXT: addi a1, a1, -819 200; RV64IM-NEXT: mulhu a0, a0, a1 201; RV64IM-NEXT: srli a0, a0, 2 202; RV64IM-NEXT: ret 203 %1 = udiv i64 %a, 5 204 ret i64 %1 205} 206 207define i32 @sdiv(i32 %a, i32 %b) nounwind { 208; RV32I-LABEL: sdiv: 209; RV32I: # %bb.0: 210; RV32I-NEXT: addi sp, sp, -16 211; RV32I-NEXT: sw ra, 12(sp) 212; RV32I-NEXT: call __divsi3 213; RV32I-NEXT: lw ra, 12(sp) 214; RV32I-NEXT: addi sp, sp, 16 215; RV32I-NEXT: ret 216; 217; RV32IM-LABEL: sdiv: 218; RV32IM: # %bb.0: 219; RV32IM-NEXT: div a0, a0, a1 220; RV32IM-NEXT: ret 221; 222; RV64I-LABEL: sdiv: 223; RV64I: # %bb.0: 224; RV64I-NEXT: addi sp, sp, -16 225; RV64I-NEXT: sd ra, 8(sp) 226; RV64I-NEXT: sext.w a0, a0 227; RV64I-NEXT: sext.w a1, a1 228; RV64I-NEXT: call __divdi3 229; RV64I-NEXT: ld ra, 8(sp) 230; RV64I-NEXT: addi sp, sp, 16 231; RV64I-NEXT: ret 232; 233; RV64IM-LABEL: sdiv: 234; RV64IM: # %bb.0: 235; RV64IM-NEXT: divw a0, a0, a1 236; RV64IM-NEXT: ret 237 %1 = sdiv i32 %a, %b 238 ret i32 %1 239} 240 241define i32 @sdiv_constant(i32 %a) nounwind { 242; RV32I-LABEL: sdiv_constant: 243; RV32I: # %bb.0: 244; RV32I-NEXT: addi sp, sp, -16 245; RV32I-NEXT: sw ra, 12(sp) 246; RV32I-NEXT: addi a1, zero, 5 247; RV32I-NEXT: call __divsi3 248; RV32I-NEXT: lw ra, 12(sp) 249; RV32I-NEXT: addi sp, sp, 16 250; RV32I-NEXT: ret 251; 252; RV32IM-LABEL: sdiv_constant: 253; RV32IM: # %bb.0: 254; RV32IM-NEXT: lui a1, 419430 255; RV32IM-NEXT: addi a1, a1, 1639 256; RV32IM-NEXT: mulh a0, a0, a1 257; RV32IM-NEXT: srli a1, a0, 31 258; RV32IM-NEXT: srai a0, a0, 1 259; RV32IM-NEXT: add a0, a0, a1 260; RV32IM-NEXT: ret 261; 262; RV64I-LABEL: sdiv_constant: 263; RV64I: # %bb.0: 264; RV64I-NEXT: addi sp, sp, -16 265; RV64I-NEXT: sd ra, 8(sp) 266; RV64I-NEXT: sext.w a0, a0 267; RV64I-NEXT: addi a1, zero, 5 268; RV64I-NEXT: call __divdi3 269; RV64I-NEXT: ld ra, 8(sp) 270; RV64I-NEXT: addi sp, sp, 16 271; RV64I-NEXT: ret 272; 273; RV64IM-LABEL: sdiv_constant: 274; RV64IM: # %bb.0: 275; RV64IM-NEXT: sext.w a0, a0 276; RV64IM-NEXT: lui a1, 13107 277; RV64IM-NEXT: addiw a1, a1, 819 278; RV64IM-NEXT: slli a1, a1, 12 279; RV64IM-NEXT: addi a1, a1, 819 280; RV64IM-NEXT: slli a1, a1, 12 281; RV64IM-NEXT: addi a1, a1, 819 282; RV64IM-NEXT: slli a1, a1, 13 283; RV64IM-NEXT: addi a1, a1, 1639 284; RV64IM-NEXT: mulh a0, a0, a1 285; RV64IM-NEXT: srli a1, a0, 63 286; RV64IM-NEXT: srai a0, a0, 1 287; RV64IM-NEXT: add a0, a0, a1 288; RV64IM-NEXT: ret 289 %1 = sdiv i32 %a, 5 290 ret i32 %1 291} 292 293define i32 @sdiv_pow2(i32 %a) nounwind { 294; RV32I-LABEL: sdiv_pow2: 295; RV32I: # %bb.0: 296; RV32I-NEXT: srai a1, a0, 31 297; RV32I-NEXT: srli a1, a1, 29 298; RV32I-NEXT: add a0, a0, a1 299; RV32I-NEXT: srai a0, a0, 3 300; RV32I-NEXT: ret 301; 302; RV32IM-LABEL: sdiv_pow2: 303; RV32IM: # %bb.0: 304; RV32IM-NEXT: srai a1, a0, 31 305; RV32IM-NEXT: srli a1, a1, 29 306; RV32IM-NEXT: add a0, a0, a1 307; RV32IM-NEXT: srai a0, a0, 3 308; RV32IM-NEXT: ret 309; 310; RV64I-LABEL: sdiv_pow2: 311; RV64I: # %bb.0: 312; RV64I-NEXT: sext.w a1, a0 313; RV64I-NEXT: srli a1, a1, 60 314; RV64I-NEXT: andi a1, a1, 7 315; RV64I-NEXT: add a0, a0, a1 316; RV64I-NEXT: sraiw a0, a0, 3 317; RV64I-NEXT: ret 318; 319; RV64IM-LABEL: sdiv_pow2: 320; RV64IM: # %bb.0: 321; RV64IM-NEXT: sext.w a1, a0 322; RV64IM-NEXT: srli a1, a1, 60 323; RV64IM-NEXT: andi a1, a1, 7 324; RV64IM-NEXT: add a0, a0, a1 325; RV64IM-NEXT: sraiw a0, a0, 3 326; RV64IM-NEXT: ret 327 %1 = sdiv i32 %a, 8 328 ret i32 %1 329} 330 331define i64 @sdiv64(i64 %a, i64 %b) nounwind { 332; RV32I-LABEL: sdiv64: 333; RV32I: # %bb.0: 334; RV32I-NEXT: addi sp, sp, -16 335; RV32I-NEXT: sw ra, 12(sp) 336; RV32I-NEXT: call __divdi3 337; RV32I-NEXT: lw ra, 12(sp) 338; RV32I-NEXT: addi sp, sp, 16 339; RV32I-NEXT: ret 340; 341; RV32IM-LABEL: sdiv64: 342; RV32IM: # %bb.0: 343; RV32IM-NEXT: addi sp, sp, -16 344; RV32IM-NEXT: sw ra, 12(sp) 345; RV32IM-NEXT: call __divdi3 346; RV32IM-NEXT: lw ra, 12(sp) 347; RV32IM-NEXT: addi sp, sp, 16 348; RV32IM-NEXT: ret 349; 350; RV64I-LABEL: sdiv64: 351; RV64I: # %bb.0: 352; RV64I-NEXT: addi sp, sp, -16 353; RV64I-NEXT: sd ra, 8(sp) 354; RV64I-NEXT: call __divdi3 355; RV64I-NEXT: ld ra, 8(sp) 356; RV64I-NEXT: addi sp, sp, 16 357; RV64I-NEXT: ret 358; 359; RV64IM-LABEL: sdiv64: 360; RV64IM: # %bb.0: 361; RV64IM-NEXT: div a0, a0, a1 362; RV64IM-NEXT: ret 363 %1 = sdiv i64 %a, %b 364 ret i64 %1 365} 366 367define i64 @sdiv64_constant(i64 %a) nounwind { 368; RV32I-LABEL: sdiv64_constant: 369; RV32I: # %bb.0: 370; RV32I-NEXT: addi sp, sp, -16 371; RV32I-NEXT: sw ra, 12(sp) 372; RV32I-NEXT: addi a2, zero, 5 373; RV32I-NEXT: mv a3, zero 374; RV32I-NEXT: call __divdi3 375; RV32I-NEXT: lw ra, 12(sp) 376; RV32I-NEXT: addi sp, sp, 16 377; RV32I-NEXT: ret 378; 379; RV32IM-LABEL: sdiv64_constant: 380; RV32IM: # %bb.0: 381; RV32IM-NEXT: addi sp, sp, -16 382; RV32IM-NEXT: sw ra, 12(sp) 383; RV32IM-NEXT: addi a2, zero, 5 384; RV32IM-NEXT: mv a3, zero 385; RV32IM-NEXT: call __divdi3 386; RV32IM-NEXT: lw ra, 12(sp) 387; RV32IM-NEXT: addi sp, sp, 16 388; RV32IM-NEXT: ret 389; 390; RV64I-LABEL: sdiv64_constant: 391; RV64I: # %bb.0: 392; RV64I-NEXT: addi sp, sp, -16 393; RV64I-NEXT: sd ra, 8(sp) 394; RV64I-NEXT: addi a1, zero, 5 395; RV64I-NEXT: call __divdi3 396; RV64I-NEXT: ld ra, 8(sp) 397; RV64I-NEXT: addi sp, sp, 16 398; RV64I-NEXT: ret 399; 400; RV64IM-LABEL: sdiv64_constant: 401; RV64IM: # %bb.0: 402; RV64IM-NEXT: lui a1, 13107 403; RV64IM-NEXT: addiw a1, a1, 819 404; RV64IM-NEXT: slli a1, a1, 12 405; RV64IM-NEXT: addi a1, a1, 819 406; RV64IM-NEXT: slli a1, a1, 12 407; RV64IM-NEXT: addi a1, a1, 819 408; RV64IM-NEXT: slli a1, a1, 13 409; RV64IM-NEXT: addi a1, a1, 1639 410; RV64IM-NEXT: mulh a0, a0, a1 411; RV64IM-NEXT: srli a1, a0, 63 412; RV64IM-NEXT: srai a0, a0, 1 413; RV64IM-NEXT: add a0, a0, a1 414; RV64IM-NEXT: ret 415 %1 = sdiv i64 %a, 5 416 ret i64 %1 417} 418 419; Although this sdiv has two sexti32 operands, it shouldn't compile to divw on 420; RV64M as that wouldn't produce the correct result for e.g. INT_MIN/-1. 421 422define i64 @sdiv64_sext_operands(i32 %a, i32 %b) nounwind { 423; RV32I-LABEL: sdiv64_sext_operands: 424; RV32I: # %bb.0: 425; RV32I-NEXT: addi sp, sp, -16 426; RV32I-NEXT: sw ra, 12(sp) 427; RV32I-NEXT: mv a2, a1 428; RV32I-NEXT: srai a1, a0, 31 429; RV32I-NEXT: srai a3, a2, 31 430; RV32I-NEXT: call __divdi3 431; RV32I-NEXT: lw ra, 12(sp) 432; RV32I-NEXT: addi sp, sp, 16 433; RV32I-NEXT: ret 434; 435; RV32IM-LABEL: sdiv64_sext_operands: 436; RV32IM: # %bb.0: 437; RV32IM-NEXT: addi sp, sp, -16 438; RV32IM-NEXT: sw ra, 12(sp) 439; RV32IM-NEXT: mv a2, a1 440; RV32IM-NEXT: srai a1, a0, 31 441; RV32IM-NEXT: srai a3, a2, 31 442; RV32IM-NEXT: call __divdi3 443; RV32IM-NEXT: lw ra, 12(sp) 444; RV32IM-NEXT: addi sp, sp, 16 445; RV32IM-NEXT: ret 446; 447; RV64I-LABEL: sdiv64_sext_operands: 448; RV64I: # %bb.0: 449; RV64I-NEXT: addi sp, sp, -16 450; RV64I-NEXT: sd ra, 8(sp) 451; RV64I-NEXT: sext.w a0, a0 452; RV64I-NEXT: sext.w a1, a1 453; RV64I-NEXT: call __divdi3 454; RV64I-NEXT: ld ra, 8(sp) 455; RV64I-NEXT: addi sp, sp, 16 456; RV64I-NEXT: ret 457; 458; RV64IM-LABEL: sdiv64_sext_operands: 459; RV64IM: # %bb.0: 460; RV64IM-NEXT: sext.w a0, a0 461; RV64IM-NEXT: sext.w a1, a1 462; RV64IM-NEXT: div a0, a0, a1 463; RV64IM-NEXT: ret 464 %1 = sext i32 %a to i64 465 %2 = sext i32 %b to i64 466 %3 = sdiv i64 %1, %2 467 ret i64 %3 468} 469