From 519930dfac3957a35c4ba48a0c29c783edf690a7 Mon Sep 17 00:00:00 2001 From: Volodymyr Kysenko Date: Wed, 17 Nov 2021 23:22:34 +0000 Subject: [PATCH 1/2] Rewrite integer lerp using intrinsics --- src/Lerp.cpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/Lerp.cpp b/src/Lerp.cpp index 9cba96e65844..72f2f8701dbd 100644 --- a/src/Lerp.cpp +++ b/src/Lerp.cpp @@ -134,17 +134,9 @@ Expr lower_lerp(Expr zero_val, Expr one_val, const Expr &weight) { case 8: case 16: case 32: { - Expr zero_expand = Cast::make(UInt(2 * bits, computation_type.lanes()), - zero_val); - Expr one_expand = Cast::make(UInt(2 * bits, one_val.type().lanes()), - one_val); - - Expr rounding = Cast::make(UInt(2 * bits), 1) << Cast::make(UInt(2 * bits), (bits - 1)); - Expr divisor = Cast::make(UInt(2 * bits), 1) << Cast::make(UInt(2 * bits), bits); - - Expr prod_sum = zero_expand * inverse_typed_weight + - one_expand * typed_weight + rounding; - Expr divided = ((prod_sum / divisor) + prod_sum) / divisor; + Expr shift = Cast::make(UInt(2 * bits), bits); + Expr prod_sum = widening_mul(zero_val, inverse_typed_weight) + widening_mul(one_val, typed_weight); + Expr divided = rounding_shift_right(rounding_shift_right(prod_sum, shift) + prod_sum, shift); result = Cast::make(UInt(bits, computation_type.lanes()), divided); break; From c1fb3e0624640c6dfe41080ce5263396f57684ef Mon Sep 17 00:00:00 2001 From: Volodymyr Kysenko Date: Thu, 18 Nov 2021 17:59:17 +0000 Subject: [PATCH 2/2] Comment --- src/Lerp.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Lerp.cpp b/src/Lerp.cpp index 72f2f8701dbd..e145780853a9 100644 --- a/src/Lerp.cpp +++ b/src/Lerp.cpp @@ -136,6 +136,8 @@ Expr lower_lerp(Expr zero_val, Expr one_val, const Expr &weight) { case 32: { Expr shift = Cast::make(UInt(2 * bits), bits); Expr prod_sum = widening_mul(zero_val, inverse_typed_weight) + widening_mul(one_val, typed_weight); + // Computes x / (2 ** N - 1) as (x / 2 ** N + x) / 2 ** N. + // TODO: on x86 it's actually one instruction cheaper to do the division directly. Expr divided = rounding_shift_right(rounding_shift_right(prod_sum, shift) + prod_sum, shift); result = Cast::make(UInt(bits, computation_type.lanes()), divided);