From: Marius Gräfe Date: Fri, 9 Jun 2017 13:39:00 +0000 (+0200) Subject: gallium: fixed modulo zero crashes in tgsi interpreter (v2) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f3c0bbe18ac65d22b2630f89fc1628bfe79695d4;p=mesa.git gallium: fixed modulo zero crashes in tgsi interpreter (v2) softpipe throws integer division by zero exceptions on windows when using % with integers in a geometry shader. v2: Made error results consistent with existing div/mod zero handling in tgsi. 64 bit signed integer division by zero returns zero like in micro_idiv, unsigned returns ~0u like in micro_udiv. Modulo operations always set all result bits to one (like in micro_umod). Reviewed-by: Roland Scheidegger --- diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index c41954cbf76..97c75e999c5 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -846,40 +846,40 @@ static void micro_u64div(union tgsi_double_channel *dst, const union tgsi_double_channel *src) { - dst->u64[0] = src[0].u64[0] / src[1].u64[0]; - dst->u64[1] = src[0].u64[1] / src[1].u64[1]; - dst->u64[2] = src[0].u64[2] / src[1].u64[2]; - dst->u64[3] = src[0].u64[3] / src[1].u64[3]; + dst->u64[0] = src[1].u64[0] ? src[0].u64[0] / src[1].u64[0] : ~0ull; + dst->u64[1] = src[1].u64[1] ? src[0].u64[1] / src[1].u64[1] : ~0ull; + dst->u64[2] = src[1].u64[2] ? src[0].u64[2] / src[1].u64[2] : ~0ull; + dst->u64[3] = src[1].u64[3] ? src[0].u64[3] / src[1].u64[3] : ~0ull; } static void micro_i64div(union tgsi_double_channel *dst, const union tgsi_double_channel *src) { - dst->i64[0] = src[0].i64[0] / src[1].i64[0]; - dst->i64[1] = src[0].i64[1] / src[1].i64[1]; - dst->i64[2] = src[0].i64[2] / src[1].i64[2]; - dst->i64[3] = src[0].i64[3] / src[1].i64[3]; + dst->i64[0] = src[1].i64[0] ? src[0].i64[0] / src[1].i64[0] : 0; + dst->i64[1] = src[1].i64[1] ? src[0].i64[1] / src[1].i64[1] : 0; + dst->i64[2] = src[1].i64[2] ? src[0].i64[2] / src[1].i64[2] : 0; + dst->i64[3] = src[1].i64[3] ? src[0].i64[3] / src[1].i64[3] : 0; } static void micro_u64mod(union tgsi_double_channel *dst, const union tgsi_double_channel *src) { - dst->u64[0] = src[0].u64[0] % src[1].u64[0]; - dst->u64[1] = src[0].u64[1] % src[1].u64[1]; - dst->u64[2] = src[0].u64[2] % src[1].u64[2]; - dst->u64[3] = src[0].u64[3] % src[1].u64[3]; + dst->u64[0] = src[1].u64[0] ? src[0].u64[0] % src[1].u64[0] : ~0ull; + dst->u64[1] = src[1].u64[1] ? src[0].u64[1] % src[1].u64[1] : ~0ull; + dst->u64[2] = src[1].u64[2] ? src[0].u64[2] % src[1].u64[2] : ~0ull; + dst->u64[3] = src[1].u64[3] ? src[0].u64[3] % src[1].u64[3] : ~0ull; } static void micro_i64mod(union tgsi_double_channel *dst, const union tgsi_double_channel *src) { - dst->i64[0] = src[0].i64[0] % src[1].i64[0]; - dst->i64[1] = src[0].i64[1] % src[1].i64[1]; - dst->i64[2] = src[0].i64[2] % src[1].i64[2]; - dst->i64[3] = src[0].i64[3] % src[1].i64[3]; + dst->i64[0] = src[1].i64[0] ? src[0].i64[0] % src[1].i64[0] : ~0ll; + dst->i64[1] = src[1].i64[1] ? src[0].i64[1] % src[1].i64[1] : ~0ll; + dst->i64[2] = src[1].i64[2] ? src[0].i64[2] % src[1].i64[2] : ~0ll; + dst->i64[3] = src[1].i64[3] ? src[0].i64[3] % src[1].i64[3] : ~0ll; } static void @@ -4653,10 +4653,10 @@ micro_mod(union tgsi_exec_channel *dst, const union tgsi_exec_channel *src0, const union tgsi_exec_channel *src1) { - dst->i[0] = src0->i[0] % src1->i[0]; - dst->i[1] = src0->i[1] % src1->i[1]; - dst->i[2] = src0->i[2] % src1->i[2]; - dst->i[3] = src0->i[3] % src1->i[3]; + dst->i[0] = src1->i[0] ? src0->i[0] % src1->i[0] : ~0; + dst->i[1] = src1->i[1] ? src0->i[1] % src1->i[1] : ~0; + dst->i[2] = src1->i[2] ? src0->i[2] % src1->i[2] : ~0; + dst->i[3] = src1->i[3] ? src0->i[3] % src1->i[3] : ~0; } static void