From patchwork Fri Nov 2 23:32:17 2012
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [Committed] Fix 54524: Wrong code with some 64bit addition with
registers as 32bits
From: Andrew Pinski
X-Patchwork-Id: 196774
Message-Id:
To: GCC Patches
Date: Fri, 2 Nov 2012 16:32:17 -0700
Hi,
For some reason cse produced:
(insn 27 43 28 2 (set (reg:SI 231 [+4 ])
(plus:SI (reg:SI 229 [+4 ])
(const_int 0 [0]))) t.c:24 10 {*addsi3}
(nil))
(insn 28 27 29 2 (set (reg:SI 212)
(ltu:SI (reg:SI 231 [+4 ])
(reg:SI 229 [+4 ]))) t.c:24 521 {*sltu_sisi}
(nil))
And then forwprop goes and does the following:
In insn 28, replacing
(ltu:SI (reg:SI 231 [+4 ])
(reg:SI 229 [+4 ]))
with (const_int 1 [0x1])
This is due to simplify-rtx.c (simplify_relational_operation_1) Having
the following optimization:
/* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
(GEU/LTU a -C). Likewise for (LTU/GEU (PLUS a C) a). */
But this is wrong when C is 0. Anyways I committed this patch as
obvious to fix the issue in simplify-rtx.c but I have not looked into
why CSE does simplify the plus.
Thanks,
Andrew Pinski
ChangeLog:
PR rtl-opt/54524
* simplify-rtx.c (simplify_relational_operation_1): Don't simplify
(LTU/GEU (PLUS a 0) 0) into (GEU/LTU a 0) since they are not equivalent.
Index: simplify-rtx.c
===================================================================
--- simplify-rtx.c (revision 193110)
+++ simplify-rtx.c (working copy)
@@ -4546,7 +4546,9 @@ simplify_relational_operation_1 (enum rt
&& GET_CODE (op0) == PLUS
&& CONST_INT_P (XEXP (op0, 1))
&& (rtx_equal_p (op1, XEXP (op0, 0))
- || rtx_equal_p (op1, XEXP (op0, 1))))
+ || rtx_equal_p (op1, XEXP (op0, 1)))
+ /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
+ && XEXP (op0, 1) != const0_rtx)
{
rtx new_cmp
= simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);