In the process of DF to SI, we generally use "unsigned_fix" rather than "truncate" for conversion. Although this has no effect in general, unexpected ICE often occurs when precise semantic analysis is required.
gcc/ChangeLog: * config/riscv/riscv.md: Change "truncate" to "unsigned_fix" for the Zfa extension on rv32. gcc/testsuite/ChangeLog: * gcc.target/riscv/zfa-fmovh-fmovp-bug.c: New test. --- gcc/config/riscv/riscv.md | 4 ++-- gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-bug.c | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-bug.c diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 9f94b5aa0232..36d7b333c456 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -2627,7 +2627,7 @@ (define_insn "*movdf_softfloat" (define_insn "movsidf2_low_rv32" [(set (match_operand:SI 0 "register_operand" "= r") - (truncate:SI + (unsigned_fix:SI (match_operand:DF 1 "register_operand" "zmvf")))] "TARGET_HARD_FLOAT && !TARGET_64BIT && TARGET_ZFA" "fmv.x.w\t%0,%1" @@ -2638,7 +2638,7 @@ (define_insn "movsidf2_low_rv32" (define_insn "movsidf2_high_rv32" [(set (match_operand:SI 0 "register_operand" "= r") - (truncate:SI + (unsigned_fix:SI (lshiftrt:DF (match_operand:DF 1 "register_operand" "zmvf") (const_int 32))))] diff --git a/gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-bug.c b/gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-bug.c new file mode 100644 index 000000000000..e00047b09e3a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zfa-fmovh-fmovp-bug.c @@ -0,0 +1,9 @@ +/* Test that we do not have ice when compile */ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_zfa -mabi=ilp32d -O2 -g" } */ + +unsigned int +foo (double a) { + unsigned int tt = *(unsigned long long *)&a & 0xffff; + return tt; +} -- 2.17.1