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; defm : FPFMADynFrmAlias_m; 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 funct7, bits<3> funct3, string opcodestr, - DAGOperand rty> + DAGOperand rty, bit Commutable> : RVInstR; + (ins rty:$rs1, rty:$rs2), opcodestr, "$rd, $rs1, $rs2"> { + let isCommutable = Commutable; +} multiclass FPALU_rr_m funct7, bits<3> funct3, string opcodestr, - list Exts> { + list Exts, bit Commutable = 0> { foreach Ext = Exts in let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in - def Ext.Suffix : FPALU_rr; + def Ext.Suffix : FPALU_rr; } let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1, UseNamedOperandTable = 1, hasPostISelHook = 1 in -class FPALU_rr_frm funct7, string opcodestr, DAGOperand rty> +class FPALU_rr_frm funct7, string opcodestr, DAGOperand rty, + bit Commutable> : RVInstRFrm; - + "$rd, $rs1, $rs2, $frm"> { + let isCommutable = Commutable; +} multiclass FPALU_rr_frm_m funct7, string opcodestr, - list Exts> { + list Exts, bit Commutable = 0> { foreach Ext = Exts in let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in - def Ext.Suffix : FPALU_rr_frm; + def Ext.Suffix : FPALU_rr_frm; } class FPALUDynFrmAlias funct7, bits<3> funct3, string opcodestr, - DAGOperand rty> + DAGOperand rty, bit Commutable> : RVInstR; + (ins rty:$rs1, rty:$rs2), opcodestr, "$rd, $rs1, $rs2"> { + let isCommutable = Commutable; +} multiclass FPCmp_rr_m funct7, bits<3> funct3, string opcodestr, - list Exts> { + list Exts, bit Commutable = 0> { foreach Ext = Exts in let Predicates = Ext.Predicates, DecoderNamespace = Ext.Space in - def Ext.Suffix : FPCmp_rr; + def Ext.Suffix : FPCmp_rr; } //===----------------------------------------------------------------------===// @@ -305,11 +311,11 @@ defm : FPFMADynFrmAlias_m; defm : FPFMADynFrmAlias_m; 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; defm : FPFMADynFrmAlias_m; 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 +}