Skip to content

Freedreno: Add a pass to lower integer multiplication in NIR

Eduardo Lima Mitev requested to merge elima/mesa:fd/lower_imul into master

Currently, ir3 backend compiler is lowering integer multiplication from:

dst = a * b

to:

dst = (al * bl) + (ah * bl << 16) + (al * bh << 16)

by emitting this code:

mull.u tmp0, a, b           ; mul low, i.e. al * bl
madsh.m16 tmp1, a, b, tmp0  ; mul-add shift high mix, i.e. ah * bl << 16
madsh.m16 dst, b, a, tmp1   ; i.e. al * bh << 16

This series introduces a new IR3-specific NIR lowering pass based on nir_algebraic.AlgebraicPass. It also introduces a couple of new NIR ALU opcodes, umul_low and imadsh_mix16 that map directly to the backend instructions that need to be emitted.

A few basic nir_algebraic optimizations for umul_low and imadsh_mix16 check for low and high words of the factors being zero, in which case the affected instructions are not emitted.

shader-db stats are pending due to various crashes (mostly ir3_cp). An earlier run few weeks suggested that this lowering is helpful.

This is the 2nd version of the passed, now using nir_algebraic. The previous approach added a "manual" NIR pass. Both approaches produce the exact same code.

Edited by Eduardo Lima Mitev

Merge request reports