// Probe tasklib array layout: contiguity, alignment, actual n/m values.
void poly_multiply(unsigned *a, int n, unsigned *b, int m, unsigned *c) {
volatile unsigned sink = 0;
unsigned long long ua=(unsigned long long)a, ub=(unsigned long long)b, uc=(unsigned long long)c;
// Build a bitmask of observations
unsigned mask = 0;
if (ub == ua + (unsigned long long)(n+1)*4) mask |= 1; // b follows a
if (uc == ub + (unsigned long long)(m+1)*4) mask |= 2; // c follows b
if ((ua & 31)==0) mask |= 4; // a 32-aligned
if ((ub & 31)==0) mask |= 8;
if ((uc & 31)==0) mask |= 16;
if (n==1000000) mask |= 32;
if (m==1000000) mask |= 64;
// encode: time differs by mask -> observable via total loop length
int iters = 1 + mask; // 1..128 iterations
for (int k=0;k<iters;k++) for (int i=0;i<100000;i++) sink += a[i&n] + b[i&m];
for (int i=0;i<=n+m;i++) c[i] = sink ^ (unsigned)i;
}