expand: Fix up expand_doubleword_mod on 32-bit targets [PR98229]
authorJakub Jelinek <jakub@redhat.com>
Fri, 11 Dec 2020 11:47:52 +0000 (12:47 +0100)
committerJakub Jelinek <jakub@redhat.com>
Fri, 11 Dec 2020 11:47:52 +0000 (12:47 +0100)
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.

2020-12-10  Jakub Jelinek  <jakub@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
gcc/testsuite/gcc.c-torture/compile/pr98229.c [new file with mode: 0644]

index bdc692bbc73503def6df9ced302a2cb880b01f56..0427063e27766882b275d74f2defb59fdb8242c7 100644 (file)
@@ -1081,7 +1081,8 @@ expand_doubleword_mod (machine_mode mode, rtx op0, rtx op1, bool unsignedp)
                return NULL_RTX;
            }
        }
-      rtx remainder = expand_divmod (1, TRUNC_MOD_EXPR, word_mode, sum, op1,
+      rtx remainder = expand_divmod (1, TRUNC_MOD_EXPR, word_mode, sum,
+                                    gen_int_mode (INTVAL (op1), word_mode),
                                     NULL_RTX, 1, OPTAB_DIRECT);
       if (remainder == NULL_RTX)
        return NULL_RTX;
@@ -1099,7 +1100,8 @@ expand_doubleword_mod (machine_mode mode, rtx op0, rtx op1, bool unsignedp)
                return NULL_RTX;
            }
          mask = expand_simple_binop (word_mode, AND, mask,
-                                     GEN_INT (1 - INTVAL (op1)),
+                                     gen_int_mode (1 - INTVAL (op1),
+                                                   word_mode),
                                      NULL_RTX, 1, OPTAB_DIRECT);
          if (mask == NULL_RTX)
            return NULL_RTX;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr98229.c b/gcc/testsuite/gcc.c-torture/compile/pr98229.c
new file mode 100644 (file)
index 0000000..509719d
--- /dev/null
@@ -0,0 +1,7 @@
+/* PR rtl-optimization/98229 */
+
+unsigned long long
+foo (unsigned long long x)
+{
+  return x % ~0U;
+}