Index: match.pd =================================================================== --- match.pd (revision 249613) +++ match.pd (working copy) @@ -155,6 +155,55 @@ || !COMPLEX_FLOAT_TYPE_P (type))) (negate @0))) +(for cmp (gt ge) + /* Transform X * (X > 0 ? 1 : -1) into ABS(X). */ + /* Transform X * (X >= 0 ? 1 : -1) into ABS(X). */ + (simplify + (mult:c @0 (cond (cmp @0 integer_zerop) integer_onep integer_all_onesp)) + (abs @0)) + /* Transform X * (X > 0.0 ? 1.0 : -1.0) into ABS(X). */ + /* Transform X * (X >= 0.0 ? 1.0 : -1.0) into ABS(X). */ + (simplify + (mult:c @0 (cond (cmp @0 real_zerop) real_onep real_minus_onep)) + (if (!HONOR_SNANS (type) && !HONOR_SIGNED_ZEROS (type)) + (abs @0))) + /* Transform X * (X > 0 ? -1 : 1) into -ABS(X). */ + /* Transform X * (X >= 0 ? -1 : 1) into -ABS(X). */ + (simplify + (mult:c @0 (cond (cmp @0 integer_zerop) integer_all_onesp integer_onep)) + (negate (abs @0))) + /* Transform X * (X > 0.0 ? -1.0 : 1.0) into -ABS(X). */ + /* Transform X * (X >= 0.0 ? -1.0 : 1.0) into -ABS(X). */ + (simplify + (mult:c @0 (cond (cmp @0 real_zerop) real_minus_onep real_onep)) + (if (!HONOR_SNANS (type) && !HONOR_SIGNED_ZEROS (type)) + (negate (abs @0))))) + +(for cmp (lt le) + /* Transform X * (X < 0 ? 1 : -1) into -ABS(X). */ + /* Transform X * (X <= 0 ? 1 : -1) into -ABS(X). */ + (simplify + (mult:c @0 (cond (cmp @0 integer_zerop) integer_onep integer_all_onesp)) + (negate (abs @0))) + /* Transform X * (X < 0.0 ? 1.0 : -1.0) into -ABS(X). */ + /* Transform X * (X <= 0.0 ? 1.0 : -1.0) into -ABS(X). */ + (simplify + (mult:c @0 (cond (cmp @0 real_zerop) real_onep real_minus_onep)) + (if (!HONOR_SNANS (type) && !HONOR_SIGNED_ZEROS (type)) + (negate (abs @0)))) + /* Transform X * (X < 0 ? -1 : 1) into ABS(X). */ + /* Transform X * (X <= 0 ? -1 : 1) into ABS(X). */ + (simplify + (mult:c @0 (cond (cmp @0 integer_zerop) integer_all_onesp integer_onep)) + (abs @0)) + /* Transform X * (X < 0.0 ? -1.0 : 1.0) into ABS(X). */ + /* Transform X * (X <= 0.0 ? -1.0 : 1.0) into ABS(X). */ + (simplify + (mult:c @0 (cond (cmp @0 real_zerop) real_minus_onep real_onep)) + (if (!HONOR_SNANS (type) && !HONOR_SIGNED_ZEROS (type)) + (abs @0)))) + + /* X * 1, X / 1 -> X. */ (for op (mult trunc_div ceil_div floor_div round_div exact_div) (simplify Index: testsuite/gcc.dg/tree-ssa/mult-abs-1.c =================================================================== --- testsuite/gcc.dg/tree-ssa/mult-abs-1.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/mult-abs-1.c (working copy) @@ -0,0 +1,35 @@ +/* { dg-options "-O2 -fdump-tree-gimple" } */ +/* { dg-do compile } */ +int f(int x) +{ + return x * (x > 0 ? -1 : 1); +} +int f1(int x) +{ + return x * (x > 0 ? 1 : -1); +} +int g(int x) +{ + return x * (x >= 0 ? -1 : 1); +} +int g1(int x) +{ + return x * (x >= 0 ? 1 : -1); +} +int h(int x) +{ + return x * (x < 0 ? -1 : 1); +} +int h1(int x) +{ + return x * (x < 0 ? 1 : -1); +} +int i(int x) +{ + return x * (x <= 0 ? -1 : 1); +} +int i1(int x) +{ + return x * (x <= 0 ? 1 : -1); +} +/* { dg-final { scan-tree-dump-times "ABS" 8 "gimple"} } */ Index: testsuite/gcc.dg/tree-ssa/mult-abs-2.c =================================================================== --- testsuite/gcc.dg/tree-ssa/mult-abs-2.c (nonexistent) +++ testsuite/gcc.dg/tree-ssa/mult-abs-2.c (working copy) @@ -0,0 +1,35 @@ +/* { dg-options "-O2 -ffast-math -fdump-tree-gimple" } */ +/* { dg-do compile } */ +float f(float x) +{ + return x * (x > 0.f ? -1.f : 1.f); +} +float f1(float x) +{ + return x * (x > 0.f ? 1.f : -1.f); +} +float g(float x) +{ + return x * (x >= 0.f ? -1.f : 1.f); +} +float g1(float x) +{ + return x * (x >= 0.f ? 1.f : -1.f); +} +float h(float x) +{ + return x * (x < 0.f ? -1.f : 1.f); +} +float h1(float x) +{ + return x * (x < 0.f ? 1.f : -1.f); +} +float i(float x) +{ + return x * (x <= 0.f ? -1.f : 1.f); +} +float i1(float x) +{ + return x * (x <= 0.f ? 1.f : -1.f); +} +/* { dg-final { scan-tree-dump-times "ABS" 8 "gimple"} } */