From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id C5114385800C; Wed, 24 Nov 2021 23:22:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C5114385800C From: "segher at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug target/102239] powerpc suboptimal boolean test of contiguous bits Date: Wed, 24 Nov 2021 23:22:58 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: target X-Bugzilla-Version: 11.2.1 X-Bugzilla-Keywords: missed-optimization X-Bugzilla-Severity: normal X-Bugzilla-Who: segher 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: Wed, 24 Nov 2021 23:22:58 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D102239 --- Comment #3 from Segher Boessenkool --- (In reply to luoxhu from comment #2) > (In reply to Segher Boessenkool from comment #1) > > Confirmed. > >=20 > > So the relevant insn > >=20 > > (parallel [(set (reg:CC 123) > > (compare:CC (and:DI (reg:DI 124) > > (const_int 25769803776 [0x600000000= ])) > > (const_int 0 [0]))) > > (clobber (scratch:DI))]) > >=20 > > is matched by *and3_2insn but not by any pattern that ends up as = just > > one insn. Not *and3_mask_dot, because that doesn't do a shift fi= rst, > > is just an AND and there are no machine insns to do that; but there is = no > > pattern for what we can do. > >=20 > > *rotl3_mask_dot cannot do this either; the base and the dot2 of t= hat > > cannot be done, they return a shifted result, but that doesn't matter f= or > > comparing it to 0. So we should add a specialised version. >=20 > Seems different with what you describe, in combine, it was combined to > anddi3_2insn_dot: >=20 > (insn 9 8 10 2 (parallel [ > (set (reg:CC 122) > (compare:CC (and:DI (reg:DI 123) > (const_int 25769803776 [0x600000000])) > (const_int 0 [0]))) > (clobber (scratch:DI)) > ]) "pr102239.c":3:6 210 {*anddi3_2insn_dot} > (expr_list:REG_DEAD (reg:DI 123) > (nil))) > (jump_insn 10 9 11 2 (set (pc) > (if_then_else (eq (reg:CC 122) > (const_int 0 [0])) > (label_ref 15) > (pc))) "pr102239.c":3:6 868 {*cbranch} > (expr_list:REG_DEAD (reg:CC 122) > (int_list:REG_BR_PROB 536870916 (nil))) >=20 >=20 >=20 > Then in pr102239.c.302r.split2, it is split by "*and3_2insn_dot" to > rotldi3_mask+lshrdi3_dot: >=20 > Splitting with gen_split_80 (rs6000.md:3721) >=20 > (insn 32 8 33 2 (set (reg:DI 3 3 [124]) > (and:DI (ashift:DI (reg:DI 3 3 [123]) > (const_int 29 [0x1d])) > (const_int -4611686018427387904 [0xc000000000000000]))) > "pr102239.c":3:6 236 {*rotldi3_mask} > (nil)) > (insn 33 32 10 2 (parallel [ > (set (reg:CC 100 0 [122]) > (compare:CC (lshiftrt:DI (reg:DI 3 3 [124]) > (const_int 29 [0x1d])) > (const_int 0 [0]))) > (clobber (reg:DI 3 3 [124])) > ]) "pr102239.c":3:6 281 {*lshrdi3_dot} > (nil)) >=20 >=20 > Why this difference happens? What difference? It is split by the same pattern that matched it, and that is the 2insn pattern. I'm not sure what problem you see? > 0x600000000 is not a valid mask for anddi3_2insn_dot: It should be though! > "(mode =3D=3D Pmode || UINTVAL (operands[2]) <=3D 0x7fffffff) > && rs6000_is_valid_2insn_and (operands[2], mode) > && !(rs6000_is_valid_and_mask (operands[2], mode) > || logical_const_operand (operands[2], mode))" >=20 >=20 > (gdb) p UINTVAL (operands[2]) <=3D 0x7fffffff > $84 =3D false But we have Pmode here so all is fine. > (gdb) p rs6000_is_valid_2insn_and (operands[2], E_DImode) > $85 =3D true > (gdb) p logical_const_operand (operands[2], E_DImode) > $86 =3D false > (gdb) p rs6000_is_valid_and_mask (operands[2], E_DImode) > $87 =3D false > (gdb) p Pmode > $88 =3D DImode Yes, and mode is DImode as well. My point is that we do not have any pattern that can recognise this that will end up as just one machine insn. anddi3_2insn_dot split to two machine insns, and it should: its name indicates we want that!=