aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-12-11 12:47:52 +0100
committerJakub Jelinek <jakub@redhat.com>2020-12-11 12:47:52 +0100
commit1423318fa778649365f5a73c2c4657733e191820 (patch)
tree422bd640d8a22ebf25c619195dd8573a52ee4ff0
parentfc7b4248172561a9ee310e2d43d8a485a5c9e108 (diff)
downloadgcc-1423318fa778649365f5a73c2c4657733e191820.zip
gcc-1423318fa778649365f5a73c2c4657733e191820.tar.gz
gcc-1423318fa778649365f5a73c2c4657733e191820.tar.bz2
expand: Fix up expand_doubleword_mod on 32-bit targets [PR98229]
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.
-rw-r--r--gcc/optabs.c6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr98229.c7
2 files changed, 11 insertions, 2 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c
index bdc692b..0427063 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -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
index 0000000..509719d
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr98229.c
@@ -0,0 +1,7 @@
+/* PR rtl-optimization/98229 */
+
+unsigned long long
+foo (unsigned long long x)
+{
+ return x % ~0U;
+}