https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116305

            Bug ID: 116305
           Summary: RISC-V: dwarf cfi_escape information is incorrect when
                    use vlenb to get scalable frame
           Product: gcc
           Version: 14.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: zhijin.zeng at spacemit dot com
  Target Milestone: ---

Created attachment 58884
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58884&action=edit
risc-v vector dwarf cfi test case

The commit bd93ef changes the chunk_num from 1 to TARGET_MIN_VLEN/128 if
TARGET_MIN_VLEN is larger than 128 in riscv_convert_vector_bits. So it changes
the value of BYTES_PER_RISCV_VECTOR. For example, before the commit bd93ef is
merged and if TARGET_MIN_VLEN is 256, the value of BYTES_PER_RISCV_VECTOR
should be [8, 8], but now [16, 16]. The value of riscv_bytes_per_vector_chunk
and BYTES_PER_RISCV_VECTOR are no longer equal.

Prologue and epilogue will use BYTES_PER_RISCV_VECTOR.coeffs[1] to estimate the
vlenb register value in riscv_legitimize_poly_move, and dwarf2cfi will also get
the estimated vlenb register value in riscv_dwarf_poly_indeterminate_value to
calculate the number of times to multiply the vlenb register value.

So need to change the factor from riscv_bytes_per_vector_chunk to
BYTES_PER_RISCV_VECTOR, otherwise we will get the incorrect dwarf information.
The incorrect example as follow:

```
csrr    t0,vlenb
slli    t1,t0,1
sub     sp,sp,t1

.cfi_escape 0xf,0xb,0x72,0,0x92,0xa2,0x38,0,0x34,0x1e,0x23,0x50,0x22
```

The sequence '0x92,0xa2,0x38,0' means the vlenb register, '0x34' means the
literal 4, '0x1e' means the multiply operation. But in fact, the vlenb register
value just need to multiply the literal 2.


My test case is in the attached file, the compile command is
'riscv64-unknown-linux-gnu-gcc -Ofast -march=rv64gcv -mabi=lp64d -S
riscv_cfi_test.c -o riscv_cfi_test.S -Wall'。


The following patch can fix the bug.
```
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 5fe4273beb7..e07adf91a9b 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -10773,12 +10773,14 @@ static unsigned int
 riscv_dwarf_poly_indeterminate_value (unsigned int i, unsigned int *factor,
                                      int *offset)
 {
-  /* Polynomial invariant 1 == (VLENB / riscv_bytes_per_vector_chunk) - 1.
-     1. TARGET_MIN_VLEN == 32, polynomial invariant 1 == (VLENB / 4) - 1.
-     2. TARGET_MIN_VLEN > 32, polynomial invariant 1 == (VLENB / 8) - 1.
+  /* Polynomial invariant 1 == (VLENB / BYTES_PER_RISCV_VECTOR) - 1.
+     1. TARGET_MIN_VLEN == 32, polynomial invariant
+         1 == (VLENB / (4 * riscv_vector_chunks)) - 1.
+     2. TARGET_MIN_VLEN > 32, polynomial invariant
+         1 == (VLENB / (8 * riscv_vector_chunks)) - 1.
   */
   gcc_assert (i == 1);
-  *factor = riscv_bytes_per_vector_chunk;
+  *factor = BYTES_PER_RISCV_VECTOR.coeffs[1];
   *offset = 1;
   return RISCV_DWARF_VLENB;
 }
```

Reply via email to