diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -2102,6 +2102,14 @@ return false; switch (MI.getOpcode()) { + case RISCV::TH_MULA: + case RISCV::TH_MULAW: + case RISCV::TH_MULAH: + case RISCV::TH_MULS: + case RISCV::TH_MULSW: + case RISCV::TH_MULSH: + // Operands 2 and 3 are commutable. + return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3); case RISCV::PseudoCCMOVGPR: // Operands 4 and 5 are commutable. return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 4, 5); diff --git a/llvm/test/CodeGen/RISCV/bitextract-mac.ll b/llvm/test/CodeGen/RISCV/bitextract-mac.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/bitextract-mac.ll @@ -0,0 +1,142 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -mattr=+m -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV32I +; RUN: llc -mtriple=riscv32 -mattr=+zbb -mattr=+m -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV32ZBB +; RUN: llc -mtriple=riscv32 -mattr=+xtheadbb -mattr=+m -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV32XTHEADBB +; RUN: llc -mtriple=riscv32 -mattr=+xtheadmac -mattr=+m -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV32XTHEADMAC +; RUN: llc -mtriple=riscv32 -mattr=+xtheadmac -mattr=+xtheadbb -mattr=+m -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV32XTHEAD +; RUN: llc -mtriple=riscv64 -mattr=+m -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV64I +; RUN: llc -mtriple=riscv64 -mattr=+zbb -mattr=+m -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV64ZBB +; RUN: llc -mtriple=riscv64 -mattr=+xtheadmac -mattr=+m -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV64XTHEADMAC +; RUN: llc -mtriple=riscv64 -mattr=+xtheadbb -mattr=+m -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV64XTHEADBB +; RUN: llc -mtriple=riscv64 -mattr=+xtheadmac -mattr=+xtheadbb -mattr=+m -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV64XTHEAD + +define i32 @f(i32 %A, i32 %B, i32 %C) { +; RV32I-LABEL: f: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: mul a0, a1, a0 +; RV32I-NEXT: slli a1, a0, 26 +; RV32I-NEXT: srli a1, a1, 28 +; RV32I-NEXT: slli a0, a0, 20 +; RV32I-NEXT: srli a0, a0, 25 +; RV32I-NEXT: mul a0, a1, a0 +; RV32I-NEXT: add a0, a0, a2 +; RV32I-NEXT: ret +; +; RV32ZBB-LABEL: f: +; RV32ZBB: # %bb.0: # %entry +; RV32ZBB-NEXT: mul a0, a1, a0 +; RV32ZBB-NEXT: slli a1, a0, 26 +; RV32ZBB-NEXT: srli a1, a1, 28 +; RV32ZBB-NEXT: slli a0, a0, 20 +; RV32ZBB-NEXT: srli a0, a0, 25 +; RV32ZBB-NEXT: mul a0, a1, a0 +; RV32ZBB-NEXT: add a0, a0, a2 +; RV32ZBB-NEXT: ret +; +; RV32XTHEADBB-LABEL: f: +; RV32XTHEADBB: # %bb.0: # %entry +; RV32XTHEADBB-NEXT: mul a0, a1, a0 +; RV32XTHEADBB-NEXT: slli a1, a0, 26 +; RV32XTHEADBB-NEXT: srli a1, a1, 28 +; RV32XTHEADBB-NEXT: slli a0, a0, 20 +; RV32XTHEADBB-NEXT: srli a0, a0, 25 +; RV32XTHEADBB-NEXT: mul a0, a1, a0 +; RV32XTHEADBB-NEXT: add a0, a0, a2 +; RV32XTHEADBB-NEXT: ret +; +; RV32XTHEADMAC-LABEL: f: +; RV32XTHEADMAC: # %bb.0: # %entry +; RV32XTHEADMAC-NEXT: mul a0, a1, a0 +; RV32XTHEADMAC-NEXT: slli a1, a0, 26 +; RV32XTHEADMAC-NEXT: srli a1, a1, 28 +; RV32XTHEADMAC-NEXT: slli a0, a0, 20 +; RV32XTHEADMAC-NEXT: srli a0, a0, 25 +; RV32XTHEADMAC-NEXT: th.mulah a2, a1, a0 +; RV32XTHEADMAC-NEXT: mv a0, a2 +; RV32XTHEADMAC-NEXT: ret +; +; RV32XTHEAD-LABEL: f: +; RV32XTHEAD: # %bb.0: # %entry +; RV32XTHEAD-NEXT: mul a0, a1, a0 +; RV32XTHEAD-NEXT: slli a1, a0, 26 +; RV32XTHEAD-NEXT: srli a1, a1, 28 +; RV32XTHEAD-NEXT: slli a0, a0, 20 +; RV32XTHEAD-NEXT: srli a0, a0, 25 +; RV32XTHEAD-NEXT: th.mulah a2, a1, a0 +; RV32XTHEAD-NEXT: mv a0, a2 +; RV32XTHEAD-NEXT: ret +; +; RV64I-LABEL: f: +; RV64I: # %bb.0: # %entry +; RV64I-NEXT: mulw a0, a1, a0 +; RV64I-NEXT: slli a1, a0, 58 +; RV64I-NEXT: srli a1, a1, 60 +; RV64I-NEXT: slli a0, a0, 52 +; RV64I-NEXT: srli a0, a0, 57 +; RV64I-NEXT: mulw a0, a1, a0 +; RV64I-NEXT: addw a0, a0, a2 +; RV64I-NEXT: ret +; +; RV64ZBB-LABEL: f: +; RV64ZBB: # %bb.0: # %entry +; RV64ZBB-NEXT: mulw a0, a1, a0 +; RV64ZBB-NEXT: slli a1, a0, 58 +; RV64ZBB-NEXT: srli a1, a1, 60 +; RV64ZBB-NEXT: slli a0, a0, 52 +; RV64ZBB-NEXT: srli a0, a0, 57 +; RV64ZBB-NEXT: mulw a0, a1, a0 +; RV64ZBB-NEXT: addw a0, a0, a2 +; RV64ZBB-NEXT: ret +; +; RV64XTHEADMAC-LABEL: f: +; RV64XTHEADMAC: # %bb.0: # %entry +; RV64XTHEADMAC-NEXT: mulw a0, a1, a0 +; RV64XTHEADMAC-NEXT: slli a1, a0, 58 +; RV64XTHEADMAC-NEXT: srli a1, a1, 60 +; RV64XTHEADMAC-NEXT: slli a0, a0, 52 +; RV64XTHEADMAC-NEXT: srli a0, a0, 57 +; RV64XTHEADMAC-NEXT: th.mulah a2, a1, a0 +; RV64XTHEADMAC-NEXT: mv a0, a2 +; RV64XTHEADMAC-NEXT: ret +; +; RV64XTHEADBB-LABEL: f: +; RV64XTHEADBB: # %bb.0: # %entry +; RV64XTHEADBB-NEXT: mulw a0, a1, a0 +; RV64XTHEADBB-NEXT: slli a1, a0, 58 +; RV64XTHEADBB-NEXT: srli a1, a1, 60 +; RV64XTHEADBB-NEXT: slli a0, a0, 52 +; RV64XTHEADBB-NEXT: srli a0, a0, 57 +; RV64XTHEADBB-NEXT: mulw a0, a1, a0 +; RV64XTHEADBB-NEXT: addw a0, a0, a2 +; RV64XTHEADBB-NEXT: ret +; +; RV64XTHEAD-LABEL: f: +; RV64XTHEAD: # %bb.0: # %entry +; RV64XTHEAD-NEXT: mulw a0, a1, a0 +; RV64XTHEAD-NEXT: slli a1, a0, 58 +; RV64XTHEAD-NEXT: srli a1, a1, 60 +; RV64XTHEAD-NEXT: slli a0, a0, 52 +; RV64XTHEAD-NEXT: srli a0, a0, 57 +; RV64XTHEAD-NEXT: th.mulah a2, a1, a0 +; RV64XTHEAD-NEXT: mv a0, a2 +; RV64XTHEAD-NEXT: ret +entry: + %mul = mul nsw i32 %B, %A + %0 = lshr i32 %mul, 2 + %and = and i32 %0, 15 + %1 = lshr i32 %mul, 5 + %and2 = and i32 %1, 127 + %mul3 = mul nuw nsw i32 %and, %and2 + %add = add i32 %mul3, %C + ret i32 %add +} diff --git a/llvm/test/CodeGen/RISCV/xtheadmac.ll b/llvm/test/CodeGen/RISCV/xtheadmac.ll --- a/llvm/test/CodeGen/RISCV/xtheadmac.ll +++ b/llvm/test/CodeGen/RISCV/xtheadmac.ll @@ -40,11 +40,12 @@ ; RV32XTHEADMAC-NEXT: mulhu a6, a2, a4 ; RV32XTHEADMAC-NEXT: th.mula a6, a2, a5 ; RV32XTHEADMAC-NEXT: th.mula a6, a3, a4 -; RV32XTHEADMAC-NEXT: th.mula a2, a0, a4 -; RV32XTHEADMAC-NEXT: sltu a0, a2, a0 +; RV32XTHEADMAC-NEXT: mv a3, a0 +; RV32XTHEADMAC-NEXT: th.mula a3, a2, a4 +; RV32XTHEADMAC-NEXT: sltu a0, a3, a0 ; RV32XTHEADMAC-NEXT: add a0, a1, a0 ; RV32XTHEADMAC-NEXT: add a1, a0, a6 -; RV32XTHEADMAC-NEXT: mv a0, a2 +; RV32XTHEADMAC-NEXT: mv a0, a3 ; RV32XTHEADMAC-NEXT: ret ; ; RV64XTHEADMAC-LABEL: mula_i64: @@ -99,11 +100,10 @@ ; RV32XTHEADMAC-NEXT: th.mula a6, a2, a5 ; RV32XTHEADMAC-NEXT: th.mula a6, a3, a4 ; RV32XTHEADMAC-NEXT: mul a3, a2, a4 -; RV32XTHEADMAC-NEXT: th.muls a2, a0, a4 -; RV32XTHEADMAC-NEXT: sltu a0, a0, a3 -; RV32XTHEADMAC-NEXT: sub a1, a1, a0 +; RV32XTHEADMAC-NEXT: sltu a3, a0, a3 +; RV32XTHEADMAC-NEXT: th.muls a0, a2, a4 +; RV32XTHEADMAC-NEXT: sub a1, a1, a3 ; RV32XTHEADMAC-NEXT: sub a1, a1, a6 -; RV32XTHEADMAC-NEXT: mv a0, a2 ; RV32XTHEADMAC-NEXT: ret ; ; RV64XTHEADMAC-LABEL: muls_i64: @@ -150,3 +150,52 @@ %h = sext i32 %g to i64 ret i64 %h } + +define i32 @commutative1(i32 %A, i32 %B, i32 %C) { +; RV32XTHEADMAC-LABEL: commutative1: +; RV32XTHEADMAC: # %bb.0: +; RV32XTHEADMAC-NEXT: th.mula a2, a1, a0 +; RV32XTHEADMAC-NEXT: mv a0, a2 +; RV32XTHEADMAC-NEXT: ret +; +; RV64XTHEADMAC-LABEL: commutative1: +; RV64XTHEADMAC: # %bb.0: +; RV64XTHEADMAC-NEXT: th.mulaw a2, a1, a0 +; RV64XTHEADMAC-NEXT: mv a0, a2 +; RV64XTHEADMAC-NEXT: ret + %mul = mul nsw i32 %B, %A + %add = add i32 %mul, %C + ret i32 %add +} + +define i32 @commutative2(i32 %A, i32 %B, i32 %C) { +; RV32XTHEADMAC-LABEL: commutative2: +; RV32XTHEADMAC: # %bb.0: +; RV32XTHEADMAC-NEXT: th.mula a0, a1, a2 +; RV32XTHEADMAC-NEXT: ret +; +; RV64XTHEADMAC-LABEL: commutative2: +; RV64XTHEADMAC: # %bb.0: +; RV64XTHEADMAC-NEXT: th.mulaw a0, a1, a2 +; RV64XTHEADMAC-NEXT: ret + %mul = mul nsw i32 %B, %C + %add = add i32 %mul, %A + ret i32 %add +} + +define i32 @commutative3(i32 %A, i32 %B, i32 %C) { +; RV32XTHEADMAC-LABEL: commutative3: +; RV32XTHEADMAC: # %bb.0: +; RV32XTHEADMAC-NEXT: th.mula a1, a2, a0 +; RV32XTHEADMAC-NEXT: mv a0, a1 +; RV32XTHEADMAC-NEXT: ret +; +; RV64XTHEADMAC-LABEL: commutative3: +; RV64XTHEADMAC: # %bb.0: +; RV64XTHEADMAC-NEXT: th.mulaw a1, a2, a0 +; RV64XTHEADMAC-NEXT: mv a0, a1 +; RV64XTHEADMAC-NEXT: ret + %mul = mul nsw i32 %C, %A + %add = add i32 %mul, %B + ret i32 %add +}