diff --git a/.pick_status.json b/.pick_status.json index 2a16faee6e9..813ca9138de 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -174,7 +174,7 @@ "description": "freedreno/ir3: Do not propagate away a widening move", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index df08024b8cf..6a74b1ce62e 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -1031,6 +1031,16 @@ is_const_mov(struct ir3_instruction *instr) type_t src_type = instr->cat1.src_type; type_t dst_type = instr->cat1.dst_type; + /* Allow a narrowing move, but not a widening one. A narrowing + * move from full c1.x can be folded into a hc1.x use in an ALU + * instruction because it is doing the same thing as constant- + * demotion. If CONSTANT_DEMOTION_ENABLE wasn't set, we'd need + * return false in all cases. + */ + if ((type_size(dst_type) > type_size(src_type)) || + (type_size(dst_type) == 8)) + return false; + return (type_float(src_type) && type_float(dst_type)) || (type_uint(src_type) && type_uint(dst_type)) || (type_sint(src_type) && type_sint(dst_type));