0014-RISC-V-Use-splitter-to-generate-zicond-in-another-ca.patch 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. From 1b1f5be20e41f14041f0ac3ec295fc114f6e3b86 Mon Sep 17 00:00:00 2001
  2. From: Philipp Tomsich <philipp.tomsich@vrull.eu>
  3. Date: Tue, 29 Aug 2023 16:48:24 -0600
  4. Subject: [PATCH 14/30] RISC-V: Use splitter to generate zicond in another case
  5. So in analyzing Ventana's internal tree against the trunk it became apparent
  6. that the current zicond code is missing a case that helps coremark's bitwise
  7. CRC implementation.
  8. Here's a minimized testcase:
  9. long xor1(long crc, long poly)
  10. {
  11. if (crc & 1)
  12. crc ^= poly;
  13. return crc;
  14. }
  15. ie, it's just a conditional xor.
  16. We generate this:
  17. andi a5,a0,1
  18. neg a5,a5
  19. and a5,a5,a1
  20. xor a0,a5,a0
  21. ret
  22. But we should instead generate:
  23. andi a5,a0,1
  24. czero.eqz a5,a1,a5
  25. xor a0,a5,a0
  26. ret
  27. Combine wants to generate:
  28. Trying 7, 8 -> 9:
  29. 7: r140:DI=r137:DI&0x1
  30. 8: r141:DI=-r140:DI
  31. REG_DEAD r140:DI
  32. 9: r142:DI=r141:DI&r144:DI
  33. REG_DEAD r144:DI
  34. REG_DEAD r141:DI
  35. Failed to match this instruction:
  36. (set (reg:DI 142)
  37. (and:DI (sign_extract:DI (reg/v:DI 137 [ crc ])
  38. (const_int 1 [0x1])
  39. (const_int 0 [0]))
  40. (reg:DI 144)))
  41. A splitter can rewrite the above into a suitable if-then-else construct and
  42. squeeze an instruction out of that pesky CRC loop. Sadly it doesn't really
  43. help anything else.
  44. The patch includes two variants. One that uses ZBS, the other uses an ANDI
  45. logical to produce the input condition.
  46. gcc/
  47. * config/riscv/zicond.md: New splitters to rewrite single bit
  48. sign extension as the condition to a czero in the desired form.
  49. gcc/testsuite
  50. * gcc.target/riscv/zicond-xor-01.c: New test.
  51. Co-authored-by: Jeff Law <jlaw@ventanamicro.com>
  52. ---
  53. gcc/config/riscv/zicond.md | 31 +++++++++++++++++++
  54. .../gcc.target/riscv/zicond-xor-01.c | 14 +++++++++
  55. 2 files changed, 45 insertions(+)
  56. create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-xor-01.c
  57. diff --git a/gcc/config/riscv/zicond.md b/gcc/config/riscv/zicond.md
  58. index 25f21d33487..4619220ef8a 100644
  59. --- a/gcc/config/riscv/zicond.md
  60. +++ b/gcc/config/riscv/zicond.md
  61. @@ -62,3 +62,34 @@
  62. "TARGET_ZICOND && rtx_equal_p (operands[1], operands[3])"
  63. "czero.nez\t%0,%2,%1"
  64. )
  65. +
  66. +;; Combine creates this form in some cases (particularly the coremark
  67. +;; CRC loop.
  68. +(define_split
  69. + [(set (match_operand:X 0 "register_operand")
  70. + (and:X (sign_extract:X (match_operand:X 1 "register_operand")
  71. + (const_int 1)
  72. + (match_operand 2 "immediate_operand"))
  73. + (match_operand:X 3 "register_operand")))
  74. + (clobber (match_operand:X 4 "register_operand"))]
  75. + "TARGET_ZICOND && TARGET_ZBS"
  76. + [(set (match_dup 4) (zero_extract:X (match_dup 1) (const_int 1) (match_dup 2)))
  77. + (set (match_dup 0) (if_then_else:X (eq:X (match_dup 4) (const_int 0))
  78. + (const_int 0)
  79. + (match_dup 3)))])
  80. +
  81. +(define_split
  82. + [(set (match_operand:X 0 "register_operand")
  83. + (and:X (sign_extract:X (match_operand:X 1 "register_operand")
  84. + (const_int 1)
  85. + (match_operand 2 "immediate_operand"))
  86. + (match_operand:X 3 "register_operand")))
  87. + (clobber (match_operand:X 4 "register_operand"))]
  88. + "TARGET_ZICOND && !TARGET_ZBS && (UINTVAL (operands[2]) < 11)"
  89. + [(set (match_dup 4) (and:X (match_dup 1) (match_dup 2)))
  90. + (set (match_dup 0) (if_then_else:X (eq:X (match_dup 4) (const_int 0))
  91. + (const_int 0)
  92. + (match_dup 3)))]
  93. +{
  94. + operands[2] = GEN_INT (1 << UINTVAL(operands[2]));
  95. +})
  96. diff --git a/gcc/testsuite/gcc.target/riscv/zicond-xor-01.c b/gcc/testsuite/gcc.target/riscv/zicond-xor-01.c
  97. new file mode 100644
  98. index 00000000000..8362ffaf5ab
  99. --- /dev/null
  100. +++ b/gcc/testsuite/gcc.target/riscv/zicond-xor-01.c
  101. @@ -0,0 +1,14 @@
  102. +/* { dg-do compile } */
  103. +/* { dg-options "-march=rv64gc_zicond -mabi=lp64" } */
  104. +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
  105. +
  106. +long xor1(long crc, long poly)
  107. +{
  108. + if (crc & 1)
  109. + crc ^= poly;
  110. +
  111. + return crc;
  112. +}
  113. +
  114. +/* { dg-final { scan-assembler-times "czero.eqz\t" 1 } } */
  115. +/* { dg-final { scan-assembler-times "xor\t" 1 } } */
  116. --
  117. 2.25.1