From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id B201C3858D31; Mon, 20 Apr 2020 03:52:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B201C3858D31 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1587354733; bh=e/v7hUNdfdckzBbZhnVHd5MsINJBr1S/vRVtVAQTo6E=; h=From:To:Subject:Date:From; b=LQKGysez49TsLIzqWTQ58Qw98tXIrjFvO1QAnvXk385MWqT1NsDM+XL8rM54gy+uV zDrWIIxrFOM4ZZhdgayBcvYUWTw9BLc2CHxoiFz0Ey0p7wi5fnaBMFMTYhDucIqTbH 5i5ADke95YXI/bORSCOqkhbsMYHhVDUUA/C00J88= From: "z.zhanghaijian at huawei dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug rtl-optimization/94665] New: missed minmax optimization opportunity for if/else structure. Date: Mon, 20 Apr 2020 03:52:13 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: rtl-optimization X-Bugzilla-Version: 10.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: z.zhanghaijian at huawei dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Apr 2020 03:52:13 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D94665 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=EF=BC=8C for example: SUBROUTINE mydepart(vara,varb,varc,res) REAL, INTENT(IN) :: vara,varb,varc REAL, INTENT(out) :: res res =3D vara if (res .lt. varb) res =3D varb if (res .gt. varc) res =3D 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 n= ot 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 =3D 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 =3D 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?=