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.
This commit is contained in:
Jakub Jelinek 2020-12-11 12:47:52 +01:00
parent fc7b424817
commit 1423318fa7
2 changed files with 11 additions and 2 deletions

View 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;

View File

@ -0,0 +1,7 @@
/* PR rtl-optimization/98229 */
unsigned long long
foo (unsigned long long x)
{
return x % ~0U;
}