diff --git a/.pick_status.json b/.pick_status.json index a4c23b33da0..3919c50e767 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -2956,7 +2956,7 @@ "description": "intel/compiler: Use CMPN for min / max on Gen4 and Gen5", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "master_sha": null, "because_sha": "2f2c00c7279e7c43e520e21de1781f8cec263e92" }, diff --git a/src/intel/compiler/brw_fs.cpp b/src/intel/compiler/brw_fs.cpp index 1c9e471f5de..dfd8e318756 100644 --- a/src/intel/compiler/brw_fs.cpp +++ b/src/intel/compiler/brw_fs.cpp @@ -4173,11 +4173,19 @@ fs_visitor::lower_minmax() if (inst->opcode == BRW_OPCODE_SEL && inst->predicate == BRW_PREDICATE_NONE) { - /* FIXME: Using CMP doesn't preserve the NaN propagation semantics of - * the original SEL.L/GE instruction + /* If src1 is an immediate value that is not NaN, then it can't be + * NaN. In that case, emit CMP because it is much better for cmod + * propagation. Likewise if src1 is not float. Gen4 and Gen5 don't + * support HF or DF, so it is not necessary to check for those. */ - ibld.CMP(ibld.null_reg_d(), inst->src[0], inst->src[1], - inst->conditional_mod); + if (inst->src[1].type != BRW_REGISTER_TYPE_F || + (inst->src[1].file == IMM && !isnan(inst->src[1].f))) { + ibld.CMP(ibld.null_reg_d(), inst->src[0], inst->src[1], + inst->conditional_mod); + } else { + ibld.CMPN(ibld.null_reg_d(), inst->src[0], inst->src[1], + inst->conditional_mod); + } inst->predicate = BRW_PREDICATE_NORMAL; inst->conditional_mod = BRW_CONDITIONAL_NONE; diff --git a/src/intel/compiler/brw_vec4.cpp b/src/intel/compiler/brw_vec4.cpp index 75bdd5934fb..ef115c741aa 100644 --- a/src/intel/compiler/brw_vec4.cpp +++ b/src/intel/compiler/brw_vec4.cpp @@ -1869,11 +1869,19 @@ vec4_visitor::lower_minmax() if (inst->opcode == BRW_OPCODE_SEL && inst->predicate == BRW_PREDICATE_NONE) { - /* FIXME: Using CMP doesn't preserve the NaN propagation semantics of - * the original SEL.L/GE instruction + /* If src1 is an immediate value that is not NaN, then it can't be + * NaN. In that case, emit CMP because it is much better for cmod + * propagation. Likewise if src1 is not float. Gen4 and Gen5 don't + * support HF or DF, so it is not necessary to check for those. */ - ibld.CMP(ibld.null_reg_d(), inst->src[0], inst->src[1], - inst->conditional_mod); + if (inst->src[1].type != BRW_REGISTER_TYPE_F || + (inst->src[1].file == IMM && !isnan(inst->src[1].f))) { + ibld.CMP(ibld.null_reg_d(), inst->src[0], inst->src[1], + inst->conditional_mod); + } else { + ibld.CMPN(ibld.null_reg_d(), inst->src[0], inst->src[1], + inst->conditional_mod); + } inst->predicate = BRW_PREDICATE_NORMAL; inst->conditional_mod = BRW_CONDITIONAL_NONE;