0009-PATCH-3-5-RISC-V-Generate-Zicond-instruction-for-sel.patch 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. From 0a068f2ee2a0ab639ca7e94b6d7a399e363d8b1a Mon Sep 17 00:00:00 2001
  2. From: Xiao Zeng <zengxiao@eswincomputing.com>
  3. Date: Thu, 3 Aug 2023 16:09:46 -0400
  4. Subject: [PATCH 09/30] [PATCH 3/5] [RISC-V] Generate Zicond instruction for
  5. select pattern with condition eq or neq to 0
  6. [ This is a partial commit. So not all the cases mentioned by
  7. Xiao are currently handled. ]
  8. This patch recognizes Zicond patterns when the select pattern
  9. with condition eq or neq to 0 (using eq as an example), namely:
  10. 1 rd = (rs2 == 0) ? non-imm : 0
  11. 2 rd = (rs2 == 0) ? non-imm : non-imm
  12. 3 rd = (rs2 == 0) ? reg : non-imm
  13. 4 rd = (rs2 == 0) ? reg : reg
  14. gcc/ChangeLog:
  15. * config/riscv/riscv.cc (riscv_expand_conditional_move): Recognize
  16. various Zicond patterns.
  17. * config/riscv/riscv.md (mov<mode>cc): Allow TARGET_ZICOND. Use
  18. sfb_alu_operand for both arms of the conditional move.
  19. Co-authored-by: Jeff Law <jlaw@ventanamicro.com>
  20. ---
  21. gcc/config/riscv/riscv.cc | 60 ++++++++++++++++++++++++++++++++++++---
  22. gcc/config/riscv/riscv.md | 4 +--
  23. 2 files changed, 58 insertions(+), 6 deletions(-)
  24. diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
  25. index dca9329608f..e4a31f7a16a 100644
  26. --- a/gcc/config/riscv/riscv.cc
  27. +++ b/gcc/config/riscv/riscv.cc
  28. @@ -3448,15 +3448,67 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
  29. riscv_emit_int_compare (&code, &op0, &op1);
  30. rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
  31. - /* The expander allows (const_int 0) for CONS for the benefit of
  32. - TARGET_XTHEADCONDMOV, but that case isn't supported for
  33. - TARGET_SFB_ALU. So force that operand into a register if
  34. - necessary. */
  35. + /* The expander is a bit loose in its specification of the true
  36. + arm of the conditional move. That allows us to support more
  37. + cases for extensions which are more general than SFB. But
  38. + does mean we need to force CONS into a register at this point. */
  39. cons = force_reg (GET_MODE (dest), cons);
  40. emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (GET_MODE (dest),
  41. cond, cons, alt)));
  42. return true;
  43. }
  44. + else if (TARGET_ZICOND
  45. + && (code == EQ || code == NE)
  46. + && GET_MODE_CLASS (mode) == MODE_INT)
  47. + {
  48. + /* The comparison must be comparing WORD_MODE objects. We must
  49. + enforce that so that we don't strip away a sign_extension
  50. + thinking it is unnecessary. We might consider using
  51. + riscv_extend_operands if they are not already properly extended. */
  52. + if (GET_MODE (op0) != word_mode || GET_MODE (op1) != word_mode)
  53. + return false;
  54. +
  55. + /* 0, reg or 0, imm */
  56. + if (cons == CONST0_RTX (mode)
  57. + && (REG_P (alt)
  58. + || (CONST_INT_P (alt) && alt != CONST0_RTX (mode))))
  59. + {
  60. + riscv_emit_int_compare (&code, &op0, &op1, true);
  61. + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
  62. + alt = force_reg (mode, alt);
  63. + emit_insn (gen_rtx_SET (dest,
  64. + gen_rtx_IF_THEN_ELSE (mode, cond,
  65. + cons, alt)));
  66. + return true;
  67. + }
  68. + /* imm, imm */
  69. + else if (CONST_INT_P (cons) && cons != CONST0_RTX (mode)
  70. + && CONST_INT_P (alt) && alt != CONST0_RTX (mode))
  71. + {
  72. + riscv_emit_int_compare (&code, &op0, &op1, true);
  73. + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
  74. + HOST_WIDE_INT t = INTVAL (alt) - INTVAL (cons);
  75. + alt = force_reg (mode, gen_int_mode (t, mode));
  76. + emit_insn (gen_rtx_SET (dest,
  77. + gen_rtx_IF_THEN_ELSE (mode, cond,
  78. + CONST0_RTX (mode),
  79. + alt)));
  80. + riscv_emit_binary (PLUS, dest, dest, cons);
  81. + return true;
  82. + }
  83. + /* reg, 0 or imm, 0 */
  84. + else if ((REG_P (cons)
  85. + || (CONST_INT_P (cons) && cons != CONST0_RTX (mode)))
  86. + && alt == CONST0_RTX (mode))
  87. + {
  88. + riscv_emit_int_compare (&code, &op0, &op1, true);
  89. + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
  90. + cons = force_reg (mode, cons);
  91. + emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (mode, cond,
  92. + cons, alt)));
  93. + return true;
  94. + }
  95. + }
  96. return false;
  97. }
  98. diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
  99. index c55132d2439..f810206f832 100644
  100. --- a/gcc/config/riscv/riscv.md
  101. +++ b/gcc/config/riscv/riscv.md
  102. @@ -2323,9 +2323,9 @@
  103. (define_expand "mov<mode>cc"
  104. [(set (match_operand:GPR 0 "register_operand")
  105. (if_then_else:GPR (match_operand 1 "comparison_operator")
  106. - (match_operand:GPR 2 "reg_or_0_operand")
  107. + (match_operand:GPR 2 "sfb_alu_operand")
  108. (match_operand:GPR 3 "sfb_alu_operand")))]
  109. - "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV"
  110. + "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV || TARGET_ZICOND"
  111. {
  112. if (riscv_expand_conditional_move (operands[0], operands[1],
  113. operands[2], operands[3]))
  114. --
  115. 2.25.1