Commit 2a889a09 authored by Daniel Schürmann's avatar Daniel Schürmann
Browse files

nir: Lower int64 in a single pass.

This commit also refactors min/max lowering into one function.
parent d7e6541c
Pipeline #48162 passed with stages
in 13 minutes and 22 seconds
......@@ -315,7 +315,7 @@ lower_ineg64(nir_builder *b, nir_ssa_def *x)
* as iadd, subtraction is actually more efficient for ineg than the usual
* 2's complement "flip the bits and add one".
return lower_isub64(b, nir_imm_int64(b, 0), x);
return nir_isub(b, nir_imm_int64(b, 0), x);
static nir_ssa_def *
......@@ -360,27 +360,23 @@ lower_int64_compare(nir_builder *b, nir_op op, nir_ssa_def *x, nir_ssa_def *y)
static nir_ssa_def *
lower_umax64(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y)
lower_minmax64(nir_builder *b, nir_op op, nir_ssa_def *x, nir_ssa_def *y)
return nir_bcsel(b, lower_int64_compare(b, nir_op_ult, x, y), y, x);
static nir_ssa_def *
lower_imax64(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y)
return nir_bcsel(b, lower_int64_compare(b, nir_op_ilt, x, y), y, x);
static nir_ssa_def *
lower_umin64(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y)
return nir_bcsel(b, lower_int64_compare(b, nir_op_ult, x, y), x, y);
nir_ssa_def *cmp;
switch (op) {
case nir_op_umax:
cmp = nir_ult(b, x, y); break;
case nir_op_imax:
cmp = nir_ilt(b, x, y); break;
case nir_op_umin:
cmp = nir_uge(b, x, y); break;
case nir_op_imin:
cmp = nir_ige(b, x, y); break;
unreachable("Invalid opcode for lower_minmax64()");
static nir_ssa_def *
lower_imin64(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y)
return nir_bcsel(b, lower_int64_compare(b, nir_op_ilt, x, y), x, y);
return nir_bcsel(b, cmp, y, x);
static nir_ssa_def *
......@@ -754,13 +750,10 @@ lower_int64_alu_instr(nir_builder *b, nir_alu_instr *alu)
case nir_op_isub:
return lower_isub64(b, src[0], src[1]);
case nir_op_imin:
return lower_imin64(b, src[0], src[1]);
case nir_op_imax:
return lower_imax64(b, src[0], src[1]);
case nir_op_umin:
return lower_umin64(b, src[0], src[1]);
case nir_op_umax:
return lower_umax64(b, src[0], src[1]);
return lower_minmax64(b, alu->op, src[0], src[1]);
case nir_op_iabs:
return lower_iabs64(b, src[0]);
case nir_op_ineg:
......@@ -792,7 +785,11 @@ lower_int64_impl(nir_function_impl *impl, nir_lower_int64_options options)
bool progress = false;
nir_foreach_block(block, impl) {
nir_foreach_instr_safe(instr, block) {
nir_instr *instr, *next_instr;
for (instr = nir_block_first_instr(block); instr; instr = next_instr) {
next_instr = instr ? nir_instr_next(instr) : NULL;
if (instr->type != nir_instr_type_alu)
......@@ -836,12 +833,23 @@ lower_int64_impl(nir_function_impl *impl, nir_lower_int64_options options)
if (!(options & nir_lower_int64_op_to_options_mask(alu->op)))
b.cursor = nir_before_instr(instr);
b.cursor = nir_after_instr(instr);
nir_ssa_def *lowered = lower_int64_alu_instr(&b, alu);
/* Before we remove the instruction, find the next instruction after it again.
* This may have changed after lowering, in which case we'll pick up and process the
* lowered instructions, lowering them too if necessary.
next_instr = nir_instr_next(instr);
/* lower_udiv64_mod64() inserts new blocks which might be inserted elsewhere */
block = next_instr->block;
progress = true;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment