From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 60579385DC2B; Sat, 24 Jul 2021 12:28:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 60579385DC2B From: "jakub at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug middle-end/78103] Failure to optimize with __builtin_clzl Date: Sat, 24 Jul 2021 12:28:42 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: middle-end X-Bugzilla-Version: 6.2.1 X-Bugzilla-Keywords: missed-optimization X-Bugzilla-Severity: normal X-Bugzilla-Who: jakub at gcc dot gnu.org X-Bugzilla-Status: NEW 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: Message-ID: In-Reply-To: References: 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: Sat, 24 Jul 2021 12:28:43 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D78103 --- Comment #8 from Jakub Jelinek --- I actually think this should be doable with combiner splitters. For the unsigned int findLastSet3(unsigned long x) { return x ? 8 * sizeof(unsigned long) - __builtin_clzl(x) : 0; } or unsigned int findLastSet4(unsigned int x) { return x ? 8 * sizeof(unsigned int) - __builtin_clz(x) : 0; } the combiner sees everything together, in the first case (parallel [ (set (reg:SI 84 [ ]) (minus:SI (const_int 64 [0x40]) (xor:SI (minus:SI (const_int 63 [0x3f]) (subreg:SI (clz:DI (reg/v:DI 85 [ x ])) 0)) (const_int 63 [0x3f])))) (clobber (reg:CC 17 flags)) ]) and in the latter case (parallel [ (set (reg/v:SI 85 [ x ]) (minus:SI (const_int 32 [0x20]) (xor:SI (minus:SI (const_int 31 [0x1f]) (clz:SI (reg/v:SI 85 [ x ]))) (const_int 31 [0x1f])))) (clobber (reg:CC 17 flags)) ]) so we just need to split it - into bsr and add 1 (of course only if !TARGET_LZCNT, otherwise it is defined even for 0 and we don't know that it will be UB on zero). For the #c0 findLastSet we don't know that, but again we should know that i= t is UB at zero when !TARGET_LZCNT and so we could first split (set (reg:DI 87 [ _1 ]) (xor:DI (sign_extend:DI (minus:SI (const_int 63 [0x3f]) (subreg:SI (clz:DI (reg/v:DI 85 [ x ])) 0))) (const_int 63 [0x3f]))) into bsr and xor (i.e. get rid of the sign extension, if it is UB at zero, = then we know clz will be in range 0 to 63 and sign extension or zero extension a= re the same and performed already when using the bs{q,l} instruction.=