[llvm] r359171 - [MIPS] Use custom bitcast lowering to avoid excessive instructions

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 25 00:47:28 PDT 2019


Author: atanasyan
Date: Thu Apr 25 00:47:28 2019
New Revision: 359171

URL: http://llvm.org/viewvc/llvm-project?rev=359171&view=rev
Log:
[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

Modified:
    llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
    llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp
    llvm/trunk/lib/Target/Mips/MipsSEISelLowering.h
    llvm/trunk/test/CodeGen/Mips/llvm-ir/bitcast.ll

Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=359171&r1=359170&r2=359171&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Thu Apr 25 00:47:28 2019
@@ -1203,8 +1203,9 @@ MipsTargetLowering::LowerOperationWrappe
                                           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

Modified: llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp?rev=359171&r1=359170&r2=359171&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp Thu Apr 25 00:47:28 2019
@@ -213,6 +213,11 @@ MipsSETargetLowering::MipsSETargetLoweri
   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::LowerOpera
   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
                       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 {

Modified: llvm/trunk/lib/Target/Mips/MipsSEISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSEISelLowering.h?rev=359171&r1=359170&r2=359171&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsSEISelLowering.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsSEISelLowering.h Thu Apr 25 00:47:28 2019
@@ -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;

Modified: llvm/trunk/test/CodeGen/Mips/llvm-ir/bitcast.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/llvm-ir/bitcast.ll?rev=359171&r1=359170&r2=359171&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/llvm-ir/bitcast.ll (original)
+++ llvm/trunk/test/CodeGen/Mips/llvm-ir/bitcast.ll Thu Apr 25 00:47:28 2019
@@ -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




More information about the llvm-commits mailing list