From b12056bd3390d8fd32782f5e3fee1fd16c136def Mon Sep 17 00:00:00 2001 From: Shiva Chen Date: Tue, 6 Aug 2019 00:24:00 +0000 Subject: [PATCH] [RISCV] Custom legalize i32 operations for RV64 to reduce signed extensions Differential Revision: https://reviews.llvm.org/D65434 llvm-svn: 367960 --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 24 +++++ llvm/test/CodeGen/RISCV/alu32.ll | 4 +- .../calling-conv-lp64-lp64f-lp64d-common.ll | 2 +- .../CodeGen/RISCV/rv64i-exhaustive-w-insts.ll | 36 +++---- .../RISCV/rv64i-w-insts-legalization.ll | 97 +++++++++++++++++++ .../CodeGen/RISCV/rv64m-exhaustive-w-insts.ll | 18 ++-- .../RISCV/rv64m-w-insts-legalization.ll | 34 +++++++ .../CodeGen/RISCV/select-optimize-multiple.ll | 8 +- llvm/test/CodeGen/RISCV/vararg.ll | 4 +- 9 files changed, 191 insertions(+), 36 deletions(-) create mode 100644 llvm/test/CodeGen/RISCV/rv64i-w-insts-legalization.ll create mode 100644 llvm/test/CodeGen/RISCV/rv64m-w-insts-legalization.ll diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 21a15ecdb440..1c139a576ac2 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -100,6 +100,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, setOperationAction(ISD::SIGN_EXTEND_INREG, VT, Expand); if (Subtarget.is64Bit()) { + setOperationAction(ISD::ADD, MVT::i32, Custom); + setOperationAction(ISD::SUB, MVT::i32, Custom); setOperationAction(ISD::SHL, MVT::i32, Custom); setOperationAction(ISD::SRA, MVT::i32, Custom); setOperationAction(ISD::SRL, MVT::i32, Custom); @@ -116,6 +118,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, } if (Subtarget.is64Bit() && Subtarget.hasStdExtM()) { + setOperationAction(ISD::MUL, MVT::i32, Custom); setOperationAction(ISD::SDIV, MVT::i32, Custom); setOperationAction(ISD::UDIV, MVT::i32, Custom); setOperationAction(ISD::UREM, MVT::i32, Custom); @@ -834,6 +837,18 @@ static SDValue customLegalizeToWOp(SDNode *N, SelectionDAG &DAG) { return DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, NewRes); } +// Converts the given 32-bit operation to a i64 operation with signed extension +// semantic to reduce the signed extension instructions. +static SDValue customLegalizeToWOpWithSExt(SDNode *N, SelectionDAG &DAG) { + SDLoc DL(N); + SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(0)); + SDValue NewOp1 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(1)); + SDValue NewWOp = DAG.getNode(N->getOpcode(), DL, MVT::i64, NewOp0, NewOp1); + SDValue NewRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i64, NewWOp, + DAG.getValueType(MVT::i32)); + return DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, NewRes); +} + void RISCVTargetLowering::ReplaceNodeResults(SDNode *N, SmallVectorImpl &Results, SelectionDAG &DAG) const { @@ -854,6 +869,15 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N, Results.push_back(RCW.getValue(2)); break; } + case ISD::ADD: + case ISD::SUB: + case ISD::MUL: + assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() && + "Unexpected custom legalisation"); + if (N->getOperand(1).getOpcode() == ISD::Constant) + return; + Results.push_back(customLegalizeToWOpWithSExt(N, DAG)); + break; case ISD::SHL: case ISD::SRA: case ISD::SRL: diff --git a/llvm/test/CodeGen/RISCV/alu32.ll b/llvm/test/CodeGen/RISCV/alu32.ll index d6f667c9c6f2..975716e53c04 100644 --- a/llvm/test/CodeGen/RISCV/alu32.ll +++ b/llvm/test/CodeGen/RISCV/alu32.ll @@ -153,7 +153,7 @@ define i32 @add(i32 %a, i32 %b) nounwind { ; ; RV64I-LABEL: add: ; RV64I: # %bb.0: -; RV64I-NEXT: add a0, a0, a1 +; RV64I-NEXT: addw a0, a0, a1 ; RV64I-NEXT: ret %1 = add i32 %a, %b ret i32 %1 @@ -167,7 +167,7 @@ define i32 @sub(i32 %a, i32 %b) nounwind { ; ; RV64I-LABEL: sub: ; RV64I: # %bb.0: -; RV64I-NEXT: sub a0, a0, a1 +; RV64I-NEXT: subw a0, a0, a1 ; RV64I-NEXT: ret %1 = sub i32 %a, %b ret i32 %1 diff --git a/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll b/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll index fb27c3ae3e9b..23bb630c67ea 100644 --- a/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll +++ b/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll @@ -63,7 +63,7 @@ define i32 @callee_many_scalars(i8 %a, i16 %b, i32 %c, i128 %d, i32 %e, i32 %f, ; RV64I-NEXT: add a0, a0, a5 ; RV64I-NEXT: add a0, a0, a6 ; RV64I-NEXT: lw a1, 8(sp) -; RV64I-NEXT: add a0, a0, a1 +; RV64I-NEXT: addw a0, a0, a1 ; RV64I-NEXT: ret %a_ext = zext i8 %a to i32 %b_ext = zext i16 %b to i32 diff --git a/llvm/test/CodeGen/RISCV/rv64i-exhaustive-w-insts.ll b/llvm/test/CodeGen/RISCV/rv64i-exhaustive-w-insts.ll index b7f513d6d22f..b14ed50315d7 100644 --- a/llvm/test/CodeGen/RISCV/rv64i-exhaustive-w-insts.ll +++ b/llvm/test/CodeGen/RISCV/rv64i-exhaustive-w-insts.ll @@ -11,7 +11,7 @@ define i32 @aext_addw_aext_aext(i32 %a, i32 %b) nounwind { ; RV64I-LABEL: aext_addw_aext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: add a0, a0, a1 +; RV64I-NEXT: addw a0, a0, a1 ; RV64I-NEXT: ret %1 = add i32 %a, %b ret i32 %1 @@ -20,7 +20,7 @@ define i32 @aext_addw_aext_aext(i32 %a, i32 %b) nounwind { define i32 @aext_addw_aext_sext(i32 %a, i32 signext %b) nounwind { ; RV64I-LABEL: aext_addw_aext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: add a0, a0, a1 +; RV64I-NEXT: addw a0, a0, a1 ; RV64I-NEXT: ret %1 = add i32 %a, %b ret i32 %1 @@ -29,7 +29,7 @@ define i32 @aext_addw_aext_sext(i32 %a, i32 signext %b) nounwind { define i32 @aext_addw_aext_zext(i32 %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: aext_addw_aext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: add a0, a0, a1 +; RV64I-NEXT: addw a0, a0, a1 ; RV64I-NEXT: ret %1 = add i32 %a, %b ret i32 %1 @@ -38,7 +38,7 @@ define i32 @aext_addw_aext_zext(i32 %a, i32 zeroext %b) nounwind { define i32 @aext_addw_sext_aext(i32 signext %a, i32 %b) nounwind { ; RV64I-LABEL: aext_addw_sext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: add a0, a0, a1 +; RV64I-NEXT: addw a0, a0, a1 ; RV64I-NEXT: ret %1 = add i32 %a, %b ret i32 %1 @@ -47,7 +47,7 @@ define i32 @aext_addw_sext_aext(i32 signext %a, i32 %b) nounwind { define i32 @aext_addw_sext_sext(i32 signext %a, i32 signext %b) nounwind { ; RV64I-LABEL: aext_addw_sext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: add a0, a0, a1 +; RV64I-NEXT: addw a0, a0, a1 ; RV64I-NEXT: ret %1 = add i32 %a, %b ret i32 %1 @@ -56,7 +56,7 @@ define i32 @aext_addw_sext_sext(i32 signext %a, i32 signext %b) nounwind { define i32 @aext_addw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: aext_addw_sext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: add a0, a0, a1 +; RV64I-NEXT: addw a0, a0, a1 ; RV64I-NEXT: ret %1 = add i32 %a, %b ret i32 %1 @@ -65,7 +65,7 @@ define i32 @aext_addw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind { define i32 @aext_addw_zext_aext(i32 zeroext %a, i32 %b) nounwind { ; RV64I-LABEL: aext_addw_zext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: add a0, a0, a1 +; RV64I-NEXT: addw a0, a0, a1 ; RV64I-NEXT: ret %1 = add i32 %a, %b ret i32 %1 @@ -74,7 +74,7 @@ define i32 @aext_addw_zext_aext(i32 zeroext %a, i32 %b) nounwind { define i32 @aext_addw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind { ; RV64I-LABEL: aext_addw_zext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: add a0, a0, a1 +; RV64I-NEXT: addw a0, a0, a1 ; RV64I-NEXT: ret %1 = add i32 %a, %b ret i32 %1 @@ -83,7 +83,7 @@ define i32 @aext_addw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind { define i32 @aext_addw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: aext_addw_zext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: add a0, a0, a1 +; RV64I-NEXT: addw a0, a0, a1 ; RV64I-NEXT: ret %1 = add i32 %a, %b ret i32 %1 @@ -279,7 +279,7 @@ define zeroext i32 @zext_addw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind define i32 @aext_subw_aext_aext(i32 %a, i32 %b) nounwind { ; RV64I-LABEL: aext_subw_aext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sub a0, a0, a1 +; RV64I-NEXT: subw a0, a0, a1 ; RV64I-NEXT: ret %1 = sub i32 %a, %b ret i32 %1 @@ -288,7 +288,7 @@ define i32 @aext_subw_aext_aext(i32 %a, i32 %b) nounwind { define i32 @aext_subw_aext_sext(i32 %a, i32 signext %b) nounwind { ; RV64I-LABEL: aext_subw_aext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sub a0, a0, a1 +; RV64I-NEXT: subw a0, a0, a1 ; RV64I-NEXT: ret %1 = sub i32 %a, %b ret i32 %1 @@ -297,7 +297,7 @@ define i32 @aext_subw_aext_sext(i32 %a, i32 signext %b) nounwind { define i32 @aext_subw_aext_zext(i32 %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: aext_subw_aext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sub a0, a0, a1 +; RV64I-NEXT: subw a0, a0, a1 ; RV64I-NEXT: ret %1 = sub i32 %a, %b ret i32 %1 @@ -306,7 +306,7 @@ define i32 @aext_subw_aext_zext(i32 %a, i32 zeroext %b) nounwind { define i32 @aext_subw_sext_aext(i32 signext %a, i32 %b) nounwind { ; RV64I-LABEL: aext_subw_sext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sub a0, a0, a1 +; RV64I-NEXT: subw a0, a0, a1 ; RV64I-NEXT: ret %1 = sub i32 %a, %b ret i32 %1 @@ -315,7 +315,7 @@ define i32 @aext_subw_sext_aext(i32 signext %a, i32 %b) nounwind { define i32 @aext_subw_sext_sext(i32 signext %a, i32 signext %b) nounwind { ; RV64I-LABEL: aext_subw_sext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sub a0, a0, a1 +; RV64I-NEXT: subw a0, a0, a1 ; RV64I-NEXT: ret %1 = sub i32 %a, %b ret i32 %1 @@ -324,7 +324,7 @@ define i32 @aext_subw_sext_sext(i32 signext %a, i32 signext %b) nounwind { define i32 @aext_subw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: aext_subw_sext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sub a0, a0, a1 +; RV64I-NEXT: subw a0, a0, a1 ; RV64I-NEXT: ret %1 = sub i32 %a, %b ret i32 %1 @@ -333,7 +333,7 @@ define i32 @aext_subw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind { define i32 @aext_subw_zext_aext(i32 zeroext %a, i32 %b) nounwind { ; RV64I-LABEL: aext_subw_zext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sub a0, a0, a1 +; RV64I-NEXT: subw a0, a0, a1 ; RV64I-NEXT: ret %1 = sub i32 %a, %b ret i32 %1 @@ -342,7 +342,7 @@ define i32 @aext_subw_zext_aext(i32 zeroext %a, i32 %b) nounwind { define i32 @aext_subw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind { ; RV64I-LABEL: aext_subw_zext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sub a0, a0, a1 +; RV64I-NEXT: subw a0, a0, a1 ; RV64I-NEXT: ret %1 = sub i32 %a, %b ret i32 %1 @@ -351,7 +351,7 @@ define i32 @aext_subw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind { define i32 @aext_subw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: aext_subw_zext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sub a0, a0, a1 +; RV64I-NEXT: subw a0, a0, a1 ; RV64I-NEXT: ret %1 = sub i32 %a, %b ret i32 %1 diff --git a/llvm/test/CodeGen/RISCV/rv64i-w-insts-legalization.ll b/llvm/test/CodeGen/RISCV/rv64i-w-insts-legalization.ll new file mode 100644 index 000000000000..8b177469fe55 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv64i-w-insts-legalization.ll @@ -0,0 +1,97 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv64 -mattr=+m -verify-machineinstrs < %s | FileCheck %s + +define signext i32 @addw(i32 signext %s, i32 signext %n, i32 signext %k) nounwind { +; CHECK-LABEL: addw: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: bge a0, a1, .LBB0_2 +; CHECK-NEXT: # %bb.1: # %for.body.preheader +; CHECK-NEXT: not a2, a0 +; CHECK-NEXT: add a2, a2, a1 +; CHECK-NEXT: sub a1, a1, a0 +; CHECK-NEXT: addi a1, a1, -2 +; CHECK-NEXT: slli a1, a1, 32 +; CHECK-NEXT: srli a1, a1, 32 +; CHECK-NEXT: slli a3, a2, 32 +; CHECK-NEXT: srli a3, a3, 32 +; CHECK-NEXT: mul a1, a3, a1 +; CHECK-NEXT: addi a3, a0, 1 +; CHECK-NEXT: mul a2, a2, a3 +; CHECK-NEXT: add a0, a2, a0 +; CHECK-NEXT: srli a1, a1, 1 +; CHECK-NEXT: addw a0, a0, a1 +; CHECK-NEXT: ret +; CHECK-NEXT: .LBB0_2: +; CHECK-NEXT: mv a0, zero +; CHECK-NEXT: ret +entry: + %cmp6 = icmp slt i32 %s, %n + br i1 %cmp6, label %for.body.preheader, label %for.cond.cleanup + +for.body.preheader: ; preds = %entry + %0 = xor i32 %s, -1 + %1 = add i32 %0, %n + %2 = add i32 %s, 1 + %3 = mul i32 %1, %2 + %4 = zext i32 %1 to i33 + %5 = add i32 %n, -2 + %6 = sub i32 %5, %s + %7 = zext i32 %6 to i33 + %8 = mul i33 %4, %7 + %9 = lshr i33 %8, 1 + %10 = trunc i33 %9 to i32 + %11 = add i32 %3, %s + %12 = add i32 %11, %10 + br label %for.cond.cleanup + +for.cond.cleanup: ; preds = %for.body.preheader, %entry + %sum.0.lcssa = phi i32 [ 0, %entry ], [ %12, %for.body.preheader ] + ret i32 %sum.0.lcssa +} + +define signext i32 @subw(i32 signext %s, i32 signext %n, i32 signext %k) nounwind { +; CHECK-LABEL: subw: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: bge a0, a1, .LBB1_2 +; CHECK-NEXT: # %bb.1: # %for.body.preheader +; CHECK-NEXT: sub a2, a1, a0 +; CHECK-NEXT: addi a2, a2, -2 +; CHECK-NEXT: slli a2, a2, 32 +; CHECK-NEXT: srli a2, a2, 32 +; CHECK-NEXT: not a3, a0 +; CHECK-NEXT: add a1, a3, a1 +; CHECK-NEXT: slli a4, a1, 32 +; CHECK-NEXT: srli a4, a4, 32 +; CHECK-NEXT: mul a2, a4, a2 +; CHECK-NEXT: mul a1, a1, a3 +; CHECK-NEXT: sub a0, a1, a0 +; CHECK-NEXT: srli a1, a2, 1 +; CHECK-NEXT: subw a0, a0, a1 +; CHECK-NEXT: ret +; CHECK-NEXT: .LBB1_2: +; CHECK-NEXT: mv a0, zero +; CHECK-NEXT: ret +entry: + %cmp6 = icmp slt i32 %s, %n + br i1 %cmp6, label %for.body.preheader, label %for.cond.cleanup + +for.body.preheader: ; preds = %entry + %0 = xor i32 %s, -1 + %1 = add i32 %0, %n + %2 = xor i32 %s, -1 + %3 = mul i32 %1, %2 + %4 = zext i32 %1 to i33 + %5 = add i32 %n, -2 + %6 = sub i32 %5, %s + %7 = zext i32 %6 to i33 + %8 = mul i33 %4, %7 + %9 = lshr i33 %8, 1 + %10 = trunc i33 %9 to i32 + %11 = sub i32 %3, %s + %12 = sub i32 %11, %10 + br label %for.cond.cleanup + +for.cond.cleanup: ; preds = %for.body.preheader, %entry + %sum.0.lcssa = phi i32 [ 0, %entry ], [ %12, %for.body.preheader ] + ret i32 %sum.0.lcssa +} diff --git a/llvm/test/CodeGen/RISCV/rv64m-exhaustive-w-insts.ll b/llvm/test/CodeGen/RISCV/rv64m-exhaustive-w-insts.ll index 980c5813944e..f980c1885707 100644 --- a/llvm/test/CodeGen/RISCV/rv64m-exhaustive-w-insts.ll +++ b/llvm/test/CodeGen/RISCV/rv64m-exhaustive-w-insts.ll @@ -9,7 +9,7 @@ define i32 @aext_mulw_aext_aext(i32 %a, i32 %b) nounwind { ; RV64IM-LABEL: aext_mulw_aext_aext: ; RV64IM: # %bb.0: -; RV64IM-NEXT: mul a0, a0, a1 +; RV64IM-NEXT: mulw a0, a0, a1 ; RV64IM-NEXT: ret %1 = mul i32 %a, %b ret i32 %1 @@ -18,7 +18,7 @@ define i32 @aext_mulw_aext_aext(i32 %a, i32 %b) nounwind { define i32 @aext_mulw_aext_sext(i32 %a, i32 signext %b) nounwind { ; RV64IM-LABEL: aext_mulw_aext_sext: ; RV64IM: # %bb.0: -; RV64IM-NEXT: mul a0, a0, a1 +; RV64IM-NEXT: mulw a0, a0, a1 ; RV64IM-NEXT: ret %1 = mul i32 %a, %b ret i32 %1 @@ -27,7 +27,7 @@ define i32 @aext_mulw_aext_sext(i32 %a, i32 signext %b) nounwind { define i32 @aext_mulw_aext_zext(i32 %a, i32 zeroext %b) nounwind { ; RV64IM-LABEL: aext_mulw_aext_zext: ; RV64IM: # %bb.0: -; RV64IM-NEXT: mul a0, a0, a1 +; RV64IM-NEXT: mulw a0, a0, a1 ; RV64IM-NEXT: ret %1 = mul i32 %a, %b ret i32 %1 @@ -36,7 +36,7 @@ define i32 @aext_mulw_aext_zext(i32 %a, i32 zeroext %b) nounwind { define i32 @aext_mulw_sext_aext(i32 signext %a, i32 %b) nounwind { ; RV64IM-LABEL: aext_mulw_sext_aext: ; RV64IM: # %bb.0: -; RV64IM-NEXT: mul a0, a0, a1 +; RV64IM-NEXT: mulw a0, a0, a1 ; RV64IM-NEXT: ret %1 = mul i32 %a, %b ret i32 %1 @@ -45,7 +45,7 @@ define i32 @aext_mulw_sext_aext(i32 signext %a, i32 %b) nounwind { define i32 @aext_mulw_sext_sext(i32 signext %a, i32 signext %b) nounwind { ; RV64IM-LABEL: aext_mulw_sext_sext: ; RV64IM: # %bb.0: -; RV64IM-NEXT: mul a0, a0, a1 +; RV64IM-NEXT: mulw a0, a0, a1 ; RV64IM-NEXT: ret %1 = mul i32 %a, %b ret i32 %1 @@ -54,7 +54,7 @@ define i32 @aext_mulw_sext_sext(i32 signext %a, i32 signext %b) nounwind { define i32 @aext_mulw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind { ; RV64IM-LABEL: aext_mulw_sext_zext: ; RV64IM: # %bb.0: -; RV64IM-NEXT: mul a0, a0, a1 +; RV64IM-NEXT: mulw a0, a0, a1 ; RV64IM-NEXT: ret %1 = mul i32 %a, %b ret i32 %1 @@ -63,7 +63,7 @@ define i32 @aext_mulw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind { define i32 @aext_mulw_zext_aext(i32 zeroext %a, i32 %b) nounwind { ; RV64IM-LABEL: aext_mulw_zext_aext: ; RV64IM: # %bb.0: -; RV64IM-NEXT: mul a0, a0, a1 +; RV64IM-NEXT: mulw a0, a0, a1 ; RV64IM-NEXT: ret %1 = mul i32 %a, %b ret i32 %1 @@ -72,7 +72,7 @@ define i32 @aext_mulw_zext_aext(i32 zeroext %a, i32 %b) nounwind { define i32 @aext_mulw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind { ; RV64IM-LABEL: aext_mulw_zext_sext: ; RV64IM: # %bb.0: -; RV64IM-NEXT: mul a0, a0, a1 +; RV64IM-NEXT: mulw a0, a0, a1 ; RV64IM-NEXT: ret %1 = mul i32 %a, %b ret i32 %1 @@ -81,7 +81,7 @@ define i32 @aext_mulw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind { define i32 @aext_mulw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind { ; RV64IM-LABEL: aext_mulw_zext_zext: ; RV64IM: # %bb.0: -; RV64IM-NEXT: mul a0, a0, a1 +; RV64IM-NEXT: mulw a0, a0, a1 ; RV64IM-NEXT: ret %1 = mul i32 %a, %b ret i32 %1 diff --git a/llvm/test/CodeGen/RISCV/rv64m-w-insts-legalization.ll b/llvm/test/CodeGen/RISCV/rv64m-w-insts-legalization.ll new file mode 100644 index 000000000000..8af41d260844 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv64m-w-insts-legalization.ll @@ -0,0 +1,34 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv64 -mattr=+m -verify-machineinstrs < %s | FileCheck %s + +define signext i32 @mulw(i32 signext %s, i32 signext %n, i32 signext %k) nounwind { +; CHECK-LABEL: mulw: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: addi a2, zero, 1 +; CHECK-NEXT: bge a0, a1, .LBB0_3 +; CHECK-NEXT: # %bb.1: # %for.body.preheader +; CHECK-NEXT: addi a2, zero, 1 +; CHECK-NEXT: .LBB0_2: # %for.body +; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-NEXT: mulw a2, a0, a2 +; CHECK-NEXT: addiw a0, a0, 1 +; CHECK-NEXT: blt a0, a1, .LBB0_2 +; CHECK-NEXT: .LBB0_3: # %for.cond.cleanup +; CHECK-NEXT: mv a0, a2 +; CHECK-NEXT: ret +entry: + %cmp6 = icmp slt i32 %s, %n + br i1 %cmp6, label %for.body, label %for.cond.cleanup + +for.cond.cleanup: ; preds = %for.body, %entry + %sum.0.lcssa = phi i32 [ 1, %entry ], [ %mul, %for.body ] + ret i32 %sum.0.lcssa + +for.body: ; preds = %entry, %for.body + %i.08 = phi i32 [ %inc, %for.body ], [ %s, %entry ] + %sum.07 = phi i32 [ %mul, %for.body ], [ 1, %entry ] + %mul = mul nsw i32 %i.08, %sum.07 + %inc = add nsw i32 %i.08, 1 + %cmp = icmp slt i32 %inc, %n + br i1 %cmp, label %for.body, label %for.cond.cleanup +} diff --git a/llvm/test/CodeGen/RISCV/select-optimize-multiple.ll b/llvm/test/CodeGen/RISCV/select-optimize-multiple.ll index 27ca82e79014..3a18b4a54ea5 100644 --- a/llvm/test/CodeGen/RISCV/select-optimize-multiple.ll +++ b/llvm/test/CodeGen/RISCV/select-optimize-multiple.ll @@ -257,7 +257,7 @@ define i32 @cmovccdep(i32 signext %a, i32 %b, i32 %c, i32 %d) nounwind { ; RV64I-NEXT: mv a2, a1 ; RV64I-NEXT: bne a0, a4, .LBB6_4 ; RV64I-NEXT: .LBB6_2: # %entry -; RV64I-NEXT: add a0, a1, a2 +; RV64I-NEXT: addw a0, a1, a2 ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB6_3: # %entry ; RV64I-NEXT: mv a1, a2 @@ -265,7 +265,7 @@ define i32 @cmovccdep(i32 signext %a, i32 %b, i32 %c, i32 %d) nounwind { ; RV64I-NEXT: beq a0, a4, .LBB6_2 ; RV64I-NEXT: .LBB6_4: # %entry ; RV64I-NEXT: mv a2, a3 -; RV64I-NEXT: add a0, a1, a2 +; RV64I-NEXT: addw a0, a1, a2 ; RV64I-NEXT: ret entry: %cmp = icmp eq i32 %a, 123 @@ -305,7 +305,7 @@ define i32 @cmovdiffcc(i1 %a, i1 %b, i32 %c, i32 %d, i32 %e, i32 %f) nounwind { ; RV64I-NEXT: andi a0, a0, 1 ; RV64I-NEXT: beqz a0, .LBB7_4 ; RV64I-NEXT: .LBB7_2: # %entry -; RV64I-NEXT: add a0, a2, a4 +; RV64I-NEXT: addw a0, a2, a4 ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB7_3: # %entry ; RV64I-NEXT: mv a4, a5 @@ -313,7 +313,7 @@ define i32 @cmovdiffcc(i1 %a, i1 %b, i32 %c, i32 %d, i32 %e, i32 %f) nounwind { ; RV64I-NEXT: bnez a0, .LBB7_2 ; RV64I-NEXT: .LBB7_4: # %entry ; RV64I-NEXT: mv a2, a3 -; RV64I-NEXT: add a0, a2, a4 +; RV64I-NEXT: addw a0, a2, a4 ; RV64I-NEXT: ret entry: %cond1 = select i1 %a, i32 %c, i32 %d diff --git a/llvm/test/CodeGen/RISCV/vararg.ll b/llvm/test/CodeGen/RISCV/vararg.ll index 34132825c2a8..b630a1b436f5 100644 --- a/llvm/test/CodeGen/RISCV/vararg.ll +++ b/llvm/test/CodeGen/RISCV/vararg.ll @@ -1320,7 +1320,7 @@ define i32 @va4_va_copy(i32 %argno, ...) nounwind { ; LP64-LP64F-LP64D-FPELIM-NEXT: add a1, a1, s0 ; LP64-LP64F-LP64D-FPELIM-NEXT: add a1, a1, a2 ; LP64-LP64F-LP64D-FPELIM-NEXT: ld a0, 0(a0) -; LP64-LP64F-LP64D-FPELIM-NEXT: add a0, a1, a0 +; LP64-LP64F-LP64D-FPELIM-NEXT: addw a0, a1, a0 ; LP64-LP64F-LP64D-FPELIM-NEXT: ld s0, 16(sp) ; LP64-LP64F-LP64D-FPELIM-NEXT: ld ra, 24(sp) ; LP64-LP64F-LP64D-FPELIM-NEXT: addi sp, sp, 96 @@ -1364,7 +1364,7 @@ define i32 @va4_va_copy(i32 %argno, ...) nounwind { ; LP64-LP64F-LP64D-WITHFP-NEXT: add a1, a1, s1 ; LP64-LP64F-LP64D-WITHFP-NEXT: add a1, a1, a2 ; LP64-LP64F-LP64D-WITHFP-NEXT: ld a0, 0(a0) -; LP64-LP64F-LP64D-WITHFP-NEXT: add a0, a1, a0 +; LP64-LP64F-LP64D-WITHFP-NEXT: addw a0, a1, a0 ; LP64-LP64F-LP64D-WITHFP-NEXT: ld s1, 24(sp) ; LP64-LP64F-LP64D-WITHFP-NEXT: ld s0, 32(sp) ; LP64-LP64F-LP64D-WITHFP-NEXT: ld ra, 40(sp)