public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug rtl-optimization/94665] New: missed minmax optimization opportunity for if/else structure.
@ 2020-04-20  3:52 z.zhanghaijian at huawei dot com
  2020-04-20  6:43 ` [Bug rtl-optimization/94665] " pinskia at gcc dot gnu.org
                   ` (19 more replies)
  0 siblings, 20 replies; 21+ messages in thread
From: z.zhanghaijian at huawei dot com @ 2020-04-20  3:52 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94665

            Bug ID: 94665
           Summary: missed minmax optimization opportunity for if/else
                    structure.
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: z.zhanghaijian at huawei dot com
  Target Milestone: ---

Minmax optimization for fortran,
for example:

SUBROUTINE mydepart(vara,varb,varc,res)
      REAL, INTENT(IN) :: vara,varb,varc
      REAL, INTENT(out) :: res

      res = vara
      if (res .lt. varb)  res = varb
      if (res .gt. varc)  res = varc
end SUBROUTINE

on aarch64, compile with -O2 -S -funsafe-math-optimizations, the asm:

ldr     s2, [x0]
ldr     s0, [x1]
ldr     s1, [x2]
fcmpe   s2, s0
fcsel   s0, s0, s2, mi
fminnm  s1, s1, s0
str     s1, [x3]
ret

The second if statement is optimized to fminnm, but the first can not.

In fact, it can be optimized to:

ldr     s2, [x0]
ldr     s1, [x1]
ldr     s0, [x2]
fmaxnm  s1, s2, s1
fminnm  s0, s0, s1
str     s0, [x3]

My proposal: I tracked the generation of fminnm is done in
simplify_if_then_else. The reason why the first statement optimization is not
done is that the conditions are not met:
rtx_equal_p (XEXP (cond, 0), true_rtx) && rtx_equal_p (XEXP (cond, 1),
false_rtx).

The RTX:

(if_then_else:SF (lt (reg:SF 92 [ _1 ])
        (reg:SF 93 [ _2 ]))
    (reg:SF 93 [ _2 ])
    (reg:SF 92 [ _1 ]))

We can swap the true_rtx/false_rtx, and take the maximum.

the patch:

diff --git a/gcc/combine.c b/gcc/combine.c
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -6641,25 +6641,43 @@ simplify_if_then_else (rtx x)

   if ((! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
       && comparison_p
-      && rtx_equal_p (XEXP (cond, 0), true_rtx)
-      && rtx_equal_p (XEXP (cond, 1), false_rtx)
       && ! side_effects_p (cond))
-    switch (true_code)
-      {
-      case GE:
-      case GT:
-       return simplify_gen_binary (SMAX, mode, true_rtx, false_rtx);
-      case LE:
-      case LT:
-       return simplify_gen_binary (SMIN, mode, true_rtx, false_rtx);
-      case GEU:
-      case GTU:
-       return simplify_gen_binary (UMAX, mode, true_rtx, false_rtx);
-      case LEU:
-      case LTU:
-       return simplify_gen_binary (UMIN, mode, true_rtx, false_rtx);
-      default:
-       break;
+    {
+      int swapped = 0;
+      if (rtx_equal_p (XEXP (cond, 0), false_rtx)
+         && rtx_equal_p (XEXP (cond, 1), true_rtx))
+       {
+         std::swap (true_rtx, false_rtx);
+         swapped = 1;
+       }
+
+      if (rtx_equal_p (XEXP (cond, 0), true_rtx)
+         && rtx_equal_p (XEXP (cond, 1), false_rtx))
+       switch (true_code)
+         {
+         case GE:
+         case GT:
+           return simplify_gen_binary (swapped ? SMIN : SMAX,
+                                       mode, true_rtx, false_rtx);
+         case LE:
+         case LT:
+           return simplify_gen_binary (swapped ? SMAX : SMIN,
+                                       mode, true_rtx, false_rtx);
+         case GEU:
+         case GTU:
+           return simplify_gen_binary (swapped ? UMIN : UMAX,
+                                       mode, true_rtx, false_rtx);
+         case LEU:
+         case LTU:
+           return simplify_gen_binary (swapped ? UMAX : UMIN,
+                                       mode, true_rtx, false_rtx);
+         default:
+           break;
+         }
+
+      /* Restore if not MIN or MAX.  */
+      if (swapped)
+       std::swap (true_rtx, false_rtx);
       }

   /* If we have (if_then_else COND (OP Z C1) Z) and OP is an identity when its

Any suggestions?

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2020-04-23  1:08 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-20  3:52 [Bug rtl-optimization/94665] New: missed minmax optimization opportunity for if/else structure z.zhanghaijian at huawei dot com
2020-04-20  6:43 ` [Bug rtl-optimization/94665] " pinskia at gcc dot gnu.org
2020-04-20  6:45 ` segher at gcc dot gnu.org
2020-04-20  6:45 ` segher at gcc dot gnu.org
2020-04-20  6:47 ` pinskia at gcc dot gnu.org
2020-04-20  7:24 ` z.zhanghaijian at huawei dot com
2020-04-20  7:50 ` segher at gcc dot gnu.org
2020-04-20  8:12 ` z.zhanghaijian at huawei dot com
2020-04-20 11:09 ` segher at gcc dot gnu.org
2020-04-20 11:47 ` z.zhanghaijian at huawei dot com
2020-04-21  9:43 ` segher at gcc dot gnu.org
2020-04-21  9:44 ` segher at gcc dot gnu.org
2020-04-21 10:18 ` segher at gcc dot gnu.org
2020-04-21 10:38 ` z.zhanghaijian at huawei dot com
2020-04-21 10:51 ` z.zhanghaijian at huawei dot com
2020-04-21 11:02 ` z.zhanghaijian at huawei dot com
2020-04-21 17:42 ` segher at gcc dot gnu.org
2020-04-22  6:23 ` z.zhanghaijian at huawei dot com
2020-04-22 17:04 ` segher at gcc dot gnu.org
2020-04-23  1:07 ` z.zhanghaijian at huawei dot com
2020-04-23  1:08 ` z.zhanghaijian at huawei dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).