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

Reply via email to