0010-PATCH-v3-RISC-V-Generate-Zicond-instruction-for-sele.patch 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. From 177f7921847524a80abe41d446b4cfb39bb6c9b8 Mon Sep 17 00:00:00 2001
  2. From: Xiao Zeng <zengxiao@eswincomputing.com>
  3. Date: Fri, 4 Aug 2023 17:23:56 -0400
  4. Subject: [PATCH 10/30] [PATCH v3] [RISC-V] Generate Zicond instruction for
  5. select pattern with condition eq or neq to 0
  6. This patch recognizes Zicond patterns when the select pattern
  7. with condition eq or neq to 0 (using eq as an example), namely:
  8. 1 rd = (rs2 == 0) ? non-imm : 0
  9. 2 rd = (rs2 == 0) ? non-imm : non-imm
  10. 3 rd = (rs2 == 0) ? reg : non-imm
  11. 4 rd = (rs2 == 0) ? reg : reg
  12. gcc/ChangeLog:
  13. * config/riscv/riscv.cc (riscv_expand_conditional_move): Recognize
  14. more Zicond patterns. Fix whitespace typo.
  15. (riscv_rtx_costs): Remove accidental code duplication.
  16. Co-authored-by: Jeff Law <jlaw@ventanamicro.com>
  17. ---
  18. gcc/config/riscv/riscv.cc | 117 +++++++++++++++++++++++++++++++++-----
  19. 1 file changed, 102 insertions(+), 15 deletions(-)
  20. diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
  21. index e4a31f7a16a..f16fb17beb5 100644
  22. --- a/gcc/config/riscv/riscv.cc
  23. +++ b/gcc/config/riscv/riscv.cc
  24. @@ -2358,20 +2358,6 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
  25. *total = COSTS_N_INSNS (1);
  26. return true;
  27. }
  28. - else if (TARGET_ZICOND
  29. - && outer_code == SET
  30. - && ((GET_CODE (XEXP (x, 1)) == REG
  31. - && XEXP (x, 2) == CONST0_RTX (GET_MODE (XEXP (x, 1))))
  32. - || (GET_CODE (XEXP (x, 2)) == REG
  33. - && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 2))))
  34. - || (GET_CODE (XEXP (x, 1)) == REG
  35. - && rtx_equal_p (XEXP (x, 1), XEXP (XEXP (x, 0), 0)))
  36. - || (GET_CODE (XEXP (x, 1)) == REG
  37. - && rtx_equal_p (XEXP (x, 2), XEXP (XEXP (x, 0), 0)))))
  38. - {
  39. - *total = COSTS_N_INSNS (1);
  40. - return true;
  41. - }
  42. else if (LABEL_REF_P (XEXP (x, 1)) && XEXP (x, 2) == pc_rtx)
  43. {
  44. if (equality_operator (XEXP (x, 0), mode)
  45. @@ -3451,7 +3437,7 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
  46. /* The expander is a bit loose in its specification of the true
  47. arm of the conditional move. That allows us to support more
  48. cases for extensions which are more general than SFB. But
  49. - does mean we need to force CONS into a register at this point. */
  50. + does mean we need to force CONS into a register at this point. */
  51. cons = force_reg (GET_MODE (dest), cons);
  52. emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (GET_MODE (dest),
  53. cond, cons, alt)));
  54. @@ -3496,6 +3482,40 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
  55. riscv_emit_binary (PLUS, dest, dest, cons);
  56. return true;
  57. }
  58. + /* imm, reg */
  59. + else if (CONST_INT_P (cons) && cons != CONST0_RTX (mode) && REG_P (alt))
  60. + {
  61. + /* Optimize for register value of 0. */
  62. + if (code == NE && rtx_equal_p (op0, alt) && op1 == CONST0_RTX (mode))
  63. + {
  64. + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
  65. + cons = force_reg (mode, cons);
  66. + emit_insn (gen_rtx_SET (dest,
  67. + gen_rtx_IF_THEN_ELSE (mode, cond,
  68. + cons, alt)));
  69. + return true;
  70. + }
  71. +
  72. + riscv_emit_int_compare (&code, &op0, &op1, true);
  73. + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
  74. +
  75. + rtx temp1 = gen_reg_rtx (mode);
  76. + rtx temp2 = gen_int_mode (-1 * INTVAL (cons), mode);
  77. +
  78. + /* TEMP2 might not fit into a signed 12 bit immediate suitable
  79. + for an addi instruction. If that's the case, force it into
  80. + a register. */
  81. + if (!SMALL_OPERAND (INTVAL (temp2)))
  82. + temp2 = force_reg (mode, temp2);
  83. +
  84. + riscv_emit_binary (PLUS, temp1, alt, temp2);
  85. + emit_insn (gen_rtx_SET (dest,
  86. + gen_rtx_IF_THEN_ELSE (mode, cond,
  87. + CONST0_RTX (mode),
  88. + temp1)));
  89. + riscv_emit_binary (PLUS, dest, dest, cons);
  90. + return true;
  91. + }
  92. /* reg, 0 or imm, 0 */
  93. else if ((REG_P (cons)
  94. || (CONST_INT_P (cons) && cons != CONST0_RTX (mode)))
  95. @@ -3508,6 +3528,73 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
  96. cons, alt)));
  97. return true;
  98. }
  99. + /* reg, imm */
  100. + else if (REG_P (cons) && CONST_INT_P (alt) && alt != CONST0_RTX (mode))
  101. + {
  102. + /* Optimize for register value of 0. */
  103. + if (code == EQ && rtx_equal_p (op0, cons) && op1 == CONST0_RTX (mode))
  104. + {
  105. + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
  106. + alt = force_reg (mode, alt);
  107. + emit_insn (gen_rtx_SET (dest,
  108. + gen_rtx_IF_THEN_ELSE (mode, cond,
  109. + cons, alt)));
  110. + return true;
  111. + }
  112. +
  113. + riscv_emit_int_compare (&code, &op0, &op1, true);
  114. + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
  115. +
  116. + rtx temp1 = gen_reg_rtx (mode);
  117. + rtx temp2 = gen_int_mode (-1 * INTVAL (alt), mode);
  118. +
  119. + /* TEMP2 might not fit into a signed 12 bit immediate suitable
  120. + for an addi instruction. If that's the case, force it into
  121. + a register. */
  122. + if (!SMALL_OPERAND (INTVAL (temp2)))
  123. + temp2 = force_reg (mode, temp2);
  124. +
  125. + riscv_emit_binary (PLUS, temp1, cons, temp2);
  126. + emit_insn (gen_rtx_SET (dest,
  127. + gen_rtx_IF_THEN_ELSE (mode, cond,
  128. + temp1,
  129. + CONST0_RTX (mode))));
  130. + riscv_emit_binary (PLUS, dest, dest, alt);
  131. + return true;
  132. + }
  133. + /* reg, reg */
  134. + else if (REG_P (cons) && REG_P (alt))
  135. + {
  136. + if ((code == EQ && rtx_equal_p (cons, op0))
  137. + || (code == NE && rtx_equal_p (alt, op0)))
  138. + {
  139. + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
  140. + if (!rtx_equal_p (cons, op0))
  141. + std::swap (alt, cons);
  142. + alt = force_reg (mode, alt);
  143. + emit_insn (gen_rtx_SET (dest,
  144. + gen_rtx_IF_THEN_ELSE (mode, cond,
  145. + cons, alt)));
  146. + return true;
  147. + }
  148. +
  149. + rtx reg1 = gen_reg_rtx (mode);
  150. + rtx reg2 = gen_reg_rtx (mode);
  151. + riscv_emit_int_compare (&code, &op0, &op1, true);
  152. + rtx cond1 = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
  153. + rtx cond2 = gen_rtx_fmt_ee (code == NE ? EQ : NE,
  154. + GET_MODE (op0), op0, op1);
  155. + emit_insn (gen_rtx_SET (reg2,
  156. + gen_rtx_IF_THEN_ELSE (mode, cond2,
  157. + CONST0_RTX (mode),
  158. + cons)));
  159. + emit_insn (gen_rtx_SET (reg1,
  160. + gen_rtx_IF_THEN_ELSE (mode, cond1,
  161. + CONST0_RTX (mode),
  162. + alt)));
  163. + riscv_emit_binary (IOR, dest, reg1, reg2);
  164. + return true;
  165. + }
  166. }
  167. return false;
  168. --
  169. 2.25.1