[llvm] r331033 - [mips] Fix how compiler fuse instructions to fmadd/fmsub

Aleksandar Beserminji via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 27 06:30:27 PDT 2018


Author: abeserminji
Date: Fri Apr 27 06:30:27 2018
New Revision: 331033

URL: http://llvm.org/viewvc/llvm-project?rev=331033&view=rev
Log:
[mips] Fix how compiler fuse instructions to fmadd/fmsub

This patch makes compiler does not fuse fmul and fadd/fsub into
fmadd/fmsub by default. Instead, -fp-contract=fast option can
be used when such behavior is desired.

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


Added:
    llvm/trunk/test/CodeGen/Mips/fp-contract.ll
Modified:
    llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
    llvm/trunk/lib/Target/Mips/MipsISelLowering.h
    llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
    llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td
    llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp
    llvm/trunk/test/CodeGen/Mips/msa/arithmetic_float.ll

Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=331033&r1=331032&r2=331033&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Fri Apr 27 06:30:27 2018
@@ -200,6 +200,7 @@ const char *MipsTargetLowering::getTarge
   case MipsISD::Ret:               return "MipsISD::Ret";
   case MipsISD::ERet:              return "MipsISD::ERet";
   case MipsISD::EH_RETURN:         return "MipsISD::EH_RETURN";
+  case MipsISD::FMS:               return "MipsISD::FMS";
   case MipsISD::FPBrcond:          return "MipsISD::FPBrcond";
   case MipsISD::FPCmp:             return "MipsISD::FPCmp";
   case MipsISD::FSELECT:           return "MipsISD::FSELECT";

Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.h?rev=331033&r1=331032&r2=331033&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.h Fri Apr 27 06:30:27 2018
@@ -90,6 +90,9 @@ class TargetRegisterClass;
       // Thread Pointer
       ThreadPointer,
 
+      // Vector Floating Point Multiply and Subtract
+      FMS,
+
       // Floating Point Branch Conditional
       FPBrcond,
 

Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.td?rev=331033&r1=331032&r2=331033&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Fri Apr 27 06:30:27 2018
@@ -252,6 +252,9 @@ def HasCRC   : Predicate<"Subtarget->has
                AssemblerPredicate<"FeatureCRC">;
 def HasVirt  : Predicate<"Subtarget->hasVirt()">,
                AssemblerPredicate<"FeatureVirt">;
+// TODO: Add support for FPOpFusion::Standard
+def AllowFPOpFusion : Predicate<"TM.Options.AllowFPOpFusion =="
+                                " FPOpFusion::Fast">;
 //===----------------------------------------------------------------------===//
 // Mips GPR size adjectives.
 // They are mutually exclusive.
@@ -490,6 +493,10 @@ class ABI_NOT_N64 {
   list<Predicate> AdditionalPredicates = [IsNotN64];
 }
 
+class FPOP_FUSION_FAST {
+  list <Predicate> AdditionalPredicates = [AllowFPOpFusion];
+}
+
 //===----------------------------------------------------------------------===//
 
 class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl {

Modified: llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td?rev=331033&r1=331032&r2=331033&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td Fri Apr 27 06:30:27 2018
@@ -46,6 +46,7 @@ def MipsILVR  : SDNode<"MipsISD::ILVR",
 def MipsPCKEV : SDNode<"MipsISD::PCKEV", SDT_ILV>;
 def MipsPCKOD : SDNode<"MipsISD::PCKOD", SDT_ILV>;
 def MipsINSVE : SDNode<"MipsISD::INSVE", SDT_INSVE>;
+def MipsFMS   : SDNode<"MipsISD::FMS", SDTFPTernaryOp>;
 
 def vsetcc : SDNode<"ISD::SETCC", SDT_VSetCC>;
 def vfsetcc : SDNode<"ISD::SETCC", SDT_VFSetCC>;
@@ -369,9 +370,6 @@ def vbset_d : PatFrag<(ops node:$ws, nod
                       (or node:$ws, (shl (v2i64 vsplati64_imm_eq_1),
                                          node:$wt))>;
 
-def fms : PatFrag<(ops node:$wd, node:$ws, node:$wt),
-                  (fsub node:$wd, (fmul node:$ws, node:$wt))>;
-
 def muladd : PatFrag<(ops node:$wd, node:$ws, node:$wt),
                      (add node:$wd, (mul node:$ws, node:$wt))>;
 
@@ -2091,8 +2089,8 @@ class FMIN_A_W_DESC : MSA_3RF_DESC_BASE<
 class FMIN_A_D_DESC : MSA_3RF_DESC_BASE<"fmin_a.d", int_mips_fmin_a_d,
                                         MSA128DOpnd>;
 
-class FMSUB_W_DESC : MSA_3RF_4RF_DESC_BASE<"fmsub.w", fms, MSA128WOpnd>;
-class FMSUB_D_DESC : MSA_3RF_4RF_DESC_BASE<"fmsub.d", fms, MSA128DOpnd>;
+class FMSUB_W_DESC : MSA_3RF_4RF_DESC_BASE<"fmsub.w", MipsFMS, MSA128WOpnd>;
+class FMSUB_D_DESC : MSA_3RF_4RF_DESC_BASE<"fmsub.d", MipsFMS, MSA128DOpnd>;
 
 class FMUL_W_DESC : MSA_3RF_DESC_BASE<"fmul.w", fmul, MSA128WOpnd>;
 class FMUL_D_DESC : MSA_3RF_DESC_BASE<"fmul.d", fmul, MSA128DOpnd>;
@@ -3135,6 +3133,20 @@ def FTRUNC_S_D : FTRUNC_S_D_ENC, FTRUNC_
 def FTRUNC_U_W : FTRUNC_U_W_ENC, FTRUNC_U_W_DESC;
 def FTRUNC_U_D : FTRUNC_U_D_ENC, FTRUNC_U_D_DESC;
 
+def : MipsPat<(fsub MSA128WOpnd:$wd, (fmul MSA128WOpnd:$ws, MSA128WOpnd:$wt)),
+              (FMSUB_W MSA128WOpnd:$wd, MSA128WOpnd:$ws, MSA128WOpnd:$wt)>,
+              FPOP_FUSION_FAST;
+def : MipsPat<(fsub MSA128DOpnd:$wd, (fmul MSA128DOpnd:$ws, MSA128DOpnd:$wt)),
+              (FMSUB_D MSA128DOpnd:$wd, MSA128DOpnd:$ws, MSA128DOpnd:$wt)>,
+              FPOP_FUSION_FAST;
+
+def : MipsPat<(fadd MSA128WOpnd:$wd, (fmul MSA128WOpnd:$ws, MSA128WOpnd:$wt)),
+              (FMADD_W MSA128WOpnd:$wd, MSA128WOpnd:$ws, MSA128WOpnd:$wt)>,
+              FPOP_FUSION_FAST;
+def : MipsPat<(fadd MSA128DOpnd:$wd, (fmul MSA128DOpnd:$ws, MSA128DOpnd:$wt)),
+              (FMADD_D MSA128DOpnd:$wd, MSA128DOpnd:$ws, MSA128DOpnd:$wt)>,
+              FPOP_FUSION_FAST;
+
 def HADD_S_H : HADD_S_H_ENC, HADD_S_H_DESC;
 def HADD_S_W : HADD_S_W_ENC, HADD_S_W_DESC;
 def HADD_S_D : HADD_S_D_ENC, HADD_S_D_DESC;

Modified: llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp?rev=331033&r1=331032&r2=331033&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp Fri Apr 27 06:30:27 2018
@@ -1858,10 +1858,8 @@ SDValue MipsSETargetLowering::lowerINTRI
   case Intrinsic::mips_fmsub_w:
   case Intrinsic::mips_fmsub_d: {
     // TODO: If intrinsics have fast-math-flags, propagate them.
-    EVT ResTy = Op->getValueType(0);
-    return DAG.getNode(ISD::FSUB, SDLoc(Op), ResTy, Op->getOperand(1),
-                       DAG.getNode(ISD::FMUL, SDLoc(Op), ResTy,
-                                   Op->getOperand(2), Op->getOperand(3)));
+    return DAG.getNode(MipsISD::FMS, SDLoc(Op), Op->getValueType(0),
+                       Op->getOperand(1), Op->getOperand(2), Op->getOperand(3));
   }
   case Intrinsic::mips_frint_w:
   case Intrinsic::mips_frint_d:

Added: llvm/trunk/test/CodeGen/Mips/fp-contract.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/fp-contract.ll?rev=331033&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/fp-contract.ll (added)
+++ llvm/trunk/test/CodeGen/Mips/fp-contract.ll Fri Apr 27 06:30:27 2018
@@ -0,0 +1,38 @@
+; Test that the compiled does not fuse fmul and fadd into fmadd when no -fp-contract=fast
+; option is set (the same applies for fmul, fsub and fmsub).
+
+; RUN: llc -march=mipsel -mattr=+msa,+fp64 < %s | FileCheck %s --check-prefixes=CHECK-CONTRACT-OFF
+; RUN: llc -march=mipsel -mattr=+msa,+fp64 -fp-contract=off < %s | FileCheck %s --check-prefixes=CHECK-CONTRACT-OFF
+; RUN: llc -march=mips -mattr=+msa,+fp64 -fp-contract=fast < %s | FileCheck %s --check-prefixes=CHECK-CONTRACT-FAST
+
+declare <4 x float> @llvm.mips.fmul.w(<4 x float>, <4 x float>)
+declare <4 x float> @llvm.mips.fadd.w(<4 x float>, <4 x float>)
+declare <4 x float> @llvm.mips.fsub.w(<4 x float>, <4 x float>)
+
+define void @foo(<4 x float>* %agg.result, <4 x float>* %acc, <4 x float>* %a, <4 x float>* %b) {
+entry:
+  %0 = load <4 x float>, <4 x float>* %a, align 16
+  %1 = load <4 x float>, <4 x float>* %b, align 16
+  %2 = call <4 x float> @llvm.mips.fmul.w(<4 x float> %0, <4 x float> %1)
+  %3 = load <4 x float>, <4 x float>* %acc, align 16
+  %4 = call <4 x float> @llvm.mips.fadd.w(<4 x float> %3, <4 x float> %2)
+  store <4 x float> %4, <4 x float>* %agg.result, align 16
+  ret void
+  ; CHECK-CONTRACT-OFF: fmul.w
+  ; CHECK-CONTRACT-OFF: fadd.w
+  ; CHECK-CONTRACT-FAST: fmadd.w
+}
+
+define void @boo(<4 x float>* %agg.result, <4 x float>* %acc, <4 x float>* %a, <4 x float>* %b) {
+entry:
+  %0 = load <4 x float>, <4 x float>* %a, align 16
+  %1 = load <4 x float>, <4 x float>* %b, align 16
+  %2 = call <4 x float> @llvm.mips.fmul.w(<4 x float> %0, <4 x float> %1)
+  %3 = load <4 x float>, <4 x float>* %acc, align 16
+  %4 = call <4 x float> @llvm.mips.fsub.w(<4 x float> %3, <4 x float> %2)
+  store <4 x float> %4, <4 x float>* %agg.result, align 16
+  ret void
+  ; CHECK-CONTRACT-OFF: fmul.w
+  ; CHECK-CONTRACT-OFF: fsub.w
+  ; CHECK-CONTRACT-FAST: fmsub.w
+}

Modified: llvm/trunk/test/CodeGen/Mips/msa/arithmetic_float.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/msa/arithmetic_float.ll?rev=331033&r1=331032&r2=331033&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/msa/arithmetic_float.ll (original)
+++ llvm/trunk/test/CodeGen/Mips/msa/arithmetic_float.ll Fri Apr 27 06:30:27 2018
@@ -137,44 +137,46 @@ define void @fma_v2f64(<2 x double>* %d,
   ; CHECK: .size fma_v2f64
 }
 
-define void @fmsub_v4f32(<4 x float>* %d, <4 x float>* %a, <4 x float>* %b,
+define void @fmlu_fsub_v4f32(<4 x float>* %d, <4 x float>* %a, <4 x float>* %b,
                        <4 x float>* %c) nounwind {
-  ; CHECK: fmsub_v4f32:
+  ; CHECK: fmlu_fsub_v4f32:
 
-  %1 = load <4 x float>, <4 x float>* %a
-  ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
-  %2 = load <4 x float>, <4 x float>* %b
-  ; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0($6)
-  %3 = load <4 x float>, <4 x float>* %c
-  ; CHECK-DAG: ld.w [[R3:\$w[0-9]+]], 0($7)
-  %4 = fmul <4 x float> %2, %3
-  %5 = fsub <4 x float> %1, %4
-  ; CHECK-DAG: fmsub.w [[R1]], [[R2]], [[R3]]
+  %1 = load <4 x float>, <4 x float>* %b
+  ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($6)
+  %2 = load <4 x float>, <4 x float>* %c
+  ; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0($7)
+  %3 = fmul <4 x float> %1, %2
+  ; CHECK-DAG: fmul.w [[R2]], [[R1]], [[R2]]
+  %4 = load <4 x float>, <4 x float>* %a
+  ; CHECK-DAG: ld.w [[R3:\$w[0-9]+]], 0($5)
+  %5 = fsub <4 x float> %4, %3
+  ; CHECK-DAG: fsub.w [[R2]], [[R3]], [[R2]]
   store <4 x float> %5, <4 x float>* %d
-  ; CHECK-DAG: st.w [[R1]], 0($4)
+  ; CHECK-DAG: st.w [[R2]], 0($4)
 
   ret void
-  ; CHECK: .size fmsub_v4f32
+  ; CHECK: .size fmlu_fsub_v4f32
 }
 
-define void @fmsub_v2f64(<2 x double>* %d, <2 x double>* %a, <2 x double>* %b,
+define void @fmul_fsub_v2f64(<2 x double>* %d, <2 x double>* %a, <2 x double>* %b,
                        <2 x double>* %c) nounwind {
-  ; CHECK: fmsub_v2f64:
+  ; CHECK: fmul_fsub_v2f64:
 
-  %1 = load <2 x double>, <2 x double>* %a
-  ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
-  %2 = load <2 x double>, <2 x double>* %b
+  %1 = load <2 x double>, <2 x double>* %b
+  ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($7)
+  %2 = load <2 x double>, <2 x double>* %c
   ; CHECK-DAG: ld.d [[R2:\$w[0-9]+]], 0($6)
-  %3 = load <2 x double>, <2 x double>* %c
-  ; CHECK-DAG: ld.d [[R3:\$w[0-9]+]], 0($7)
-  %4 = fmul <2 x double> %2, %3
-  %5 = fsub <2 x double> %1, %4
-  ; CHECK-DAG: fmsub.d [[R1]], [[R2]], [[R3]]
+  %3 = fmul <2 x double> %1, %2
+  ; CHECK-DAG: fmul.d [[R1]], [[R2]], [[R1]]
+  %4 = load <2 x double>, <2 x double>* %a
+  ; CHECK-DAG: ld.d [[R3:\$w[0-9]+]], 0($5)
+  %5 = fsub <2 x double> %4, %3
+  ; CHECK-DAG: fsub.d [[R1]], [[R3]], [[R1]]
   store <2 x double> %5, <2 x double>* %d
   ; CHECK-DAG: st.d [[R1]], 0($4)
 
   ret void
-  ; CHECK: .size fmsub_v2f64
+  ; CHECK: .size fmul_fsub_v2f64
 }
 
 define void @fdiv_v4f32(<4 x float>* %c, <4 x float>* %a, <4 x float>* %b) nounwind {




More information about the llvm-commits mailing list