0025-RISC-V-Fold-all-the-cond-move-variants-together.patch 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. From 687b8b8b116d51a7533c270a4fba87efa51a0629 Mon Sep 17 00:00:00 2001
  2. From: "Maciej W. Rozycki" <macro@embecosm.com>
  3. Date: Wed, 22 Nov 2023 01:18:27 +0000
  4. Subject: [PATCH 25/30] RISC-V: Fold all the cond-move variants together
  5. Code in `riscv_expand_conditional_move' for Ventana and Zicond targets
  6. seems like bolted on as an afterthought rather than properly merged so
  7. as to handle all the cases together.
  8. Fold the existing code pieces together then (observing that for short
  9. forward branch targets no integer comparisons need to be canonicalized),
  10. letting T-Head targets produce branchless sequences for all the integer
  11. comparisons rather than for equality ones only, and preparing for the
  12. handling of floating-point comparisons here across all conditional-move
  13. targets.
  14. gcc/
  15. * config/riscv/riscv.cc (riscv_expand_conditional_move): Unify
  16. conditional-move handling across all the relevant targets.
  17. ---
  18. gcc/config/riscv/riscv.cc | 79 ++++++++++++++++-----------------------
  19. 1 file changed, 33 insertions(+), 46 deletions(-)
  20. diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
  21. index 4784fa051e1..6ed3c2d1d1d 100644
  22. --- a/gcc/config/riscv/riscv.cc
  23. +++ b/gcc/config/riscv/riscv.cc
  24. @@ -3533,7 +3533,6 @@ riscv_expand_conditional_move_onesided (rtx dest, rtx cons, rtx alt,
  25. /* Emit a cond move: If OP holds, move CONS to DEST; else move ALT to DEST.
  26. Return 0 if expansion failed. */
  27. -
  28. bool
  29. riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
  30. {
  31. @@ -3542,50 +3541,28 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
  32. rtx op0 = XEXP (op, 0);
  33. rtx op1 = XEXP (op, 1);
  34. - if (TARGET_XTHEADCONDMOV
  35. - && GET_MODE_CLASS (mode) == MODE_INT
  36. - && reg_or_0_operand (cons, mode)
  37. - && reg_or_0_operand (alt, mode)
  38. - && GET_MODE (op) == mode
  39. - && GET_MODE (op0) == mode
  40. - && GET_MODE (op1) == mode
  41. - && (code == EQ || code == NE))
  42. + if ((TARGET_ZICOND_LIKE && GET_MODE_CLASS (mode) == MODE_INT)
  43. + || TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
  44. {
  45. - riscv_expand_conditional_move_onesided (dest, cons, alt, code, op0, op1);
  46. - return true;
  47. - }
  48. - else if (TARGET_SFB_ALU
  49. - && mode == word_mode)
  50. - {
  51. - riscv_emit_int_compare (&code, &op0, &op1);
  52. - rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
  53. + machine_mode mode0 = GET_MODE (op0);
  54. + machine_mode mode1 = GET_MODE (op1);
  55. - /* The expander is a bit loose in its specification of the true
  56. - arm of the conditional move. That allows us to support more
  57. - cases for extensions which are more general than SFB. But
  58. - does mean we need to force CONS into a register at this point. */
  59. - cons = force_reg (GET_MODE (dest), cons);
  60. - emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (GET_MODE (dest),
  61. - cond, cons, alt)));
  62. - return true;
  63. - }
  64. - else if (TARGET_ZICOND_LIKE
  65. - && GET_MODE_CLASS (mode) == MODE_INT)
  66. - {
  67. /* The comparison must be comparing WORD_MODE objects. We must
  68. enforce that so that we don't strip away a sign_extension
  69. thinking it is unnecessary. We might consider using
  70. riscv_extend_operands if they are not already properly extended. */
  71. - if (GET_MODE (op0) != word_mode || GET_MODE (op1) != word_mode)
  72. + if ((mode0 != word_mode && mode0 != VOIDmode)
  73. + || (mode1 != word_mode && mode1 != VOIDmode))
  74. return false;
  75. /* Canonicalize the comparison. It must be an equality comparison
  76. - of integer operands. If it isn't, then emit an SCC instruction
  77. + of integer operands, or with SFB it can be any comparison of
  78. + integer operands. If it isn't, then emit an SCC instruction
  79. so that we can then use an equality comparison against zero. */
  80. - if (!equality_operator (op, VOIDmode) || !INTEGRAL_MODE_P (mode0))
  81. + if ((!TARGET_SFB_ALU && !equality_operator (op, VOIDmode))
  82. + || !INTEGRAL_MODE_P (mode0))
  83. {
  84. - enum rtx_code new_code = NE;
  85. - bool *invert_ptr = 0;
  86. + bool *invert_ptr = nullptr;
  87. bool invert = false;
  88. /* If riscv_expand_int_scc inverts the condition, then it will
  89. @@ -3599,21 +3576,15 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
  90. rtx tmp = gen_reg_rtx (word_mode);
  91. /* We can support both FP and integer conditional moves. */
  92. - if (INTEGRAL_MODE_P (GET_MODE (XEXP (op, 0))))
  93. + if (INTEGRAL_MODE_P (mode0))
  94. riscv_expand_int_scc (tmp, code, op0, op1, invert_ptr);
  95. - else if (FLOAT_MODE_P (GET_MODE (XEXP (op, 0)))
  96. + else if (FLOAT_MODE_P (mode0)
  97. && fp_scc_comparison (op, GET_MODE (op)))
  98. riscv_expand_float_scc (tmp, code, op0, op1);
  99. else
  100. return false;
  101. - /* If riscv_expand_int_scc inverts the condition, then it will
  102. - flip the value of INVERT. We need to know where so that
  103. - we can adjust it for our needs. */
  104. - if (invert)
  105. - new_code = EQ;
  106. -
  107. - op = gen_rtx_fmt_ee (new_code, mode, tmp, const0_rtx);
  108. + op = gen_rtx_fmt_ee (invert ? EQ : NE, mode, tmp, const0_rtx);
  109. /* We've generated a new comparison. Update the local variables. */
  110. code = GET_CODE (op);
  111. @@ -3621,10 +3592,26 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
  112. op1 = XEXP (op, 1);
  113. }
  114. + if (TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
  115. + {
  116. + riscv_emit_int_compare (&code, &op0, &op1, !TARGET_SFB_ALU);
  117. + rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
  118. +
  119. + /* The expander is a bit loose in its specification of the true
  120. + arm of the conditional move. That allows us to support more
  121. + cases for extensions which are more general than SFB. But
  122. + does mean we need to force CONS into a register at this point. */
  123. + cons = force_reg (mode, cons);
  124. + /* With XTheadCondMov we need to force ALT into a register too. */
  125. + alt = force_reg (mode, alt);
  126. + emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (mode, cond,
  127. + cons, alt)));
  128. + return true;
  129. + }
  130. /* 0, reg or 0, imm */
  131. - if (cons == CONST0_RTX (mode)
  132. - && (REG_P (alt)
  133. - || (CONST_INT_P (alt) && alt != CONST0_RTX (mode))))
  134. + else if (cons == CONST0_RTX (mode)
  135. + && (REG_P (alt)
  136. + || (CONST_INT_P (alt) && alt != CONST0_RTX (mode))))
  137. {
  138. riscv_emit_int_compare (&code, &op0, &op1, true);
  139. rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
  140. --
  141. 2.25.1