Commit 5c561248 by Jakub Jelinek Committed by Jakub Jelinek

re PR target/89434 (wrong code with -Og and __builtin_mul_overflow())

	PR target/89434
	* config/arm/arm.md (*subsi3_carryin_const): Use
	arm_neg_immediate_operand predicate instead of
	arm_not_immediate_operand, "L" constraint instead of "K" and
	print it using %n2 instead of %B2.
	(*subsi3_carryin_const0): New define_insn.
	(*subsi3_carryin_compare_const): Use const_int_I_operand predicate
	instead of arm_not_operand and "I" constraint instead of "K" and
	print it using %n3 instead of %B2.  Instead of using match_dup 2 add
	another match_operand and in the condition check that it is negation
	of operands[2].
	(*subsi3_carryin_compare_const0): New define_ins.
	(*subdi_di_zesidi): Adjust to use *subsi3_carryin_const0 instead of
	*subsi3_carryin_const.
	(*arm_cmpdi_insn): Fix splitting into *subsi3_carryin_compare_const,
	split into *subsi3_carryin_compare_const0 if the highpart is zero.

	* gcc.c-torture/execute/pr89434.c: New test.

From-SVN: r269186
parent 4199c859
2019-02-25 Jakub Jelinek <jakub@redhat.com>
PR target/89434
* config/arm/arm.md (*subsi3_carryin_const): Use
arm_neg_immediate_operand predicate instead of
arm_not_immediate_operand, "L" constraint instead of "K" and
print it using %n2 instead of %B2.
(*subsi3_carryin_const0): New define_insn.
(*subsi3_carryin_compare_const): Use const_int_I_operand predicate
instead of arm_not_operand and "I" constraint instead of "K" and
print it using %n3 instead of %B2. Instead of using match_dup 2 add
another match_operand and in the condition check that it is negation
of operands[2].
(*subsi3_carryin_compare_const0): New define_ins.
(*subdi_di_zesidi): Adjust to use *subsi3_carryin_const0 instead of
*subsi3_carryin_const.
(*arm_cmpdi_insn): Fix splitting into *subsi3_carryin_compare_const,
split into *subsi3_carryin_compare_const0 if the highpart is zero.
PR target/89438
* config/arm.vfp.md (*negdf2_vfp): Use
gen_int_mode (0x80000000, SImode) instead of GEN_INT (0x80000000).
......
......@@ -1145,10 +1145,20 @@
(define_insn "*subsi3_carryin_const"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
(match_operand:SI 2 "arm_not_immediate_operand" "K"))
(match_operand:SI 2 "arm_neg_immediate_operand" "L"))
(ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
"TARGET_32BIT"
"sbc\\t%0, %1, #%B2"
"sbc\\t%0, %1, #%n2"
[(set_attr "conds" "use")
(set_attr "type" "adc_imm")]
)
(define_insn "*subsi3_carryin_const0"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(minus:SI (match_operand:SI 1 "s_register_operand" "r")
(ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
"TARGET_32BIT"
"sbc\\t%0, %1, #0"
[(set_attr "conds" "use")
(set_attr "type" "adc_imm")]
)
......@@ -1170,13 +1180,26 @@
(define_insn "*subsi3_carryin_compare_const"
[(set (reg:CC CC_REGNUM)
(compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
(match_operand:SI 2 "arm_not_operand" "K")))
(match_operand:SI 2 "const_int_I_operand" "I")))
(set (match_operand:SI 0 "s_register_operand" "=r")
(minus:SI (plus:SI (match_dup 1)
(match_dup 2))
(match_operand:SI 3 "arm_neg_immediate_operand" "L"))
(ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
"TARGET_32BIT && UINTVAL (operands[2]) == -UINTVAL (operands[3])"
"sbcs\\t%0, %1, #%n3"
[(set_attr "conds" "set")
(set_attr "type" "adcs_imm")]
)
(define_insn "*subsi3_carryin_compare_const0"
[(set (reg:CC CC_REGNUM)
(compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
(const_int 0)))
(set (match_operand:SI 0 "s_register_operand" "=r")
(minus:SI (match_dup 1)
(ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
"TARGET_32BIT"
"sbcs\\t%0, %1, #%B2"
"sbcs\\t%0, %1, #0"
[(set_attr "conds" "set")
(set_attr "type" "adcs_imm")]
)
......@@ -1301,14 +1324,13 @@
[(parallel [(set (reg:CC CC_REGNUM)
(compare:CC (match_dup 1) (match_dup 2)))
(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
(set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
(set (match_dup 3) (minus:SI (match_dup 4)
(ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
operands[4] = gen_highpart (SImode, operands[1]);
operands[1] = gen_lowpart (SImode, operands[1]);
operands[5] = GEN_INT (~0);
}
[(set_attr "conds" "clob")
(set_attr "length" "8")
......@@ -7423,16 +7445,19 @@
(compare:CC (match_dup 3) (match_dup 4)))
(set (match_dup 2)
(minus:SI (match_dup 5)
(ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
(ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
if (CONST_INT_P (operands[1]))
{
operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
DImode,
operands[1])));
operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);
if (operands[4] == const0_rtx)
operands[5] = operands[3];
else
operands[5] = gen_rtx_PLUS (SImode, operands[3],
gen_int_mode (-UINTVAL (operands[4]),
SImode));
}
else
{
......
2019-02-25 Jakub Jelinek <jakub@redhat.com>
PR target/89434
* gcc.c-torture/execute/pr89434.c: New test.
PR target/89438
* gcc.dg/pr89438.c: New test.
......
/* PR target/89434 */
#if __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 && __CHAR_BIT__ == 8
long g = 0;
static inline unsigned long long
foo (unsigned long long u)
{
unsigned x;
__builtin_mul_overflow (-1, g, &x);
u |= (unsigned) u < (unsigned short) x;
return x - u;
}
int
main ()
{
unsigned long long x = foo (0x222222222ULL);
if (x != 0xfffffffddddddddeULL)
__builtin_abort ();
return 0;
}
#else
int
main ()
{
return 0;
}
#endif
/* PR target/89434 */
/* { dg-do run } */
/* { dg-options "-Og" } */
#include "../gcc.c-torture/execute/pr89434.c"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment