convert_move does not know how to zero-extend a constant integer to the target mode -- simply because it does not know the target mode. As a result, 32-bit SImode with the high bit set would be effectively sign- extended instead of zero-extended.
This patch fixes it. Is this okay for trunk? (bootstrap+regtest in progress, on powerpc64-linux). Segher 2015-12-14 Segher Boessenkool <seg...@kernel.crashing.org> PR target/68865 PR target/68879 * rs6000.md (cstore_si_as_di): Force all operands into registers. --- gcc/config/rs6000/rs6000.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index e2dca1b..f962f04 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -10618,6 +10618,8 @@ (define_expand "cstore_si_as_di" int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0; enum rtx_code cond_code = signed_condition (GET_CODE (operands[1])); + operands[2] = force_reg (SImode, operands[2]); + operands[3] = force_reg (SImode, operands[3]); rtx op1 = gen_reg_rtx (DImode); rtx op2 = gen_reg_rtx (DImode); convert_move (op1, operands[2], uns_flag); -- 1.9.3