Source: orc
Version: 1:0.4.42-3
Severity: important

Dear maintainer,

gst-plugins-bad1.0 fails to build from source when built on a RISC-V CPU
with vector instructions [1], due to a SIGILL in the elements_openjpeg
test. Disabling rvv instruction detection in ORC workarounds the issue.

I tracked the issue down to the following ORC generated code:

   0x0000003f878a9220:  ld      a1,24(a0)
   0x0000003f878a9224:  ld      a2,56(a0)
   0x0000003f878a9228:  ld      a3,64(a0)
   0x0000003f878a922c:  ld      a4,72(a0)
   0x0000003f878a9230:  ld      a5,80(a0)
   0x0000003f878a9234:  vsetvli t0,zero,e16,m4,ta,ma
   0x0000003f878a9238:  li      t0,4
   0x0000003f878a923c:  vmv.v.x v16,t0
   0x0000003f878a9240:  lw      t2,8(a0)
   0x0000003f878a9244:  beqz    t2,0x3f878a9308
   0x0000003f878a9248:  vsetvli t1,t2,e16,m2,ta,ma
   0x0000003f878a924c:  sub     t2,t2,t1
   0x0000003f878a9250:  vle32.v v24,(a2)
   0x0000003f878a9254:  vnsrl.wi        v8,v24,16
   0x0000003f878a9258:  vnsrl.wi        v0,v24,0
   0x0000003f878a925c:  vsetvli t0,zero,e16,m4,ta,ma
   0x0000003f878a9260:  vzext.vf2       v24,v8
   0x0000003f878a9264:  vsetvli zero,t1,e16,m2,ta,ma
   0x0000003f878a9268:  vle32.v v4,(a5)
   0x0000003f878a926c:  vnsrl.wi        v8,v4,16
   0x0000003f878a9270:  vsetvli t0,zero,e16,m4,ta,ma
   0x0000003f878a9274:  vzext.vf2       v4,v8
   0x0000003f878a9278:  vadd.vv v12,v24,v4
   0x0000003f878a927c:  vsetvli zero,t1,e16,m2,ta,ma
   0x0000003f878a9280:  vle32.v v24,(a3)
   0x0000003f878a9284:  vnsrl.wi        v8,v24,16
   0x0000003f878a9288:  vsetvli t0,zero,e16,m4,ta,ma
   0x0000003f878a928c:  vzext.vf2       v24,v8
   0x0000003f878a9290:  vsetvli zero,t1,e16,m2,ta,ma
   0x0000003f878a9294:  vle32.v v4,(a4)
   0x0000003f878a9298:  vnsrl.wi        v8,v4,16
   0x0000003f878a929c:  vsetvli t0,zero,e16,m4,ta,ma
   0x0000003f878a92a0:  vzext.vf2       v4,v8
   0x0000003f878a92a4:  vadd.vv v28,v24,v4
   0x0000003f878a92a8:  li      t0,1
   0x0000003f878a92ac:  vsll.vx v4,v28,t0
   0x0000003f878a92b0:  vadd.vv v24,v28,v4
   0x0000003f878a92b4:  vadd.vv v4,v12,v24
   0x0000003f878a92b8:  vadd.vv v24,v4,v16
   0x0000003f878a92bc:  li      t0,3
   0x0000003f878a92c0:  vsrl.vx v4,v24,t0
   0x0000003f878a92c4:  vmax.vx v8,v4,zero
   0x0000003f878a92c8:  vsetvli zero,zero,e8,m1,ta,ma
=> 0x0000003f878a92cc:  vnclipu.wi      v8,v8,0
   0x0000003f878a92d0:  vsetvli zero,zero,e16,m2,ta,ma
   0x0000003f878a92d4:  vsetvli zero,t1,e32,m4,ta,ma
   0x0000003f878a92d8:  vzext.vf2       v12,v0
   0x0000003f878a92dc:  vzext.vf2       v4,v8
   0x0000003f878a92e0:  vsll.vi v4,v4,16
   0x0000003f878a92e4:  vor.vv  v24,v12,v4
   0x0000003f878a92e8:  vse32.v v24,(a1)
   0x0000003f878a92ec:  slli    t1,t1,0x2
   0x0000003f878a92f0:  add     a1,a1,t1
   0x0000003f878a92f4:  add     a2,a2,t1
   0x0000003f878a92f8:  add     a3,a3,t1
   0x0000003f878a92fc:  add     a4,a4,t1
   0x0000003f878a9300:  add     a5,a5,t1
   0x0000003f878a9304:  bnez    t2,0x3f878a9248
   0x0000003f878a9308:  ret

The trap occurs at the vnclipu.wi instruction. But further debugging
shows that it is actually not the relevant instruction. SIGILL happens
because the preceding vsetvli instruction set vtype to vill (unsupported
vector configuration), so any following vector instruction fail.

Digging a bit more into the problem, it is caused by the two following
vsetvli instructions:

   0x0000003f878a929c:  vsetvli t0,zero,e16,m4,ta,ma
   ...
   0x0000003f878a92c8:  vsetvli zero,zero,e8,m1,ta,ma

On the SpacemiT K1 (used by the rv-manda-04 build daemon where it
fails), VLEN=256 bits. Therefore the first vsetvli instruction
configures:
- SEW = 16
- LMUL = 4
- VLMAX = VLEN / SEW * LMUL = 256 / 16 * 4 = 64
- VL = VLMAX (as AVL = x0) = 64

The second instructions configures:
- SEW = 8
- LMUL = 1
- VLMAX = VLEN / SEW * LMUL = 256 / 8 * 1 = 32

Since both rs1 = x0 and rd = x0, the current vl is reused as the AVL.
However, according to the RVV 1.0 specification:

"When rs1=x0 and rd=x0, the instruction operates as if the current
vector length in vl is used as the AVL, and the resulting value is
written to vl, but not to a destination register. This form can only be
used when VLMAX and hence vl is not actually changed by the new SEW/LMUL
ratio. Use of the instruction with a new SEW/LMUL ratio that would
result in a change of VLMAX is reserved. Implementations may set vill in
this case."

The SpacemiT K1 (and also the SpacemiT K3) sets vill in this situation,
which is a permitted way to signal the undefined behaviour of this
sequence. That explains why vtype is set to vill and why the next vector
instruction fails.

I still have to understand why the ORC RVV backend emits such sequence
(and looking at above it also generate redundant vsetvli sequences
without vector instructions in between.

Regards
Aurelien

[1] 
https://buildd.debian.org/status/fetch.php?pkg=gst-plugins-bad1.0&arch=riscv64&ver=1.28.5-2&stamp=1784782699&raw=0
 

Reply via email to