Fix edge case of bitfield extract with count == numbits. Closes #3813

* This is only legal if offset is 0 and so degenerate, but it is valid and needs
  to be handled.
This commit is contained in:
baldurk
2026-03-11 22:43:24 +00:00
parent faf3e01248
commit dc82c117f5
2 changed files with 21 additions and 11 deletions
+12 -11
View File
@@ -2234,17 +2234,18 @@ void ThreadState::StepNext(bool useDebugState, const uint32_t steps,
for(uint8_t c = 0; c < var.columns; c++)
{
#undef _IMPL
#define _IMPL(I, S, U) \
const U mask = (U(1) << comp<U>(count, c)) - U(1); \
\
comp<U>(var, c) >>= comp<U>(offset, c); \
comp<U>(var, c) &= mask; \
\
if(opdata.op == Op::BitFieldSExtract) \
{ \
U topbit = (mask + U(1)) >> U(1); \
if(comp<U>(var, c) & topbit) \
comp<U>(var, c) |= (~0ULL ^ mask); \
#define _IMPL(I, S, U) \
const U bitcount = comp<U>(count, c); \
const U mask = bitcount == sizeof(U) * 8 ? ~0ULL : (U(1) << bitcount) - U(1); \
\
comp<U>(var, c) >>= comp<U>(offset, c); \
comp<U>(var, c) &= mask; \
\
if(opdata.op == Op::BitFieldSExtract) \
{ \
U topbit = (mask + U(1)) >> U(1); \
if(comp<U>(var, c) & topbit) \
comp<U>(var, c) |= (~0ULL ^ mask); \
}
IMPL_FOR_INT_TYPES(_IMPL);
@@ -1675,6 +1675,15 @@ void main()
Color = vec4(x, y, z, w);
break;
}
case 187:
{
uint a = zerou + 0x44b82a80;
int b = zeroi + 0x44b82a80;
Color = vec4(float(bitfieldExtract(a, 0, 32)), float(bitfieldExtract(b, 0, 32)),
float(bitfieldExtract(a, 32, 0)), float(bitfieldExtract(b, 32, 0)));
break;
}
default: break;
}
}