Message ID | alpine.DEB.2.20.2311182054440.5892@tpp.orcam.me.uk |
---|---|
State | New |
Headers | show |
Series | RISC-V: Various if-conversion fixes and improvements | expand |
On 11/18/23 22:41, Maciej W. Rozycki wrote: > Provide RTL expansion of conditional-add operations for generic targets > using a suitable sequence of base integer machine instructions according > to cost evaluation by if-conversion. Use existing `-mmovcc' command > line option to enable this transformation. > > gcc/ > * config/riscv/riscv.md (add<mode>cc): New expander. Is this an improvement over what if-convert creates for a conditional add or is the goal to expose the sequence earlier in the pipeline rather than waiting for ifcvt? Either way this is fine, just questioning slightly if really improves things. I don't see any way it'd be hurting. jeff
On Sun, 19 Nov 2023, Jeff Law wrote: > Is this an improvement over what if-convert creates for a conditional add or > is the goal to expose the sequence earlier in the pipeline rather than waiting > for ifcvt? TBH I haven't ever seen if-convert eliminate a branch here without this pattern supplied. Maybe I've missed something in my previous evaluation, but building a representative subset of the add*.c test cases from this patch series without the `-mmovcc' option seems to confirm my observation, so I consider it a new feature rather than just an improvement. This is also why in the cover letter I suggested that we may consider moving this optimisation into if-convert proper later on, to benefit other targets. Maciej
Index: gcc/gcc/config/riscv/riscv.md =================================================================== --- gcc.orig/gcc/config/riscv/riscv.md +++ gcc/gcc/config/riscv/riscv.md @@ -2655,6 +2655,8 @@ [(set_attr "type" "branch") (set_attr "mode" "none")]) +;; Conditional move and add patterns. + (define_expand "mov<mode>cc" [(set (match_operand:GPR 0 "register_operand") (if_then_else:GPR (match_operand 1 "comparison_operator") @@ -2670,6 +2672,45 @@ FAIL; }) +(define_expand "add<mode>cc" + [(match_operand:GPR 0 "register_operand") + (match_operand 1 "comparison_operator") + (match_operand:GPR 2 "arith_operand") + (match_operand:GPR 3 "arith_operand")] + "TARGET_MOVCC" +{ + rtx cmp = operands[1]; + rtx cmp0 = XEXP (cmp, 0); + rtx cmp1 = XEXP (cmp, 1); + machine_mode mode0 = GET_MODE (cmp0); + + /* We only handle word mode integer compares for now. */ + if (INTEGRAL_MODE_P (mode0) && mode0 != word_mode) + FAIL; + + enum rtx_code code = GET_CODE (cmp); + rtx reg0 = gen_reg_rtx (<MODE>mode); + rtx reg1 = gen_reg_rtx (<MODE>mode); + rtx reg2 = gen_reg_rtx (<MODE>mode); + bool invert = false; + + if (INTEGRAL_MODE_P (mode0)) + riscv_expand_int_scc (reg0, code, cmp0, cmp1, &invert); + else if (FLOAT_MODE_P (mode0) && fp_scc_comparison (cmp, GET_MODE (cmp))) + riscv_expand_float_scc (reg0, code, cmp0, cmp1); + else + FAIL; + + if (invert) + riscv_emit_binary (PLUS, reg1, reg0, constm1_rtx); + else + riscv_emit_unary (NEG, reg1, reg0); + riscv_emit_binary (AND, reg2, reg1, operands[3]); + riscv_emit_binary (PLUS, operands[0], reg2, operands[2]); + + DONE; +}) + ;; Patterns for implementations that optimize short forward branches. (define_insn "*mov<GPR:mode><X:mode>cc"