Skip to content

Commit

Permalink
[MIPS] Use custom bitcast lowering to avoid excessive instructions
Browse files Browse the repository at this point in the history
On Mips32r2 bitcast can be expanded to two sw instructions and an ldc1
when using bitcast i64 to double or an sdc1 and two lw instructions when
using bitcast double to i64. By introducing custom lowering that uses
mtc1/mthc1 we can avoid excessive instructions.

Patch by Mirko Brkusanin.

Differential Revision: https://reviews.llvm.org/D61069

llvm-svn: 359171
  • Loading branch information
atanasyan committed Apr 25, 2019
1 parent 013503c commit a029111
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 7 deletions.
5 changes: 3 additions & 2 deletions llvm/lib/Target/Mips/MipsISelLowering.cpp
Expand Up @@ -1203,8 +1203,9 @@ MipsTargetLowering::LowerOperationWrapper(SDNode *N,
SelectionDAG &DAG) const {
SDValue Res = LowerOperation(SDValue(N, 0), DAG);

for (unsigned I = 0, E = Res->getNumValues(); I != E; ++I)
Results.push_back(Res.getValue(I));
if (Res)
for (unsigned I = 0, E = Res->getNumValues(); I != E; ++I)
Results.push_back(Res.getValue(I));
}

void
Expand Down
36 changes: 36 additions & 0 deletions llvm/lib/Target/Mips/MipsSEISelLowering.cpp
Expand Up @@ -213,6 +213,11 @@ MipsSETargetLowering::MipsSETargetLowering(const MipsTargetMachine &TM,
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);

if (Subtarget.hasMips32r2() && !Subtarget.useSoftFloat() &&
!Subtarget.hasMips64()) {
setOperationAction(ISD::BITCAST, MVT::i64, Custom);
}

if (NoDPLoadStore) {
setOperationAction(ISD::LOAD, MVT::f64, Custom);
setOperationAction(ISD::STORE, MVT::f64, Custom);
Expand Down Expand Up @@ -462,6 +467,7 @@ SDValue MipsSETargetLowering::LowerOperation(SDValue Op,
case ISD::BUILD_VECTOR: return lowerBUILD_VECTOR(Op, DAG);
case ISD::VECTOR_SHUFFLE: return lowerVECTOR_SHUFFLE(Op, DAG);
case ISD::SELECT: return lowerSELECT(Op, DAG);
case ISD::BITCAST: return lowerBITCAST(Op, DAG);
}

return MipsTargetLowering::LowerOperation(Op, DAG);
Expand Down Expand Up @@ -1220,6 +1226,36 @@ SDValue MipsSETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {
Nd.getMemOperand()->getFlags(), Nd.getAAInfo());
}

SDValue MipsSETargetLowering::lowerBITCAST(SDValue Op,
SelectionDAG &DAG) const {
SDLoc DL(Op);
MVT Src = Op.getOperand(0).getValueType().getSimpleVT();
MVT Dest = Op.getValueType().getSimpleVT();

// Bitcast i64 to double.
if (Src == MVT::i64 && Dest == MVT::f64) {
SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32,
Op.getOperand(0), DAG.getIntPtrConstant(0, DL));
SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32,
Op.getOperand(0), DAG.getIntPtrConstant(1, DL));
return DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
}

// Bitcast double to i64.
if (Src == MVT::f64 && Dest == MVT::i64) {
SDValue Lo =
DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0),
DAG.getConstant(0, DL, MVT::i32));
SDValue Hi =
DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0),
DAG.getConstant(1, DL, MVT::i32));
return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
}

// Skip other cases of bitcast and use default lowering.
return SDValue();
}

SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
bool HasLo, bool HasHi,
SelectionDAG &DAG) const {
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/Mips/MipsSEISelLowering.h
Expand Up @@ -72,6 +72,7 @@ class TargetRegisterClass;

SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const;

SDValue lowerMulDiv(SDValue Op, unsigned NewOpc, bool HasLo, bool HasHi,
SelectionDAG &DAG) const;
Expand Down
10 changes: 5 additions & 5 deletions llvm/test/CodeGen/Mips/llvm-ir/bitcast.ll
@@ -1,13 +1,13 @@
; RUN: llc -march=mips -mcpu=mips32r2 -asm-show-inst \
; RUN: -mno-ldc1-sdc1 < %s | FileCheck %s --check-prefix=MIPS32R2
; RUN: < %s | FileCheck %s --check-prefix=MIPS32R2
; RUN: llc -march=mips -mcpu=mips32r2 -mattr=+fp64 -asm-show-inst \
; RUN: -mno-ldc1-sdc1 < %s | FileCheck %s --check-prefix=MIPS32FP64
; RUN: < %s | FileCheck %s --check-prefix=MIPS32FP64
; RUN: llc -march=mips -mcpu=mips32r3 -mattr=+micromips -asm-show-inst \
; RUN: -mno-ldc1-sdc1 < %s | FileCheck %s --check-prefix=MM
; RUN: < %s | FileCheck %s --check-prefix=MM
; RUN: llc -march=mips -mcpu=mips32r3 -mattr=+micromips,+fp64 -asm-show-inst \
; RUN: -mno-ldc1-sdc1 < %s | FileCheck %s --check-prefix=MMFP64
; RUN: < %s | FileCheck %s --check-prefix=MMFP64
; RUN: llc -march=mips -mcpu=mips32r6 -mattr=+micromips -asm-show-inst \
; RUN: -mno-ldc1-sdc1 < %s | FileCheck %s --check-prefix=MMR6
; RUN: < %s | FileCheck %s --check-prefix=MMR6

define double @mthc1(i64 %a) {
; MIPS32R2: mthc1 {{.*}} # <MCInst #{{[0-9]+}} MTHC1_D32
Expand Down

0 comments on commit a029111

Please sign in to comment.