Hi!

As the testcase shows, for 32-bit word size we can end up with op1
up to 0xffffffff (0x100000000 % 0xffffffff == 1 and so we use bit == 32
for that), but the CONST_INT we got from caller is for DImode in that case
and not valid for SImode operations.

The following patch canonicalizes the two spots where the constant needs
canonicalization.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2020-12-11  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/98229
        * optabs.c (expand_doubleword_mod): Canonicalize op1 and
        1 - INTVAL (op1) as word_mode constants when used in
        word_mode arithmetics.

        * gcc.c-torture/compile/pr98229.c: New test.

--- gcc/optabs.c.jj     2020-12-02 11:40:47.574338088 +0100
+++ gcc/optabs.c        2020-12-10 19:00:46.151434474 +0100
@@ -1081,7 +1081,8 @@ expand_doubleword_mod (machine_mode mode
                return NULL_RTX;
            }
        }
-      rtx remainder = expand_divmod (1, TRUNC_MOD_EXPR, word_mode, sum, op1,
+      rtx op1w = GEN_INT (trunc_int_for_mode (INTVAL (op1), word_mode));
+      rtx remainder = expand_divmod (1, TRUNC_MOD_EXPR, word_mode, sum, op1w,
                                     NULL_RTX, 1, OPTAB_DIRECT);
       if (remainder == NULL_RTX)
        return NULL_RTX;
@@ -1098,8 +1099,9 @@ expand_doubleword_mod (machine_mode mode
              if (mask == NULL_RTX)
                return NULL_RTX;
            }
-         mask = expand_simple_binop (word_mode, AND, mask,
-                                     GEN_INT (1 - INTVAL (op1)),
+         rtx oneminusop1
+           = GEN_INT (trunc_int_for_mode (1 - INTVAL (op1), word_mode));
+         mask = expand_simple_binop (word_mode, AND, mask, oneminusop1,
                                      NULL_RTX, 1, OPTAB_DIRECT);
          if (mask == NULL_RTX)
            return NULL_RTX;
--- gcc/testsuite/gcc.c-torture/compile/pr98229.c.jj    2020-12-10 
19:08:25.502328354 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr98229.c       2020-12-10 
19:08:10.062499943 +0100
@@ -0,0 +1,7 @@
+/* PR rtl-optimization/98229 */
+
+unsigned long long
+foo (unsigned long long x)
+{
+  return x % ~0U;
+}

        Jakub

Reply via email to