Skip to content

Commit

Permalink
[RISCV] Add isCommutable to FADD/FMUL/FMIN/FMAX/FEQ.
Browse files Browse the repository at this point in the history
Reviewed By: arcbbb

Differential Revision: https://reviews.llvm.org/D123972
  • Loading branch information
topperc committed May 3, 2022
1 parent 589b9df commit 72a6635
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 28 deletions.
10 changes: 5 additions & 5 deletions llvm/lib/Target/RISCV/RISCVInstrInfoD.td
Original file line number Diff line number Diff line change
Expand Up @@ -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>;
Expand All @@ -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">,
Expand All @@ -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>;
}
Expand Down
42 changes: 24 additions & 18 deletions llvm/lib/Target/RISCV/RISCVInstrInfoF.td
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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>;
}

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -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>;
Expand All @@ -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">,
Expand All @@ -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>;
}
Expand Down
10 changes: 5 additions & 5 deletions llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
Original file line number Diff line number Diff line change
Expand Up @@ -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>;
Expand All @@ -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">,
Expand Down Expand Up @@ -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>;
}
Expand Down
204 changes: 204 additions & 0 deletions llvm/test/CodeGen/RISCV/machine-cse.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

0 comments on commit 72a6635

Please sign in to comment.