Hi Segher, >>>> This patch fixes a combiner bug in simplify_set which calls >>>> CANNOT_CHANGE_MODE_CLASS with wrong mode params. >>>> It occurs when trying to simplify paradoxical subregs of hw regs (whose >>>> natural mode is lower than a word). >>>> >>>> In fact, changing from (set x:m1 (subreg:m1 (op:m2))) to (set (subreg:m2 >>>> x) op2) is valid if REG_CANNOT_CHANGE_MODE_P (x, m1, m2) is false >>>> and REG_CANNOT_CHANGE_MODE_P (x, GET_MODE (src), GET_MODE (SUBREG_REG >>>> (src)) >>> r62212 (in 2003) changed it to what we have now, it used to be what you >>> want to change it back to. >>> >>> You say m1 > m2, which means you have WORD_REGISTER_OPERATIONS defined. >> No, just some hard regs whose natural mode size is 2 and UNIT_PER_WORD >> is 4... > You said it is a paradoxical subreg? Or do you mean the result is > a paradoxical subreg? I mean that the result is a paradoxical subreg: (subreg:SI (reg:HI r0) 0) = (reg:SI r0) whith r0 is a HI reg. >>> Where does this transformation go wrong? Why is the resulting insn >>> recognised at all? For example, general_operand should refuse it. >>> Maybe you have custom *_operand that do not handle subreg correctly? >>> >>> The existing code looks correct: what we want to know is if an m2 >>> interpreted as an m1 yields the correct value. We might *also* want >>> your condition, but I'm not sure about that. >> OK, looks like both m1->m2 & m2 -> m1 checks would be needed, but the m1 >> -> m2 should be filtererd by valid predicates (general_operand). >> Sorry about that. > Hrm, maybe you can show the RTL before and after this transform? RTL before combine: (set (reg:SI 31 (lshiftt:SI (reg:SI 29) (const_int 16)))) (set (reg:HI 1 "r1") (reg:HI 25)) (set (reg:HI 0 "r0") (subreg:HI (reg:SI 31) 0)) ; LE target
r0 and r1 are HI regs RTL after combining 1 --> 3: (set (reg:HI 1 "r1") (reg:HI 25)) (set (reg:SI 0 "r0") (lshift:SI (reg:SI 29) (const_int 16))) and r1 is clobbered by last insn. Thanks, Aurélien