[llvm] 2f3b738 - [RISCV] Add optimizations for FMV_X_ANYEXTH similar to FMV_X_ANYEXTW_RV64.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 8 18:34:22 PDT 2021


Author: Craig Topper
Date: 2021-08-08T18:30:48-07:00
New Revision: 2f3b738960e919d0138c8c4e9813a9155c193398

URL: https://github.com/llvm/llvm-project/commit/2f3b738960e919d0138c8c4e9813a9155c193398
DIFF: https://github.com/llvm/llvm-project/commit/2f3b738960e919d0138c8c4e9813a9155c193398.diff

LOG: [RISCV] Add optimizations for FMV_X_ANYEXTH similar to FMV_X_ANYEXTW_RV64.

This enables the fneg and fabs combines we have for FMV_X_ANYEXTW_RV64.

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVISelLowering.cpp
    llvm/test/CodeGen/RISCV/half-bitmanip-dagcombines.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index c5227eeb66da..e9ae4e685b29 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -6103,14 +6103,19 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
 
     break;
   }
+  case RISCVISD::FMV_X_ANYEXTH:
   case RISCVISD::FMV_X_ANYEXTW_RV64: {
     SDLoc DL(N);
     SDValue Op0 = N->getOperand(0);
+    MVT VT = N->getSimpleValueType(0);
     // If the input to FMV_X_ANYEXTW_RV64 is just FMV_W_X_RV64 then the
-    // conversion is unnecessary and can be replaced with an ANY_EXTEND
-    // of the FMV_W_X_RV64 operand.
-    if (Op0->getOpcode() == RISCVISD::FMV_W_X_RV64) {
-      assert(Op0.getOperand(0).getValueType() == MVT::i64 &&
+    // conversion is unnecessary and can be replaced with the FMV_W_X_RV64
+    // operand. Similar for FMV_X_ANYEXTH and FMV_H_X.
+    if ((N->getOpcode() == RISCVISD::FMV_X_ANYEXTW_RV64 &&
+         Op0->getOpcode() == RISCVISD::FMV_W_X_RV64) ||
+        (N->getOpcode() == RISCVISD::FMV_X_ANYEXTH &&
+         Op0->getOpcode() == RISCVISD::FMV_H_X)) {
+      assert(Op0.getOperand(0).getValueType() == VT &&
              "Unexpected value type!");
       return Op0.getOperand(0);
     }
@@ -6122,16 +6127,16 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
     if (!(Op0.getOpcode() == ISD::FNEG || Op0.getOpcode() == ISD::FABS) ||
         !Op0.getNode()->hasOneUse())
       break;
-    SDValue NewFMV = DAG.getNode(RISCVISD::FMV_X_ANYEXTW_RV64, DL, MVT::i64,
-                                 Op0.getOperand(0));
-    APInt SignBit = APInt::getSignMask(32).sext(64);
+    SDValue NewFMV = DAG.getNode(N->getOpcode(), DL, VT, Op0.getOperand(0));
+    unsigned FPBits = N->getOpcode() == RISCVISD::FMV_X_ANYEXTW_RV64 ? 32 : 16;
+    APInt SignBit = APInt::getSignMask(FPBits).sextOrSelf(VT.getSizeInBits());
     if (Op0.getOpcode() == ISD::FNEG)
-      return DAG.getNode(ISD::XOR, DL, MVT::i64, NewFMV,
-                         DAG.getConstant(SignBit, DL, MVT::i64));
+      return DAG.getNode(ISD::XOR, DL, VT, NewFMV,
+                         DAG.getConstant(SignBit, DL, VT));
 
     assert(Op0.getOpcode() == ISD::FABS);
-    return DAG.getNode(ISD::AND, DL, MVT::i64, NewFMV,
-                       DAG.getConstant(~SignBit, DL, MVT::i64));
+    return DAG.getNode(ISD::AND, DL, VT, NewFMV,
+                       DAG.getConstant(~SignBit, DL, VT));
   }
   case ISD::AND:
     return performANDCombine(N, DCI, Subtarget);

diff  --git a/llvm/test/CodeGen/RISCV/half-bitmanip-dagcombines.ll b/llvm/test/CodeGen/RISCV/half-bitmanip-dagcombines.ll
index 7a3465516b35..d37f1ad5abb8 100644
--- a/llvm/test/CodeGen/RISCV/half-bitmanip-dagcombines.ll
+++ b/llvm/test/CodeGen/RISCV/half-bitmanip-dagcombines.ll
@@ -23,9 +23,8 @@ define half @fneg(half %a) nounwind {
 ;
 ; RV32IZFH-LABEL: fneg:
 ; RV32IZFH:       # %bb.0:
-; RV32IZFH-NEXT:    fmv.h.x ft0, a0
-; RV32IZFH-NEXT:    fneg.h ft0, ft0
-; RV32IZFH-NEXT:    fmv.x.h a0, ft0
+; RV32IZFH-NEXT:    lui a1, 1048568
+; RV32IZFH-NEXT:    xor a0, a0, a1
 ; RV32IZFH-NEXT:    ret
 ;
 ; RV64I-LABEL: fneg:
@@ -36,9 +35,8 @@ define half @fneg(half %a) nounwind {
 ;
 ; RV64IZFH-LABEL: fneg:
 ; RV64IZFH:       # %bb.0:
-; RV64IZFH-NEXT:    fmv.h.x ft0, a0
-; RV64IZFH-NEXT:    fneg.h ft0, ft0
-; RV64IZFH-NEXT:    fmv.x.h a0, ft0
+; RV64IZFH-NEXT:    lui a1, 1048568
+; RV64IZFH-NEXT:    xor a0, a0, a1
 ; RV64IZFH-NEXT:    ret
   %1 = fneg half %a
   ret half %1
@@ -56,9 +54,9 @@ define half @fabs(half %a) nounwind {
 ;
 ; RV32IZFH-LABEL: fabs:
 ; RV32IZFH:       # %bb.0:
-; RV32IZFH-NEXT:    fmv.h.x ft0, a0
-; RV32IZFH-NEXT:    fabs.h ft0, ft0
-; RV32IZFH-NEXT:    fmv.x.h a0, ft0
+; RV32IZFH-NEXT:    lui a1, 8
+; RV32IZFH-NEXT:    addi a1, a1, -1
+; RV32IZFH-NEXT:    and a0, a0, a1
 ; RV32IZFH-NEXT:    ret
 ;
 ; RV64I-LABEL: fabs:
@@ -70,9 +68,9 @@ define half @fabs(half %a) nounwind {
 ;
 ; RV64IZFH-LABEL: fabs:
 ; RV64IZFH:       # %bb.0:
-; RV64IZFH-NEXT:    fmv.h.x ft0, a0
-; RV64IZFH-NEXT:    fabs.h ft0, ft0
-; RV64IZFH-NEXT:    fmv.x.h a0, ft0
+; RV64IZFH-NEXT:    lui a1, 8
+; RV64IZFH-NEXT:    addiw a1, a1, -1
+; RV64IZFH-NEXT:    and a0, a0, a1
 ; RV64IZFH-NEXT:    ret
   %1 = call half @llvm.fabs.f16(half %a)
   ret half %1


        


More information about the llvm-commits mailing list