summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Atanasyan <simon@atanasyan.com>2019-04-25 07:47:28 +0000
committerSimon Atanasyan <simon@atanasyan.com>2019-04-25 07:47:28 +0000
commita0291110da6835f5c5afa4b77cda31a5b1af3ef8 (patch)
tree202065df3713f7c9dcecaa7bee6de936a48ed83d
parent013503c78d7b648152a07022e75b98219aba2ba9 (diff)
downloadbcm5719-llvm-a0291110da6835f5c5afa4b77cda31a5b1af3ef8.tar.gz
bcm5719-llvm-a0291110da6835f5c5afa4b77cda31a5b1af3ef8.zip
[MIPS] Use custom bitcast lowering to avoid excessive instructions
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
-rw-r--r--llvm/lib/Target/Mips/MipsISelLowering.cpp5
-rw-r--r--llvm/lib/Target/Mips/MipsSEISelLowering.cpp36
-rw-r--r--llvm/lib/Target/Mips/MipsSEISelLowering.h1
-rw-r--r--llvm/test/CodeGen/Mips/llvm-ir/bitcast.ll10
4 files changed, 45 insertions, 7 deletions
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index 99de079788e..943f4f2d4c4 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -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
diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
index 9698a4979e5..6fbdba4c691 100644
--- a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
@@ -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);
@@ -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);
@@ -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 {
diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.h b/llvm/lib/Target/Mips/MipsSEISelLowering.h
index 3da78921f84..787e2ac394d 100644
--- a/llvm/lib/Target/Mips/MipsSEISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsSEISelLowering.h
@@ -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;
diff --git a/llvm/test/CodeGen/Mips/llvm-ir/bitcast.ll b/llvm/test/CodeGen/Mips/llvm-ir/bitcast.ll
index 6593103de8d..a649234342d 100644
--- a/llvm/test/CodeGen/Mips/llvm-ir/bitcast.ll
+++ b/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
OpenPOWER on IntegriCloud