A few define_split's in the i386 backend modify RTL in place. This does not work. This patch fixes all cases that do PUT_MODE on existing RTL.
Bootstrapped and tested; no regressions. Is this okay for trunk? Hrm, this wants the testcase in that PR added I suppose. Will send it separately. Segher 2015-06-24 Segher Boessenkool <seg...@kernel.crashing.org> * config/i386/i386.md (various splitters): Use copy_rtx before doing PUT_MODE on operands. --- gcc/config/i386/i386.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index d75b2e1..5425cec 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -10865,7 +10865,10 @@ (const_int 0)))] "" [(set (match_dup 0) (match_dup 1))] - "PUT_MODE (operands[1], QImode);") +{ + operands[1] = copy_rtx (operands[1]); + PUT_MODE (operands[1], QImode); +}) (define_split [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand")) @@ -10874,7 +10877,10 @@ (const_int 0)))] "" [(set (match_dup 0) (match_dup 1))] - "PUT_MODE (operands[1], QImode);") +{ + operands[1] = copy_rtx (operands[1]); + PUT_MODE (operands[1], QImode); +}) (define_split [(set (match_operand:QI 0 "nonimmediate_operand") @@ -11031,7 +11037,10 @@ (if_then_else (match_dup 0) (label_ref (match_dup 1)) (pc)))] - "PUT_MODE (operands[0], VOIDmode);") +{ + operands[0] = copy_rtx (operands[0]); + PUT_MODE (operands[0], VOIDmode); +}) (define_split [(set (pc) @@ -17298,6 +17307,7 @@ operands[1] = gen_lowpart (SImode, operands[1]); if (GET_CODE (operands[3]) != ASHIFT) operands[2] = gen_lowpart (SImode, operands[2]); + operands[3] = copy_rtx (operands[3]); PUT_MODE (operands[3], SImode); }) -- 1.7.10.4