diff --git a/src/intel/compiler/brw_fs_combine_constants.cpp b/src/intel/compiler/brw_fs_combine_constants.cpp index 9847f1ff706..09adc776d9a 100644 --- a/src/intel/compiler/brw_fs_combine_constants.cpp +++ b/src/intel/compiler/brw_fs_combine_constants.cpp @@ -1111,7 +1111,7 @@ add_candidate_immediate(struct table *table, fs_inst *inst, unsigned ip, bool must_promote, bool allow_one_constant, bblock_t *block, - ASSERTED const struct intel_device_info *devinfo, + const struct intel_device_info *devinfo, void *const_ctx) { struct value *v = new_value(table, const_ctx); @@ -1119,15 +1119,20 @@ add_candidate_immediate(struct table *table, fs_inst *inst, unsigned ip, unsigned box_idx = box_instruction(table, const_ctx, inst, ip, block, must_promote); - /* Just for now... */ - assert(inst->can_do_source_mods(devinfo)); - v->value.u64 = inst->src[i].d64; v->bit_size = 8 * type_sz(inst->src[i].type); v->instr_index = box_idx; v->src = i; v->allow_one_constant = allow_one_constant; - v->no_negations = false; + + /* Right-shift instructions are special. They can have source modifiers, + * but changing the type can change the semantic of the instruction. Only + * allow negations on a right shift if the source type is already signed. + */ + v->no_negations = !inst->can_do_source_mods(devinfo) || + ((inst->opcode == BRW_OPCODE_SHR || + inst->opcode == BRW_OPCODE_ASR) && + brw_reg_type_is_unsigned_integer(inst->src[i].type)); switch (inst->src[i].type) { case BRW_REGISTER_TYPE_DF: @@ -1200,8 +1205,15 @@ fs_visitor::opt_combine_constants() ip++; switch (inst->opcode) { + case SHADER_OPCODE_INT_QUOTIENT: + case SHADER_OPCODE_INT_REMAINDER: case SHADER_OPCODE_POW: - assert(inst->src[0].file != IMM); + if (inst->src[0].file == IMM) { + assert(inst->opcode != SHADER_OPCODE_POW); + + add_candidate_immediate(&table, inst, ip, 0, true, false, block, + devinfo, const_ctx); + } if (inst->src[1].file == IMM && devinfo->ver < 8) { add_candidate_immediate(&table, inst, ip, 1, true, false, block, @@ -1226,6 +1238,8 @@ fs_visitor::opt_combine_constants() break; } + case BRW_OPCODE_BFE: + case BRW_OPCODE_BFI2: case BRW_OPCODE_LRP: for (int i = 0; i < inst->sources; i++) { if (inst->src[i].file != IMM) @@ -1260,6 +1274,18 @@ fs_visitor::opt_combine_constants() } break; + case BRW_OPCODE_ASR: + case BRW_OPCODE_BFI1: + case BRW_OPCODE_ROL: + case BRW_OPCODE_ROR: + case BRW_OPCODE_SHL: + case BRW_OPCODE_SHR: + if (inst->src[0].file == IMM) { + add_candidate_immediate(&table, inst, ip, 0, true, false, block, + devinfo, const_ctx); + } + break; + case BRW_OPCODE_MOV: if (could_coissue(devinfo, inst) && inst->src[0].file == IMM) { add_candidate_immediate(&table, inst, ip, 0, false, false, block, @@ -1464,6 +1490,10 @@ fs_visitor::opt_combine_constants() unreachable("Bad type size"); } } + } else if ((link->inst->opcode == BRW_OPCODE_SHL || + link->inst->opcode == BRW_OPCODE_ASR) && + link->negate) { + reg->type = brw_int_type(type_sz(reg->type), true); } #ifdef DEBUG @@ -1508,6 +1538,8 @@ fs_visitor::opt_combine_constants() } #endif + assert(link->inst->can_do_source_mods(devinfo) || !link->negate); + reg->file = VGRF; reg->offset = table.imm[i].subreg_offset; reg->stride = 0; diff --git a/src/intel/compiler/brw_fs_copy_propagation.cpp b/src/intel/compiler/brw_fs_copy_propagation.cpp index 37737e112f1..8151b7d1878 100644 --- a/src/intel/compiler/brw_fs_copy_propagation.cpp +++ b/src/intel/compiler/brw_fs_copy_propagation.cpp @@ -896,12 +896,6 @@ fs_visitor::try_constant_propagate(fs_inst *inst, acp_entry *entry) progress = true; break; - case SHADER_OPCODE_INT_QUOTIENT: - case SHADER_OPCODE_INT_REMAINDER: - /* FINISHME: Promote non-float constants and remove this. */ - if (devinfo->ver < 8) - break; - FALLTHROUGH; case SHADER_OPCODE_POW: /* Allow constant propagation into src1 (except on Gen 6 which * doesn't support scalar source math), and let constant combining @@ -909,23 +903,15 @@ fs_visitor::try_constant_propagate(fs_inst *inst, acp_entry *entry) */ if (devinfo->ver == 6) break; - FALLTHROUGH; - case BRW_OPCODE_BFI1: - case BRW_OPCODE_ASR: - case BRW_OPCODE_SHR: - case BRW_OPCODE_SUBB: + if (i == 1) { inst->src[i] = val; progress = true; } break; - case BRW_OPCODE_SHL: - /* Only constant propagate into src0 if src1 is also constant. In that - * specific case, constant folding will eliminate the instruction. - */ - if ((i == 0 && inst->src[1].file == IMM) || - i == 1) { + case BRW_OPCODE_SUBB: + if (i == 1) { inst->src[i] = val; progress = true; } @@ -1075,7 +1061,26 @@ fs_visitor::try_constant_propagate(fs_inst *inst, acp_entry *entry) } break; + case SHADER_OPCODE_INT_QUOTIENT: + case SHADER_OPCODE_INT_REMAINDER: + /* Allow constant propagation into either source (except on Gen 6 + * which doesn't support scalar source math). Constant combining + * promote the src1 constant on Gen < 8, and it will promote the src0 + * constant on all platforms. + */ + if (devinfo->ver == 6) + break; + + FALLTHROUGH; case BRW_OPCODE_AND: + case BRW_OPCODE_ASR: + case BRW_OPCODE_BFE: + case BRW_OPCODE_BFI1: + case BRW_OPCODE_BFI2: + case BRW_OPCODE_ROL: + case BRW_OPCODE_ROR: + case BRW_OPCODE_SHL: + case BRW_OPCODE_SHR: case BRW_OPCODE_OR: case SHADER_OPCODE_TEX_LOGICAL: case SHADER_OPCODE_TXD_LOGICAL: