[v2] RISC-V: Correct the mode that is causing the program to fail for XTheadCondMov
Checks
Context |
Check |
Description |
rivoscibot/toolchain-ci-rivos-apply-patch |
success
|
Patch applied
|
rivoscibot/toolchain-ci-rivos-lint |
success
|
Lint passed
|
rivoscibot/toolchain-ci-rivos-build--newlib-rv64gcv-lp64d-multilib |
success
|
Build passed
|
rivoscibot/toolchain-ci-rivos-build--linux-rv64gcv-lp64d-multilib |
success
|
Build passed
|
rivoscibot/toolchain-ci-rivos-build--linux-rv64gc_zba_zbb_zbc_zbs-lp64d-multilib |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_build--master-arm |
success
|
Build passed
|
rivoscibot/toolchain-ci-rivos-test |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-arm |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 |
success
|
Test passed
|
Commit Message
For XTheadCondMov, the bit width of rs2 should always be XLEN-sized, otherwise
the program logic will be wrong.
Reference form
https://github.com/XUANTIE-RV/thead-extension-spec/releases/download/2.3.0/xthead-2023-11-10-2.3.0.pdf
Synopsis
Move if equal zero.
Mnemonic
th.mveqz rd, rs1, rs2
Description
This instruction moves the content of register rs1 into rd if the content of rs2 is 0x0.
Otherwise, the value of rd does not change.
Operation
if (reg[rs2] == 0x0)
reg[rd] := reg[rs1]
gcc/ChangeLog:
* config/riscv/thead.md (*th_cond_mov<GPR:mode><GPR2:mode>):
Change GPR2 to X.
(*th_cond_mov<GPR:mode>): Likewise.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/xtheadcondmov-bug.c: New test.
---
gcc/config/riscv/thead.md | 4 ++--
gcc/testsuite/gcc.target/riscv/xtheadcondmov-bug.c | 12 ++++++++++++
2 files changed, 14 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-bug.c
Comments
On 1/19/25 10:56 PM, Jin Ma wrote:
> For XTheadCondMov, the bit width of rs2 should always be XLEN-sized, otherwise
> the program logic will be wrong.
>
> Reference form
> https://github.com/XUANTIE-RV/thead-extension-spec/releases/download/2.3.0/xthead-2023-11-10-2.3.0.pdf
>
> Synopsis
> Move if equal zero.
>
> Mnemonic
> th.mveqz rd, rs1, rs2
>
> Description
> This instruction moves the content of register rs1 into rd if the content of rs2 is 0x0.
> Otherwise, the value of rd does not change.
>
> Operation
> if (reg[rs2] == 0x0)
> reg[rd] := reg[rs1]
>
> gcc/ChangeLog:
>
> * config/riscv/thead.md (*th_cond_mov<GPR:mode><GPR2:mode>):
> Change GPR2 to X.
> (*th_cond_mov<GPR:mode>): Likewise.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/riscv/xtheadcondmov-bug.c: New test.
Thanks. I've pushed this to the trunk.
Interestingly enough I was wandering around a bit in this code over the
last week as part of the work on pr114277 (and its related bzs). We
need to improve riscv_expand_conditional_move to handle sub-word sizes
better -- which we've known for a while.
First for the comparison if we start using riscv_extend_operands we'll
be able to handle the sub-word comparison case at expansion time.
Second we probably need to support sub-word source/destinations. I'm
still pondering the best way to handle these -- it's a known weakness
that we don't handle the sub-word cases well.
Anyway, point is we probably want to do more work in the expander and
your fix will be critical once we start handling more cases in the expander.
Thanks again,
jeff
@@ -154,11 +154,11 @@ (define_insn "*th_tst<mode>3"
;; XTheadCondMov
-(define_insn "*th_cond_mov<GPR:mode><GPR2:mode>"
+(define_insn "*th_cond_mov<GPR:mode>"
[(set (match_operand:GPR 0 "register_operand" "=r,r")
(if_then_else:GPR
(match_operator 4 "equality_operator"
- [(match_operand:GPR2 1 "register_operand" "r,r")
+ [(match_operand:X 1 "register_operand" "r,r")
(const_int 0)])
(match_operand:GPR 2 "reg_or_0_operand" "rJ,0")
(match_operand:GPR 3 "reg_or_0_operand" "0,rJ")))]
new file mode 100644
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { rv64 } } } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mabi=lp64d -O2" } */
+
+long long int
+foo (long long int x, long long int y)
+{
+ if (((int) x | (int) y) != 0)
+ return 6;
+ return x + y;
+}
+
+/* { dg-final { scan-assembler-times {\msext\.w\M} 1 } } */