[llvm] 72a6635 - [RISCV] Add isCommutable to FADD/FMUL/FMIN/FMAX/FEQ.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Mon May 2 20:31:53 PDT 2022


Author: Craig Topper
Date: 2022-05-02T20:21:16-07:00
New Revision: 72a66358f6b7b5c4da842e80ccb2aa916fe113c2

URL: https://github.com/llvm/llvm-project/commit/72a66358f6b7b5c4da842e80ccb2aa916fe113c2
DIFF: https://github.com/llvm/llvm-project/commit/72a66358f6b7b5c4da842e80ccb2aa916fe113c2.diff

LOG: [RISCV] Add isCommutable to FADD/FMUL/FMIN/FMAX/FEQ.

Reviewed By: arcbbb

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

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVInstrInfoD.td
    llvm/lib/Target/RISCV/RISCVInstrInfoF.td
    llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
    llvm/test/CodeGen/RISCV/machine-cse.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
index f7a1998388c3e..3831dc5bb5a12 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
@@ -114,11 +114,11 @@ defm : FPFMADynFrmAlias_m<FNMSUB_D, "fnmsub.d", DINX>;
 defm : FPFMADynFrmAlias_m<FNMADD_D, "fnmadd.d", DINX>;
 
 let SchedRW = [WriteFALU64, ReadFALU64, ReadFALU64] in {
-defm FADD_D : FPALU_rr_frm_m<0b0000001, "fadd.d", DINX>;
+defm FADD_D : FPALU_rr_frm_m<0b0000001, "fadd.d", DINX, /*Commutable*/1>;
 defm FSUB_D : FPALU_rr_frm_m<0b0000101, "fsub.d", DINX>;
 }
 let SchedRW = [WriteFMul64, ReadFMul64, ReadFMul64] in
-defm FMUL_D : FPALU_rr_frm_m<0b0001001, "fmul.d", DINX>;
+defm FMUL_D : FPALU_rr_frm_m<0b0001001, "fmul.d", DINX, /*Commutable*/1>;
 
 let SchedRW = [WriteFDiv64, ReadFDiv64, ReadFDiv64] in
 defm FDIV_D : FPALU_rr_frm_m<0b0001101, "fdiv.d", DINX>;
@@ -140,8 +140,8 @@ defm FSGNJX_D : FPALU_rr_m<0b0010001, 0b010, "fsgnjx.d", DINX>;
 }
 
 let SchedRW = [WriteFMinMax64, ReadFMinMax64, ReadFMinMax64] in {
-defm FMIN_D   : FPALU_rr_m<0b0010101, 0b000, "fmin.d", DINX>;
-defm FMAX_D   : FPALU_rr_m<0b0010101, 0b001, "fmax.d", DINX>;
+defm FMIN_D   : FPALU_rr_m<0b0010101, 0b000, "fmin.d", DINX, /*Commutable*/1>;
+defm FMAX_D   : FPALU_rr_m<0b0010101, 0b001, "fmax.d", DINX, /*Commutable*/1>;
 }
 
 defm FCVT_S_D : FPUnaryOp_r_frm_m<0b0100000, 0b00001, FDINX, "fcvt.s.d">,
@@ -152,7 +152,7 @@ defm FCVT_D_S : FPUnaryOp_r_m<0b0100001, 0b00000, 0b000, DFINX, "fcvt.d.s">,
                 Sched<[WriteFCvtF32ToF64, ReadFCvtF32ToF64]>;
 
 let SchedRW = [WriteFCmp64, ReadFCmp64, ReadFCmp64] in {
-defm FEQ_D : FPCmp_rr_m<0b1010001, 0b010, "feq.d", DINX>;
+defm FEQ_D : FPCmp_rr_m<0b1010001, 0b010, "feq.d", DINX, /*Commutable*/1>;
 defm FLT_D : FPCmp_rr_m<0b1010001, 0b001, "flt.d", DINX>;
 defm FLE_D : FPCmp_rr_m<0b1010001, 0b000, "fle.d", DINX>;
 }

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td
index a2cd4a0f618cc..b1077aedf8112 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td
@@ -187,28 +187,32 @@ multiclass FPFMADynFrmAlias_m<FPFMA_rrr_frm Inst, string OpcodeStr,
 
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in
 class FPALU_rr<bits<7> funct7, bits<3> funct3, string opcodestr,
-               DAGOperand rty>
+               DAGOperand rty, bit Commutable>
     : RVInstR<funct7, funct3, OPC_OP_FP, (outs rty:$rd),
-              (ins rty:$rs1, rty:$rs2), opcodestr, "$rd, $rs1, $rs2">;
+              (ins rty:$rs1, rty:$rs2), opcodestr, "$rd, $rs1, $rs2"> {
+  let isCommutable = Commutable;
+}
 multiclass FPALU_rr_m<bits<7> funct7, bits<3> funct3, string opcodestr,
-                      list<ExtInfo_r> Exts> {
+                      list<ExtInfo_r> Exts, bit Commutable = 0> {
   foreach Ext = Exts in
     let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
-    def Ext.Suffix : FPALU_rr<funct7, funct3, opcodestr, Ext.Reg>;
+    def Ext.Suffix : FPALU_rr<funct7, funct3, opcodestr, Ext.Reg, Commutable>;
 }
 
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1,
     UseNamedOperandTable = 1, hasPostISelHook = 1 in
-class FPALU_rr_frm<bits<7> funct7, string opcodestr, DAGOperand rty>
+class FPALU_rr_frm<bits<7> funct7, string opcodestr, DAGOperand rty,
+                   bit Commutable>
     : RVInstRFrm<funct7, OPC_OP_FP, (outs rty:$rd),
                  (ins rty:$rs1, rty:$rs2, frmarg:$frm), opcodestr,
-                  "$rd, $rs1, $rs2, $frm">;
-
+                  "$rd, $rs1, $rs2, $frm"> {
+  let isCommutable = Commutable;
+}
 multiclass FPALU_rr_frm_m<bits<7> funct7, string opcodestr,
-                          list<ExtInfo_r> Exts> {
+                          list<ExtInfo_r> Exts, bit Commutable = 0> {
   foreach Ext = Exts in
     let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
-    def Ext.Suffix : FPALU_rr_frm<funct7, opcodestr, Ext.Reg>;
+    def Ext.Suffix : FPALU_rr_frm<funct7, opcodestr, Ext.Reg, Commutable>;
 }
 
 class FPALUDynFrmAlias<FPALU_rr_frm Inst, string OpcodeStr,
@@ -269,14 +273,16 @@ multiclass FPUnaryOpDynFrmAlias_m<FPUnaryOp_r_frm Inst, string OpcodeStr,
 
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in
 class FPCmp_rr<bits<7> funct7, bits<3> funct3, string opcodestr,
-               DAGOperand rty>
+               DAGOperand rty, bit Commutable>
     : RVInstR<funct7, funct3, OPC_OP_FP, (outs GPR:$rd),
-              (ins rty:$rs1, rty:$rs2), opcodestr, "$rd, $rs1, $rs2">;
+              (ins rty:$rs1, rty:$rs2), opcodestr, "$rd, $rs1, $rs2"> {
+  let isCommutable = Commutable;
+}
 multiclass FPCmp_rr_m<bits<7> funct7, bits<3> funct3, string opcodestr,
-                      list<ExtInfo_r> Exts> {
+                      list<ExtInfo_r> Exts, bit Commutable = 0> {
   foreach Ext = Exts in
     let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in
-    def Ext.Suffix : FPCmp_rr<funct7, funct3, opcodestr, Ext.Reg>;
+    def Ext.Suffix : FPCmp_rr<funct7, funct3, opcodestr, Ext.Reg, Commutable>;
 }
 
 //===----------------------------------------------------------------------===//
@@ -305,11 +311,11 @@ defm : FPFMADynFrmAlias_m<FNMSUB_S, "fnmsub.s", FINX>;
 defm : FPFMADynFrmAlias_m<FNMADD_S, "fnmadd.s", FINX>;
 
 let SchedRW = [WriteFALU32, ReadFALU32, ReadFALU32] in {
-defm FADD_S : FPALU_rr_frm_m<0b0000000, "fadd.s", FINX>;
+defm FADD_S : FPALU_rr_frm_m<0b0000000, "fadd.s", FINX, /*Commutable*/1>;
 defm FSUB_S : FPALU_rr_frm_m<0b0000100, "fsub.s", FINX>;
 }
 let SchedRW = [WriteFMul32, ReadFMul32, ReadFMul32] in
-defm FMUL_S : FPALU_rr_frm_m<0b0001000, "fmul.s", FINX>;
+defm FMUL_S : FPALU_rr_frm_m<0b0001000, "fmul.s", FINX, /*Commutable*/1>;
 
 let SchedRW = [WriteFDiv32, ReadFDiv32, ReadFDiv32] in
 defm FDIV_S : FPALU_rr_frm_m<0b0001100, "fdiv.s", FINX>;
@@ -331,8 +337,8 @@ defm FSGNJX_S : FPALU_rr_m<0b0010000, 0b010, "fsgnjx.s", FINX>;
 }
 
 let SchedRW = [WriteFMinMax32, ReadFMinMax32, ReadFMinMax32] in {
-defm FMIN_S   : FPALU_rr_m<0b0010100, 0b000, "fmin.s", FINX>;
-defm FMAX_S   : FPALU_rr_m<0b0010100, 0b001, "fmax.s", FINX>;
+defm FMIN_S   : FPALU_rr_m<0b0010100, 0b000, "fmin.s", FINX, /*Commutable*/1>;
+defm FMAX_S   : FPALU_rr_m<0b0010100, 0b001, "fmax.s", FINX, /*Commutable*/1>;
 }
 
 defm FCVT_W_S : FPUnaryOp_r_frm_m<0b1100000, 0b00000, XFINX, "fcvt.w.s">,
@@ -348,7 +354,7 @@ def FMV_X_W : FPUnaryOp_r<0b1110000, 0b00000, 0b000, GPR, FPR32, "fmv.x.w">,
               Sched<[WriteFMovF32ToI32, ReadFMovF32ToI32]>;
 
 let SchedRW = [WriteFCmp32, ReadFCmp32, ReadFCmp32] in {
-defm FEQ_S : FPCmp_rr_m<0b1010000, 0b010, "feq.s", FINX>;
+defm FEQ_S : FPCmp_rr_m<0b1010000, 0b010, "feq.s", FINX, /*Commutable*/1>;
 defm FLT_S : FPCmp_rr_m<0b1010000, 0b001, "flt.s", FINX>;
 defm FLE_S : FPCmp_rr_m<0b1010000, 0b000, "fle.s", FINX>;
 }

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
index edaf1585c0662..835a0f536a1d2 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
@@ -109,11 +109,11 @@ defm : FPFMADynFrmAlias_m<FNMSUB_H, "fnmsub.h", HINX>;
 defm : FPFMADynFrmAlias_m<FNMADD_H, "fnmadd.h", HINX>;
 
 let SchedRW = [WriteFALU16, ReadFALU16, ReadFALU16] in {
-defm FADD_H : FPALU_rr_frm_m<0b0000010, "fadd.h", HINX>;
+defm FADD_H : FPALU_rr_frm_m<0b0000010, "fadd.h", HINX, /*Commutable*/1>;
 defm FSUB_H : FPALU_rr_frm_m<0b0000110, "fsub.h", HINX>;
 }
 let SchedRW = [WriteFMul16, ReadFMul16, ReadFMul16] in
-defm FMUL_H : FPALU_rr_frm_m<0b0001010, "fmul.h", HINX>;
+defm FMUL_H : FPALU_rr_frm_m<0b0001010, "fmul.h", HINX, /*Commutable*/1>;
 
 let SchedRW = [WriteFDiv16, ReadFDiv16, ReadFDiv16] in
 defm FDIV_H : FPALU_rr_frm_m<0b0001110, "fdiv.h", HINX>;
@@ -135,8 +135,8 @@ defm FSGNJX_H : FPALU_rr_m<0b0010010, 0b010, "fsgnjx.h", HINX>;
 }
 
 let SchedRW = [WriteFMinMax16, ReadFMinMax16, ReadFMinMax16] in {
-defm FMIN_H   : FPALU_rr_m<0b0010110, 0b000, "fmin.h", HINX>;
-defm FMAX_H   : FPALU_rr_m<0b0010110, 0b001, "fmax.h", HINX>;
+defm FMIN_H   : FPALU_rr_m<0b0010110, 0b000, "fmin.h", HINX, /*Commutable*/1>;
+defm FMAX_H   : FPALU_rr_m<0b0010110, 0b001, "fmax.h", HINX, /*Commutable*/1>;
 }
 
 defm FCVT_W_H : FPUnaryOp_r_frm_m<0b1100010, 0b00000, XHINX, "fcvt.w.h">,
@@ -173,7 +173,7 @@ def FMV_H_X : FPUnaryOp_r<0b1111010, 0b00000, 0b000, FPR16, GPR, "fmv.h.x">,
 } // Predicates = [HasStdExtZfhOrZfhmin]
 
 let SchedRW = [WriteFCmp16, ReadFCmp16, ReadFCmp16] in {
-defm FEQ_H : FPCmp_rr_m<0b1010010, 0b010, "feq.h", HINX>;
+defm FEQ_H : FPCmp_rr_m<0b1010010, 0b010, "feq.h", HINX, /*Commutable*/1>;
 defm FLT_H : FPCmp_rr_m<0b1010010, 0b001, "flt.h", HINX>;
 defm FLE_H : FPCmp_rr_m<0b1010010, 0b000, "fle.h", HINX>;
 }

diff  --git a/llvm/test/CodeGen/RISCV/machine-cse.ll b/llvm/test/CodeGen/RISCV/machine-cse.ll
index cd8ae1ce7fbd1..2e36f3ceab41b 100644
--- a/llvm/test/CodeGen/RISCV/machine-cse.ll
+++ b/llvm/test/CodeGen/RISCV/machine-cse.ll
@@ -504,3 +504,207 @@ trueblock:
 falseblock:
   ret void
 }
+
+define void @commute_fadd_f16(half %x, half %y, half* %p1, half* %p2, i1 zeroext %cond) {
+; RV32-LABEL: commute_fadd_f16:
+; RV32:       # %bb.0:
+; RV32-NEXT:    fadd.h ft0, fa0, fa1
+; RV32-NEXT:    fsh ft0, 0(a0)
+; RV32-NEXT:    beqz a2, .LBB14_2
+; RV32-NEXT:  # %bb.1: # %trueblock
+; RV32-NEXT:    fsh ft0, 0(a0)
+; RV32-NEXT:  .LBB14_2: # %falseblock
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: commute_fadd_f16:
+; RV64:       # %bb.0:
+; RV64-NEXT:    fadd.h ft0, fa0, fa1
+; RV64-NEXT:    fsh ft0, 0(a0)
+; RV64-NEXT:    beqz a2, .LBB14_2
+; RV64-NEXT:  # %bb.1: # %trueblock
+; RV64-NEXT:    fsh ft0, 0(a0)
+; RV64-NEXT:  .LBB14_2: # %falseblock
+; RV64-NEXT:    ret
+  %a = fadd half %x, %y
+  store half %a, half* %p1
+  br i1 %cond, label %trueblock, label %falseblock
+
+trueblock:
+  %b = fadd half %y, %x
+  store half %b, half* %p1
+  br label %falseblock
+
+falseblock:
+  ret void
+}
+
+define void @commute_fadd_f32(float %x, float %y, float* %p1, float* %p2, i1 zeroext %cond) {
+; RV32-LABEL: commute_fadd_f32:
+; RV32:       # %bb.0:
+; RV32-NEXT:    fadd.s ft0, fa0, fa1
+; RV32-NEXT:    fsw ft0, 0(a0)
+; RV32-NEXT:    beqz a2, .LBB15_2
+; RV32-NEXT:  # %bb.1: # %trueblock
+; RV32-NEXT:    fsw ft0, 0(a0)
+; RV32-NEXT:  .LBB15_2: # %falseblock
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: commute_fadd_f32:
+; RV64:       # %bb.0:
+; RV64-NEXT:    fadd.s ft0, fa0, fa1
+; RV64-NEXT:    fsw ft0, 0(a0)
+; RV64-NEXT:    beqz a2, .LBB15_2
+; RV64-NEXT:  # %bb.1: # %trueblock
+; RV64-NEXT:    fsw ft0, 0(a0)
+; RV64-NEXT:  .LBB15_2: # %falseblock
+; RV64-NEXT:    ret
+  %a = fadd float %x, %y
+  store float %a, float* %p1
+  br i1 %cond, label %trueblock, label %falseblock
+
+trueblock:
+  %b = fadd float %y, %x
+  store float %b, float* %p1
+  br label %falseblock
+
+falseblock:
+  ret void
+}
+
+define void @commute_fadd_f64(double %x, double %y, double* %p1, double* %p2, i1 zeroext %cond) {
+; RV32-LABEL: commute_fadd_f64:
+; RV32:       # %bb.0:
+; RV32-NEXT:    fadd.d ft0, fa0, fa1
+; RV32-NEXT:    fsd ft0, 0(a0)
+; RV32-NEXT:    beqz a2, .LBB16_2
+; RV32-NEXT:  # %bb.1: # %trueblock
+; RV32-NEXT:    fsd ft0, 0(a0)
+; RV32-NEXT:  .LBB16_2: # %falseblock
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: commute_fadd_f64:
+; RV64:       # %bb.0:
+; RV64-NEXT:    fadd.d ft0, fa0, fa1
+; RV64-NEXT:    fsd ft0, 0(a0)
+; RV64-NEXT:    beqz a2, .LBB16_2
+; RV64-NEXT:  # %bb.1: # %trueblock
+; RV64-NEXT:    fsd ft0, 0(a0)
+; RV64-NEXT:  .LBB16_2: # %falseblock
+; RV64-NEXT:    ret
+  %a = fadd double %x, %y
+  store double %a, double* %p1
+  br i1 %cond, label %trueblock, label %falseblock
+
+trueblock:
+  %b = fadd double %y, %x
+  store double %b, double* %p1
+  br label %falseblock
+
+falseblock:
+  ret void
+}
+
+define void @commute_feq_f16(half %x, half %y, i8* %p1, i8* %p2, i1 zeroext %cond) {
+; RV32-LABEL: commute_feq_f16:
+; RV32:       # %bb.0:
+; RV32-NEXT:    feq.h a1, fa0, fa1
+; RV32-NEXT:    sb a1, 0(a0)
+; RV32-NEXT:    beqz a2, .LBB17_2
+; RV32-NEXT:  # %bb.1: # %trueblock
+; RV32-NEXT:    sb a1, 0(a0)
+; RV32-NEXT:  .LBB17_2: # %falseblock
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: commute_feq_f16:
+; RV64:       # %bb.0:
+; RV64-NEXT:    feq.h a1, fa0, fa1
+; RV64-NEXT:    sb a1, 0(a0)
+; RV64-NEXT:    beqz a2, .LBB17_2
+; RV64-NEXT:  # %bb.1: # %trueblock
+; RV64-NEXT:    sb a1, 0(a0)
+; RV64-NEXT:  .LBB17_2: # %falseblock
+; RV64-NEXT:    ret
+  %a = fcmp oeq half %x, %y
+  %b = zext i1 %a to i8
+  store i8 %b, i8* %p1
+  br i1 %cond, label %trueblock, label %falseblock
+
+trueblock:
+  %c = fcmp oeq half %y, %x
+  %d = zext i1 %c to i8
+  store i8 %d, i8* %p1
+  br label %falseblock
+
+falseblock:
+  ret void
+}
+
+define void @commute_feq_f32(float %x, float %y, i8* %p1, i8* %p2, i1 zeroext %cond) {
+; RV32-LABEL: commute_feq_f32:
+; RV32:       # %bb.0:
+; RV32-NEXT:    feq.s a1, fa0, fa1
+; RV32-NEXT:    sb a1, 0(a0)
+; RV32-NEXT:    beqz a2, .LBB18_2
+; RV32-NEXT:  # %bb.1: # %trueblock
+; RV32-NEXT:    sb a1, 0(a0)
+; RV32-NEXT:  .LBB18_2: # %falseblock
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: commute_feq_f32:
+; RV64:       # %bb.0:
+; RV64-NEXT:    feq.s a1, fa0, fa1
+; RV64-NEXT:    sb a1, 0(a0)
+; RV64-NEXT:    beqz a2, .LBB18_2
+; RV64-NEXT:  # %bb.1: # %trueblock
+; RV64-NEXT:    sb a1, 0(a0)
+; RV64-NEXT:  .LBB18_2: # %falseblock
+; RV64-NEXT:    ret
+  %a = fcmp oeq float %x, %y
+  %b = zext i1 %a to i8
+  store i8 %b, i8* %p1
+  br i1 %cond, label %trueblock, label %falseblock
+
+trueblock:
+  %c = fcmp oeq float %y, %x
+  %d = zext i1 %c to i8
+  store i8 %d, i8* %p1
+  br label %falseblock
+
+falseblock:
+  ret void
+}
+
+define void @commute_feq_f64(double %x, double %y, i8* %p1, i8* %p2, i1 zeroext %cond) {
+; RV32-LABEL: commute_feq_f64:
+; RV32:       # %bb.0:
+; RV32-NEXT:    feq.d a1, fa0, fa1
+; RV32-NEXT:    sb a1, 0(a0)
+; RV32-NEXT:    beqz a2, .LBB19_2
+; RV32-NEXT:  # %bb.1: # %trueblock
+; RV32-NEXT:    sb a1, 0(a0)
+; RV32-NEXT:  .LBB19_2: # %falseblock
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: commute_feq_f64:
+; RV64:       # %bb.0:
+; RV64-NEXT:    feq.d a1, fa0, fa1
+; RV64-NEXT:    sb a1, 0(a0)
+; RV64-NEXT:    beqz a2, .LBB19_2
+; RV64-NEXT:  # %bb.1: # %trueblock
+; RV64-NEXT:    sb a1, 0(a0)
+; RV64-NEXT:  .LBB19_2: # %falseblock
+; RV64-NEXT:    ret
+  %a = fcmp oeq double %x, %y
+  %b = zext i1 %a to i8
+  store i8 %b, i8* %p1
+  br i1 %cond, label %trueblock, label %falseblock
+
+trueblock:
+  %c = fcmp oeq double %y, %x
+  %d = zext i1 %c to i8
+  store i8 %d, i8* %p1
+  br label %falseblock
+
+falseblock:
+  ret void
+}


        


More information about the llvm-commits mailing list