nir/lower_int64: lower 64-bit amul
authorRhys Perry <pendingchaos02@gmail.com>
Wed, 1 Jul 2020 15:14:16 +0000 (16:14 +0100)
committerMarge Bot <eric+marge@anholt.net>
Tue, 21 Jul 2020 06:47:10 +0000 (06:47 +0000)
Fixes an issue with Renderdoc's shader debugging with ACO.

If nir_opt_algebraic isn't called in-between nir_lower_explicit_io and
nir_lower_int64, we can end up with 64-bit multiplications.

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Fixes: 6320e37d4be ('nir: add amul instruction')
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5709>

src/compiler/nir/nir_lower_int64.c

index 7eb0ae5240307609c0d9dffb72f31d040a3231ec..6b4b28e873b161655431ef3ae01ae6de91284b0c 100644 (file)
@@ -675,6 +675,7 @@ nir_lower_int64_op_to_options_mask(nir_op opcode)
 {
    switch (opcode) {
    case nir_op_imul:
+   case nir_op_amul:
       return nir_lower_imul64;
    case nir_op_imul_2x32_64:
    case nir_op_umul_2x32_64:
@@ -759,6 +760,7 @@ lower_int64_alu_instr(nir_builder *b, nir_instr *instr, void *_state)
 
    switch (alu->op) {
    case nir_op_imul:
+   case nir_op_amul:
       return lower_imul64(b, src[0], src[1]);
    case nir_op_imul_2x32_64:
       return lower_mul_2x32_64(b, src[0], src[1], true);
@@ -864,11 +866,16 @@ lower_int64_alu_instr(nir_builder *b, nir_instr *instr, void *_state)
    }
 }
 
+typedef struct {
+   const nir_shader_compiler_options *shader_options;
+   nir_lower_int64_options options;
+} should_lower_cb_data;
+
 static bool
-should_lower_int64_alu_instr(const nir_instr *instr, const void *_options)
+should_lower_int64_alu_instr(const nir_instr *instr, const void *_data)
 {
-   const nir_lower_int64_options options =
-      *(const nir_lower_int64_options *)_options;
+   const should_lower_cb_data *cb_data = (const should_lower_cb_data *)_data;
+   const nir_lower_int64_options options = cb_data->options;
 
    if (instr->type != nir_instr_type_alu)
       return false;
@@ -913,6 +920,13 @@ should_lower_int64_alu_instr(const nir_instr *instr, const void *_options)
       if (alu->src[0].src.ssa->bit_size != 64)
          return false;
       break;
+   case nir_op_amul:
+      assert(alu->dest.dest.is_ssa);
+      if (cb_data->shader_options->has_imul24)
+         return false;
+      if (alu->dest.dest.ssa.bit_size != 64)
+         return false;
+      break;
    default:
       assert(alu->dest.dest.is_ssa);
       if (alu->dest.dest.ssa.bit_size != 64)
@@ -926,8 +940,12 @@ should_lower_int64_alu_instr(const nir_instr *instr, const void *_options)
 bool
 nir_lower_int64(nir_shader *shader, nir_lower_int64_options options)
 {
+   should_lower_cb_data cb_data;
+   cb_data.shader_options = shader->options;
+   cb_data.options = options;
+
    return nir_shader_lower_instructions(shader,
                                         should_lower_int64_alu_instr,
                                         lower_int64_alu_instr,
-                                        &options);
+                                        &cb_data);
 }