264 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_urem_positive_odd(i32 %x) nounwind {12; RV32I-LABEL: fold_urem_positive_odd:13; RV32I: # %bb.0:14; RV32I-NEXT: li a1, 9515; RV32I-NEXT: tail __umodsi316;17; RV32IM-LABEL: fold_urem_positive_odd:18; RV32IM: # %bb.0:19; RV32IM-NEXT: lui a1, 36424220; RV32IM-NEXT: addi a1, a1, 77721; RV32IM-NEXT: mulhu a1, a0, a122; RV32IM-NEXT: sub a2, a0, a123; RV32IM-NEXT: srli a2, a2, 124; RV32IM-NEXT: add a1, a2, a125; RV32IM-NEXT: srli a1, a1, 626; RV32IM-NEXT: li a2, 9527; RV32IM-NEXT: mul a1, a1, a228; RV32IM-NEXT: sub a0, a0, a129; RV32IM-NEXT: ret30;31; RV64I-LABEL: fold_urem_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: slli a0, a0, 3236; RV64I-NEXT: srli a0, a0, 3237; RV64I-NEXT: li a1, 9538; RV64I-NEXT: call __umoddi339; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload40; RV64I-NEXT: addi sp, sp, 1641; RV64I-NEXT: ret42;43; RV64IM-LABEL: fold_urem_positive_odd:44; RV64IM: # %bb.0:45; RV64IM-NEXT: slli a1, a0, 3246; RV64IM-NEXT: lui a2, 36424247; RV64IM-NEXT: addi a2, a2, 77748; RV64IM-NEXT: slli a2, a2, 3249; RV64IM-NEXT: mulhu a1, a1, a250; RV64IM-NEXT: srli a1, a1, 3251; RV64IM-NEXT: sub a2, a0, a152; RV64IM-NEXT: srliw a2, a2, 153; RV64IM-NEXT: add a1, a2, a154; RV64IM-NEXT: srli a1, a1, 655; RV64IM-NEXT: li a2, 9556; RV64IM-NEXT: mul a1, a1, a257; RV64IM-NEXT: subw a0, a0, a158; RV64IM-NEXT: ret59 %1 = urem i32 %x, 9560 ret i32 %161}62 63 64define i32 @fold_urem_positive_even(i32 %x) nounwind {65; RV32I-LABEL: fold_urem_positive_even:66; RV32I: # %bb.0:67; RV32I-NEXT: li a1, 106068; RV32I-NEXT: tail __umodsi369;70; RV32IM-LABEL: fold_urem_positive_even:71; RV32IM: # %bb.0:72; RV32IM-NEXT: lui a1, 101296473; RV32IM-NEXT: addi a1, a1, -6174; RV32IM-NEXT: mulhu a1, a0, a175; RV32IM-NEXT: srli a1, a1, 1076; RV32IM-NEXT: li a2, 106077; RV32IM-NEXT: mul a1, a1, a278; RV32IM-NEXT: sub a0, a0, a179; RV32IM-NEXT: ret80;81; RV64I-LABEL: fold_urem_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: slli a0, a0, 3286; RV64I-NEXT: srli a0, a0, 3287; RV64I-NEXT: li a1, 106088; RV64I-NEXT: call __umoddi389; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload90; RV64I-NEXT: addi sp, sp, 1691; RV64I-NEXT: ret92;93; RV64IM-LABEL: fold_urem_positive_even:94; RV64IM: # %bb.0:95; RV64IM-NEXT: slli a1, a0, 3296; RV64IM-NEXT: lui a2, 101296497; RV64IM-NEXT: addi a2, a2, -6198; RV64IM-NEXT: slli a2, a2, 3299; RV64IM-NEXT: mulhu a1, a1, a2100; RV64IM-NEXT: srli a1, a1, 42101; RV64IM-NEXT: li a2, 1060102; RV64IM-NEXT: mul a1, a1, a2103; RV64IM-NEXT: subw a0, a0, a1104; RV64IM-NEXT: ret105 %1 = urem i32 %x, 1060106 ret i32 %1107}108 109 110; Don't fold if we can combine urem with udiv.111define i32 @combine_urem_udiv(i32 %x) nounwind {112; RV32I-LABEL: combine_urem_udiv:113; RV32I: # %bb.0:114; RV32I-NEXT: addi sp, sp, -16115; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill116; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill117; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill118; RV32I-NEXT: mv s0, a0119; RV32I-NEXT: li a1, 95120; RV32I-NEXT: call __umodsi3121; RV32I-NEXT: mv s1, a0122; RV32I-NEXT: li a1, 95123; RV32I-NEXT: mv a0, s0124; RV32I-NEXT: call __udivsi3125; RV32I-NEXT: add a0, s1, a0126; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload127; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload128; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload129; RV32I-NEXT: addi sp, sp, 16130; RV32I-NEXT: ret131;132; RV32IM-LABEL: combine_urem_udiv:133; RV32IM: # %bb.0:134; RV32IM-NEXT: lui a1, 364242135; RV32IM-NEXT: addi a1, a1, 777136; RV32IM-NEXT: mulhu a1, a0, a1137; RV32IM-NEXT: sub a2, a0, a1138; RV32IM-NEXT: srli a2, a2, 1139; RV32IM-NEXT: add a1, a2, a1140; RV32IM-NEXT: li a2, 95141; RV32IM-NEXT: srli a1, a1, 6142; RV32IM-NEXT: mul a2, a1, a2143; RV32IM-NEXT: add a0, a0, a1144; RV32IM-NEXT: sub a0, a0, a2145; RV32IM-NEXT: ret146;147; RV64I-LABEL: combine_urem_udiv:148; RV64I: # %bb.0:149; RV64I-NEXT: addi sp, sp, -32150; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill151; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill152; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill153; RV64I-NEXT: slli a0, a0, 32154; RV64I-NEXT: srli s0, a0, 32155; RV64I-NEXT: li a1, 95156; RV64I-NEXT: mv a0, s0157; RV64I-NEXT: call __umoddi3158; RV64I-NEXT: mv s1, a0159; RV64I-NEXT: li a1, 95160; RV64I-NEXT: mv a0, s0161; RV64I-NEXT: call __udivdi3162; RV64I-NEXT: add a0, s1, a0163; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload164; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload165; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload166; RV64I-NEXT: addi sp, sp, 32167; RV64I-NEXT: ret168;169; RV64IM-LABEL: combine_urem_udiv:170; RV64IM: # %bb.0:171; RV64IM-NEXT: slli a1, a0, 32172; RV64IM-NEXT: lui a2, 364242173; RV64IM-NEXT: addi a2, a2, 777174; RV64IM-NEXT: slli a2, a2, 32175; RV64IM-NEXT: mulhu a1, a1, a2176; RV64IM-NEXT: srli a1, a1, 32177; RV64IM-NEXT: sub a2, a0, a1178; RV64IM-NEXT: srliw a2, a2, 1179; RV64IM-NEXT: add a1, a2, a1180; RV64IM-NEXT: li a2, 95181; RV64IM-NEXT: srli a1, a1, 6182; RV64IM-NEXT: mul a2, a1, a2183; RV64IM-NEXT: add a0, a0, a1184; RV64IM-NEXT: subw a0, a0, a2185; RV64IM-NEXT: ret186 %1 = urem i32 %x, 95187 %2 = udiv i32 %x, 95188 %3 = add i32 %1, %2189 ret i32 %3190}191 192; Don't fold for divisors that are a power of two.193define i32 @dont_fold_urem_power_of_two(i32 %x) nounwind {194; CHECK-LABEL: dont_fold_urem_power_of_two:195; CHECK: # %bb.0:196; CHECK-NEXT: andi a0, a0, 63197; CHECK-NEXT: ret198 %1 = urem i32 %x, 64199 ret i32 %1200}201 202; Don't fold if the divisor is one.203define i32 @dont_fold_urem_one(i32 %x) nounwind {204; CHECK-LABEL: dont_fold_urem_one:205; CHECK: # %bb.0:206; CHECK-NEXT: li a0, 0207; CHECK-NEXT: ret208 %1 = urem i32 %x, 1209 ret i32 %1210}211 212; Don't fold if the divisor is 2^32.213define i32 @dont_fold_urem_i32_umax(i32 %x) nounwind {214; CHECK-LABEL: dont_fold_urem_i32_umax:215; CHECK: # %bb.0:216; CHECK-NEXT: ret217 %1 = urem i32 %x, 4294967296218 ret i32 %1219}220 221; Don't fold i64 urem222define i64 @dont_fold_urem_i64(i64 %x) nounwind {223; RV32I-LABEL: dont_fold_urem_i64:224; RV32I: # %bb.0:225; RV32I-NEXT: addi sp, sp, -16226; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill227; RV32I-NEXT: li a2, 98228; RV32I-NEXT: li a3, 0229; RV32I-NEXT: call __umoddi3230; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload231; RV32I-NEXT: addi sp, sp, 16232; RV32I-NEXT: ret233;234; RV32IM-LABEL: dont_fold_urem_i64:235; RV32IM: # %bb.0:236; RV32IM-NEXT: addi sp, sp, -16237; RV32IM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill238; RV32IM-NEXT: li a2, 98239; RV32IM-NEXT: li a3, 0240; RV32IM-NEXT: call __umoddi3241; RV32IM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload242; RV32IM-NEXT: addi sp, sp, 16243; RV32IM-NEXT: ret244;245; RV64I-LABEL: dont_fold_urem_i64:246; RV64I: # %bb.0:247; RV64I-NEXT: li a1, 98248; RV64I-NEXT: tail __umoddi3249;250; RV64IM-LABEL: dont_fold_urem_i64:251; RV64IM: # %bb.0:252; RV64IM-NEXT: lui a1, %hi(.LCPI6_0)253; RV64IM-NEXT: ld a1, %lo(.LCPI6_0)(a1)254; RV64IM-NEXT: srli a2, a0, 1255; RV64IM-NEXT: mulhu a1, a2, a1256; RV64IM-NEXT: srli a1, a1, 4257; RV64IM-NEXT: li a2, 98258; RV64IM-NEXT: mul a1, a1, a2259; RV64IM-NEXT: sub a0, a0, a1260; RV64IM-NEXT: ret261 %1 = urem i64 %x, 98262 ret i64 %1263}264