diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 28244728f656e..994aa942b8dff 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -1065,17 +1065,21 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) { if (!isMask_64(C2)) break; - // If this can be an ANDI, ZEXT.H or ZEXT.W, don't do this if the ANDI/ZEXT - // has multiple users or the constant is a simm12. This prevents inserting - // a shift and still have uses of the AND/ZEXT. Shifting a simm12 will - // likely make it more costly to materialize. Otherwise, using a SLLI - // might allow it to be compressed. + // If this can be an ANDI or ZEXT.H, don't do this if the ANDI/ZEXT has + // multiple users or the constant is a simm12. This prevents inserting a + // shift and still have uses of the AND/ZEXT. Shifting a simm12 will likely + // make it more costly to materialize. Otherwise, using a SLLI might allow + // it to be compressed. bool IsANDIOrZExt = isInt<12>(C2) || - (C2 == UINT64_C(0xFFFF) && Subtarget->hasStdExtZbb()) || - (C2 == UINT64_C(0xFFFFFFFF) && Subtarget->hasStdExtZba()); + (C2 == UINT64_C(0xFFFF) && Subtarget->hasStdExtZbb()); if (IsANDIOrZExt && (isInt<12>(N1C->getSExtValue()) || !N0.hasOneUse())) break; + // If this can be a ZEXT.w, don't do this if the ZEXT has multiple users or + // the constant is a simm32. + bool IsZExtW = C2 == UINT64_C(0xFFFFFFFF) && Subtarget->hasStdExtZba(); + if (IsZExtW && (isInt<32>(N1C->getSExtValue()) || !N0.hasOneUse())) + break; // We need to shift left the AND input and C1 by a total of XLen bits. diff --git a/llvm/test/CodeGen/RISCV/div-by-constant.ll b/llvm/test/CodeGen/RISCV/div-by-constant.ll index da3045614a245..05200f33e3ea6 100644 --- a/llvm/test/CodeGen/RISCV/div-by-constant.ll +++ b/llvm/test/CodeGen/RISCV/div-by-constant.ll @@ -46,19 +46,32 @@ define i32 @udiv_constant_add(i32 %a) nounwind { ; RV32-NEXT: srli a0, a0, 2 ; RV32-NEXT: ret ; -; RV64-LABEL: udiv_constant_add: -; RV64: # %bb.0: -; RV64-NEXT: slli a1, a0, 32 -; RV64-NEXT: lui a2, 149797 -; RV64-NEXT: addiw a2, a2, -1755 -; RV64-NEXT: slli a2, a2, 32 -; RV64-NEXT: mulhu a1, a1, a2 -; RV64-NEXT: srli a1, a1, 32 -; RV64-NEXT: subw a0, a0, a1 -; RV64-NEXT: srliw a0, a0, 1 -; RV64-NEXT: add a0, a0, a1 -; RV64-NEXT: srli a0, a0, 2 -; RV64-NEXT: ret +; RV64IM-LABEL: udiv_constant_add: +; RV64IM: # %bb.0: +; RV64IM-NEXT: slli a1, a0, 32 +; RV64IM-NEXT: lui a2, 149797 +; RV64IM-NEXT: addiw a2, a2, -1755 +; RV64IM-NEXT: slli a2, a2, 32 +; RV64IM-NEXT: mulhu a1, a1, a2 +; RV64IM-NEXT: srli a1, a1, 32 +; RV64IM-NEXT: subw a0, a0, a1 +; RV64IM-NEXT: srliw a0, a0, 1 +; RV64IM-NEXT: add a0, a0, a1 +; RV64IM-NEXT: srli a0, a0, 2 +; RV64IM-NEXT: ret +; +; RV64IMZB-LABEL: udiv_constant_add: +; RV64IMZB: # %bb.0: +; RV64IMZB-NEXT: zext.w a1, a0 +; RV64IMZB-NEXT: lui a2, 149797 +; RV64IMZB-NEXT: addiw a2, a2, -1755 +; RV64IMZB-NEXT: mul a1, a1, a2 +; RV64IMZB-NEXT: srli a1, a1, 32 +; RV64IMZB-NEXT: subw a0, a0, a1 +; RV64IMZB-NEXT: srliw a0, a0, 1 +; RV64IMZB-NEXT: add a0, a0, a1 +; RV64IMZB-NEXT: srli a0, a0, 2 +; RV64IMZB-NEXT: ret %1 = udiv i32 %a, 7 ret i32 %1 }