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) # 4-byte Folded Spill 16; RV32I-NEXT: call __udivsi3@plt 17; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 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) # 8-byte Folded Spill 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@plt 35; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 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) # 4-byte Folded Spill 52; RV32I-NEXT: addi a1, zero, 5 53; RV32I-NEXT: call __udivsi3@plt 54; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 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) # 8-byte Folded Spill 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@plt 74; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 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, 205 83; RV64IM-NEXT: addiw a1, a1, -819 84; RV64IM-NEXT: slli a1, a1, 12 85; RV64IM-NEXT: addi a1, a1, -819 86; RV64IM-NEXT: mul a0, a0, a1 87; RV64IM-NEXT: srli a0, a0, 34 88; RV64IM-NEXT: ret 89 %1 = udiv i32 %a, 5 90 ret i32 %1 91} 92 93define i32 @udiv_pow2(i32 %a) nounwind { 94; RV32I-LABEL: udiv_pow2: 95; RV32I: # %bb.0: 96; RV32I-NEXT: srli a0, a0, 3 97; RV32I-NEXT: ret 98; 99; RV32IM-LABEL: udiv_pow2: 100; RV32IM: # %bb.0: 101; RV32IM-NEXT: srli a0, a0, 3 102; RV32IM-NEXT: ret 103; 104; RV64I-LABEL: udiv_pow2: 105; RV64I: # %bb.0: 106; RV64I-NEXT: srliw a0, a0, 3 107; RV64I-NEXT: ret 108; 109; RV64IM-LABEL: udiv_pow2: 110; RV64IM: # %bb.0: 111; RV64IM-NEXT: srliw a0, a0, 3 112; RV64IM-NEXT: ret 113 %1 = udiv i32 %a, 8 114 ret i32 %1 115} 116 117define i64 @udiv64(i64 %a, i64 %b) nounwind { 118; RV32I-LABEL: udiv64: 119; RV32I: # %bb.0: 120; RV32I-NEXT: addi sp, sp, -16 121; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 122; RV32I-NEXT: call __udivdi3@plt 123; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 124; RV32I-NEXT: addi sp, sp, 16 125; RV32I-NEXT: ret 126; 127; RV32IM-LABEL: udiv64: 128; RV32IM: # %bb.0: 129; RV32IM-NEXT: addi sp, sp, -16 130; RV32IM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 131; RV32IM-NEXT: call __udivdi3@plt 132; RV32IM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 133; RV32IM-NEXT: addi sp, sp, 16 134; RV32IM-NEXT: ret 135; 136; RV64I-LABEL: udiv64: 137; RV64I: # %bb.0: 138; RV64I-NEXT: addi sp, sp, -16 139; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 140; RV64I-NEXT: call __udivdi3@plt 141; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 142; RV64I-NEXT: addi sp, sp, 16 143; RV64I-NEXT: ret 144; 145; RV64IM-LABEL: udiv64: 146; RV64IM: # %bb.0: 147; RV64IM-NEXT: divu a0, a0, a1 148; RV64IM-NEXT: ret 149 %1 = udiv i64 %a, %b 150 ret i64 %1 151} 152 153define i64 @udiv64_constant(i64 %a) nounwind { 154; RV32I-LABEL: udiv64_constant: 155; RV32I: # %bb.0: 156; RV32I-NEXT: addi sp, sp, -16 157; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 158; RV32I-NEXT: addi a2, zero, 5 159; RV32I-NEXT: mv a3, zero 160; RV32I-NEXT: call __udivdi3@plt 161; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 162; RV32I-NEXT: addi sp, sp, 16 163; RV32I-NEXT: ret 164; 165; RV32IM-LABEL: udiv64_constant: 166; RV32IM: # %bb.0: 167; RV32IM-NEXT: addi sp, sp, -16 168; RV32IM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 169; RV32IM-NEXT: addi a2, zero, 5 170; RV32IM-NEXT: mv a3, zero 171; RV32IM-NEXT: call __udivdi3@plt 172; RV32IM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 173; RV32IM-NEXT: addi sp, sp, 16 174; RV32IM-NEXT: ret 175; 176; RV64I-LABEL: udiv64_constant: 177; RV64I: # %bb.0: 178; RV64I-NEXT: addi sp, sp, -16 179; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 180; RV64I-NEXT: addi a1, zero, 5 181; RV64I-NEXT: call __udivdi3@plt 182; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 183; RV64I-NEXT: addi sp, sp, 16 184; RV64I-NEXT: ret 185; 186; RV64IM-LABEL: udiv64_constant: 187; RV64IM: # %bb.0: 188; RV64IM-NEXT: lui a1, 1035469 189; RV64IM-NEXT: addiw a1, a1, -819 190; RV64IM-NEXT: slli a1, a1, 12 191; RV64IM-NEXT: addi a1, a1, -819 192; RV64IM-NEXT: slli a1, a1, 12 193; RV64IM-NEXT: addi a1, a1, -819 194; RV64IM-NEXT: slli a1, a1, 12 195; RV64IM-NEXT: addi a1, a1, -819 196; RV64IM-NEXT: mulhu a0, a0, a1 197; RV64IM-NEXT: srli a0, a0, 2 198; RV64IM-NEXT: ret 199 %1 = udiv i64 %a, 5 200 ret i64 %1 201} 202 203define i8 @udiv8(i8 %a, i8 %b) nounwind { 204; RV32I-LABEL: udiv8: 205; RV32I: # %bb.0: 206; RV32I-NEXT: addi sp, sp, -16 207; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 208; RV32I-NEXT: andi a0, a0, 255 209; RV32I-NEXT: andi a1, a1, 255 210; RV32I-NEXT: call __udivsi3@plt 211; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 212; RV32I-NEXT: addi sp, sp, 16 213; RV32I-NEXT: ret 214; 215; RV32IM-LABEL: udiv8: 216; RV32IM: # %bb.0: 217; RV32IM-NEXT: andi a1, a1, 255 218; RV32IM-NEXT: andi a0, a0, 255 219; RV32IM-NEXT: divu a0, a0, a1 220; RV32IM-NEXT: ret 221; 222; RV64I-LABEL: udiv8: 223; RV64I: # %bb.0: 224; RV64I-NEXT: addi sp, sp, -16 225; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 226; RV64I-NEXT: andi a0, a0, 255 227; RV64I-NEXT: andi a1, a1, 255 228; RV64I-NEXT: call __udivdi3@plt 229; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 230; RV64I-NEXT: addi sp, sp, 16 231; RV64I-NEXT: ret 232; 233; RV64IM-LABEL: udiv8: 234; RV64IM: # %bb.0: 235; RV64IM-NEXT: andi a1, a1, 255 236; RV64IM-NEXT: andi a0, a0, 255 237; RV64IM-NEXT: divuw a0, a0, a1 238; RV64IM-NEXT: ret 239 %1 = udiv i8 %a, %b 240 ret i8 %1 241} 242 243define i8 @udiv8_constant(i8 %a) nounwind { 244; RV32I-LABEL: udiv8_constant: 245; RV32I: # %bb.0: 246; RV32I-NEXT: addi sp, sp, -16 247; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 248; RV32I-NEXT: andi a0, a0, 255 249; RV32I-NEXT: addi a1, zero, 5 250; RV32I-NEXT: call __udivsi3@plt 251; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 252; RV32I-NEXT: addi sp, sp, 16 253; RV32I-NEXT: ret 254; 255; RV32IM-LABEL: udiv8_constant: 256; RV32IM: # %bb.0: 257; RV32IM-NEXT: andi a0, a0, 255 258; RV32IM-NEXT: addi a1, zero, 205 259; RV32IM-NEXT: mul a0, a0, a1 260; RV32IM-NEXT: srli a0, a0, 10 261; RV32IM-NEXT: ret 262; 263; RV64I-LABEL: udiv8_constant: 264; RV64I: # %bb.0: 265; RV64I-NEXT: addi sp, sp, -16 266; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 267; RV64I-NEXT: andi a0, a0, 255 268; RV64I-NEXT: addi a1, zero, 5 269; RV64I-NEXT: call __udivdi3@plt 270; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 271; RV64I-NEXT: addi sp, sp, 16 272; RV64I-NEXT: ret 273; 274; RV64IM-LABEL: udiv8_constant: 275; RV64IM: # %bb.0: 276; RV64IM-NEXT: andi a0, a0, 255 277; RV64IM-NEXT: addi a1, zero, 205 278; RV64IM-NEXT: mul a0, a0, a1 279; RV64IM-NEXT: srli a0, a0, 10 280; RV64IM-NEXT: ret 281 %1 = udiv i8 %a, 5 282 ret i8 %1 283} 284 285define i8 @udiv8_pow2(i8 %a) nounwind { 286; RV32I-LABEL: udiv8_pow2: 287; RV32I: # %bb.0: 288; RV32I-NEXT: andi a0, a0, 248 289; RV32I-NEXT: srli a0, a0, 3 290; RV32I-NEXT: ret 291; 292; RV32IM-LABEL: udiv8_pow2: 293; RV32IM: # %bb.0: 294; RV32IM-NEXT: andi a0, a0, 248 295; RV32IM-NEXT: srli a0, a0, 3 296; RV32IM-NEXT: ret 297; 298; RV64I-LABEL: udiv8_pow2: 299; RV64I: # %bb.0: 300; RV64I-NEXT: andi a0, a0, 248 301; RV64I-NEXT: srli a0, a0, 3 302; RV64I-NEXT: ret 303; 304; RV64IM-LABEL: udiv8_pow2: 305; RV64IM: # %bb.0: 306; RV64IM-NEXT: andi a0, a0, 248 307; RV64IM-NEXT: srli a0, a0, 3 308; RV64IM-NEXT: ret 309 %1 = udiv i8 %a, 8 310 ret i8 %1 311} 312 313define i16 @udiv16(i16 %a, i16 %b) nounwind { 314; RV32I-LABEL: udiv16: 315; RV32I: # %bb.0: 316; RV32I-NEXT: addi sp, sp, -16 317; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 318; RV32I-NEXT: lui a2, 16 319; RV32I-NEXT: addi a2, a2, -1 320; RV32I-NEXT: and a0, a0, a2 321; RV32I-NEXT: and a1, a1, a2 322; RV32I-NEXT: call __udivsi3@plt 323; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 324; RV32I-NEXT: addi sp, sp, 16 325; RV32I-NEXT: ret 326; 327; RV32IM-LABEL: udiv16: 328; RV32IM: # %bb.0: 329; RV32IM-NEXT: lui a2, 16 330; RV32IM-NEXT: addi a2, a2, -1 331; RV32IM-NEXT: and a1, a1, a2 332; RV32IM-NEXT: and a0, a0, a2 333; RV32IM-NEXT: divu a0, a0, a1 334; RV32IM-NEXT: ret 335; 336; RV64I-LABEL: udiv16: 337; RV64I: # %bb.0: 338; RV64I-NEXT: addi sp, sp, -16 339; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 340; RV64I-NEXT: lui a2, 16 341; RV64I-NEXT: addiw a2, a2, -1 342; RV64I-NEXT: and a0, a0, a2 343; RV64I-NEXT: and a1, a1, a2 344; RV64I-NEXT: call __udivdi3@plt 345; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 346; RV64I-NEXT: addi sp, sp, 16 347; RV64I-NEXT: ret 348; 349; RV64IM-LABEL: udiv16: 350; RV64IM: # %bb.0: 351; RV64IM-NEXT: lui a2, 16 352; RV64IM-NEXT: addiw a2, a2, -1 353; RV64IM-NEXT: and a1, a1, a2 354; RV64IM-NEXT: and a0, a0, a2 355; RV64IM-NEXT: divuw a0, a0, a1 356; RV64IM-NEXT: ret 357 %1 = udiv i16 %a, %b 358 ret i16 %1 359} 360 361define i16 @udiv16_constant(i16 %a) nounwind { 362; RV32I-LABEL: udiv16_constant: 363; RV32I: # %bb.0: 364; RV32I-NEXT: addi sp, sp, -16 365; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 366; RV32I-NEXT: lui a1, 16 367; RV32I-NEXT: addi a1, a1, -1 368; RV32I-NEXT: and a0, a0, a1 369; RV32I-NEXT: addi a1, zero, 5 370; RV32I-NEXT: call __udivsi3@plt 371; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 372; RV32I-NEXT: addi sp, sp, 16 373; RV32I-NEXT: ret 374; 375; RV32IM-LABEL: udiv16_constant: 376; RV32IM: # %bb.0: 377; RV32IM-NEXT: lui a1, 16 378; RV32IM-NEXT: addi a1, a1, -1 379; RV32IM-NEXT: and a0, a0, a1 380; RV32IM-NEXT: lui a1, 13 381; RV32IM-NEXT: addi a1, a1, -819 382; RV32IM-NEXT: mul a0, a0, a1 383; RV32IM-NEXT: srli a0, a0, 18 384; RV32IM-NEXT: ret 385; 386; RV64I-LABEL: udiv16_constant: 387; RV64I: # %bb.0: 388; RV64I-NEXT: addi sp, sp, -16 389; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 390; RV64I-NEXT: lui a1, 16 391; RV64I-NEXT: addiw a1, a1, -1 392; RV64I-NEXT: and a0, a0, a1 393; RV64I-NEXT: addi a1, zero, 5 394; RV64I-NEXT: call __udivdi3@plt 395; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 396; RV64I-NEXT: addi sp, sp, 16 397; RV64I-NEXT: ret 398; 399; RV64IM-LABEL: udiv16_constant: 400; RV64IM: # %bb.0: 401; RV64IM-NEXT: lui a1, 16 402; RV64IM-NEXT: addiw a1, a1, -1 403; RV64IM-NEXT: and a0, a0, a1 404; RV64IM-NEXT: lui a1, 13 405; RV64IM-NEXT: addiw a1, a1, -819 406; RV64IM-NEXT: mul a0, a0, a1 407; RV64IM-NEXT: srli a0, a0, 18 408; RV64IM-NEXT: ret 409 %1 = udiv i16 %a, 5 410 ret i16 %1 411} 412 413define i16 @udiv16_pow2(i16 %a) nounwind { 414; RV32I-LABEL: udiv16_pow2: 415; RV32I: # %bb.0: 416; RV32I-NEXT: slli a0, a0, 16 417; RV32I-NEXT: srli a0, a0, 19 418; RV32I-NEXT: ret 419; 420; RV32IM-LABEL: udiv16_pow2: 421; RV32IM: # %bb.0: 422; RV32IM-NEXT: slli a0, a0, 16 423; RV32IM-NEXT: srli a0, a0, 19 424; RV32IM-NEXT: ret 425; 426; RV64I-LABEL: udiv16_pow2: 427; RV64I: # %bb.0: 428; RV64I-NEXT: slliw a0, a0, 16 429; RV64I-NEXT: srliw a0, a0, 19 430; RV64I-NEXT: ret 431; 432; RV64IM-LABEL: udiv16_pow2: 433; RV64IM: # %bb.0: 434; RV64IM-NEXT: slliw a0, a0, 16 435; RV64IM-NEXT: srliw a0, a0, 19 436; RV64IM-NEXT: ret 437 %1 = udiv i16 %a, 8 438 ret i16 %1 439} 440 441define i32 @sdiv(i32 %a, i32 %b) nounwind { 442; RV32I-LABEL: sdiv: 443; RV32I: # %bb.0: 444; RV32I-NEXT: addi sp, sp, -16 445; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 446; RV32I-NEXT: call __divsi3@plt 447; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 448; RV32I-NEXT: addi sp, sp, 16 449; RV32I-NEXT: ret 450; 451; RV32IM-LABEL: sdiv: 452; RV32IM: # %bb.0: 453; RV32IM-NEXT: div a0, a0, a1 454; RV32IM-NEXT: ret 455; 456; RV64I-LABEL: sdiv: 457; RV64I: # %bb.0: 458; RV64I-NEXT: addi sp, sp, -16 459; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 460; RV64I-NEXT: sext.w a0, a0 461; RV64I-NEXT: sext.w a1, a1 462; RV64I-NEXT: call __divdi3@plt 463; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 464; RV64I-NEXT: addi sp, sp, 16 465; RV64I-NEXT: ret 466; 467; RV64IM-LABEL: sdiv: 468; RV64IM: # %bb.0: 469; RV64IM-NEXT: divw a0, a0, a1 470; RV64IM-NEXT: ret 471 %1 = sdiv i32 %a, %b 472 ret i32 %1 473} 474 475define i32 @sdiv_constant(i32 %a) nounwind { 476; RV32I-LABEL: sdiv_constant: 477; RV32I: # %bb.0: 478; RV32I-NEXT: addi sp, sp, -16 479; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 480; RV32I-NEXT: addi a1, zero, 5 481; RV32I-NEXT: call __divsi3@plt 482; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 483; RV32I-NEXT: addi sp, sp, 16 484; RV32I-NEXT: ret 485; 486; RV32IM-LABEL: sdiv_constant: 487; RV32IM: # %bb.0: 488; RV32IM-NEXT: lui a1, 419430 489; RV32IM-NEXT: addi a1, a1, 1639 490; RV32IM-NEXT: mulh a0, a0, a1 491; RV32IM-NEXT: srli a1, a0, 31 492; RV32IM-NEXT: srai a0, a0, 1 493; RV32IM-NEXT: add a0, a0, a1 494; RV32IM-NEXT: ret 495; 496; RV64I-LABEL: sdiv_constant: 497; RV64I: # %bb.0: 498; RV64I-NEXT: addi sp, sp, -16 499; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 500; RV64I-NEXT: sext.w a0, a0 501; RV64I-NEXT: addi a1, zero, 5 502; RV64I-NEXT: call __divdi3@plt 503; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 504; RV64I-NEXT: addi sp, sp, 16 505; RV64I-NEXT: ret 506; 507; RV64IM-LABEL: sdiv_constant: 508; RV64IM: # %bb.0: 509; RV64IM-NEXT: sext.w a0, a0 510; RV64IM-NEXT: lui a1, 419430 511; RV64IM-NEXT: addiw a1, a1, 1639 512; RV64IM-NEXT: mul a0, a0, a1 513; RV64IM-NEXT: srli a1, a0, 63 514; RV64IM-NEXT: srai a0, a0, 33 515; RV64IM-NEXT: add a0, a0, a1 516; RV64IM-NEXT: ret 517 %1 = sdiv i32 %a, 5 518 ret i32 %1 519} 520 521define i32 @sdiv_pow2(i32 %a) nounwind { 522; RV32I-LABEL: sdiv_pow2: 523; RV32I: # %bb.0: 524; RV32I-NEXT: srai a1, a0, 31 525; RV32I-NEXT: srli a1, a1, 29 526; RV32I-NEXT: add a0, a0, a1 527; RV32I-NEXT: srai a0, a0, 3 528; RV32I-NEXT: ret 529; 530; RV32IM-LABEL: sdiv_pow2: 531; RV32IM: # %bb.0: 532; RV32IM-NEXT: srai a1, a0, 31 533; RV32IM-NEXT: srli a1, a1, 29 534; RV32IM-NEXT: add a0, a0, a1 535; RV32IM-NEXT: srai a0, a0, 3 536; RV32IM-NEXT: ret 537; 538; RV64I-LABEL: sdiv_pow2: 539; RV64I: # %bb.0: 540; RV64I-NEXT: sext.w a1, a0 541; RV64I-NEXT: srli a1, a1, 60 542; RV64I-NEXT: andi a1, a1, 7 543; RV64I-NEXT: add a0, a0, a1 544; RV64I-NEXT: sraiw a0, a0, 3 545; RV64I-NEXT: ret 546; 547; RV64IM-LABEL: sdiv_pow2: 548; RV64IM: # %bb.0: 549; RV64IM-NEXT: sext.w a1, a0 550; RV64IM-NEXT: srli a1, a1, 60 551; RV64IM-NEXT: andi a1, a1, 7 552; RV64IM-NEXT: add a0, a0, a1 553; RV64IM-NEXT: sraiw a0, a0, 3 554; RV64IM-NEXT: ret 555 %1 = sdiv i32 %a, 8 556 ret i32 %1 557} 558 559define i64 @sdiv64(i64 %a, i64 %b) nounwind { 560; RV32I-LABEL: sdiv64: 561; RV32I: # %bb.0: 562; RV32I-NEXT: addi sp, sp, -16 563; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 564; RV32I-NEXT: call __divdi3@plt 565; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 566; RV32I-NEXT: addi sp, sp, 16 567; RV32I-NEXT: ret 568; 569; RV32IM-LABEL: sdiv64: 570; RV32IM: # %bb.0: 571; RV32IM-NEXT: addi sp, sp, -16 572; RV32IM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 573; RV32IM-NEXT: call __divdi3@plt 574; RV32IM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 575; RV32IM-NEXT: addi sp, sp, 16 576; RV32IM-NEXT: ret 577; 578; RV64I-LABEL: sdiv64: 579; RV64I: # %bb.0: 580; RV64I-NEXT: addi sp, sp, -16 581; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 582; RV64I-NEXT: call __divdi3@plt 583; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 584; RV64I-NEXT: addi sp, sp, 16 585; RV64I-NEXT: ret 586; 587; RV64IM-LABEL: sdiv64: 588; RV64IM: # %bb.0: 589; RV64IM-NEXT: div a0, a0, a1 590; RV64IM-NEXT: ret 591 %1 = sdiv i64 %a, %b 592 ret i64 %1 593} 594 595define i64 @sdiv64_constant(i64 %a) nounwind { 596; RV32I-LABEL: sdiv64_constant: 597; RV32I: # %bb.0: 598; RV32I-NEXT: addi sp, sp, -16 599; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 600; RV32I-NEXT: addi a2, zero, 5 601; RV32I-NEXT: mv a3, zero 602; RV32I-NEXT: call __divdi3@plt 603; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 604; RV32I-NEXT: addi sp, sp, 16 605; RV32I-NEXT: ret 606; 607; RV32IM-LABEL: sdiv64_constant: 608; RV32IM: # %bb.0: 609; RV32IM-NEXT: addi sp, sp, -16 610; RV32IM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 611; RV32IM-NEXT: addi a2, zero, 5 612; RV32IM-NEXT: mv a3, zero 613; RV32IM-NEXT: call __divdi3@plt 614; RV32IM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 615; RV32IM-NEXT: addi sp, sp, 16 616; RV32IM-NEXT: ret 617; 618; RV64I-LABEL: sdiv64_constant: 619; RV64I: # %bb.0: 620; RV64I-NEXT: addi sp, sp, -16 621; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 622; RV64I-NEXT: addi a1, zero, 5 623; RV64I-NEXT: call __divdi3@plt 624; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 625; RV64I-NEXT: addi sp, sp, 16 626; RV64I-NEXT: ret 627; 628; RV64IM-LABEL: sdiv64_constant: 629; RV64IM: # %bb.0: 630; RV64IM-NEXT: lui a1, 13107 631; RV64IM-NEXT: addiw a1, a1, 819 632; RV64IM-NEXT: slli a1, a1, 12 633; RV64IM-NEXT: addi a1, a1, 819 634; RV64IM-NEXT: slli a1, a1, 12 635; RV64IM-NEXT: addi a1, a1, 819 636; RV64IM-NEXT: slli a1, a1, 13 637; RV64IM-NEXT: addi a1, a1, 1639 638; RV64IM-NEXT: mulh a0, a0, a1 639; RV64IM-NEXT: srli a1, a0, 63 640; RV64IM-NEXT: srai a0, a0, 1 641; RV64IM-NEXT: add a0, a0, a1 642; RV64IM-NEXT: ret 643 %1 = sdiv i64 %a, 5 644 ret i64 %1 645} 646 647; Although this sdiv has two sexti32 operands, it shouldn't compile to divw on 648; RV64M as that wouldn't produce the correct result for e.g. INT_MIN/-1. 649 650define i64 @sdiv64_sext_operands(i32 %a, i32 %b) nounwind { 651; RV32I-LABEL: sdiv64_sext_operands: 652; RV32I: # %bb.0: 653; RV32I-NEXT: addi sp, sp, -16 654; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 655; RV32I-NEXT: mv a2, a1 656; RV32I-NEXT: srai a1, a0, 31 657; RV32I-NEXT: srai a3, a2, 31 658; RV32I-NEXT: call __divdi3@plt 659; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 660; RV32I-NEXT: addi sp, sp, 16 661; RV32I-NEXT: ret 662; 663; RV32IM-LABEL: sdiv64_sext_operands: 664; RV32IM: # %bb.0: 665; RV32IM-NEXT: addi sp, sp, -16 666; RV32IM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 667; RV32IM-NEXT: mv a2, a1 668; RV32IM-NEXT: srai a1, a0, 31 669; RV32IM-NEXT: srai a3, a2, 31 670; RV32IM-NEXT: call __divdi3@plt 671; RV32IM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 672; RV32IM-NEXT: addi sp, sp, 16 673; RV32IM-NEXT: ret 674; 675; RV64I-LABEL: sdiv64_sext_operands: 676; RV64I: # %bb.0: 677; RV64I-NEXT: addi sp, sp, -16 678; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 679; RV64I-NEXT: sext.w a0, a0 680; RV64I-NEXT: sext.w a1, a1 681; RV64I-NEXT: call __divdi3@plt 682; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 683; RV64I-NEXT: addi sp, sp, 16 684; RV64I-NEXT: ret 685; 686; RV64IM-LABEL: sdiv64_sext_operands: 687; RV64IM: # %bb.0: 688; RV64IM-NEXT: sext.w a0, a0 689; RV64IM-NEXT: sext.w a1, a1 690; RV64IM-NEXT: div a0, a0, a1 691; RV64IM-NEXT: ret 692 %1 = sext i32 %a to i64 693 %2 = sext i32 %b to i64 694 %3 = sdiv i64 %1, %2 695 ret i64 %3 696} 697 698define i8 @sdiv8(i8 %a, i8 %b) nounwind { 699; RV32I-LABEL: sdiv8: 700; RV32I: # %bb.0: 701; RV32I-NEXT: addi sp, sp, -16 702; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 703; RV32I-NEXT: slli a0, a0, 24 704; RV32I-NEXT: srai a0, a0, 24 705; RV32I-NEXT: slli a1, a1, 24 706; RV32I-NEXT: srai a1, a1, 24 707; RV32I-NEXT: call __divsi3@plt 708; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 709; RV32I-NEXT: addi sp, sp, 16 710; RV32I-NEXT: ret 711; 712; RV32IM-LABEL: sdiv8: 713; RV32IM: # %bb.0: 714; RV32IM-NEXT: slli a1, a1, 24 715; RV32IM-NEXT: srai a1, a1, 24 716; RV32IM-NEXT: slli a0, a0, 24 717; RV32IM-NEXT: srai a0, a0, 24 718; RV32IM-NEXT: div a0, a0, a1 719; RV32IM-NEXT: ret 720; 721; RV64I-LABEL: sdiv8: 722; RV64I: # %bb.0: 723; RV64I-NEXT: addi sp, sp, -16 724; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 725; RV64I-NEXT: slli a0, a0, 56 726; RV64I-NEXT: srai a0, a0, 56 727; RV64I-NEXT: slli a1, a1, 56 728; RV64I-NEXT: srai a1, a1, 56 729; RV64I-NEXT: call __divdi3@plt 730; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 731; RV64I-NEXT: addi sp, sp, 16 732; RV64I-NEXT: ret 733; 734; RV64IM-LABEL: sdiv8: 735; RV64IM: # %bb.0: 736; RV64IM-NEXT: slli a1, a1, 56 737; RV64IM-NEXT: srai a1, a1, 56 738; RV64IM-NEXT: slli a0, a0, 56 739; RV64IM-NEXT: srai a0, a0, 56 740; RV64IM-NEXT: divw a0, a0, a1 741; RV64IM-NEXT: ret 742 %1 = sdiv i8 %a, %b 743 ret i8 %1 744} 745 746define i8 @sdiv8_constant(i8 %a) nounwind { 747; RV32I-LABEL: sdiv8_constant: 748; RV32I: # %bb.0: 749; RV32I-NEXT: addi sp, sp, -16 750; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 751; RV32I-NEXT: slli a0, a0, 24 752; RV32I-NEXT: srai a0, a0, 24 753; RV32I-NEXT: addi a1, zero, 5 754; RV32I-NEXT: call __divsi3@plt 755; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 756; RV32I-NEXT: addi sp, sp, 16 757; RV32I-NEXT: ret 758; 759; RV32IM-LABEL: sdiv8_constant: 760; RV32IM: # %bb.0: 761; RV32IM-NEXT: slli a0, a0, 24 762; RV32IM-NEXT: srai a0, a0, 24 763; RV32IM-NEXT: addi a1, zero, 103 764; RV32IM-NEXT: mul a0, a0, a1 765; RV32IM-NEXT: srai a1, a0, 9 766; RV32IM-NEXT: srli a0, a0, 15 767; RV32IM-NEXT: andi a0, a0, 1 768; RV32IM-NEXT: add a0, a1, a0 769; RV32IM-NEXT: ret 770; 771; RV64I-LABEL: sdiv8_constant: 772; RV64I: # %bb.0: 773; RV64I-NEXT: addi sp, sp, -16 774; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 775; RV64I-NEXT: slli a0, a0, 56 776; RV64I-NEXT: srai a0, a0, 56 777; RV64I-NEXT: addi a1, zero, 5 778; RV64I-NEXT: call __divdi3@plt 779; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 780; RV64I-NEXT: addi sp, sp, 16 781; RV64I-NEXT: ret 782; 783; RV64IM-LABEL: sdiv8_constant: 784; RV64IM: # %bb.0: 785; RV64IM-NEXT: slli a0, a0, 56 786; RV64IM-NEXT: srai a0, a0, 56 787; RV64IM-NEXT: addi a1, zero, 103 788; RV64IM-NEXT: mul a0, a0, a1 789; RV64IM-NEXT: srai a1, a0, 9 790; RV64IM-NEXT: srli a0, a0, 15 791; RV64IM-NEXT: andi a0, a0, 1 792; RV64IM-NEXT: add a0, a1, a0 793; RV64IM-NEXT: ret 794 %1 = sdiv i8 %a, 5 795 ret i8 %1 796} 797 798define i8 @sdiv8_pow2(i8 %a) nounwind { 799; RV32I-LABEL: sdiv8_pow2: 800; RV32I: # %bb.0: 801; RV32I-NEXT: slli a1, a0, 24 802; RV32I-NEXT: srai a1, a1, 24 803; RV32I-NEXT: srli a1, a1, 12 804; RV32I-NEXT: andi a1, a1, 7 805; RV32I-NEXT: add a0, a0, a1 806; RV32I-NEXT: slli a0, a0, 24 807; RV32I-NEXT: srai a0, a0, 27 808; RV32I-NEXT: ret 809; 810; RV32IM-LABEL: sdiv8_pow2: 811; RV32IM: # %bb.0: 812; RV32IM-NEXT: slli a1, a0, 24 813; RV32IM-NEXT: srai a1, a1, 24 814; RV32IM-NEXT: srli a1, a1, 12 815; RV32IM-NEXT: andi a1, a1, 7 816; RV32IM-NEXT: add a0, a0, a1 817; RV32IM-NEXT: slli a0, a0, 24 818; RV32IM-NEXT: srai a0, a0, 27 819; RV32IM-NEXT: ret 820; 821; RV64I-LABEL: sdiv8_pow2: 822; RV64I: # %bb.0: 823; RV64I-NEXT: slli a1, a0, 56 824; RV64I-NEXT: srai a1, a1, 56 825; RV64I-NEXT: srli a1, a1, 12 826; RV64I-NEXT: andi a1, a1, 7 827; RV64I-NEXT: add a0, a0, a1 828; RV64I-NEXT: slli a0, a0, 56 829; RV64I-NEXT: srai a0, a0, 59 830; RV64I-NEXT: ret 831; 832; RV64IM-LABEL: sdiv8_pow2: 833; RV64IM: # %bb.0: 834; RV64IM-NEXT: slli a1, a0, 56 835; RV64IM-NEXT: srai a1, a1, 56 836; RV64IM-NEXT: srli a1, a1, 12 837; RV64IM-NEXT: andi a1, a1, 7 838; RV64IM-NEXT: add a0, a0, a1 839; RV64IM-NEXT: slli a0, a0, 56 840; RV64IM-NEXT: srai a0, a0, 59 841; RV64IM-NEXT: ret 842 %1 = sdiv i8 %a, 8 843 ret i8 %1 844} 845 846define i16 @sdiv16(i16 %a, i16 %b) nounwind { 847; RV32I-LABEL: sdiv16: 848; RV32I: # %bb.0: 849; RV32I-NEXT: addi sp, sp, -16 850; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 851; RV32I-NEXT: slli a0, a0, 16 852; RV32I-NEXT: srai a0, a0, 16 853; RV32I-NEXT: slli a1, a1, 16 854; RV32I-NEXT: srai a1, a1, 16 855; RV32I-NEXT: call __divsi3@plt 856; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 857; RV32I-NEXT: addi sp, sp, 16 858; RV32I-NEXT: ret 859; 860; RV32IM-LABEL: sdiv16: 861; RV32IM: # %bb.0: 862; RV32IM-NEXT: slli a1, a1, 16 863; RV32IM-NEXT: srai a1, a1, 16 864; RV32IM-NEXT: slli a0, a0, 16 865; RV32IM-NEXT: srai a0, a0, 16 866; RV32IM-NEXT: div a0, a0, a1 867; RV32IM-NEXT: ret 868; 869; RV64I-LABEL: sdiv16: 870; RV64I: # %bb.0: 871; RV64I-NEXT: addi sp, sp, -16 872; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 873; RV64I-NEXT: slli a0, a0, 48 874; RV64I-NEXT: srai a0, a0, 48 875; RV64I-NEXT: slli a1, a1, 48 876; RV64I-NEXT: srai a1, a1, 48 877; RV64I-NEXT: call __divdi3@plt 878; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 879; RV64I-NEXT: addi sp, sp, 16 880; RV64I-NEXT: ret 881; 882; RV64IM-LABEL: sdiv16: 883; RV64IM: # %bb.0: 884; RV64IM-NEXT: slli a1, a1, 48 885; RV64IM-NEXT: srai a1, a1, 48 886; RV64IM-NEXT: slli a0, a0, 48 887; RV64IM-NEXT: srai a0, a0, 48 888; RV64IM-NEXT: divw a0, a0, a1 889; RV64IM-NEXT: ret 890 %1 = sdiv i16 %a, %b 891 ret i16 %1 892} 893 894define i16 @sdiv16_constant(i16 %a) nounwind { 895; RV32I-LABEL: sdiv16_constant: 896; RV32I: # %bb.0: 897; RV32I-NEXT: addi sp, sp, -16 898; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 899; RV32I-NEXT: slli a0, a0, 16 900; RV32I-NEXT: srai a0, a0, 16 901; RV32I-NEXT: addi a1, zero, 5 902; RV32I-NEXT: call __divsi3@plt 903; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 904; RV32I-NEXT: addi sp, sp, 16 905; RV32I-NEXT: ret 906; 907; RV32IM-LABEL: sdiv16_constant: 908; RV32IM: # %bb.0: 909; RV32IM-NEXT: slli a0, a0, 16 910; RV32IM-NEXT: srai a0, a0, 16 911; RV32IM-NEXT: lui a1, 6 912; RV32IM-NEXT: addi a1, a1, 1639 913; RV32IM-NEXT: mul a0, a0, a1 914; RV32IM-NEXT: srli a1, a0, 31 915; RV32IM-NEXT: srai a0, a0, 17 916; RV32IM-NEXT: add a0, a0, a1 917; RV32IM-NEXT: ret 918; 919; RV64I-LABEL: sdiv16_constant: 920; RV64I: # %bb.0: 921; RV64I-NEXT: addi sp, sp, -16 922; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 923; RV64I-NEXT: slli a0, a0, 48 924; RV64I-NEXT: srai a0, a0, 48 925; RV64I-NEXT: addi a1, zero, 5 926; RV64I-NEXT: call __divdi3@plt 927; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 928; RV64I-NEXT: addi sp, sp, 16 929; RV64I-NEXT: ret 930; 931; RV64IM-LABEL: sdiv16_constant: 932; RV64IM: # %bb.0: 933; RV64IM-NEXT: slli a0, a0, 48 934; RV64IM-NEXT: srai a0, a0, 48 935; RV64IM-NEXT: lui a1, 6 936; RV64IM-NEXT: addiw a1, a1, 1639 937; RV64IM-NEXT: mul a0, a0, a1 938; RV64IM-NEXT: srai a1, a0, 17 939; RV64IM-NEXT: srli a0, a0, 31 940; RV64IM-NEXT: andi a0, a0, 1 941; RV64IM-NEXT: add a0, a1, a0 942; RV64IM-NEXT: ret 943 %1 = sdiv i16 %a, 5 944 ret i16 %1 945} 946 947define i16 @sdiv16_pow2(i16 %a) nounwind { 948; RV32I-LABEL: sdiv16_pow2: 949; RV32I: # %bb.0: 950; RV32I-NEXT: slli a1, a0, 16 951; RV32I-NEXT: srai a1, a1, 16 952; RV32I-NEXT: srli a1, a1, 28 953; RV32I-NEXT: andi a1, a1, 7 954; RV32I-NEXT: add a0, a0, a1 955; RV32I-NEXT: slli a0, a0, 16 956; RV32I-NEXT: srai a0, a0, 19 957; RV32I-NEXT: ret 958; 959; RV32IM-LABEL: sdiv16_pow2: 960; RV32IM: # %bb.0: 961; RV32IM-NEXT: slli a1, a0, 16 962; RV32IM-NEXT: srai a1, a1, 16 963; RV32IM-NEXT: srli a1, a1, 28 964; RV32IM-NEXT: andi a1, a1, 7 965; RV32IM-NEXT: add a0, a0, a1 966; RV32IM-NEXT: slli a0, a0, 16 967; RV32IM-NEXT: srai a0, a0, 19 968; RV32IM-NEXT: ret 969; 970; RV64I-LABEL: sdiv16_pow2: 971; RV64I: # %bb.0: 972; RV64I-NEXT: slli a1, a0, 48 973; RV64I-NEXT: srai a1, a1, 48 974; RV64I-NEXT: srli a1, a1, 28 975; RV64I-NEXT: andi a1, a1, 7 976; RV64I-NEXT: add a0, a0, a1 977; RV64I-NEXT: slli a0, a0, 48 978; RV64I-NEXT: srai a0, a0, 51 979; RV64I-NEXT: ret 980; 981; RV64IM-LABEL: sdiv16_pow2: 982; RV64IM: # %bb.0: 983; RV64IM-NEXT: slli a1, a0, 48 984; RV64IM-NEXT: srai a1, a1, 48 985; RV64IM-NEXT: srli a1, a1, 28 986; RV64IM-NEXT: andi a1, a1, 7 987; RV64IM-NEXT: add a0, a0, a1 988; RV64IM-NEXT: slli a0, a0, 48 989; RV64IM-NEXT: srai a0, a0, 51 990; RV64IM-NEXT: ret 991 %1 = sdiv i16 %a, 8 992 ret i16 %1 993} 994