The Combine Pass may generate zero_extract instructions that are out of range.
Drawing from other architectures like AArch64, we should impose restrictions
on the "*th_extu<mode>4" pattern.
gcc/
* config/riscv/thead.md (*th_extu<mode>4): Fix th.extu
operands exceeding range on rv32.
gcc/testsuite/
* gcc.target/riscv/xtheadbb-extu-4.c: New.
(zero_extract:GPR (match_operand:GPR 1 "register_operand" "r")
(match_operand 2 "const_int_operand")
(match_operand 3 "const_int_operand")))]
- "TARGET_XTHEADBB"
+ "TARGET_XTHEADBB
+ && (UINTVAL (operands[2]) + UINTVAL (operands[3])
+ <= GET_MODE_BITSIZE (<MODE>mode))"
{
operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]) - 1);
return "th.extu\t%0,%1,%2,%3";
--- /dev/null
+/* { dg-do compile { target { rv32 } } } */
+/* { dg-options "-march=rv32gc_xtheadbb" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Og" "-Oz" } } */
+
+struct c {
+ int f : 25;
+} d;
+
+int b;
+extern unsigned int e[];
+
+void g()
+{
+ d.f = e[2] >> (b << ~4194303 + 4194332) - 58096371;
+}
+
+/* { dg-final { scan-assembler-not {th.extu\t[ax][0-9]+,[ax][0-9]+,37,13} } } */
\ No newline at end of file