Take the following function: int f(int a, int c) { return -a - (5); } Fold should have converted that to: int f(int a, int c) { return (-5) - a; } So that we only have one constant (-5) and one decl (a) and one expression (MINUS_EXPR) instead of one constant (5), one decl (a) and two expressions (MINUS_EXPR and NEG_EXPR).
This is done in simplify-rtx.c for the rtl level.
And then we can get optimial rtl generation right away for PPC: (insn 20 17 26 0 (set (reg/i:SI 3 r3 [ <result> ]) (minus:SI (const_int -5 [0xfffffffffffffffb]) (reg:SI 3 r3 [ a ]))) 78 {*rs6000.md:1236} (nil) (nil)) If we expand it correctly instead of depending on combine :).
Oh, and we remove one gimplfier tempary variable too.
This transformation is done with -fwrapv.
I am going to move this to minor as this could be considered a regression in a way. It was introduced by: (fold): Optimize "-A - B" as "-B - A" if overflow wraps around. But in a way since wrapv is false, that means overflow is undefined and can be either wraps or anything else. Maybe Roger can comment on this?
Note fixing this will also fix PR 23666 after my patch for moving "- ~a = a+1" to negate_expr. But this needs to depend on the fix for PR 25125 since otherwise we expose a latent bug in convert.c which shows up in the testsuite.
Didn't we have the canonicalization to put the constant in operand2 if possible? A lot of transformations rely on that.
(In reply to comment #7) > Didn't we have the canonicalization to put the constant in operand2 if > possible? A lot of transformations rely on that. Why should they in this case, they only rely on that for operations that are comunitive and minus is not. "(-5) - a" is simplier than -a - 5 in reality.
Mine.
Subject: Bug 23295 Author: rguenth Date: Mon Oct 23 07:19:34 2006 New Revision: 117969 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117969 Log: 2006-10-24 Richard Guenther <rguenther@suse.de> PR middle-end/27132 PR middle-end/23295 * builtins.c (fold_binary): Remove checks for flag_wrapv and flag_trapv where negate_expr_p covers these cases. * gcc.dg/pr27132.c: New testcase. * gcc.dg/pr23295.c: Likewise. * gcc.dg/tree-ssa/pr23294.c: Adjust patterns. * g++.dg/tree-ssa/pr19807.C: Likewise. 2006-10-23 Richard Guenther <rguenther@suse.de> PR middle-end/29548 * fold-const.c (fold_plusminus_mult_expr): Check exact power of two on the absolute value. (fold_binary): Fold x * -C to -x * C if x is easily negatable and negating -C does not overflow. Added: trunk/gcc/testsuite/gcc.dg/pr23295.c trunk/gcc/testsuite/gcc.dg/pr27132.c Modified: trunk/gcc/ChangeLog trunk/gcc/fold-const.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/g++.dg/tree-ssa/pr19807.C trunk/gcc/testsuite/gcc.dg/tree-ssa/pr23294.c
Fixed.