From 69a3559efd6ec036749c3f460f092b7a38c12d2a Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Mon, 26 Oct 2020 13:27:43 -0500 Subject: [PATCH] intel/reg,fs: Handle immediates properly in subscript() Just returning the original type isn't what we want in basically any case. Mask and shift the immediate as needed. Reviewed-by: Kenneth Graunke Part-of: --- src/intel/compiler/brw_fs.cpp | 15 ++++----------- src/intel/compiler/brw_ir_fs.h | 8 ++++++-- src/intel/compiler/brw_reg.h | 12 +++++++++--- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/intel/compiler/brw_fs.cpp b/src/intel/compiler/brw_fs.cpp index 46354ca..fd46625 100644 --- a/src/intel/compiler/brw_fs.cpp +++ b/src/intel/compiler/brw_fs.cpp @@ -2715,17 +2715,10 @@ fs_visitor::opt_algebraic() assert(!inst->src[0].negate); const brw::fs_builder ibld(this, block, inst); - if (inst->src[0].file == IMM) { - ibld.MOV(subscript(inst->dst, BRW_REGISTER_TYPE_UD, 1), - brw_imm_ud(inst->src[0].u64 >> 32)); - ibld.MOV(subscript(inst->dst, BRW_REGISTER_TYPE_UD, 0), - brw_imm_ud(inst->src[0].u64)); - } else { - ibld.MOV(subscript(inst->dst, BRW_REGISTER_TYPE_UD, 1), - subscript(inst->src[0], BRW_REGISTER_TYPE_UD, 1)); - ibld.MOV(subscript(inst->dst, BRW_REGISTER_TYPE_UD, 0), - subscript(inst->src[0], BRW_REGISTER_TYPE_UD, 0)); - } + ibld.MOV(subscript(inst->dst, BRW_REGISTER_TYPE_UD, 1), + subscript(inst->src[0], BRW_REGISTER_TYPE_UD, 1)); + ibld.MOV(subscript(inst->dst, BRW_REGISTER_TYPE_UD, 0), + subscript(inst->src[0], BRW_REGISTER_TYPE_UD, 0)); inst->remove(block); progress = true; diff --git a/src/intel/compiler/brw_ir_fs.h b/src/intel/compiler/brw_ir_fs.h index 3a4acc1..60f0c8b 100644 --- a/src/intel/compiler/brw_ir_fs.h +++ b/src/intel/compiler/brw_ir_fs.h @@ -303,8 +303,12 @@ subscript(fs_reg reg, brw_reg_type type, unsigned i) reg.vstride += (reg.vstride ? delta : 0); } else if (reg.file == IMM) { - assert(reg.type == type); - + unsigned bit_size = type_sz(type) * 8; + reg.u64 >>= i * bit_size; + reg.u64 &= BITFIELD64_MASK(bit_size); + if (bit_size <= 16) + reg.u64 |= reg.u64 << 16; + return retype(reg, type); } else { reg.stride *= type_sz(reg.type) / type_sz(type); } diff --git a/src/intel/compiler/brw_reg.h b/src/intel/compiler/brw_reg.h index 620b872..b6405ca 100644 --- a/src/intel/compiler/brw_reg.h +++ b/src/intel/compiler/brw_reg.h @@ -1022,12 +1022,18 @@ spread(struct brw_reg reg, unsigned s) static inline struct brw_reg subscript(struct brw_reg reg, enum brw_reg_type type, unsigned i) { - if (reg.file == IMM) - return reg; - unsigned scale = type_sz(reg.type) / type_sz(type); assert(scale >= 1 && i < scale); + if (reg.file == IMM) { + unsigned bit_size = type_sz(type) * 8; + reg.u64 >>= i * bit_size; + reg.u64 &= BITFIELD64_MASK(bit_size); + if (bit_size <= 16) + reg.u64 |= reg.u64 << 16; + return retype(reg, type); + } + return suboffset(retype(spread(reg, scale), type), i); } -- 2.7.4