[RISCV] Use signed target constants for XCVmem post-inc loads (#189276)
First time opening a PR against LLVM, so please let me know if anything
is missing / wrong.
This fixes an assertion in RISC-V DAG isel for CORE-V xcvmem
post-increment loads with negative immediate offsets.
`RISCVDAGToDAGISel::Select` recognizes `xcvmem POST_INC` loads and
checks whether the offset fits the signed 12-bit immediate form used by
`cv.lb/cv.lbu/cv.lh/cv.lhu/cv.lw ... , (rs1), imm12`. That path was
extracting the offset with `getSExtValue()`, but then rebuilding it with
`getTargetConstant(...)`, which takes the unsigned constant path.
For negative offsets, that could trip the APInt assertion:
```
Assertion failed: (llvm::isUIntN(BitWidth, val) && "Value is not an N-bit unsigned value")
```
during `RISC-V DAG->DAG Pattern Instruction Selection`.
The fix is to use `getSignedTargetConstant(...)` for the xcvmem
immediate case.
A regression test is added to llvm/test/CodeGen/RISCV/xcvmem.ll that
covers a reduced negative post-increment load case and checks the
expected codegen:
```asm
lw a2, 0(a0)
cv.lw a1, (a2), -4
sw a2, 0(a0)
mv a0, a1
ret
```
Reproducer before the fix:
```c
int f(int **pp) {
int *p = *pp;
int x = *p;
*pp = p - 1;
return x;
}
```
Example failing invocation:
```bash
clang --target=riscv32-unknown-elf \
-march=rv32imf_zicsr_zifencei_xcvmem \
-mabi=ilp32f -O2 -ffreestanding -c repro.c
```
Validation:
```bash
llc -O3 -mtriple=riscv32 -mattr=+xcvmem -verify-machineinstrs llvm/test/CodeGen/RISCV/xcvmem.ll
```
Confirmed the reduced repro no longer crashes