430 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \3; RUN: | FileCheck -check-prefixes=CHECK,RV32I %s4; RUN: llc -mtriple=riscv32 -mattr=+m -verify-machineinstrs < %s \5; RUN: | FileCheck -check-prefixes=CHECK,RV32IM %s6; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \7; RUN: | FileCheck -check-prefixes=CHECK,RV64I %s8; RUN: llc -mtriple=riscv64 -mattr=+m -verify-machineinstrs < %s \9; RUN: | FileCheck -check-prefixes=CHECK,RV64IM %s10 11define i32 @fold_srem_positive_odd(i32 %x) nounwind {12; RV32I-LABEL: fold_srem_positive_odd:13; RV32I: # %bb.0:14; RV32I-NEXT: li a1, 9515; RV32I-NEXT: tail __modsi316;17; RV32IM-LABEL: fold_srem_positive_odd:18; RV32IM: # %bb.0:19; RV32IM-NEXT: lui a1, 70640920; RV32IM-NEXT: addi a1, a1, 38921; RV32IM-NEXT: mulh a1, a0, a122; RV32IM-NEXT: add a1, a1, a023; RV32IM-NEXT: srli a2, a1, 3124; RV32IM-NEXT: srai a1, a1, 625; RV32IM-NEXT: add a1, a1, a226; RV32IM-NEXT: li a2, 9527; RV32IM-NEXT: mul a1, a1, a228; RV32IM-NEXT: sub a0, a0, a129; RV32IM-NEXT: ret30;31; RV64I-LABEL: fold_srem_positive_odd:32; RV64I: # %bb.0:33; RV64I-NEXT: addi sp, sp, -1634; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill35; RV64I-NEXT: sext.w a0, a036; RV64I-NEXT: li a1, 9537; RV64I-NEXT: call __moddi338; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload39; RV64I-NEXT: addi sp, sp, 1640; RV64I-NEXT: ret41;42; RV64IM-LABEL: fold_srem_positive_odd:43; RV64IM: # %bb.0:44; RV64IM-NEXT: sext.w a1, a045; RV64IM-NEXT: lui a2, 70640946; RV64IM-NEXT: addi a2, a2, 38947; RV64IM-NEXT: mul a1, a1, a248; RV64IM-NEXT: srli a1, a1, 3249; RV64IM-NEXT: add a1, a1, a050; RV64IM-NEXT: srliw a2, a1, 3151; RV64IM-NEXT: sraiw a1, a1, 652; RV64IM-NEXT: add a1, a1, a253; RV64IM-NEXT: li a2, 9554; RV64IM-NEXT: mul a1, a1, a255; RV64IM-NEXT: subw a0, a0, a156; RV64IM-NEXT: ret57 %1 = srem i32 %x, 9558 ret i32 %159}60 61 62define i32 @fold_srem_positive_even(i32 %x) nounwind {63; RV32I-LABEL: fold_srem_positive_even:64; RV32I: # %bb.0:65; RV32I-NEXT: li a1, 106066; RV32I-NEXT: tail __modsi367;68; RV32IM-LABEL: fold_srem_positive_even:69; RV32IM: # %bb.0:70; RV32IM-NEXT: lui a1, 25324171; RV32IM-NEXT: addi a1, a1, -1572; RV32IM-NEXT: mulh a1, a0, a173; RV32IM-NEXT: srli a2, a1, 3174; RV32IM-NEXT: srai a1, a1, 875; RV32IM-NEXT: add a1, a1, a276; RV32IM-NEXT: li a2, 106077; RV32IM-NEXT: mul a1, a1, a278; RV32IM-NEXT: sub a0, a0, a179; RV32IM-NEXT: ret80;81; RV64I-LABEL: fold_srem_positive_even:82; RV64I: # %bb.0:83; RV64I-NEXT: addi sp, sp, -1684; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill85; RV64I-NEXT: sext.w a0, a086; RV64I-NEXT: li a1, 106087; RV64I-NEXT: call __moddi388; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload89; RV64I-NEXT: addi sp, sp, 1690; RV64I-NEXT: ret91;92; RV64IM-LABEL: fold_srem_positive_even:93; RV64IM: # %bb.0:94; RV64IM-NEXT: sext.w a1, a095; RV64IM-NEXT: lui a2, 25324196; RV64IM-NEXT: addi a2, a2, -1597; RV64IM-NEXT: mul a1, a1, a298; RV64IM-NEXT: srli a2, a1, 6399; RV64IM-NEXT: srai a1, a1, 40100; RV64IM-NEXT: add a1, a1, a2101; RV64IM-NEXT: li a2, 1060102; RV64IM-NEXT: mul a1, a1, a2103; RV64IM-NEXT: subw a0, a0, a1104; RV64IM-NEXT: ret105 %1 = srem i32 %x, 1060106 ret i32 %1107}108 109 110define i32 @fold_srem_negative_odd(i32 %x) nounwind {111; RV32I-LABEL: fold_srem_negative_odd:112; RV32I: # %bb.0:113; RV32I-NEXT: li a1, -723114; RV32I-NEXT: tail __modsi3115;116; RV32IM-LABEL: fold_srem_negative_odd:117; RV32IM: # %bb.0:118; RV32IM-NEXT: lui a1, 677296119; RV32IM-NEXT: addi a1, a1, -91120; RV32IM-NEXT: mulh a1, a0, a1121; RV32IM-NEXT: srli a2, a1, 31122; RV32IM-NEXT: srai a1, a1, 8123; RV32IM-NEXT: add a1, a1, a2124; RV32IM-NEXT: li a2, -723125; RV32IM-NEXT: mul a1, a1, a2126; RV32IM-NEXT: sub a0, a0, a1127; RV32IM-NEXT: ret128;129; RV64I-LABEL: fold_srem_negative_odd:130; RV64I: # %bb.0:131; RV64I-NEXT: addi sp, sp, -16132; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill133; RV64I-NEXT: sext.w a0, a0134; RV64I-NEXT: li a1, -723135; RV64I-NEXT: call __moddi3136; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload137; RV64I-NEXT: addi sp, sp, 16138; RV64I-NEXT: ret139;140; RV64IM-LABEL: fold_srem_negative_odd:141; RV64IM: # %bb.0:142; RV64IM-NEXT: sext.w a1, a0143; RV64IM-NEXT: lui a2, 677296144; RV64IM-NEXT: addi a2, a2, -91145; RV64IM-NEXT: mul a1, a1, a2146; RV64IM-NEXT: srli a2, a1, 63147; RV64IM-NEXT: srai a1, a1, 40148; RV64IM-NEXT: add a1, a1, a2149; RV64IM-NEXT: li a2, -723150; RV64IM-NEXT: mul a1, a1, a2151; RV64IM-NEXT: subw a0, a0, a1152; RV64IM-NEXT: ret153 %1 = srem i32 %x, -723154 ret i32 %1155}156 157 158define i32 @fold_srem_negative_even(i32 %x) nounwind {159; RV32I-LABEL: fold_srem_negative_even:160; RV32I: # %bb.0:161; RV32I-NEXT: lui a1, 1048570162; RV32I-NEXT: addi a1, a1, 1595163; RV32I-NEXT: tail __modsi3164;165; RV32IM-LABEL: fold_srem_negative_even:166; RV32IM: # %bb.0:167; RV32IM-NEXT: lui a1, 1036895168; RV32IM-NEXT: addi a1, a1, 999169; RV32IM-NEXT: mulh a1, a0, a1170; RV32IM-NEXT: srli a2, a1, 31171; RV32IM-NEXT: srai a1, a1, 8172; RV32IM-NEXT: add a1, a1, a2173; RV32IM-NEXT: lui a2, 1048570174; RV32IM-NEXT: addi a2, a2, 1595175; RV32IM-NEXT: mul a1, a1, a2176; RV32IM-NEXT: sub a0, a0, a1177; RV32IM-NEXT: ret178;179; RV64I-LABEL: fold_srem_negative_even:180; RV64I: # %bb.0:181; RV64I-NEXT: addi sp, sp, -16182; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill183; RV64I-NEXT: sext.w a0, a0184; RV64I-NEXT: lui a1, 1048570185; RV64I-NEXT: addi a1, a1, 1595186; RV64I-NEXT: call __moddi3187; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload188; RV64I-NEXT: addi sp, sp, 16189; RV64I-NEXT: ret190;191; RV64IM-LABEL: fold_srem_negative_even:192; RV64IM: # %bb.0:193; RV64IM-NEXT: sext.w a1, a0194; RV64IM-NEXT: lui a2, 1036895195; RV64IM-NEXT: addi a2, a2, 999196; RV64IM-NEXT: mul a1, a1, a2197; RV64IM-NEXT: srli a2, a1, 63198; RV64IM-NEXT: srai a1, a1, 40199; RV64IM-NEXT: add a1, a1, a2200; RV64IM-NEXT: lui a2, 1048570201; RV64IM-NEXT: addi a2, a2, 1595202; RV64IM-NEXT: mul a1, a1, a2203; RV64IM-NEXT: subw a0, a0, a1204; RV64IM-NEXT: ret205 %1 = srem i32 %x, -22981206 ret i32 %1207}208 209 210; Don't fold if we can combine srem with sdiv.211define i32 @combine_srem_sdiv(i32 %x) nounwind {212; RV32I-LABEL: combine_srem_sdiv:213; RV32I: # %bb.0:214; RV32I-NEXT: addi sp, sp, -16215; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill216; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill217; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill218; RV32I-NEXT: mv s0, a0219; RV32I-NEXT: li a1, 95220; RV32I-NEXT: call __modsi3221; RV32I-NEXT: mv s1, a0222; RV32I-NEXT: li a1, 95223; RV32I-NEXT: mv a0, s0224; RV32I-NEXT: call __divsi3225; RV32I-NEXT: add a0, s1, a0226; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload227; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload228; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload229; RV32I-NEXT: addi sp, sp, 16230; RV32I-NEXT: ret231;232; RV32IM-LABEL: combine_srem_sdiv:233; RV32IM: # %bb.0:234; RV32IM-NEXT: lui a1, 706409235; RV32IM-NEXT: addi a1, a1, 389236; RV32IM-NEXT: mulh a1, a0, a1237; RV32IM-NEXT: add a1, a1, a0238; RV32IM-NEXT: srli a2, a1, 31239; RV32IM-NEXT: srai a1, a1, 6240; RV32IM-NEXT: add a1, a1, a2241; RV32IM-NEXT: li a2, 95242; RV32IM-NEXT: mul a2, a1, a2243; RV32IM-NEXT: add a0, a0, a1244; RV32IM-NEXT: sub a0, a0, a2245; RV32IM-NEXT: ret246;247; RV64I-LABEL: combine_srem_sdiv:248; RV64I: # %bb.0:249; RV64I-NEXT: addi sp, sp, -32250; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill251; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill252; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill253; RV64I-NEXT: sext.w s0, a0254; RV64I-NEXT: li a1, 95255; RV64I-NEXT: mv a0, s0256; RV64I-NEXT: call __moddi3257; RV64I-NEXT: mv s1, a0258; RV64I-NEXT: li a1, 95259; RV64I-NEXT: mv a0, s0260; RV64I-NEXT: call __divdi3261; RV64I-NEXT: addw a0, s1, a0262; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload263; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload264; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload265; RV64I-NEXT: addi sp, sp, 32266; RV64I-NEXT: ret267;268; RV64IM-LABEL: combine_srem_sdiv:269; RV64IM: # %bb.0:270; RV64IM-NEXT: sext.w a1, a0271; RV64IM-NEXT: lui a2, 706409272; RV64IM-NEXT: addi a2, a2, 389273; RV64IM-NEXT: mul a1, a1, a2274; RV64IM-NEXT: srli a1, a1, 32275; RV64IM-NEXT: add a1, a1, a0276; RV64IM-NEXT: srliw a2, a1, 31277; RV64IM-NEXT: sraiw a1, a1, 6278; RV64IM-NEXT: add a1, a1, a2279; RV64IM-NEXT: li a2, 95280; RV64IM-NEXT: mul a2, a1, a2281; RV64IM-NEXT: add a0, a0, a1282; RV64IM-NEXT: subw a0, a0, a2283; RV64IM-NEXT: ret284 %1 = srem i32 %x, 95285 %2 = sdiv i32 %x, 95286 %3 = add i32 %1, %2287 ret i32 %3288}289 290; Don't fold for divisors that are a power of two.291define i32 @dont_fold_srem_power_of_two(i32 %x) nounwind {292; RV32I-LABEL: dont_fold_srem_power_of_two:293; RV32I: # %bb.0:294; RV32I-NEXT: srai a1, a0, 31295; RV32I-NEXT: srli a1, a1, 26296; RV32I-NEXT: add a1, a0, a1297; RV32I-NEXT: andi a1, a1, -64298; RV32I-NEXT: sub a0, a0, a1299; RV32I-NEXT: ret300;301; RV32IM-LABEL: dont_fold_srem_power_of_two:302; RV32IM: # %bb.0:303; RV32IM-NEXT: srai a1, a0, 31304; RV32IM-NEXT: srli a1, a1, 26305; RV32IM-NEXT: add a1, a0, a1306; RV32IM-NEXT: andi a1, a1, -64307; RV32IM-NEXT: sub a0, a0, a1308; RV32IM-NEXT: ret309;310; RV64I-LABEL: dont_fold_srem_power_of_two:311; RV64I: # %bb.0:312; RV64I-NEXT: sraiw a1, a0, 31313; RV64I-NEXT: srliw a1, a1, 26314; RV64I-NEXT: add a1, a0, a1315; RV64I-NEXT: andi a1, a1, -64316; RV64I-NEXT: subw a0, a0, a1317; RV64I-NEXT: ret318;319; RV64IM-LABEL: dont_fold_srem_power_of_two:320; RV64IM: # %bb.0:321; RV64IM-NEXT: sraiw a1, a0, 31322; RV64IM-NEXT: srliw a1, a1, 26323; RV64IM-NEXT: add a1, a0, a1324; RV64IM-NEXT: andi a1, a1, -64325; RV64IM-NEXT: subw a0, a0, a1326; RV64IM-NEXT: ret327 %1 = srem i32 %x, 64328 ret i32 %1329}330 331; Don't fold if the divisor is one.332define i32 @dont_fold_srem_one(i32 %x) nounwind {333; CHECK-LABEL: dont_fold_srem_one:334; CHECK: # %bb.0:335; CHECK-NEXT: li a0, 0336; CHECK-NEXT: ret337 %1 = srem i32 %x, 1338 ret i32 %1339}340 341; Don't fold if the divisor is 2^31.342define i32 @dont_fold_srem_i32_smax(i32 %x) nounwind {343; RV32I-LABEL: dont_fold_srem_i32_smax:344; RV32I: # %bb.0:345; RV32I-NEXT: srai a1, a0, 31346; RV32I-NEXT: srli a1, a1, 1347; RV32I-NEXT: add a1, a0, a1348; RV32I-NEXT: lui a2, 524288349; RV32I-NEXT: and a1, a1, a2350; RV32I-NEXT: add a0, a0, a1351; RV32I-NEXT: ret352;353; RV32IM-LABEL: dont_fold_srem_i32_smax:354; RV32IM: # %bb.0:355; RV32IM-NEXT: srai a1, a0, 31356; RV32IM-NEXT: srli a1, a1, 1357; RV32IM-NEXT: add a1, a0, a1358; RV32IM-NEXT: lui a2, 524288359; RV32IM-NEXT: and a1, a1, a2360; RV32IM-NEXT: add a0, a0, a1361; RV32IM-NEXT: ret362;363; RV64I-LABEL: dont_fold_srem_i32_smax:364; RV64I: # %bb.0:365; RV64I-NEXT: sraiw a1, a0, 31366; RV64I-NEXT: srliw a1, a1, 1367; RV64I-NEXT: add a1, a0, a1368; RV64I-NEXT: lui a2, 524288369; RV64I-NEXT: and a1, a1, a2370; RV64I-NEXT: addw a0, a0, a1371; RV64I-NEXT: ret372;373; RV64IM-LABEL: dont_fold_srem_i32_smax:374; RV64IM: # %bb.0:375; RV64IM-NEXT: sraiw a1, a0, 31376; RV64IM-NEXT: srliw a1, a1, 1377; RV64IM-NEXT: add a1, a0, a1378; RV64IM-NEXT: lui a2, 524288379; RV64IM-NEXT: and a1, a1, a2380; RV64IM-NEXT: addw a0, a0, a1381; RV64IM-NEXT: ret382 %1 = srem i32 %x, 2147483648383 ret i32 %1384}385 386; Don't fold i64 srem387define i64 @dont_fold_srem_i64(i64 %x) nounwind {388; RV32I-LABEL: dont_fold_srem_i64:389; RV32I: # %bb.0:390; RV32I-NEXT: addi sp, sp, -16391; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill392; RV32I-NEXT: li a2, 98393; RV32I-NEXT: li a3, 0394; RV32I-NEXT: call __moddi3395; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload396; RV32I-NEXT: addi sp, sp, 16397; RV32I-NEXT: ret398;399; RV32IM-LABEL: dont_fold_srem_i64:400; RV32IM: # %bb.0:401; RV32IM-NEXT: addi sp, sp, -16402; RV32IM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill403; RV32IM-NEXT: li a2, 98404; RV32IM-NEXT: li a3, 0405; RV32IM-NEXT: call __moddi3406; RV32IM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload407; RV32IM-NEXT: addi sp, sp, 16408; RV32IM-NEXT: ret409;410; RV64I-LABEL: dont_fold_srem_i64:411; RV64I: # %bb.0:412; RV64I-NEXT: li a1, 98413; RV64I-NEXT: tail __moddi3414;415; RV64IM-LABEL: dont_fold_srem_i64:416; RV64IM: # %bb.0:417; RV64IM-NEXT: lui a1, %hi(.LCPI8_0)418; RV64IM-NEXT: ld a1, %lo(.LCPI8_0)(a1)419; RV64IM-NEXT: mulh a1, a0, a1420; RV64IM-NEXT: srli a2, a1, 63421; RV64IM-NEXT: srai a1, a1, 5422; RV64IM-NEXT: add a1, a1, a2423; RV64IM-NEXT: li a2, 98424; RV64IM-NEXT: mul a1, a1, a2425; RV64IM-NEXT: sub a0, a0, a1426; RV64IM-NEXT: ret427 %1 = srem i64 %x, 98428 ret i64 %1429}430